Skip to content

Detectors Documentation

Contains code documentation for pyhtools.Detectors

ARP spoof detector

Helps to detect ARP spoofing/poisoning attacks in the network

SpoofDetector

SpoofDetector class to detect Local MITM attacks

Source code in pyhtools\detectors\arp_spoof_detector.py
class SpoofDetector:
    '''
    SpoofDetector class to detect Local MITM attacks
    '''

    def __init__(self, interface: str) -> None:
        '''SpoofDetector class constructor

        Args:
            interface (str): network interface on which spoofing needs to be detected

        Returns:
            None
        '''
        self.interface = interface


    def get_mac(self, ip: str):
        '''returns mac address of the ip

        Args:
            ip (str): ip address of the string

        Returns:
            str: Mac address of the ip in the network
        '''
        arp_req = sp.ARP(pdst=ip)
        brdcst = sp.Ether(dst='ff:ff:ff:ff:ff:ff')

        packet = brdcst / arp_req
        responded_list = sp.srp(packet, timeout=1, verbose=False)[0]

        return str(responded_list[0][1].hwsrc)


    def check_spoof(self, packet) -> bool:
        '''checks if machine is under ARP/MITM attack

        Args:
            packet (scapy.Packet): sniffed scapy packet from the interface

        Returns:
            bool: True if ARP spoofing/poisoning detected else False
        '''
        if packet.haslayer(sp.ARP) and packet[sp.ARP].op == 2:
            try:
                real_mac = self.get_mac(packet[sp.ARP].psrc)
                response_mac = packet[sp.ARP].hwsrc
                if real_mac != response_mac:
                    print(
                        f"[!] ARP Spoof Detected! {response_mac} is imposter. {response_mac} is spoofing as {real_mac}")
            except IndexError:
                pass


    def start(self):
        '''captures and processes packets to check whether network is being attacked or not

        Args:
            None:

        Returns:
            None
        '''
        sp.sniff(iface=self.interface, store=False, prn=self.check_spoof)

__init__(interface)

SpoofDetector class constructor

Parameters:

Name Type Description Default
interface str

network interface on which spoofing needs to be detected

required

Returns:

Type Description
None

None

Source code in pyhtools\detectors\arp_spoof_detector.py
def __init__(self, interface: str) -> None:
    '''SpoofDetector class constructor

    Args:
        interface (str): network interface on which spoofing needs to be detected

    Returns:
        None
    '''
    self.interface = interface

check_spoof(packet)

checks if machine is under ARP/MITM attack

Parameters:

Name Type Description Default
packet scapy.Packet

sniffed scapy packet from the interface

required

Returns:

Name Type Description
bool bool

True if ARP spoofing/poisoning detected else False

Source code in pyhtools\detectors\arp_spoof_detector.py
def check_spoof(self, packet) -> bool:
    '''checks if machine is under ARP/MITM attack

    Args:
        packet (scapy.Packet): sniffed scapy packet from the interface

    Returns:
        bool: True if ARP spoofing/poisoning detected else False
    '''
    if packet.haslayer(sp.ARP) and packet[sp.ARP].op == 2:
        try:
            real_mac = self.get_mac(packet[sp.ARP].psrc)
            response_mac = packet[sp.ARP].hwsrc
            if real_mac != response_mac:
                print(
                    f"[!] ARP Spoof Detected! {response_mac} is imposter. {response_mac} is spoofing as {real_mac}")
        except IndexError:
            pass

get_mac(ip)

returns mac address of the ip

Parameters:

Name Type Description Default
ip str

ip address of the string

required

Returns:

Name Type Description
str

Mac address of the ip in the network

Source code in pyhtools\detectors\arp_spoof_detector.py
def get_mac(self, ip: str):
    '''returns mac address of the ip

    Args:
        ip (str): ip address of the string

    Returns:
        str: Mac address of the ip in the network
    '''
    arp_req = sp.ARP(pdst=ip)
    brdcst = sp.Ether(dst='ff:ff:ff:ff:ff:ff')

    packet = brdcst / arp_req
    responded_list = sp.srp(packet, timeout=1, verbose=False)[0]

    return str(responded_list[0][1].hwsrc)

start()

captures and processes packets to check whether network is being attacked or not

Parameters:

Name Type Description Default
None required

Returns:

Type Description

None

Source code in pyhtools\detectors\arp_spoof_detector.py
def start(self):
    '''captures and processes packets to check whether network is being attacked or not

    Args:
        None:

    Returns:
        None
    '''
    sp.sniff(iface=self.interface, store=False, prn=self.check_spoof)

Win Block USB

Blocks all root hubs on windows machine

block_root_hubs()

Blocks USB root hubs on windows machine

Returns:

Type Description

None

Source code in pyhtools\detectors\win_block_usb.py
def block_root_hubs():
    '''Blocks USB root hubs on windows machine

    Args:
        None

    Returns:
        None
    '''
    res, rcode = run_cmd(
        cmd='pnputil /enum-devices /class "USB"',
        succ_msg='Fetched USB devices ids list',
        err_msg='Error occurred while device ids list',
    )

    if rcode == 0:
        for line in res.splitlines():
            if "USB\ROOT_HUB" in line:
                device_id = line.split(':')[-1].strip()
                res, rcode = run_cmd(
                    cmd=f'pnputil /disable-device "{device_id}"',
                    succ_msg=f'USB {device_id} blocked',
                    err_msg=f'Cannot disable USB {device_id}'
                )

run_cmd(cmd, succ_msg, err_msg, succ_rcode=0)

Run shell commands

Parameters:

Name Type Description Default
cmd str

command to be executed

required
succ_msg str

message to be logged if cmd is executed successfully

required
err_msg str

message to be logged if cmd is interrupted

required
succ_rcode int

return status code after successfully executing code

0

Returns:

Name Type Description
tuple tuple

returns executed command output/error along with status code

Source code in pyhtools\detectors\win_block_usb.py
def run_cmd(cmd:str, succ_msg:str, err_msg:str, succ_rcode:int=0) -> tuple:
    '''Run shell commands

    Args:
        cmd (str): command to be executed
        succ_msg (str): message to be logged if cmd is executed successfully
        err_msg (str): message to be logged if cmd is interrupted
        succ_rcode (int): return status code after successfully executing code

    Returns:
        tuple: returns executed command output/error along with status code
    '''
    result = run(split(cmd), stderr=PIPE, stdout=PIPE)
    res = result.stdout.decode('utf-8') or result.stderr.decode('utf-8')
    rcode = result.returncode

    if rcode == succ_rcode:
        logger.info(succ_msg)
    else:
        logger.error(err_msg)

    return (res, rcode)