限定源端口访问目标

限定源端口访问目标

1.1. 起因

在渗透测试时,客户需要对我们的测试IP进行加白,但是此次客户要求精确到固定端口或者小范围端口(不能1-65535),根据以前的经验,默认是加白IP和全端口,因为代理建立连接使用的端口是随机的,所以这次算是从头查找资料总结一下各种指定源端口的方式。

这里的端口是指与目标建立连接时使用的源端口,而不是代理监听的端口。

1.2. 注意

最好使用服务器(VPS)发送请求。如果在局域网内向外网发起请求,即使本机指定了端口,也无济于事,因为实际发出请求的是最外层网络设备。

1.3. 方法一:NC

# 指定12345端口,缺点是一次一用,比较麻烦
nc <IP> <Port> -p 12345

nc

1.4. 方法二:批量占用端口

查找了很多资料,但都没能找到合适的工具。最终我想到了一种笨拙的方法:强制占用所有可用的端口。这样当代理发起请求时,就会自动选择未被占用的端口。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后的端口连接。

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

自己实现一个代理。监听一个端口,然后将流量发送到代理中,再由代理去固定源端口发送请求并返回结果。

Warning

因为都是走的这个端口去建立连接,一旦出现异常情况,那这个端口可能会长期保持TIME_WAIT状态从而导致无法正常使用。

python代码如下:

import http.server                  # 导入HTTP服务器相关的模块
import socketserver                 # 导入socket服务器相关的模块
import http.client                  # 导入HTTP客户端相关的模块
import urllib.parse                 # 导入URL解析相关的模块
import socket                       # 导入socket相关的模块
from loguru import logger           # 导入日志库

LISTEN_PORT = 8080                  # 本地监听端口
CONNECT_PORT = 22333                # 用于建立代理服务器与目标服务器连接的本地端口

# 继承http.server.BaseHTTPRequestHandler类,实现代理服务器的请求处理
class ProxyRequestHandler(http.server.BaseHTTPRequestHandler):

    # 处理CONNECT方法
    def do_CONNECT(self):
        # 解析URL
        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))
        # 返回200连接已建立响应
        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):
        # 解析URL
        u = urllib.parse.urlparse(self.path)
        # 创建一个HTTP连接
        conn = http.client.HTTPConnection(u.hostname, port=u.port or 80, timeout=10, source_address=('0.0.0.0', CONNECT_PORT))
        # 发送HTTP请求
        conn.request(self.command, self.path, headers=self.headers)
        # 获取HTTP响应
        resp = conn.getresponse()
        # 发送HTTP响应头
        self.send_response(resp.status)
        for header, value in resp.getheaders():
            self.send_header(header, value)
        self.end_headers()
        # 发送HTTP响应体
        while True:
            data = resp.read(1024)
            if not data:
                break
            self.wfile.write(data)

    # 处理POST方法
    def do_POST(self):
        # 解析URL
        u = urllib.parse.urlparse(self.path)
        # 获取请求体长度
        content_len = int(self.headers.get('Content-Length', 0))
        # 读取请求体
        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))  # 创建 HTTP 连接对象
        conn.request(self.command, self.path, body=body, headers=self.headers)  # 发送 HTTP POST 请求
        resp = conn.getresponse()  # 获取响应对象

        self.send_response(resp.status)  # 发送 HTTP 响应状态码
        for header, value in resp.getheaders():  # 遍历响应头部信息
            self.send_header(header, value)  # 发送响应头部信息
        self.end_headers()  # 结束响应头部信息的发送

        while True:
            data = resp.read(1024)  # 按照每次读取 1024 字节的方式获取响应数据
            if not data:  # 如果读取完毕,跳出循环
                break
            self.wfile.write(data)  # 将响应数据写入连接,响应给客户端

if __name__ == '__main__':
    try:
        # 创建一个 TCPServer 对象,绑定到 0.0.0.0:LISTEN_PORT 的地址,用于监听来自客户端的连接请求,当有连接请求时,将使用 ProxyRequestHandler 类进行处理。
        httpd = socketserver.TCPServer(('0.0.0.0', LISTEN_PORT), ProxyRequestHandler)
        logger.info(f"Proxy server is listening on port {LISTEN_PORT}")
        #  开始监听并接受来自客户端的连接请求,直到出现 KeyboardInterrupt 异常为止
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.server_close()

效果如下,均为22333端口。

1.6. 尝试过的失败方法记录

  • Nginx反向代理
  • SSH动态代理 ssh -N -D 0.0.0.0:9999 ubuntu@hongkong
  • socat sudo socat TCP-LISTEN:<new_source_port>,fork,reuseaddr TCP:<destination_IP>:<destination_port>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容