限定源端口访问目标
字数 824 2025-08-10 23:41:50

限定源端口访问目标技术指南

1. 背景与概念

在渗透测试或网络安全操作中,有时需要将测试IP加入白名单,但客户可能要求精确到固定端口或小范围端口(不能是1-65535全端口)。这种情况下,需要控制与目标建立连接时使用的源端口。

重要注意事项

  • 服务器环境要求:最好使用VPS服务器发送请求。在局域网内向外网发起请求时,即使本机指定了端口,实际发出请求的是最外层网络设备,本机设置无效。
  • 端口概念:这里指的是与目标建立连接时使用的源端口,而非代理监听的端口。

2. 实现方法

方法一:使用NC(netcat)工具

nc <目标IP> <目标端口> -p 12345

特点

  • 简单直接
  • 一次一用,比较麻烦
  • 只能用于单次连接

方法二:批量占用端口法

通过Python脚本强制占用所有可用端口,使代理发起请求时自动选择未被占用的端口(高段端口)。

import socket
import time

# 配置参数
start_port = 1      # 起始端口
end_port = 60000    # 结束端口

# 创建套接字列表
socks = []
for port in range(start_port, end_port+1):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind(('0.0.0.0', port))
        sock.listen(1)
        socks.append(sock)
    except:
        print(f"{port} 被其他应用占用")

print(f'已占用端口范围: {start_port} - {end_port}')

# 长期保持端口占用
while True:
    time.sleep(60)

效果

  • 代理将被迫使用60000以上的端口进行连接
  • 实现了源端口范围的控制

方法三:手动实现代理转发

自己实现代理服务,监听一个端口,然后固定源端口发送请求。

警告

  • 所有连接都使用同一端口,可能出现TIME_WAIT状态导致端口无法使用
import http.server
import socketserver
import http.client
import urllib.parse
import socket
from loguru import logger

# 配置参数
LISTEN_PORT = 8080    # 本地监听端口
CONNECT_PORT = 22333  # 用于建立连接的本地源端口

class ProxyRequestHandler(http.server.BaseHTTPRequestHandler):
    
    # 处理CONNECT方法(HTTPS)
    def do_CONNECT(self):
        u = urllib.parse.urlparse('http://' + self.path)
        p_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        p_sock.bind(('0.0.0.0', CONNECT_PORT))
        p_sock.connect((u.hostname, u.port or 80))
        self.wfile.write(b'HTTP/1.1 200 Connection Established\r\n\r\n')
        
        p_sock.setblocking(False)
        self.connection.setblocking(False)
        
        while True:
            try:
                data = self.connection.recv(1024)
                if not data: break
                p_sock.sendall(data)
            except: pass
            
            try:
                data = p_sock.recv(1024)
                if not data: break
                self.connection.sendall(data)
            except: pass
            
        self.connection.close()
        p_sock.close()
    
    # 处理GET方法
    def do_GET(self):
        u = urllib.parse.urlparse(self.path)
        conn = http.client.HTTPConnection(u.hostname, port=u.port or 80, 
                                         timeout=10, source_address=('0.0.0.0', CONNECT_PORT))
        conn.request(self.command, self.path, headers=self.headers)
        resp = conn.getresponse()
        
        self.send_response(resp.status)
        for header, value in resp.getheaders():
            self.send_header(header, value)
        self.end_headers()
        
        while True:
            data = resp.read(1024)
            if not data: break
            self.wfile.write(data)
    
    # 处理POST方法
    def do_POST(self):
        u = urllib.parse.urlparse(self.path)
        content_len = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(content_len)
        
        conn = http.client.HTTPConnection(u.hostname, port=u.port or 80, 
                                        timeout=10, source_address=('0.0.0.0', CONNECT_PORT))
        conn.request(self.command, self.path, body=body, headers=self.headers)
        resp = conn.getresponse()
        
        self.send_response(resp.status)
        for header, value in resp.getheaders():
            self.send_header(header, value)
        self.end_headers()
        
        while True:
            data = resp.read(1024)
            if not data: break
            self.wfile.write(data)

if __name__ == '__main__':
    try:
        httpd = socketserver.TCPServer(('0.0.0.0', LISTEN_PORT), ProxyRequestHandler)
        logger.info(f"Proxy server is listening on port {LISTEN_PORT}")
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.server_close()

效果

  • 所有对外连接均使用固定的22333源端口
  • 支持HTTP/HTTPS协议

3. 尝试过但失败的方法

以下方法经测试无法实现限定源端口的功能:

  1. Nginx反向代理

    • 无法控制源端口
  2. SSH动态代理

    ssh -N -D 0.0.0.0:9999 ubuntu@hongkong
    
    • 无法指定源端口
  3. socat工具

    sudo socat TCP-LISTEN:<new_source_port>,fork,reuseaddr TCP:<destination_IP>:<destination_port>
    
    • 虽然可以监听指定端口,但无法控制源端口

4. 方法选择建议

  1. 简单临时需求:使用NC方法
  2. 需要大范围端口控制:使用批量占用端口法
  3. 需要精确固定端口:使用自定义代理方法
  4. 避免使用:Nginx反向代理、SSH动态代理和socat方法(对源端口控制无效)

5. 技术原理总结

控制源端口的关键在于:

  • 在建立TCP连接时强制绑定特定的本地端口
  • 通过占用低端口段迫使系统选择高端口
  • 通过自定义代理中间层实现端口固定

以上方法在实际应用中可根据具体场景和需求灵活选择。

限定源端口访问目标技术指南 1. 背景与概念 在渗透测试或网络安全操作中,有时需要将测试IP加入白名单,但客户可能要求精确到固定端口或小范围端口(不能是1-65535全端口)。这种情况下,需要控制与目标建立连接时使用的源端口。 重要注意事项 服务器环境要求 :最好使用VPS服务器发送请求。在局域网内向外网发起请求时,即使本机指定了端口,实际发出请求的是最外层网络设备,本机设置无效。 端口概念 :这里指的是与目标建立连接时使用的源端口,而非代理监听的端口。 2. 实现方法 方法一:使用NC(netcat)工具 特点 : 简单直接 一次一用,比较麻烦 只能用于单次连接 方法二:批量占用端口法 通过Python脚本强制占用所有可用端口,使代理发起请求时自动选择未被占用的端口(高段端口)。 效果 : 代理将被迫使用60000以上的端口进行连接 实现了源端口范围的控制 方法三:手动实现代理转发 自己实现代理服务,监听一个端口,然后固定源端口发送请求。 警告 : 所有连接都使用同一端口,可能出现TIME_ WAIT状态导致端口无法使用 效果 : 所有对外连接均使用固定的22333源端口 支持HTTP/HTTPS协议 3. 尝试过但失败的方法 以下方法经测试无法实现限定源端口的功能: Nginx反向代理 : 无法控制源端口 SSH动态代理 : 无法指定源端口 socat工具 : 虽然可以监听指定端口,但无法控制源端口 4. 方法选择建议 简单临时需求 :使用NC方法 需要大范围端口控制 :使用批量占用端口法 需要精确固定端口 :使用自定义代理方法 避免使用 :Nginx反向代理、SSH动态代理和socat方法(对源端口控制无效) 5. 技术原理总结 控制源端口的关键在于: 在建立TCP连接时强制绑定特定的本地端口 通过占用低端口段迫使系统选择高端口 通过自定义代理中间层实现端口固定 以上方法在实际应用中可根据具体场景和需求灵活选择。