MKCMS代碼審計小結
MKCMS V6.2 (以下源碼來自網絡)
MKCMS米酷影視源碼6.2開源CMS
下載地址鏈接:https://pan.baidu.com/s/1cZX5x9SbcXMCMXismfH4ow 提取碼:k3ox
備用下載地址:https://www.lanzous.com/ib7zwmh
0x00 全局過濾分析
/system/library.php:使用addslashes轉義入參, 注意到$_SERVER未被過濾
0x01 驗證碼重用
/admin/cms_login.php驗證碼處的邏輯如下,比較session中的驗證碼和輸入的是否一致,不一致就進入alert_href,這個js跳轉,實際是在刷新頁面
/admin/cms_login.php:
<?php 6 ... 7 if(isset($_POST['submit'])){ 8: if ($_SESSION['verifycode'] != $_POST['verifycode']) { 9 alert_href('驗證碼錯誤','cms_login.php'); 10 } ...

跳轉后就會刷新驗證碼,然而我用的是burp,默認是不解析js的
全局搜索這個$_SESSION['verifycode'],發現只在/system/verifycode.php有賦值,也就是說,如果使用驗證碼后,我們不跟隨js跳轉,就不會重置驗證碼,驗證碼也就能被重復使用了
使用burp重放,的確如此,驗證碼形同虛設
0x02 前台注入1:/ucenter/repass.php
看了下歷史的漏洞,在/ucenter/repass.php有個越權修改密碼的洞(CVE-2019-11332),跟進去發現原來還有注入,以下是分析過程
/ucenter/repass.php
<?php ... if(isset($_POST['submit'])){ $username = stripslashes(trim($_POST['name'])); $email = trim($_POST['email']); // 檢測用戶名是否存在 $query = mysql_query("select u_id from mkcms_user where u_name='$username' and u_email='$email'"); ...
前面說到全局對$_POST存在addslash的過濾(加\轉義),上面又把參數給stripslashes了(去掉\),這不就是個注入?
后來復盤,實際上,這個問題coolcat師傅早在去年就在先知上提出來了:某KCMS5.0 代碼審計 (前台注入&任意用戶密碼重置),師傅nb!
0x03 前台注入2:/ucenter/active.php
/ucenter/active.php?verify=1存在注入
/ucenter/active.php
<?php ... $verify = stripslashes(trim($_GET['verify'])); //去掉了轉義用的\ $nowtime = time(); $query = mysql_query("select u_id from mkcms_user where u_question='$verify'"); $row = mysql_fetch_array($query); ...
sqlmap直接跑即可
[INFO] GET parameter 'verify' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
[INFO] GET parameter 'verify' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
0x04 前台注入3:/ucenter/reg.php
/ucenter/reg.php的name參數,存在注入
/ucenter/reg.php
<?php ... if(isset($_POST['submit'])){ $username = stripslashes(trim($_POST['name'])); // 檢測用戶名是否存在 $query = mysql_query("select u_id from mkcms_user where u_name='$username'"); ...
0x05 任意用戶密碼找回(密碼可被窮舉)
任意用戶密碼找回
這個問題主要是/ucenter/repass.php代碼里,找回密碼的邏輯有問題,第10行查詢到username、 email能對應上之后,14行就直接重置密碼了。。。而且密碼的范圍在12行有寫,只有90000種可能,重置之后,burp跑一下不就ok了?(當然要結合驗證碼重用才能有效爆破)
0x06 備份文件路徑可猜解
這個備份功能也太頂了,而且還是那么簡單的文件名/backupdata/movie.sql
/admin/cms_backup.php
<?php $filename="../backupdata/".DATA_NAME.".sql"; //存放路徑,默認存放到項目最外層 $fp = fopen($filename,'w'); fputs($fp,$mysql); fclose($fp); alert_href('備份成功!','cms_data.php'); ?>
全局搜DATA_NAME變量,是安裝時候設置的數據庫名
默認的DATA_NAME值是movie
0x07 前台文件上傳
/editor/php/upload_json.php?dir=file
源碼如下
<?php
$ext_arr = array( 'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'), 'flash' => array('swf', 'flv'), 'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'), 'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2' ,'7z'), ); ... $file_name = $_FILES['imgFile']['name']; ... //獲得文件擴展名 $temp_arr = explode(".", $file_name); $file_ext = array_pop($temp_arr); $file_ext = trim($file_ext); /*將file_ext轉換為字符串。。。無弱類型問題了**/ $file_ext = strtolower($file_ext); //將file_ext轉換為字符串。。。無弱類型問題了 //檢查擴展名,是否在大的數組中,in_array存在若類型問題 if (in_array($file_ext, $ext_arr[$dir_name]) === false) { alert("上傳文件擴展名是不允許的擴展名。\n只允許" . implode(",", $ext_arr[$dir_name]) . "格式。"); }result ...
可以上傳列表里的文件,只是無法拿shell
POST /editor/php/upload_json.php?dir=file HTTP/1.1 Host: localhost Content-Length: 306 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryni3BwmVzIUwKfSSC Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://www.ygtv520.com/editor/php/upload_json.php Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close ------WebKitFormBoundaryni3BwmVzIUwKfSSC Content-Disposition: form-data; name="imgFile"; filename="1.jpg.html" Content-Type: application/octet-stream 11111111 ------WebKitFormBoundaryni3BwmVzIUwKfSSC Content-Disposition: form-data; name="upload" Send ------WebKitFormBoundaryni3BwmVzIUwKfSSC--
響應里返回文件地址

