依旧是Python黑帽子这本书
先附上代码,我在原书代码上加了注释,更好理解
python
import sys
import socket
import threading
#生成可打印字符映射
HEX_FILTER=''.join(
[(len(repr(chr(i)))==3) and chr(i) or '.' for i in range(256)])
#接收bytes或string类型的输入,并将其转换为十六进制格式输出
#数值存储
def hexdump(src,length=16,show=True):
if isinstance(src,bytes):
src=src.decode()
results=list()
for i in range(0,len(src),length):
word=str(src[i:i+length])
printable=word.translate(HEX_FILTER)
hexa=' '.join([f'{ord(c):02X}' for c in word])
hexwidth=length*3
results.append(f'{i:04x} {hexa:<{hexwidth}} {printable}')
if show:
for line in results:
print(line)
else:
return results
#接收本地或远程数据
def receive_from(connection):
buffer=b""
connection.settimeout(5)
try:
while True:
data=connection.recv(4096)
if not data:
break
buffer +=data
except Exception as e:
pass
return buffer
#数据处理函数
#预留数据修改的钩子,可以在这里修改客户端请求或服务器响应
def request_handler(buffer):
return buffer
def response_handler(buffer):
return buffer
#代理处理,负责处理客户端与远程服务器间的通信,是代理的核心
def proxy_handler(client_socket,remote_host,remote_port,receive_first):
#创建远程连接
remote_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建TCP连接
remote_socket.connect((remote_host,remote_port))#连接到远程服务器
#接收远程服务器数据
if receive_first:
remote_buffer=receive_from(remote_socket)
hexdump(remote_buffer)
#处理服务器返回数据
remote_buffer=response_handler(remote_buffer)
if len(remote_buffer):
print("[<==] Sending %d bytes to localhost." % len(remote_buffer))
client_socket.send(remote_buffer)
#循环监听客户端与服务器间的通信,直到连接关闭
while True:
#处理客户端数据
local_buffer=receive_from(client_socket)#读取数据
if len(local_buffer):
line= "[==>]Received %d bytes from localhost." % len(local_buffer)
print(line)#打印数据
hexdump(local_buffer)
local_buffer=request_handler(local_buffer)#数据修改
remote_socket.send(local_buffer)#转发给远程服务器
print("[==>]Sent to remote.")
#处理远程服务器返回的数据
remote_buffer=receive_from(remote_socket)
if len(remote_buffer):
print("[<==] Received %d bytes from remote." % len(remote_buffer))
hexdump(remote_buffer)
remote_buffer=response_handler(remote_buffer)
client_socket.send(remote_buffer)
print("[<==] Sent to localhost.")
#关闭连接
if not len(local_buffer) or not len(remote_buffer):
client_socket.close()
remote_socket.close()
print("[*] No more data. Closing connections.")
#服务器监听
def server_loop(local_host, local_port, remote_host, remote_port, receive_first):
#创建socket并绑定端口
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
server.bind((local_host, local_port))
except Exception as e:
print('problem on bind: %r' % e)
print("[!!] Failed to listen on %s:%d" % (local_host, local_port))
print("[!!] Check for other listening sockets or correct permissions.")
sys.exit(0)
#监听并等待客户端连接
print("[*] Listening on %s:%d" % (local_host, local_port))
server.listen(5)
while True:
#处理客户端连接
client_socket, addr = server.accept()
#输出连接信息
line = "> Received incomming connection from %s:%d" % (addr[0], addr[1])
print(line)
#启动代理线程
proxy_thread = threading.Thread(
target=proxy_handler,
args=(client_socket, remote_host,
remote_port, receive_first)
)
proxy_thread.start()
def main():
if len(sys.argv[1:]) != 5:
print("Usage: ./proxy.py [localhost] [localport]", end='')
print("[remotehost] [remoteport] [receive_first]")
print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
sys.exit(0)
local_host = sys.argv[1]
local_port = int(sys.argv[2])
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
receive_first = sys.argv[5]
if "True" in receive_first:
receive_first = True
else:
receive_first = False
#启动服务器
server_loop(local_host, local_port, remote_host, remote_port, receive_first)
if __name__ == '__main__':
main()
windows物理机和kali我都试了,不知道为什么只有kali能用
python
sudo python TCP_proxy.py 192.168.65.128 8887 www.baidu.com 80 True

再另起一个终端,输入:
python
curl -x 192.168.65.128:8887 www.baidu.com

这时候我们的脚本就会接收到数据,并以hex的形式输出
本来原书用的是ftp,但是我怎么也复现不出来,只能简单用这个代替一下的,但是原理也差不了太多
但是我发现这个似乎不太稳定,我也是试了两次才成功的
还有个问题就是程序没加入ctrl+c退出的功能,虽然我也懒得加了喵(