从ssrfmap源码中学习ssrf (二)
ssrfmap源码解读
modules
portscan [scan]
功能
端口扫描
原理
如果在存在ssrf的服务器上,向目标IP的不同端口发出请求,开放端口和未开放的端口返回的报文不一样,即可利用此判断端口是否是开放的
代码实现
首先将测试点全部置空,发出请求,收到的报文作为参照报文 compare
随后填入不同的端口,并发发出请求,将其得到的报文与 compare 相比较,如果不相同,则判断端口是开放的1
2
3
4
5
6
7
8
9
10
11
12
13
14# Copyright (c) 2018 Swissky
payload = wrapper_http("", host, port.strip())
r = requester.do_request(param, payload)
# Display Open port
if r != None and not "Connection refused" in r.text:
timer = datetime.today().time().replace(microsecond=0)
port = port.strip() + " "*20
# Check if the request is the same
if r.text != '' and r.text != compare.text:
print(f"\t[{timer}] IP:{host:12s}, Found \033[32mopen \033[0m port n°{port}")
else:
print(f"\t[{timer}] IP:{host:12s}, Found \033[31mfiltered\033[0m port n°{port}")
httpcollaborator [detect]
功能
类似于 burp 的 collaborator,用来检测目标是否含有ssrf漏洞
原理
如果服务器存在SSRF漏洞,那么向有公网 IP 的服务器发出的请求会被记录,由此可以判断是否存在SSRF漏洞
代码实现1
2
3
4
5# Copyright (c) 2018 Swissky
for param in params:
logging.info(f"Testing PARAM: {param}")
payload = wrapper_http(f"?{param}", args.lhost, args.lport.strip() )
r = requester.do_request(param, payload)
smtp [detect]
功能
如果存在ssrf的点有发送 smtp 邮件功能,则可以利用这个验证 ssrf
原理
使用gopher协议来发送smtp指令,从而发送邮件
前置知识
SMTP
简单邮件传输协议(SMTP)是一种通过网络传输电子邮件(email)的技术标准,一般监听25号端口
gopher协议
gopher协议是一个古老且强大的协议,可以理解为是http协议的前身,他可以实现多个数据包整合发送。通过gopher协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。
gopher请求的格式:1
gopher://<ip>:<port>/_<tcp数据流>
多条请求需要 %0d%0a 或 %0a 隔开,特殊字符需要进行 url 编码, 从这里看得出来和http协议很相似
利用gopher协议发送tcp数据
监听

发送

收到数据

利用gopher协议发起http请求1
curl gopher://www.baidu.com:80/_GET%20/%20HTTP/1.1%0d%0aHost:%20www.baidu.com%0d%0a

注意http请求以 \r\n表示请求结束,但我测试了下,发现 %0a 结尾也是可以的:

代码实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# Copyright (c) 2018 Swissky
for ip in gen_host:
port = 25
commands = [
'MAIL FROM:' + self.mailfrom,
'RCPT To:' + self.mailto,
'DATA',
'From:' + self.mailfrom,
'Subject:' + self.subject,
'Message:' + self.msg,
'.',
''
]
data = "%0A".join(commands) # 使用\n作为分割符
data = urllib.quote_plus(data).replace("+","%20")
data = data.replace("%2F","/")
data = data.replace("%25","%")
data = data.replace("%3A",":")
payload = wrapper_gopher(data, ip , port)
logging.info("Generated payload : {}".format(payload))
logging.info("Mail sent, look your inbox !")
r = requester.do_request(args.param, payload)
docker [info leaks]
功能
docker 暴露 2375 端口,从而任何人都可以管理这台主机上的容器和镜像.利用 ssrf 可以泄露内网主机上运行的 docker 信息
前置知识
2375端口
2375端口是Docker守护进程的默认监听端口。通过该端口,可以与Docker守护进程进行通信,发送Docker API请求,管理Docker容器和镜像。
如果 2375 端口是开放的,则可以通过向 /containers/json 发送 http 请求查看 docker 镜像信息,获取 id , container name , command 等信息
利用命令行查看信息:1
docker -H tcp://*.*.*.*:2375 info
总结
在绕过服务器过滤后,利用 gopher 协议可以对多种服务进行攻击.