1

I am using the following function to implement a program that changes its behavior depending on the IP of the connected PC.
There is a problem with this function that if something tries to login and fails, it may get the IP of the failed one.
And now that we've encountered that possibility, the program is broken.
What edits do I need to make to make this function behave as expected?

import psutil

def get_ip(port=3389):
    ip = ""
    for x in psutil.net_connections():
        if x.status == "ESTABLISHED" and x.laddr.port == port:
            ip = x.raddr.ip
            break
Simon Macy
  • 11
  • 3
  • 1
    I think you generally need different approach. Better approach would be to wait to successful event logon as it contains all the login info as per this article : https://ponderthebits.com/2018/02/windows-rdp-related-event-logs-identification-tracking-and-investigation/ You want to read specific events detailed in that article some way like this : https://stackoverflow.com/questions/11219213/read-specific-windows-event-log-event – Bijay Regmi Feb 24 '22 at 14:22
  • Thanks for the info. There are so many approaches. What I'm struggling with now looking at the links is how to take out only the successful ones from any point in time. As I should not process multiple times for the same logon. – Simon Macy Feb 24 '22 at 16:14
  • I just realized that I can't run it without admin rights... – Simon Macy Feb 24 '22 at 17:05
  • I changed the detection to use event 4624 and event 40. I don't understand if this is the right number, but so far it's working as intended. This conversation has not been posted as an answer, but what should I do? – Simon Macy Mar 01 '22 at 07:36
  • Post relevant part of your code yourself and mark it as an answer. Glad it worked for you. – Bijay Regmi Mar 01 '22 at 09:38

1 Answers1

0

I changed the function based on Bijay Regmi's comment. Thank you. wmi was difficult for me, so I used win32evtlog to read it out little by little. I am working on improving readability and finding bugs little by little.

    def systime(xml):
        return datetime.fromisoformat(xml.find(f'{ns}System/{ns}TimeCreated').get('SystemTime')[:-2] + "+00:00")

    def last_event(handle,
                   event_id,
                   condition: Callable[['Event'], bool] = None) -> Optional['Event']:
        now = datetime.now(tz=timezone.utc)
        while True:
            events = win32evtlog.EvtNext(handle, 20)
            if not events:
                break
            for event in events:
                xml_content = win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml)
                obj = Event(ET.fromstring(xml_content))
                if obj.EventID == event_id:
                    if obj.SystemTime + timedelta(minutes=5) < now:
                        return None
                    if condition and not condition(obj):
                        continue
                    return obj

    class Event:
        def __init__(self, xml: ET.Element):
            self.EventID = xml and xml.find(f'{ns}System/{ns}EventID').text
            self.SystemTime = xml and systime(xml)
            self.xml = xml
            if self.EventID == '24':
                self.IpAddress = xml.find(f'{ns}UserData/{{Event_NS}}EventXML/{{Event_NS}}Address').text
            elif self.EventID == '4624':
                self.IpAddress = xml.find(f'{ns}EventData/{ns}Data[@Name="IpAddress"]').text
            else:
                self.IpAddress = None
Simon Macy
  • 11
  • 3