首页 > 技术文章 > ssrf简单使用

one-seven 2021-09-14 15:58 原文

简介

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

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

漏洞危害:探测内网信息、攻击内网应用

常见场景:远程图片加载、网站采集抓取、头像、让你输入网址和ip的地方、webmail收发其他邮箱邮件、转码服务、在线翻译、收藏功能等。

支持的协议:

file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流

这里写几个常用的协议

file协议

最常用的协议,使用方法也十分简单 直接 file://路径 就行

使用file协议读不出文件

1、权限不够:当前用户对此文件没有可读权限

2、路径输错了:linux系统中,file之后加路径是三个斜线,不能少:比如file:///etc/passwd(其实就是file://和/etc/passwd的组合)

3、存在open_basedir:当open_basedir配置有值时,curl_exec不能使用file协议,并不是受open_basedir的值限制某些文件读不了,而是整个file协议都不能用。这是写在php的curl_exec源码里的,目前没找到绕过的方式。

4、php源码不显示:读取php源码,即使读成功了也不会在浏览器里回显(类似html的注释一样),要在返回包里或者view-source中去看。

5、不回显的ssrf:代码没写echo,返回值赋到变量里,读成功了你也看不到。

http协议

用来探测内网http服务 http://10.17.64.180

gopher协议

gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议

使用限制

PHP版本大于等于5.3
PHP.ini开启了php_curl
gopher没有默认端口,需要指定:gopher://127.0.0.1:80
在传送GET或POST数据时需要经过二次URl编码
url编码时回车换行需要使用%0d%0a替换%0a
POST中的&也需要url编码。

格式

gopher://<host>:<post>/<gopher-path>_后面接TCP数据流

ssrf的gopher协议加redis,反弹shell,写shell
网上一堆就不操作了

dict协议

定义:词典网络协议,在RFC 2009中进行描述。它的目标是超越Webster protocol,并允许客户端在使用过程中访问更多字典。Dict服务器和客户机使用TCP端口2628。(摘自百度百科)

使用方法和gopher的差不多 dict://id:port 不同的是只能一条命令一条命令的传入

在gopher协议无法使用时,dict协议就是最好的选择

特殊符号使用

特殊符号的研究
测试一下各协议对特殊符号的支持,中文符号不测试,测试的所有符号如下:

`~!@#$%^&*()_-+=/|\'";:<>,.?{}[]

gopher协议

正常符号:直接传,一次二次url编码都可以
% 直接传可以,但后面接16进制字符就会转义,一次url编码后还是不能接16进制,二次url编码可以
# 会截断,一次url编码绕不过,二次url编码后可以
& 会截断,一次url编码可以,二次url编码也可以
+ 会变成空格,一次二次url编码后都可以

dict协议

正常符号:直接传,一次url编码可以,二次url编码不行(不支持二次解码)
以下均不支持二次url解码
% 直接传可以,后面接16进制不行会转义,一次url编码后可以
# 会截断,一次url编码绕不过
& 会截断,一次url编码可以
? 会截断,一次url编码绕不过
+ 会变成空格,一次url编码可以
: 会变成空格,一次url编码绕不过

http/s协议

正常符号:直接传,一次url编码可以,二次url编码不行(不支持二次解码)
以下均不支持二次url解码
% 直接传可以,后面接16进制不行会转义,一次url编码后可以
# 会截断,一次url编码绕不过
& 会截断,一次url编码可以
+ 会变成空格,一次url编码可以

总结

%#&+符号容易出问题
dict协议额外不支持?:两个符号,url编码无法绕过
一次url编码可以绕过%&+三种符号,不能绕过#
gopher协议的%需要编码两次绕过,只一次不行
gopher万能协议,支持二次url解码,没有绕不过的特殊符号。

常见的绕过方式

IP与主机名

http://example.com/?url=http://66.102.7.147/

URL编码

http://example.com/?url=http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D

双字编码

http://example.com/?url=http://1113982867/

十六进制编码

http://example.com/?url=http://0x42.0x0000066.0x7.0x93/

八进制编码

http://example.com/?url=http://0102.0146.0007.00000223/

协议解析绕过

http://example.com/?url=//www.google.com/

使用@(%40)

http://example.com/?url=http://example.com@google.com/

使用#(%23)

http://example.com/?url=http://google.com#http://example.com

添加端口号

http://example.com/?url=http://google.com:443

授信域名重定向

http://example.com/?url=http://abc.com/?redirect=https://google.com

定制DNS服务
这些网站可以使用它们将其指向特定的IP

http://xip.io/
http://nip.io/
https://ip6.name/
https://sslip.io/

比如:10.0.0.1.xip.io   -->10.0.0.1

也可以创建一个子域并使用DNS A记录指向192.168.0.1

使用封闭式数字字母

http://ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ = example.com

参考

https://segmentfault.com/a/1190000021960060
https://mp.weixin.qq.com/s/xlmY8Riwmi9ukO66bn3Iqw

推荐阅读