Python开发流量代理工具(内网穿透)
C:\out>dnf.exe -h
██████╗ ███╗ ██╗███████╗ ██████╗███████╗
██╔══██╗████╗ ██║██╔════╝ ██╔════╝██╔════╝
██║ ██║██╔██╗ ██║█████╗█████╗██║ ███████╗
██║ ██║██║╚██╗██║██╔══╝╚════╝██║ ╚════██║
██████╔╝██║ ╚████║██║ ╚██████╗███████║
╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═════╝╚══════╝
-h 查看帮助 by 0x6a0x71
-s 服务端模式
-c 客户端模式
usage: dnf.exe [-h] [-key KEY] [-s] [-c] [-srh SRH] [-srp SRP] [-slh SLH] [-slp SLP] [-crh CRH] [-crp CRP] [-clh CLH]
[-clp CLP] [-llp1 LLP1] [-llp2 LLP2] [-cm {r,l}]
DNF流量代理工具
optional arguments:
-h, --help show this help message and exit
-key KEY 自定义密钥,可以随机生成,注:服务端必须与客户端一致,密钥为16位【A-Za-z0-9+/=】字符【默认随机】
-s 服务端模式
-c 客户端模式
服务端:
通常放置在服务器上,若以下端口都已开启,可直接x.exe -s【例如:代理内网3389,可直接在服务端连接127.0.0.1:8002访问】
-srh SRH 远程连接地址【默认:0.0.0.0】
-srp SRP 远程连接端口【默认:5050】
-slh SLH 本地查看地址【默认:127.0.0.1】
-slp SLP 本地查看端口【默认:8002】
客户端:
通常放置在内网机器上(可出网)【例如:代理3389到服务器,可直接x.exe -c -crh x.x.x.x(服务器地址) -clp 3389】
-crh CRH 远程连接地址【默认:127.0.0.1】
-crp CRP 远程连接端口【默认:5050】
-clh CLH 本地代理地址【默认:127.0.0.1】
-clp CLP 本地代理端口【默认:80】
-llp1 LLP1 本地代理模式,本地原端口【默认:80】
-llp2 LLP2 本地代理模式,映射端口【默认:5050】
-cm {r,l} 代理类型,r:远程连接代理,l:本地端口代理【默认r】
这是工具的使用说明
现在的目标是把本地的80服务(http)代理到公网上进行访问
流量路径
127.0.0.1:80 -> xx.xx.xx.xx:5050 -> xx.xx.xx.xx:8002
本地80服务
key值:0r+mS7C4UnH/zhG8
import argparse
import socket
BUFFSIZE = 1024
MAX_LISTEN = 32
CODING = "ISO-8859-1"
import base64
import random
key_num = 16
kill_sokcet_list =[]
max_out_time = 30
key_table = "0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
class My_lock:
def OR_key(self):
pass
def encrypt_random(self,text,key):
pass
def decrypt_random(self,text,key):
pass
def _recv_data(socketi):
"""
接收服务端数据
:return: 接收服务端数据-ERROR=None
"""
global kill_sokcet_list
data = b''
while True:
try:
socketi.settimeout(10) # 设置超时时间为10s超过10s判定为服务端没有返回状态,未收到数据
recv_data = socketi.recv(BUFFSIZE)
if len(recv_data) > 0:
if len(recv_data) < BUFFSIZE:
data += recv_data
break
else:
data += recv_data
else:
break
except Exception as e:
kill_sokcet_list.append(1)
print(f"Loading... {str(e)}:{len(kill_sokcet_list)}")
if len(kill_sokcet_list) == max_out_time:
return None
# print(e.__traceback__.tb_frame.f_globals["__file__"]) # 发生异常所在的文件
# print(e.__traceback__.tb_lineno) # 发生异常所在的行数
return b"" # 出现异常返回None
print(f"DATA::{data}")
kill_sokcet_list.clear()
if len(data) != 0:
return data
else:
return b"" # 非异常无数据,返回空字符串
# 远程代理
def tcpServer3(ADDR,ADDR2,KEY):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM,proto=0) as rs: #远程
# 绑定服务器地址和端口
while True:
try:
rs.connect(ADDR)
print("等待远程请求回复...")
rrec = _recv_data(rs)
# rrec = rs.recv(BUFFSIZE)
print(f"rrec={rrec}")
dc_rrec = LOCK.decrypt_random(rrec.decode(),KEY) # 解密远程回复 2:解密服务器返回的数据
print(f"\ndc_rrec={dc_rrec}")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM,proto=0) as ls: #本地
while True:
ls.connect(ADDR2)
ls.sendall(dc_rrec)
lrec = _recv_data(ls)
# lrec = ls.recv(BUFFSIZE)
print(f"lrec={lrec}")
# key = LOCK.out_key(lrec.decode(CODING)) # 加密本地回复
ec_lrec = LOCK.encrypt_random(lrec, KEY).encode() # 4
print(f"\nec_lrec={ec_lrec}")
ls.close()
rs.sendall(ec_lrec) # 发送加密后给远程回复
except Exception as e:
print(e)
print(e.__traceback__.tb_frame.f_globals["__file__"]) # 发生异常所在的文件
print(e.__traceback__.tb_lineno) # 发生异常所在的行数
break
rs.close()
# 本地代理
def tcpServer2(ADDR,ADDR2):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM,proto=0) as s:
# 绑定服务器地址和端口
s.bind(ADDR)
# 启动服务监听
s.listen(MAX_LISTEN)
print('等待用户接入')
while True:
try:
# 等待客户端连接请求,获取connSock
conn, addr = s.accept()
print('远端客户:{} 接入系统!!!'.format(addr))
with conn:
while True:
print('接收请求信息')
# 接收请求信息
data = conn.recv(BUFFSIZE)
print('data=%s' % data)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM,proto=0) as rs:
rs.connect(ADDR2)
rs.send(data)
rec = rs.recv(BUFFSIZE)
print(rec)
rs.close()
conn.send(rec)
# 发送请求数据
except Exception as e:
print(e)
print(e.__traceback__.tb_frame.f_globals["__file__"]) # 发生异常所在的文件
print(e.__traceback__.tb_lineno) # 发生异常所在的行数
break
s.close()
def tcp1(ADDR2,ADDR,KEY):
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,proto=0) as rs:
rs.bind(ADDR2)
# 启动服务监听
rs.listen(MAX_LISTEN)
print('远程监听开启')
while True:
try:
# 等待客户端连接请求,获取connSock
rconn, raddr = rs.accept()
print(f'远程服务接入成功!{raddr}')
with rconn:
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,proto=0) as ls:
ls.bind(ADDR)
ls.listen(MAX_LISTEN)
print('本地监听开启')
while True:
lconn, laddr = ls.accept()
print(f"本地服务接入成功!{laddr}")
with lconn:
print("等待本地用户请求...")
ldata = _recv_data(lconn)
# ldata = lconn.recv(BUFFSIZE)
print(f"ldata={ldata}")
# key = LOCK.out_key(ldata.decode(CODING)) # 加密本地请求
ec_ldata = LOCK.encrypt_random(ldata,KEY).encode() # 1 :服务请求
print(f"\nec_ldata={ec_ldata}")
rconn.sendall(ec_ldata) # 加密后发送给远程
rdata =_recv_data(rconn)
# rdata = rconn.recv(BUFFSIZE)
print(f"rdata={rdata}")
dc_rdata = LOCK.decrypt_random(rdata.decode(),KEY) # 解密远程回复 3
print(f"\ndc_rdatac={dc_rdata}")
lconn.sendall(dc_rdata)
lconn.close()
ls.close()
rconn.close()
except Exception as e:
print(e)
print(e.__traceback__.tb_frame.f_globals["__file__"]) # 发生异常所在的文件
print(e.__traceback__.tb_lineno) # 发生异常所在的行数
break
rs.close()
def mx_key(key):
global key_table
if key == "Random":
ikey = LOCK.OR_key()
else:
okl = False
for i in key:
if i not in key_table:
okl = True
if len(set(key))!=len(key):
okl = True
if okl or len(key) != key_num:
print("密钥不符合规定16位(不同字符) 【A-Za-z0-9】已自动生成KEY")
ikey = 'ABCD12345678abcd'
else:
ikey = args.key
return ikey
if __name__ == '__main__':
print('''██████╗ ███╗ ██╗███████╗ ██████╗███████╗
██╔══██╗████╗ ██║██╔════╝ ██╔════╝██╔════╝
██║ ██║██╔██╗ ██║█████╗█████╗██║ ███████╗
██║ ██║██║╚██╗██║██╔══╝╚════╝██║ ╚════██║
██████╔╝██║ ╚████║██║ ╚██████╗███████║
╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═════╝╚══════╝
-h 查看帮助 by 0x6a0x71
-s 服务端模式
-c 客户端模式''')
parser = argparse.ArgumentParser(description='DNF流量代理工具')
parser.add_argument('-key', type=str, default="Random",
help='自定义密钥,可以随机生成,注:服务端必须与客户端一致,密钥为16位(不同字符)【A-Za-z0-9】【默认:随机】')
parser.add_argument('-s', action="store_true", help='服务端模式')
parser.add_argument('-c', action="store_true", help='客户端模式')
parser.add_argument('-tt1', type=str,default="30", help='超时次数(每次10s)【默认:30】')
group_s = parser.add_argument_group('服务端', '通常放置在服务器上,若以下端口都已开启,可直接x.exe -s【例如:代理内网3389,可直接在服务端连接127.0.0.1:8002访问】')
group_s.add_argument('-srh', type=str, default="0.0.0.0", help='远程连接地址【默认:0.0.0.0】')
group_s.add_argument('-srp', type=str, default="5050", help='远程连接端口【默认:5050】')
group_s.add_argument('-slh', type=str, default="127.0.0.1", help='本地查看地址【默认:127.0.0.1】')
group_s.add_argument('-slp', type=str, default="8002", help='本地查看端口【默认:8002】')
group_c = parser.add_argument_group('客户端',
'通常放置在内网机器上(可出网)【例如:代理3389到服务器,可直接x.exe -c -crh x.x.x.x(服务器地址) -clp 3389】')
group_c.add_argument('-crh', type=str, default="127.0.0.1", help='远程连接地址【默认:127.0.0.1】')
group_c.add_argument('-crp', type=str, default="5050", help='远程连接端口【默认:5050】')
group_c.add_argument('-clh', type=str, default="127.0.0.1", help='本地代理地址【默认:127.0.0.1】')
group_c.add_argument('-clp', type=str, default="80", help='本地代理端口【默认:80】')
group_c.add_argument('-llp1', type=str, default="80", help='本地代理模式,本地原端口【默认:80】')
group_c.add_argument('-llp2', type=str, default="5050", help='本地代理模式,映射端口【默认:5050】')
group_c.add_argument('-cm', type=str, choices=["r", "l"], default="r", help='代理类型:(r:远程连接代理)(l:本地端口代理)【默认:r】')
args = parser.parse_args()
if int(args.tt1)<0:
print("设置超时次数无效")
else:
max_out_time = int(args.tt1)
print(f"【TimeOut】:{int(args.tt1)}")
LOCK = My_lock()
if args.s:
args.key = mx_key(args.key)
print(f"【KEY】:{args.key}")
lADDR = (args.slh, int(args.slp))
rADDR = (args.srh, int(args.srp))
A = tcp1(rADDR, lADDR, args.key)
else:
pass
if args.c:
args.key = mx_key(args.key)
print(f"【KEY】:{args.key}")
if args.cm == "r":
lADDR = (args.clh, int(args.clp))
rADDR = (args.crh, int(args.crp))
A = tcpServer3(rADDR, lADDR, args.key)
elif args.cm == "l":
ADDR = ("127.0.0.1", int(args.llp1))
ADDR2 = ("127.0.0.1", int(args.llp2))
B = tcpServer2(ADDR, ADDR)
else:
pass
分开的程序:客户端:
import argparse
import socket
BUFFSIZE = 262144
MAX_LISTEN = 32
import lock
CODING = "ISO-8859-1"
# 远程代理
def tcpServer3(ADDR,ADDR2,KEY):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as rs: #远程
# 绑定服务器地址和端口
rs.connect(ADDR)
while True:
try:
print("等待远程请求回复...")
rrec = rs.recv(BUFFSIZE)
print(f"rrec={rrec}")
dc_rrec = LOCK.decrypt_random(rrec.decode(CODING),KEY).encode(CODING) # 解密远程回复
print(f"\ndc_rrec={dc_rrec}")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as ls: #本地
ls.connect(ADDR2)
ls.send(dc_rrec)
lrec = ls.recv(BUFFSIZE)
print(f"lrec={lrec}")
# key = LOCK.out_key(lrec.decode(CODING)) # 加密本地回复
ec_lrec = LOCK.encrypt_random(lrec.decode(CODING), KEY).encode(CODING)
print(f"\nec_lrec={ec_lrec}")
ls.close()
rs.send(ec_lrec) # 发送加密后给远程回复
except Exception as e:
print(e)
break
rs.close()
# 本地代理
def tcpServer2(ADDR,ADDR2,KEY):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# 绑定服务器地址和端口
s.bind(ADDR)
# 启动服务监听
s.listen(MAX_LISTEN)
print('等待用户接入')
while True:
# 等待客户端连接请求,获取connSock
conn, addr = s.accept()
print('远端客户:{} 接入系统!!!'.format(addr))
with conn:
while True:
print('接收请求信息。。。。。')
# 接收请求信息
data = conn.recv(BUFFSIZE)
print('data=%s' % data)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as rs:
rs.connect(ADDR2)
rs.send(data)
rec = rs.recv(BUFFSIZE)
print(rec)
rs.close()
conn.send(rec)
# 发送请求数据
s.close()
if __name__ == '__main__':
# ADDR = ('127.0.0.1', 5000)
# ADDR2 = ('127.0.0.1', 80)
# a = tcpServer3(ADDR,ADDR2)
parser = argparse.ArgumentParser(
description='DNF流量代理工具')
parser.add_argument('-rh',type=str,default="127.0.0.1", help='远程连接地址,默认:127.0.0.1')
parser.add_argument('-rp',type=str,default="5050", help='远程连接端口,默认:5050')
parser.add_argument('-lh',type=str,default="127.0.0.1", help='本地代理地址,默认:127.0.0.1')
parser.add_argument('-lp',type=str,default="80", help='本地代理端口,默认:80')
parser.add_argument('-llp1', type=str, default="80", help='本地代理模式,本地原端口,默认:80')
parser.add_argument('-llp2', type=str, default="5050", help='本地代理模式,映射端口,默认:5050')
parser.add_argument('-m', type=str,choices=["r","l"],default="r",help='代理类型,r:远程回连代理,l:本地端口代理,默认r')
parser.add_argument('-key', type=str, default="Random", help='自定义密钥,可以随机生成,注:服务端必须与客户端一致,密钥为10位,ASCII(48-90)区间字符【默认随机】')
args = parser.parse_args()
LOCK = lock.My_lock()
if args.key == "Random":
args.key = LOCK.OR_key()
else:
okl = False
for i in args.key:
if ord(i)>90 or ord(i)<48:
okl = True
if okl or len(args.key)<10:
print("密钥不符合规定【10位,ASCII(48-90)区间字符")
if args.m == "r":
lADDR = (args.lh,int(args.lp))
rADDR = (args.rh,int(args.rp))
A = tcpServer3(rADDR,lADDR,args.key)
elif args.m == "l":
ADDR = ("127.0.0.1", int(args.llp1))
ADDR2 = ("127.0.0.1", int(args.llp2))
B = tcpServer3(ADDR, ADDR,args.key)
服务端:
import argparse
import socket
import lock
CODING = "ISO-8859-1"
BUFFSIZE = 262144
MAX_LISTEN = 32
def tcp1(ADDR2,ADDR,KEY):
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) as rs:
rs.bind(ADDR2)
# 启动服务监听
rs.listen(MAX_LISTEN)
print('远程监听开启')
while True:
try:
# 等待客户端连接请求,获取connSock
rconn, raddr = rs.accept()
print(f'远程服务接入成功!{raddr}')
with rconn:
while True:
# LOCK = lock.My_lock()
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) as ls:
ls.bind(ADDR)
ls.listen(MAX_LISTEN)
print('本地监听开启')
lconn, laddr = ls.accept()
print(f"本地服务接入成功!{laddr}")
with lconn:
print("等待本地用户请求...")
ldata = lconn.recv(BUFFSIZE)
print(f"ldata={ldata}")
# key = LOCK.out_key(ldata.decode(CODING)) # 加密本地请求
ec_ldata = LOCK.encrypt_random(ldata.decode(CODING),KEY).encode(CODING)
print(f"\nec_ldata={ec_ldata}")
rconn.send(ec_ldata) # 加密后发送给远程
rdata = rconn.recv(BUFFSIZE)
print(f"rdata={rdata}")
dc_rdata = LOCK.decrypt_random(rdata.decode(CODING),KEY).encode(CODING) # 解密远程回复
print(f"\ndc_rdatac={dc_rdata}")
lconn.send(dc_rdata)
lconn.close()
ls.close()
rconn.close()
except Exception as e:
print(e)
break
rs.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='DNF流量代理工具')
parser.add_argument('-rh',type=str,default="0.0.0.0", help='远程回连地址,默认:0.0.0.0')
parser.add_argument('-rp',type=str,default="5050", help='远程回连端口,默认:5050')
parser.add_argument('-lh',type=str,default="127.0.0.1", help='本地查看地址,默认:127.0.0.1')
parser.add_argument('-lp',type=str,default="8002", help='本地查看端口,默认:8002')
parser.add_argument('-key', type=str, default="Random", help='自定义密钥,可以随机生成,注:服务端必须与客户端一致,密钥为10位,ASCII(48-90)区间字符【默认随机】')
args = parser.parse_args()
LOCK = lock.My_lock()
if args.key == "Random":
args.key = LOCK.OR_key()
else:
okl = False
for i in args.key:
if ord(i)>90 or ord(i)<48:
okl = True
if okl or len(args.key)<10:
print("密钥不符合规定【10位,ASCII(48-90)区间字符")
print(f"【KEY】:{args.key}")
lADDR = (args.lh,int(args.lp))
rADDR = (args.rh,int(args.rp))
A = tcp1(rADDR,lADDR,args.key)