pythonpython-3.xnetwork-programmingscapysniffing

scapy sniff function doesnt seem to work in moniter mode?


I'm trying to write a packet sniffer that will take an interface and a regex expresion as optional parameter and search the sniffed packets for matches, but it seems to not be able to sniff packets at all, The whole code is:

#!/home/khaled/PycharmProjects/networking/venv/bin/python3
# A regular expresion finder

from scapy.all import *
import re
import os
import argparse
import subprocess
import sys

def test(num):
    num = num.sprintf('%Raw.load%')
    print("Packet Data: {}".format(num))
    res = re.findall("TESTING", num)


def parser():
    parser = argparse.ArgumentParser(usage="command -i <interface>",
                                     description="Listen for incoming traffic on specified interface for specified"
                                                 "regex expresion")
    parser.add_argument("-i", help="The interface to listen on", dest="interface", required=True)
    parser.add_argument("-r", help="regex expresion to look for", dest="regex", required=False, default=False)
    env = parser.parse_args()
    global interface
    global regex
    interface = env.interface
    regex = env.regex

def start_sniff(interface):
    # Check if a
    print(conf.iface)
    print("[+] Started Sniffing For regex in HTTP data at interface {}".format(interface))
    sniff(prn=test, filter="tcp", iface=interface, count=0, monitor=True)


def start_moniter_interface(iface):

    try:
        # subprocess.run(['airmon-ng', "check", "kill"], check=True)
        rslt = subprocess.run(["airmon-ng", "start", iface], check=True, capture_output=True)
    except subprocess.CalledProcessError as e:
        print("[+] Error Has Occurred when putting Interface in monitor mode {}".format(e.stderr))
        sys.exit(1)
    else:
        print("[+] Started interface in moniter mode")
        interface_name = re.findall("wlp[0-9a-z]+mon", rslt.stdout.decode("utf-8"))[0]
        print("[+] Found interface Name is {}".format(interface_name))
        if interface_name:  # Found interface name
            return interface_name
        else:               # Else Run iwconfig
            # nfig manually
            print("Unable to determine interface name")
            print("Run iwconfig and rerun script with new interface name")
            sys.exit(1)


def main():
    parser()

    if os.getuid() != 0:    # Not running as root run with sudo
        print("Error Need to run script as root, run with sudo")
        sys.exit(1)
    else:   # running as root
        result = subprocess.run(["iwconfig", interface], capture_output=True, check=True)
        if "mode:moniter" in result.stdout.decode("utf-8").lower(): # Check Moniter mode
            start_sniff(interface)
        else:   # Else start Interface in moniter mode then sniff for packets
            moniter_interface = start_moniter_interface(interface)
            start_sniff(moniter_interface)


if __name__ == "__main__":
    main()

It uses airmon to put network card in monitor mode then use iwconfig to grab name of card after being put in monitor mode. The regular expression passed by user is ignored for now. The test function doesn't seem to be called at all which I dont know why since sniff function seems to work when wireless card is in managed mode. It just hang at doing nothing

[+] Started Sniffing For regex in HTTP data at interface wlp2s0mon

sniff function called as:

    sniff(prn=card_type, filter="tcp", iface=interface, count=0, monitor=True)

also running iwconfig shows that network card is in monitor mode.


Solution

  • You are filtering for tcp on kernel level using BPF filter. I bet that you sniff from a WPA2 protected network, meaning that payload in 802.11 (Wi-Fi) frame is encrypted, so you can't actually take a look inside a frame. I suggest trying to sniff without monitor mode at all, so you capture regular 802.3 Ethernet frames and not raw 802.11 with as I mentioned payload encrypted.