SSRF - ctfhub -2【FastCGI协议、Redis协议、URL Bypass、数字IP Bypass、302跳转 Bypass、DNS重绑定Bypass】
FastCGI协议
知识参考:CTFhub官方链接
首先介绍一下原理(这里简单介绍,详情请看官方附件)
如果说HTTP
来完成浏览器到中间件的请求,那么FastCGI
就是从中间件到某语言后端进行交换的协议。
和浏览器请求包一样,也是由header、body
组成。
还需要提到一个PHP-FPM
,FastCGI
进程管理器,即在php
中(nginx
等服务器中间件)FastCGI
规则打包好后传递的终点,最后由FPM
按照fastcgi
的协议将TCP
流解析成真正的数据。
比如打包好的数据长这样
{
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'REQUEST_METHOD': 'GET',
'SCRIPT_FILENAME': '/var/www/html/index.php',
'SCRIPT_NAME': '/index.php',
'QUERY_STRING': '?a=1&b=2',
'REQUEST_URI': '/index.php?a=1&b=2',
'DOCUMENT_ROOT': '/var/www/html',
'SERVER_SOFTWARE': 'php/fcgiclient',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '12345',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': "localhost",
'SERVER_PROTOCOL': 'HTTP/1.1'
}
这个数组其实就是PHP中$_SERVER数组的一部分,也就是PHP里的环境变量。但环境变量的作用不仅是填充$_SERVER数组,也是告诉fpm
:“我要执行哪个PHP文件”。
PHP-FPM
拿到fastcgi
的数据包后,进行解析,得到上述这些环境变量。然后,执行SCRIPT_FILENAME
的值指向的PHP文件,也就是/var/www/html/index.php。
上述工作方式出现的几种漏洞:
Nginx解析漏洞:
正常来说,SCRIPT_FILENAME
的值是一个不存在的文件/var/www/html/favicon.ico/.php
,是PHP设置中的一个选项fix_pathinfo
导致了这个漏洞。PHP
为了支持Path Info
模式而创造了fix_pathinfo
,在这个选项被打开的情况下,fpm
会判断SCRIPT_FILENAME
是否存在,如果不存在则去掉最后一个/及以后的所有内容,再次判断文件是否存在,往次循环,直到文件存在。
所以,第一次fpm
发现/var/www/html/favicon.ico/.php
不存在,则去掉/.php
,再判断/var/www/html/favicon.ico是
否存在。显然这个文件是存在的,于是被作为PHP文件执行,导致解析漏洞。
当然,这个漏洞的直接利用比较少,一般结合其他漏洞使用
正确的解决方法有两种,一是在Nginx
端使用fastcgi_split_path_info
将path info
信息去除后,用tryfiles
判断文件是否存在;二是借助PHP-FPM
的security.limit_extensions
配置项,避免其他后缀文件被解析。
PHP-FPM未授权访问漏洞
PHP-FPM
默认监听9000
端口,如果这个端口暴露在公网,则我们可以自己构造fastcgi
协议,和fpm
进行通信。构造通信时,当然我们想要请求敏感文件,但是现在一般都有文件后缀限制,即你不能直接请求敏感文件夹。(默认后缀一般是.php)
拓展至任意代码执行
上一个漏洞的问题就在于无法执行我们想要的文件,无法进行敏感操作,即使找到了未授权访问,那也只能执行服务器上的固有文件。
不过既然能操作环境变量,就可以设置自动包含伪协议。
auto_prepend_file = php://input
且allow_url_include = On
从post进就可以了。基于这个原理,也有工具和相应的exp,我们只用填入我们需要的敏感信息即可。
工具地址:https://github.com/tarunkant/Gopherus
exp地址:https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75
任意代码执行,使用终端写马就可以了。
终端写马的方法和原理,这里不再细说,就像这样:
echo "<?php \$_POST['c']; ?>" > 1.php
使用工具
其实最后是落在了gopher
上哦,因为POST
嘛,让gopher
从服务器上请求9000
端口。记得多url编码一次
最后连接木马即可
Redis协议
资料参考:https://blog.csdn.net/iamsongyu/article/details/84171826
简单说一下redis
协议, Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value
数据库,并提供多种语言的API。
大概的意思就是这是一个数据库,存储在内存中,可以与磁盘交互,并且支持远程连接。Redis因配置不当可以未授权访问,攻击者无需认证访问到内部数据,可导致敏感信息泄露,也可以恶意执行flushall
来清空所有数据。
和上面的Fastcgi
原理差不多,一旦将特定端口暴露在公网中,就及其容易受到攻击。
Redis
在默认情况下,会绑定在0.0.0.0:6379
。如果没有采取相关的安全策略,比如添加防火墙规则、避免其他非信任来源IP访问等,这样会使Redis服务完全暴露在公网上。如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在访问目标服务器时,可以在未授权的情况下访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下,利用Redis自身的提供的config命令,可以进行文件的读写等操作。攻击者可以成功地将自己的ssh公钥写入到目标服务器的 /root/.ssh
文件夹下的authotrized_keys
文件中,进而可以使用对应地私钥直接使用ssh服务登录目标服务器。
攻击方式:
攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以通过恶意执行flushall
来清空所有数据
攻击者可通过EVAL
执行代码,或通过数据备份功能往磁盘写入后门文件
如果Redis以root身份运行,黑客可以给root账户写入SSH
公钥文件,直接通过SSH
登录受害者服务器
当然一般情况下,会避免其他非信任来源IP访问,所以这里的攻击思路也是和前面一样,通过gopher协议
从服务器上进入redis
,然后通过终端写马完成攻击。
同样利用工具:
它已经完成%0A到%0D%0A的转换了,二次编码后注入
这里返回为504,没有办法返回内容。
但是已经写入了
再请求敏感文件
值得注意的是,这里的默认shell使用的是get型,连shell工具不一定行,手动看看最好。
URL Bypass
写了一定的waf,了解常见的绕过方法。这里模拟的就是后端远程请求时的一个过滤。
可以得知,NodeJS url
、Perl URI
、Go net/url
、PHP parser_url
以及Ruby addressable
解析函数与cURL libcurl
请求函数差异性都可能造成漏洞的产生
下图的实例中,我们看到上述所述编程语言的解析函数得到的IP是google.com
,而cURL请求得到的却是evil.com:80
学习链接:https://www.cnblogs.com/-qing-/p/10908842.html
- 单斜线"/"绕过
https://www.landgrey.me/redirect.php?url=/www.evil.com- 缺少协议绕过
https://www.landgrey.me/redirect.php?url=//www.evil.com- 多斜线"/"前缀绕过
https://www.landgrey.me/redirect.php?url=///www.evil.com
https://www.landgrey.me/redirect.php?url=www.evil.com- 利用"@"符号绕过
https://www.landgrey.me/redirect.php?url=https://www.landgrey.me@www.evil.com- 利用反斜线""绕过
https://www.landgrey.me/redirect.php?url=https://www.evil.com\www.landgrey.me- 利用"#"符号绕过
https://www.landgrey.me/redirect.php?url=https://www.evil.com#www.landgrey.me- 利用"?"号绕过
https://www.landgrey.me/redirect.php?url=https://www.evil.com?www.landgrey.me- 利用"\"绕过
https://www.landgrey.me/redirect.php?url=https://www.evil.com\www.landgrey.me- 利用"."绕过
https://www.landgrey.me/redirect.php?url=.evil (可能会跳转到www.landgrey.me.evil域名)
https://www.landgrey.me/redirect.php?url=.evil.com (可能会跳转到evil.com域名)
10.重复特殊字符绕过
https://www.landgrey.me/redirect.php?url=///www.evil.com//…
https://www.landgrey.me/redirect.php?url=www.evil.com//…
题目要求请求的url必须有http://notfound.ctfhub.com
这里就是@绕过
payload:
?url=http://notfound.ctfhub.com@127.0.0.1/flag.php
数字IP Bypass
这里题目是不允许一些特定数字出现
有好几种绕过方式
进制转换
就像这样
http://127.0.0.1 >>> http://0177.0.0.1/
http://127.0.0.1 >>> http://2130706433/
http://192.168.0.1 >>> http://3232235521/
http://192.168.1.1 >>> http://3232235777/
ip进制转换链接推荐:https://tool.520101.com/wangluo/jinzhizhuanhuan/
特殊字体绕过:
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
①②⑦.⓿.⓿.① >>> 127.0.0.1
特殊地址:
http://0/ # 0.0.0.0可以直接访问到本地
http://127。0。0。1 # 绕过后端正则规则
http://localhost/
payload参考:
?url=localhost/flag.php
?url=http://2130706433/flag.php
302跳转 Bypass
题目应该是将本地访问地址进行了黑名单过滤。
这里是 短链接变换
短链接变换推荐链接:https://www.985.so/
短链接变换通过检索短网址上的数据库链接,再跳转原(长)链接访问。
实际上这就是一种302
这里转换为:http://r6d.cn/b2mk6
还有一种是
开源泛域名服务–xip.io
主要在未申请域名时用于测试的泛用dns解析服务
请求是http://www.127.0.0.1.xip.io
这个绕过是在SSRF场景中的绕过,比如SSRF你要读取内网地址,一般都做了限制,可以尝试用这方法进行绕过限制,从而访问到内网。
不过这里貌似不太行
DNS重绑定 Bypass
当我们给出一个网址链接时,首先会使用服务器端的dns服务器进行dns解析,解析出ip后,再与黑名单比对,进行过滤或请求。
这是使用的原理是,让一个网址绑定两个ip,或者也可以理解为快速的更换绑定对象。
进行dns解析时会随机返回一个ip
通过这样的操作,我们就可以快速进行注入来达到目的
要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL(TTL表示DNS记录在DNS服务器上缓存时间)时间为0,这是为了防止有DNS服务器对第一次的解析结果进行缓存
完整的DNS重绑定攻击流程为:
1.服务器端获得URL参数,进行第一次DNS解析,获得了一个非内网的IP
2.对于获得的IP进行判断,发现为指定范围IP,则通过验证
3.接下来服务器端对URL进行访问,由于DNS服务器设置的TTL为0,所以再次进行DNS解析,这一次DNS服务器返回的是内网地址
4.由于已经绕过验证,所以服务器端返回访问内网资源的内容
看得出来,虽然请求得网址一样,但返回的ip不同
工具链接:https://lock.cmpxchg8b.com/rebinder.html
这就需要一点欧气了,需要先解析为正常网址,然后解析为服务器端的网址,多试几次,建议使用bp上的repeater
多点几次