Python套接字.accept()未接收任何连接请求

Python套接字.accept()未接收任何连接请求,python,linux,sockets,proxy,Python,Linux,Sockets,Proxy,我最近买了Justin Seitz的《黑帽Python》一书,因为我对Python和网络安全感兴趣 我在Kali Linux中工作,书中的一个例子是一个简单的TCP代理。我已经编写了一些通过端口连接的脚本,但现在我在尝试创建到远程服务器(如Google)的连接时遇到了问题 现在,我承认我是Python的完全新手。我主要是用C++编程的。作为公开,我确实将main()函数移到了代码的顶部,以便按照执行顺序进行组织。在实际震源中,它位于最底部 import sys import socket imp

我最近买了Justin Seitz的《黑帽Python》一书,因为我对Python和网络安全感兴趣

我在Kali Linux中工作,书中的一个例子是一个简单的TCP代理。我已经编写了一些通过端口连接的脚本,但现在我在尝试创建到远程服务器(如Google)的连接时遇到了问题

现在,我承认我是Python的完全新手。我主要是用C++编程的。作为公开,我确实将main()函数移到了代码的顶部,以便按照执行顺序进行组织。在实际震源中,它位于最底部

import sys
import socket
import threading
import time
import os

def main():
    if len(sys.argv[1:]) != 5:
        print "Usage: nproxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]"
        print "Example: nproxy.py 127.0.0.1 5555 ftp.example.com 5555 True"
        sys.exit(0)

    #setup listening parameters
    local_host = sys.argv[1]
    local_port = sys.argv[2]
    #setup remote target
    remote_host = sys.argv[3]
    remote_port = sys.argv[4]
    #this tells our proxy to connect and receive data before sending to the remote host
    receive_first = sys.argv[5]

    if "True" in receive_first:
        receive_first = True
    else:
        receive_first = False
从这里开始的一切都是main()函数,它将解析并设置所有参数和变量

    #spin listening socket
    server_loop(local_host, local_port, remote_host, remote_port, receive_first)

#status class for my timeout function to stop the socket.accept()
class status:
    connected = False
server_loop()函数是我的问题的源函数。它包含将客户端连接到服务器的所有代码

第一部分只是设置我的服务器套接字以及为我自己创建一些执行快捷方式

def server_loop(local_host, local_port, remote_host, remote_port, receive_first):
    #setup server socket
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    if "@" in local_host:
        local_host = "127.0.0.1"

    if "@" in local_port:
        local_port = remote_port

    local_addr = (local_host, int(local_port))
    remote_addr = (remote_host, int(remote_port))
将服务器绑定到我的本地地址就可以了。我认为,问题是在while循环中开始的

    try:
        server.bind(local_addr)
    except:
        print "[!!] Failed to listen on %s:%d" % local_addr
        print "[!!] Check for other listening sockets or correct permissions."
        sys.exit(0)

    print "[*] Listening on %s:%d" % local_addr
    server.listen(5)
这里启动while循环以保持程序打开以处理传入连接。tout线程包含超时和关闭服务器套接字的代码

    while True:
        tout = threading.Thread(target=timeout, args=(local_host, local_port))
        tout.start()
        print "[*] Connecting..."
这似乎是我的程序挂起的地方。你看,我不是100%确定这应该如何处理。在这本书中,代码对他来说运行良好,并将成功地从server.accept()返回,并将客户机_套接字连接到正确的地址

然而,在我的执行过程中,程序在accept()函数处停止,并且从不返回任何套接字或地址数据。除非我对accept()函数的理解是错误的,并且代码设计时没有考虑远程服务器

我甚至不完全确定accept()函数是如何工作的。它是否向主机发送SYN数据包以启动连接请求,或者该函数只是坐在那里等待,以为主机将在根本没有发送SYN的情况下发送SYN-ACK返回

        client_socket, addr = server.accept()

        #The timeout function is designed to close the server by feeding     
        #it the localhost address. If this happens, the statement below catches the 
        #program and calls that the server request has timed out.

        if "127.0.0.1" in addr[0]:
            print "[!!] Server connection has timed out."
            sys.exit(0)
        #print out the local connection information
        status.connected = True
        print "[==>] Received incoming connection from %s:%d" % (addr[0], addr[1])

        #start a thread to talk to the remote host
如果server.accept()正常返回,则客户端_套接字将连接到主机,并在正常发送和接收数据时初始化代理的其余部分。代码的其余部分是为了完成,以防我遗漏了一些实际上是导致失败的关键因素

        proxy_thread = threading.Thread(target=proxy_handler, args=(client_socket, remote_addr, receive_first))
        proxy_thread.start()

def timeout(local_host, local_port):
    t = 5
    while True:
        if status.connected is True:
            break
        if t <= 0:
            wake = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            wake.connect((local_host, int(local_port)))
            break
        time.sleep(0.1)
        t-=0.1


def proxy_handler(client_socket, remote_host, remote_port, receive_first):
    #connect to the remote host
    remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    remote_socket.connect(remote_addr)

    if receive_first:
        remote_buffer = receive_from(remote_socket)
        hexdump(remote_buffer)

        #send it to our response handler
        remote_buffer = response_handler(remote_buffer)

        #if we have data to send to our local client, send it
        if len(remote_buffer):
            print "[<==] Sending %d bytes to localhost." % len(remote_buffer)
            client_socket.send(remote_buffer)

    #now let's loop and read from local
    #send to remote, send to local
    #rinse and repeat
    while True:
        #read from localhost
        local_buffer = receive_from(client_socket)
        if len(local_buffer):
            print "[==>] Received %d bytes from localhost." % len(local_buffer)
            hexdump(local_buffer)

            #send it to our request handler
            local_buffer = request_handler(local_buffer)

            #send off the data to the remote host
            remote_socket.send(local_buffer)
            print "[==>] Sent to remote."

        #receive back a response
        remote_buffer = receive_from(remote_socket)

        if len(remote_buffer):
            print "[<==] Received %d bytes from remote" % len(remote_buffer)
            hexdump(remote_buffer)

            #send to our response handler
            remote_buffer = response_handler(remote_buffer)

            #send the response to the local socket
            client_socket.send(remote_buffer)
            print "[<==] Sent to localhost."

        #if no more data on either side, close the connection
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()
            print "[*] No more data. Closing connections..."
            break

def hexdump(src, length=16):
    result = []
    digits = 4 if isinstance(src, unicode) else 2
    for i in xrange(0, len(src), length):
        s = src[i:i+length]
        hexa = b' '.join(["%0*X" % (digits, ord(x)) for x in s])
        text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
        result.append(b"%04X   %-*s   %s" % (i, length*digits + 1), hexa, text)
    print b'\n'.join(result)

def receive_from(connection):
    buffer = ""

    #we set a 2 second timeout; depending on your target, this may need to be adjusted
    connection.settimeout(2)

    try:
        #keep reading into the buffer until there's no more data or we time out
        while True:
            data = connection.recv(4096)
            if not data:
                break
            buffer += data
    except:
        pass
    return buffer

#modify any requests destined for remote host
def request_handler(buffer):
    #perform packet modifications
    return buffer

#modify any responses destined for the localhost
def response_handler(buffer):
    #perform packet modification
    return buffer

main()
proxy\u-thread=threading.thread(target=proxy\u-handler,args=(客户端\u套接字,远程\u-addr,接收\u-first))
proxy_thread.start()
def超时(本地_主机、本地_端口):
t=5
尽管如此:
如果status.connected为True:
打破

如果程序按预期运行,尽管
hexdump
中的格式字符串无效,并且
proxy\u handler
应该是
proxy\u handler(客户端套接字、远程地址、首先接收)
。我还禁用了超时,因为我在本地使用代理,我不希望请求关闭它。以以下方式使用它对我很有用:

# Start proxy on local port 12345 and route to google
$ python @ 12345 www.google.com 80 True

# In another terminal, request from the server
# This should print the same as `curl www.google.com`
$ curl 127.0.0.1:1235
我认为你误解了这应该做什么。这句话是最主要的原因

然而,在我的执行过程中,程序在accept()函数处停止,并且从不返回任何套接字或地址数据。除非我对accept()函数的理解是错误的,并且代码设计时没有考虑远程服务器

首先,我要说套接字上的方法基本上是围绕相应C函数的薄型包装,使用
man2socket
man2accept
了解python文档可能提供的更多细节


不过为了回答您的问题,
accept()
正在阻塞,因为没有客户端。它正在等待另一个程序向其打开的套接字发送SYN数据包,并用SYN | ACK响应。这部分内容都与连接到代理的客户端有关,您似乎认为它与远程主机有关。

这是一个非常好的信息。非常感谢你。我现在不在电脑旁。但我会做必要的调整,然后再回来看看结果。总的来说,信息量很大。我想服务器套接字等待syn数据包而不是发送syn数据包更有意义。说到远程主机,我指的是我试图请求连接的服务器。在这个测试用例中,google.com。对网络还是相当陌生的。绝对完美!非常感谢你。现在我似乎明白它在做什么了。proxy_处理程序基本上只是一个服务器,但它要求我从客户机向代理打电话,以便实际将请求传送到Google。非常感谢你。