1. 対象マルウェア
前回と同じく sha256: da8140274788214c9451d950e0f323c0c51188c5bf847bafef9f48c023e91a55 のファイルを対象とする.前回やったときは VirusTotal の結果はなかったけれど,今検索してみると Linux/DDoS-Xor.A などと結果が出てくる (https://www.virustotal.com/en/file/da8140274788214c9451d950e0f323c0c51188c5bf847bafef9f48c023e91a55/analysis/).2. Cuckoo による解析の続き
前回の投稿では Linux マルウェアではstrace
や子プロセスの追跡ができないと書いたが,実行のタイミングを調整することでうまく動作させることができた.(そして Pull Request デビューした: https://github.com/cuckoosandbox/cuckoo/pull/1007)トレースありの Cuckoo レポートを https://drmn.jp/blog/20160726-reversing/2.zip にアップロードした.一応 PCAP 等含むのでパスワード “infected” をかけている.
トレースが見れると非常にはかどる.このマルウェアは何回もプロセスを作ったり消したりする動作をしていたのだけれど,たとえば外部ホストに接続しに行こうとしたプロセスのトレースは以下.
わかりづらく表記された .org のドメインの名前解決をして当該 IP アドレスに接続しているように見受けられる.ではこの接続先を
strings
などで探すことができないかと考えたが,できなかった.cuckoo@cactus /data/cuckoo/storage/analyses/2 $ strings binary | grep org
C/o Keld Simonsen, Skt. Jorgens Alle 8, DK-1615 Kobenhavn V
TLS generation counter wrapped! Please report as described in <http://www.gnu.org/software/libc/bugs.html>.
DNS に使用されるアドレスのほうは出てくる.cuckoo@cactus /data/cuckoo/storage/analyses/2 $ strings binary | grep -F 114.114.114.114
114.114.114.114
ということで,strings
だけでは得られない情報を求めてリバージングしていく.できれば動作全体の解明をしていきたいのだけれど,まだまだ始めたばかりなので…….3. リバージング
リバージングには Radare2 を使用している.main
の逆アセンブル結果を見ていくと,最初のほうにこんなパートが出てくる.PATH
環境変数をセットしているのは良いとして,0x0804b67f
以降,謎の文字列をセットして dec_conf
が呼び出されている.これは怪しい.次に dec_conf
を見てみる.いろいろと値のコピーなどを行っているようだが,結局のところ
encrypt_code
が呼び出されていて,これが肝のようだ.encrypt_code
自体は小さな関数で,さらにそこからどこかにも飛んでいない純粋な処理を行う関数のようなので,ここを丹念に見ることにする.しかし,decrypt_conf
の中で encrypt_code
という名前の関数が呼び出されるということは……2 回処理にかけたら元に戻るアルゴリズム? XOR 的な? という想像が働いてくる.コードの中にもちらっと見えるし.読んだ結果を以下に書き込んだ.どうやら,この関数は文字列とその長さを引数に受けとり,その文字列と “BB2FA36AAA9541F0” (の繰り返し) の ASCII コードで 1 文字ずつ XOR をかける処理を行うもののようだ.
ということで,同等の関数を Python で書いてみた.
main
とのあいだには memmove
している dec_conf
関数があるが,たぶん特に何も考えず,dec_conf
への引数を渡してみたら良いのではないかとやってみる.# decrypt.py
import sys
def decrypt(code):
div = 0x10 # len(key)
key = "BB2FA36AAA9541F0"
result = ""
for i in range(len(code)):
result = result + chr(ord(code[i]) ^ ord(key[i % div]))
return result
for code in sys.stdin:
print(decrypt(code.rstrip()))
main
で渡されていた文字列をいくつか試してみる.cuckoo@cactus ~/work $ python decrypt.py
m ])5
/boot
m4S4nAC/n2_AD
/var/run/sftp
m.[$nFR$7nLQQGF
/lib/udev/udev
良さそう!もともとのドメインを探して
strings
を全部喰わせてみる:cuckoo@cactus ~/work $ strings /data/cuckoo/storage/analyses/2/binary | python decrypt.py | grep -a org
2.org
2.org
まだもう少しちゃんとコードを追う必要がありそうだけれども,まあまあいい線行っているのではないか.参考
- LiveOverflow—YouTube Channel
https://www.youtube.com/channel/UClcE-kVhqyiHCcjYwcpfj9w
0 件のコメント:
コメントを投稿