Smishingが来たので解析した #フィッシングSMS #Androidマルウェア解析

はじめに

こんにちは。morimolymolyです。
今日は僕の携帯にきた不正なSMSとそれからもたらされる不正なapkファイル(マルウェア)の解析をします。

注意

これはサイバー犯罪注意喚起、マルウェア解析学習のために執筆した記事です。
読者の皆様は不審なURLなどはくれぐれも開かないように注意してください。

SMS受信

2021/02/02、家でぼーっとしていると1件のSMSが到着した。
番号は携帯電話の番号。
緊急事態宣言中にむやみに外に出る人間ではないため、スパムと判定し自らリンクを踏むことにした。
f:id:morimolymoly:20210203155047j:plain

するとどう解釈してもGoogleに結びつかないURLからChromeのセキュリティを指摘され、謎のapkファイルをインストールするように要求される。
f:id:morimolymoly:20210203155243j:plain

検体をダウンロードし、解析用のマシンに移しすぐさま解析に取り掛かった。

検体の表層解析

ダウンロードしたファイルはdroxdlgomh.apkと騙す気があるのか謎のapkファイルだった。
まずはapkをバラすことにした。
Apktoolでバラすと以下のような構成になっていた。

% tree
.
├── AndroidManifest.xml
├── apktool.yml
├── assets
│   └── svc
│       └── 1k7vcor
├── classes.dex
├── kotlin
│   ├── annotation
│   │   └── annotation.kotlin_builtins
│   ├── collections
│   │   └── collections.kotlin_builtins
│   ├── coroutines
│   │   └── coroutines.kotlin_builtins
│   ├── internal
│   │   └── internal.kotlin_builtins
│   ├── kotlin.kotlin_builtins
│   ├── ranges
│   │   └── ranges.kotlin_builtins
│   └── reflect
│       └── reflect.kotlin_builtins
├── lib
│   └── arm64-v8a
│       └── libnative-lib.so
├── original
│   ├── AndroidManifest.xml
│   └── META-INF
│       ├── CERT.RSA
│       ├── CERT.SF
│       └── MANIFEST.MF
└── res
    ├── drawable-xhdpi
    │   ├── ic_launcher.png
    │   └── icon.xml
    ├── layout
    │   └── main.xml
    └── values
        ├── ids.xml
        └── public.xml

17 directories, 21 files

怪しいファイルは

  • classes.dex
  • AndroidManifest.xml
  • assets/svc/1k7vcor
  • lib/arm64-v8a/libnative-lib.so

だろう。

とりあえずAndroidManifest.xmlを確認し、権限などをみていく。

<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="qkd.kavvng.va" platformBuildVersionCode="23" platformBuildVersionName="6.0-2438415">
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.WRITE_SMS"/>
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.READ_PROFILE"/>
    <application android:icon="@drawable/ic_launcher" android:label=" Chrome" android:name="uynj.NlApplication">

権限としては以下のようなものがある(いろいろ省いているので各自確認してください)

  • WiFiの状態取得
  • ネットワークの接続管理
  • 電話の発信
  • オーディオ設定
  • スクリーンロックの解除(!!!!!!!!!)
  • SMSの受信/送信

おそらくapkをインストールした端末がbotになりフィッシングSMSを送信するのだろう。(これを受信したときの番号はあきらかに携帯電話だったのはそのため)

classes.dexは文字列を検索してもろくなものが引っかからないし、サイズが小さすぎる。
assets/svc/1k7vcorはわけのわからない小さなバイナリファイルだった。

またエントリポイントはNlApplicationであることがわかった。

検体の静的解析

Ghidraにclasses.dexとlib/arm64-v8a/libnative-lib.soを食わせる。

classes.dexには9個のclassが存在した。
しかしまともに機能するクラスは3つだった。
おそらく解析妨害のためにクラスをむやみに増やしている。

1つめはアラームサービスを設定するクラス(MaService)でlib/arm64-v8a/libnative-lib.soの中にあるJava,Util.Cov関数と連携している。
あまり重要なクラスではないのでパス。

2つめはK1ActivityでAndroid素人のためよくわからないが、大した動作を行っていない。アラームサービスを設定するクラスを呼び出したりしていた。

3つめが一番大事なクラスで、NlApplicationだ。
これはパッキングされたバイナリをアンパッキングしクラスとしてロードする。

検体によるパッキングを用いた対解析耐性

以上からわかるとおり、単に静的解析しても不正な動作をみつけることができない。
マルウェアにおいてはよくあることだが、重要な動作は解析されるのを避けるためにパッキングすることが多い。

それでは、NlApplicationのアンパック機構を解析していく。
……解析していくと意気込んでいたがそう難しいものではない。
なんとアンパックのアルゴリズムがそのままNlApplicationクラス内に存在するからだ。

NlApplicationクラスにはメソッドとして

  • a
  • b
  • c
  • d
  • e
  • f
  • g
  • h
  • i
  • コンストラク
  • onCreate

が実装されている。

NlApplicationは onCreate() → d() →h() → … と遷移していく。
この onCreate() → d() →h() のみでアンパックをする術を理解することができる。  

アンパック

アンパックアルゴリズムは d, hメソッドを読むだけで良い。
読むだけで良いのはそのままの意味で、GhidraがJavaのコードにデコンパイルしてくれるからだ。

アンパックする対象は assets/svc/1k7vcor であることがわかった。

以下にアンパックするコードを示す。(例外とか何もかもが汚いのはゆるして)

gist.github.com


変数名が謎なのは解析するときに適当に手動で名付けたのとGhidraの自動命名のため。

ペイロードの読み込み

さて、正常にペイロードを取得することができた。
上記のコードを assets/svc/1k7vcor にたいして実行するとdecryptedというファイルを取得できる。
これはzlibで圧縮されている。各自解凍すればdexファイルを得ることができるはずだ。

さて、マルウェアの解析に戻る。
アンパックが終わった後、dメソッドからiメソッドが呼ばれる。
iメソッドではアンパックされたdexから最初にロードするクラスを指定するための文字列を生成している。
単にコード中に埋め込んでしまうと解析者に有利に働くために、難読化していると思われる。
具体的には、com.Loaderというクラス名を得るために、Compilerクラスの名前をsubstring(切り取り)し、Loaderクラスの名前と文字列の合成することでcom.Loaderという文字列を動的に生成している。

iメソッドでcom.Loaderという文字列を得た後、aメソッドに遷移する。
aメソッドではbメソッドで実際にcom.Loaderクラスを得て、lib/arm64-v8a/libnative-lib.soの中にあるjava.util.c関数を呼び出し、クラスをロードさせる。

lib/arm64-v8a/libnative-lib.soの中ではわちゃわちゃとやっているが大した動作を行っていないと思う。
Javaの型定義が不足していてイマイチわからないコードになっている。

f:id:morimolymoly:20210203164944p:plain

今後もJavaの型定義が必要ならつくって公開していきたい。

アンパックされたペイロードの解析

ペイロードのエントリポイントがわからなかった。
AndroidManifest.xmlに記述はないし、デコンパイルしたapkにもそれらしきコードがない。

ひとまずcom.Loaderのコンストラクタから順にざっと確認。
以下のような機能が実装されていることがわかった。

  • Chromeとしてシステムに侵入(base64エンコードされたChromeのアイコンで偽装)(タップすると本物のChromeが立ち上がる)
  • default SMSアプリとして動作、
  • 詐欺の文言を提示するダイアログ
  • 外部SNSへ接続(htmlから正規表現でなにかを取得)(
  • インストールされているアプリのチェック
  • ローカルサーバの立ち上げ

C2機能のようなものが存在することから、botとして動き、SMSをばらまくはず。

またSMSで送信するコンテンツはどうやらSNSから取得している可能性がある。
megalodon.jp

ちょうど今日ばらまかれたSMSの文面がのっている。
これらに着目すれば今後の文面も予め予想できるのではないか。

マルウェアファミリ名が明らかに

XLoaderらしいです

www.talent-jump.com

動き

去年の3月から観測*1はされているようで、使用しているアカウントなどは変わっていない
C2はvk, youtube, instagram, GoogleDocs, blogspot, bloggerに対応できるように作られているが、今回の検体ではblogspotのみになっている。

;zc|y43wrgsdf@blogspot|wqeeqwgfdty@blogspot|y4wgres@blogspot という特徴的な文字列がアンパックしたマルウェアの中に埋め込まれていて、それを | で分割して取り出している。
日本語と韓国語で設定を変えている動きもあった。
それではC&Cサーバを特定していこう。

C2特定

実際にblogpostに訪問してみた
https://y43wrgsdf.blogspot.com/?m=1
https://y4wgres.blogspot.com/?m=1
https://wqeeqwgfdty.blogspot.com/?m=1

f:id:morimolymoly:20210206172322p:plain

どれも
woztxebZIaOjNbHBWXq877npuwlRaTZe
なる文字列が埋め込んであった。

ペイロードリバースエンジニアリングしていくと、上記のURLに訪問し、正規表現で上の文字列を取り出していることがわかった。
その文字列をbase64でデコードして、埋め込まれている Ab5d1Q32 という鍵(1年前と変わっていない)でDES暗号を復号化し、C2のアドレスを解決しているようだった。

実際にコードを書いてみて復号化してみるとC2のアドレスが取得できた。
C2: 45.114.129[.]48:28866

get_c2_from_xloader_2021-02-06.java · GitHub

一年程度では基本構造は変えないようですね。

まとめ

簡単にAndroid向けマルウェアを静的解析した。
検体はXLoaderというファミリで、おそらく基本的な構造やパッキング、難読化手法、暗号化手法も変わっていないはずだ。
C&Cサーバの監視、詐欺文面隠蔽場所の監視をすればいち早く攻撃者の動向がわかるはずだ。

それでは。

IOCs

詐欺文面等

日本語のみ抜粋。
他にも、ロシア語、中国語、韓国語、ジョージア語、タイ語ベンガル語アラビア語ヘブライ語アルメニア語に対応していた

  • [氏名]、[生年月日]を確認した後、再度入力してください
  • Googleアカウント危険、認証完了後使用してください
  • 」はより速くサイトを訪問し、そしてスマホのサーフィン体験を向上します。
  • 【JIBUN】お客様がご利用のじぶん銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • JNB】お客様がご利用のジャパンネット銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • JNB】お客様がご利用のジャパンネット銀行に対し、第三者からの不正なアクセスを検知しました。ご確認ください。
  • 【JPPOST】お客様がご利用のゆうちょ銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • MUFG】お客様がご利用の三菱UFJ銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • 【RTBK】お客様がご利用の楽天銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • 【SBI】お客様がご利用の住信SBIネット銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • 【SEVEN】お客様がご利用のセブン銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください。
  • SMBC】お客様がご利用の三井住友銀行に対し、第三者からの不正なアクセスをブロックしました。必ずご確認ください
  • お客様がキャリア決済にご登録のクレジットカードが外部によるアクセスを検知しました、セキュリティ強化更新手続きをお願いいたします。
  • 新バージョンが発見、アップデート完了後ご使用ください