#我的武器库系列#之TCP代理实现

8 篇文章 0 订阅
0 篇文章 0 订阅

       本文通过python实现了TCP代理,TCP代理可以在业务性能、安全防护及渗透攻击多个场景下使用,本文中更多解决是针对特殊环境导致我们不能安装wireshark,而又需要对数据包进行分析的场景。正常情况下客户端直接请求服务端,而TCP代理是加入了代理层,客户端请求代理层,代理层再请求服务端,代理层起到了承上启下的作用。

一、代码实现     

#!/usr/bin/python3.6
#coding:utf-8
import sys;
import socket;
import threading;

local_host = "";#源
local_port = "";#源端口
remote_host = "";#目标
remote_port = "";#目标端口
receive_first = True; #是否显示第一个数据包

#十六进制数据输出
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 = "";
    #设置10秒超时。
    connection.settimeout(2);
    try:
        while True:
             data = connection.recv(4096);#获取数据
             buffer +=data;
             if not data:
                 break;
    except Exception as e:
        print("获取数据失败");
        #print(e);
        pass;
    return buffer;

#可用于数据包处理-发送给远程
def response_handler(remote_buffer):
    return remote_buffer;

#可用于数据包处理-发送给本地
def request_handle(local_buffer):
    return local_buffer;

#TCP代理连接
def proxy_handler(client_socket):
    global remote_host;
    global remote_port;
    global receive_first;
    remote_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
    remote_socket.connect((remote_host,int(remote_port)));
    print(receive_first);
    if receive_first:
        remote_buffer = receive_from(remote_socket);#从远程主机接收数据
        hexdump(remote_buffer); #输出远程数据
        remote_buffer = response_handler(remote_buffer);
        if len(remote_buffer):
            print("<==远程向本地主机发送%d字节" % len(remote_buffer));
            client_socket.send(remote_buffer);#发送给客户端
    #remote_server.recv(4096);
    while True:
        #读取本地数据发送至远程
        local_buffer = receive_from(client_socket); 
        if len(local_buffer):
            print("==>本地主机接收远程%d字节" % len(local_buffer));
            hexdump(local_buffer);
            local_buffer = request_handle(local_buffer);
            remote_socket.send(local_buffer);
            print("<==发送数据至远程");
        #读取远程数据发送至本地
        remote_buffer = receive_from(remote_socket);
        if len(remote_buffer):
            print("==>接收远程数据 %d 字节" % len(remote_buffer));
            hexdump(remote_buffer);
            remote_buffer = response_handler(remote_buffer);#可用于业务处理
            client_socket.send(remote_buffer);
            print("<==发送数据至本地");
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close();
            remote_socket.close();
            print("没有数据,关闭连接");
            break;#跳出while循环

#服务端
def server_loop():
    global local_host;
    global local_port;
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
    try:
        server.bind((local_host,int(local_port)));
    except Exception as e:
        print("创建服务端错误");
        print(e);
        sys.exit(0);
    server.listen(5);#最大连接次数
    while True:
       client_socket,addr = server.accept();#监听连接,返回socket及连接信息
       print("==>连接信息,来自 %s:%d" % (addr[0],addr[1]));
       proxy_handle = threading.Thread(target=proxy_handler,args=(client_socket,));
       proxy_handle.start();

#主方法
def main():
    #判断是否输入正确
    global local_host;
    global local_port;
    global remote_host;
    global remote_port;
    global receive_first;
    if len(sys.argv[1:]) != 5:
        print("输入参数有误:./tcpproxy.py [local_host] [localhost_port] [remote_host] [remote_port] [receive_first]");
        sys.exit(0);
    local_host = sys.argv[1]; 
    local_port = sys.argv[2];
    remote_host = sys.argv[3];
    remote_port = sys.argv[4];
    receive_first = sys.argv[5]; #告诉代理在发送给远程主机之前连接和接收数据
    if "True" in receive_first:
        receive_first = True;
    else:
        receive_first = False;
    server_loop();#启动服务端
main();

效果图如下:

ftp连接:

tcp代理输出:

可以看到,我们将ftp连接的数据包信息进行了打印,同时我们可以看到ftp连接登录时的敏感信息。

 

二、如何使用

  我们可以通过 sudo python tcpproxy.py 127.0.0.1 21 192.168.1.104 21 True   方式来进行使用,127.0.0.1为代理地址,192.168.1.104为目标地址。

三、场景扩展

       我们可以对tcp代理进一步完善,源代码中response_handler与request_handle两个方法可以进行数据包处理(文中只实现tcp代码的核心功能,未对两方法进行完善),我们可以通过匹配00 00 00 0a识别为mysql,通过00 00 01 00 00 00 来识别为oracle,通过匹配46 54 50 20 53 65 72 76 69 63 65来识别为ftp协议,近一步通过匹配 55 53 45 52 可以提取ftp中的用户名。通过匹配50 41 53 53提取ftp中的密码(你懂得,有些工具的自动提取)等等,总之可以做的事情非常多,在此不不一一列举。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

登峰造Geek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值