APT28 DLLバックドアによる攻撃の実態

By The Cylance Threat Research Team

本ブログ記事は、2019年8月28日に米国で公開された抄訳版です。原文はこちらからご覧頂けます。

このブログ記事は、IDA Proシグネチャを生成して無害のライブラリコードを確認、除外する方法を解説した記事、Flirting With IDA and APT28(IDAとAPT28についての考察)の続編にあたります。前回の手順を踏むことで、インプラントの動作を定義する役目を担うカスタムコードに注力することができます。

今回は同じAPT28サンプルを詳しく調べ、その機能を解析して特徴を明らかにします。

概要


ハッシュ:
B40909AC0B70B7BD82465DFC7761A6B4E0DF55B894DD42290E3F72CB4280FA44
ファイルタイプ:Windows x64 DLL
PEコンパイルタイムスタンプ:4th July 2018 14:38:54
 

図1:APT28サンプルの詳細

解析結果から、インプラントはマルチスレッドDLLバックドアであることが判明しています。攻撃者(TA)は、標的となるホストに対するフルアクセスと制御をこのバックドアを通じて獲得します。C2の命令を受けたインプラントは、ファイルのアップロードやダウンロード、プロセスの作成、コマンドシェルを介したホストの操作、定義されたスリープ/アクティビティスケジュールに基づくC2への接続を行うことができます。

前回の記事に記載されているように、このインプラントはC++で作成されており、OpenSSLとPoco C++フレームワークへの静的リンクが設定されています。ファイルはDLLとしてパッケージ化されているため、長期間にわたって実行される、インターネットアクセス権限を持つプロセスか(NetSvcサービスグループなど)、ローカルファイアウォールの許可を得たプロセスへの注入を意図したものと思われます。私たちは、より大きなツールのモジュールとして機能することがこのDLLの目的であるとは考えていません。

エントリポイント

悪意のあるコードの入力は、DllMainエクスポートを介して行われます。インプラントの最初のタスクは、"c:\windows\system32"にあるMicrosoftの正規のnpmproxy.dllをロードすることです。ロードが完了すると、インプラントの5つのエクスポート(DllCanUnloadNow、DllGetClassObject、DllRegisterServer、DllUnregisterServer、GetProxyDllInfo)のアドレスがMicrosoft DLLに含まれる無害の同じエクスポートのアドレスに設定されます。

こうした操作が行われる理由については未確認ですが、エンドポイント保護を回避するための防衛策である可能性が高いと思われます。エンドポイント保護では、コードの変更箇所を探してエクスポートアドレスをスキャンするか(事前定義のシグネチャデータベースと比較)、既知の悪意のあるコードのデータベースと照合します。無害のエクスポートのコピーにインプラントの各エクスポートを設定することで、検知を逃れようと試みている可能性もあります。

図2:PEエクスポートアドレスの置換

エクスポートアドレスが置き換えられると、メインコードパスを実行するためにスレッドが開始されます。それに続いて、C2による操作を送受信する2番目のスレッドが開始されます。C2メッセージを処理するために、グローバル変数がスレッド間同期の基礎を形成します。

ミューテックス

プライマリスレッドの最初のタスクは、グローバル一意識別子(GUID)のミューテックス"1b8232f6-6806-4733-901d-62bf3ef33e6c"を作成することです。GUID文字列はプレーンテキストとしてバイナリ内に配置され、侵入の可能性を示す痕跡(IOC)を明らかにします。ミューテックスを作成できない場合、通常、サンプルはそれ以上何もせずに終了します。

マシンのフィンガープリント

ミューテックスの作成に続いて、インプラントはCRC-32ホストのそれぞれ固有のフィンガープリントを生成します。その際、プライマリネットワークインターフェイスのイーサネット(MAC)アドレス、ホスト名、Windowsバージョン文字列が使用されます。最終的なCRC-32の結果は、固定した定数0x64113とXORされます。生成されたホストのフィンガープリントは、後でC2ビーコンURLをビルドするときに使用されます。さらに、感染した各マシンにおけるインプラントの悪意のある使用を特定する際にも役立つと思われます。

コマンドアンドコントロール(C2)

C2サーバーの主要な通信プロトコルはRSAで暗号化されており、Base64でエンコードされたJSONによる交換がHTTPS(TLS、ポート443)またはフォールバックとしてプレーンHTTP(ポート80)で行われます。私たちの解析では、インプラントは他のアプリケーションプロトコルの使用を試みませんでした。

HTTP要求のユーザーエージェント文字列は、"ObtainUserAgentString" APIコールの戻り値か、(それに失敗した場合は)ハードコードされた代替文字列(後述の「IOC」を参照)のいずれかから取り込まれます。

出口プロキシサーバーは、"WinHttpGetIEProxyConfigForCurrentUser"の呼び出しを通じてサポートされています。C2アクティビティに先立って、結果は解析されてPocoフレームワークの"HTTPClientSession::setProxyConfig"に提供されます。

1024ビットのRSAキーペアがインプラント内に埋め込まれており、ホストとC2の間で行われる通信の暗号化/復号で使用されます。秘密鍵は着信トラフィックを復号し、公開鍵は発信トラフィックを暗号化します。ストリーム暗号やセッションキーはネゴシエーションされません。

"malaytravelgroup[.]com"の最初のHTTPSビーコンは、ランダムに選択されたURLパス連結のほか、パラメータの分割数を含むクエリ文字列、XOR定数の0x64113(ホストCRC-32の生成時にも使用)、計算されたCRC-32のフィンガープリントで構成されるGET要求です。クエリ文字列にはアドホック分析を防ぐランダムデータが埋め込まれており、最終的にBase64でエンコードされます。

フィールド

名前

バイト数

コメント

1

-

1

1-254

パラメータの分割数(ASCII値)

2

“aid”

4

0x64113

ホストCRC-32の生成時に使用されるXOR定数。場合によってはそれぞれ固有のインプラントID

3

“bid”

4

変数

CRC-32ホストのフィンガープリント

表1:C2ビーコンのクエリパラメータ

URLパスのコンポーネントは、暗号化された一連の文字列テーブルから生成された1~3の文字列("/"で分割)としてビルドされます。復号バージョンは”付録”に記載されています。

Base64エンコードデータはランダムな数のパラメータに分割され、難読化の手段として埋め込まれます。クエリのパラメータ名は、1~4の大文字/小文字を使用してランダムに生成されます。

名前

説明

<rand_str>

<2_rand_chars> + b64(<n>)

ビーコンデータが何個のパラメータに分割されるのかを指定します。

<rand_str_1>

<2_rand_chars> + b64(<rand_byte> +

<data_part_1>)

値にはエンコードデータの最初の部分が含まれ、2つのランダム文字がその前に付きます。

<rand_str_2>

<2_rand_chars> + b64(<rand_byte> +

<data_part_2>)

値にはエンコードデータの2番目の部分が含まれ、2つのランダム文字がその前に付きます。

...

...

...

<rand_str_n>

<2_rand_chars> + b64(<rand_byte> +

<data_part_n>)

値にはエンコードデータの最後の部分が含まれ、2つのランダム文字がその前に付きます。

表2:クエリパラメータのデコンストラクション

ビーコン要求URLの例:

GET /pricing/training/news/?GPFi=mLMg&CYlp=Tj9RNBBg%3D%3D&JOM=uJfgAz9Zpw

GET /forum/feedback/switch/?LnY=YNA&D=TH%2FRM%3D&rMuo=BFXUEG&cs=bkqgA%3D&HZql=bXgTP1mnA%3D HTTP/1.1

GET /activity/?FLVE=JNA&Y=vKYxNB&F=Hg6wY%3D&Slq=QBuAAz&ux=lSGfWacA%3D%3D HTTP/1.1

図3:ビーコンURLの例

図3の最初の例に基づくと、ビーコンデータの分割数を示す最初のクエリパラメータは、次のようにBase64でデコードされます。

                        GPFi=mLMg >> b64_decode(Mg) >>0x32 ("2")

連続するすべてのクエリパラメータでは、Base64デコードに先立って最初の2文字が除去されます。デコード結果の最初のバイトは破棄されて最終値に到達します。

                        CYlp=Tj9RNBBg== >> b64_decode(9RNBBg==) >> F5 13 41 06
                        JOM=uJfgAz9Zpw >> b64_decode(fgAz9Zpw)  >> 7E 00 33 F5 9A 70



0x00064113 >> XOR定数/インプラントID
0x709AF533>> ホストCRC-32フィンガープリント

ビーコンの受信とデコードが完了すると、インプラントの関数を機能させるコマンドの発行という次の段階に操作が進みます。この関数には、インプラントのアクティビティを制限するアクティビティスケジュール/スリープ間隔のプロビジョニングなどがあります。

ドメイン生成アルゴリズム(DGA)

"malaytravelgroup[.]com"のC2プライマリドメインは最初のビーコンで使用されています。すべての機密文字列と同様に、この文字列はXORでエンコードされ、必要な場合にのみ開示されます。

このインプラントには、C2のバックアップドメイン名と思われるものを生成するアルゴリズムに基づく線形合同法(LCG)も組み込まれています。興味深いことにLCGの実装は100%決定しており、これは図5が示すように固定シード値(0xC31)を使用していることに起因します。DGAが呼び出されるたびに、以下に示す同じ5つのドメインが生成されます。

schooltillhungryprocess[.]com
reasonwithusefulpolicy[.]com
streetunderrelevantpeople[.]com
experiencewithweakkid[.]com
systembeforeniceparent[.]com

図4:エンコードされたC2サーバー

生成されたドメインはXORでエンコードされます。LCGの実装を定数のシード値とともにここで確認できます。

図5:固定シード値を使用したDGA LCG

 暗号化された3つの文字列テーブルからの4つの文字列テーブルルックアップの連結としてドメイン名が生成されています。テーブル3は生成中に2回参照されています。最上位ドメイン(TLD)の接尾辞が".com"にハードコードされています。

テーブル

文字列の数

1

99

2

31

3

149

表3:ドメイン生成における文字列テーブルのサイズ

4つの部分で構成されるドメイン名の採用が今後も続くと仮定すると、LCGでは何百万件ものそれぞれ固有の順列を生成できることになります。日付や時刻、ホストID、その他の入力変数に関係なく、同じ5つのドメイン名に出力が制限されている理由ははっきりしません。復号された文字列テーブルのコピーが“付録”に収録されています。

私たちは、チェックイン試行間の遅延を手動で減らして、インプラントにより生成されるC2アクティビティの量を増やしました。不思議なことに、生成されたドメインとの通信の試みは、24時間の観察期間中には見られませんでした。間違った形式の応答から到達不能なIPアドレスまで、さまざまな到達可能性のシナリオが吟味されました。しかし、生成されたドメインに関連するDNS/HTTPトラフィックをインプラントが生成することはありませんでした。

プライマリサイトが発行したHTTP 302リダイレクトを介してバックアップドメインにアクセスしていることも考えられますが、障害、移行、シャットダウンの要求に応じるためにプライマリドメインとバックアップドメインを使用するという目的に合わないと思われます。生成されたC2ドメインがファイルのアップロードやダウンロードなどの特定のインプラントコマンドに対してのみアクティブになる可能性もあります。

直接使用されたという証拠はありませんが、生成されたドメインがハニーポットとして機能していると推測することはできます。これらのドメインにインターネットアドレスからアクセスすると、ただちに「疑わしい」行為と見なされることになります。ドメインはインプラントコード内のみに隠れて存在しているからです。こうした要求は、インプラント内部の働きを調べている脅威の調査担当者やアナリストから直接送られてきた可能性があります。

関数

このインプラントはモジュール性に欠けるため、8つの関数に限定されています。それぞれの関数はC2によって呼び出されます。その際に指定された値に基づいて、既知のCRC-32が計算されます。計算されたCRC-32の値は、対応する関数を実行するキーまたはルックアップとして機能します。

バックドアがサポートする各関数のパラメータがそれぞれのコマンドで指定されます。詳細については表4を参照してください。

CRC-32

関数

パラメータ

説明

15512FB9

Spawn process

file_name, file_path, args

指定された引数を使用してプロセスを作成します。

76BCDC67

Create file

file_name, file_path, body

提供された本体でファイルを作成します。すなわち、ファイルはC2からプッシュ(ダウンロード)されます。ファイルにはDOSの非表示属性がデフォルトで設定されています。

B21CEBD4

Delete file/folder

file_name, file_path, recursive

ファイルまたはフォルダーを削除します。フォルダーとコンテンツの削除に使用する任意指定の再帰的パラメータがあります。

406C9E35

Launch shell

start, stop, status, bash

COMSPEC(cmd.exe)シェルを起動します。stdin、stdout、stderrがメインのC2チャネルを介して中継されます。

72E99D37

Read file

file_name, file_path

ファイルの読み取り、すなわちC2へのアップロードが行われます。

04365407

Set C2 check-in interval

timeout

C2のチェックイン間隔を設定します。デフォルト設定は3時間です。

99598005

Set C2 check-in/activity schedule

day_of_month, day_of_week, hour,

インプラントがC2への接続を試みる日付/曜日、時刻を設定します。デフォルト設定ではすべての値が0であり、除外なしを意味します。そのため、チェックインは3時間ごとに行われます(デフォルトのスリープ間隔)。

1E46EC18

Get status information

None

インプラントのBuild_Id、Computer_Id、Full_Infoを返します。最後のコマンドの詳細とステータス(成功/失敗)

表4:インプラントの関数

おそらく、シェル機能は最も興味深いものです。全二重のCOMSPEC(cmd.exe)対話型セッションをオペレーターに提供し、HTTPS C2チャネルを介してリダイレクトされるstdin(入力)、stdout、tderr(コマンドが返す出力)を利用できます。シェルへのコマンドは攻撃者が発行し、その結果出力はほとんど瞬時に返されます。

Pocoフレームワークの"SMTPChannel"コンストラクターでシェルパイプが作成されているにもかかわらず(IDAシグネチャによって識別)、インプラントはSMTPをトランスポートとして利用していません。Linux環境の代名詞である"bash"パラメータは、さまざまなプラットフォームで使用できます。しかし、この例ではシェルへのコマンド送信に"bash"が使用されています。これは、付随する値をstdinに書き込むことで行われます。bashシェルはWindows 10が提供するLinux Subsystemで使用できますが、オペレーターがLinux Subsystemをインストールして使用していることを示す証拠がありません。

図6:インプラントの関数ディスパッチ

文字列の暗号化

インプラントにおける機密文字列のランタイムデコード全体で13個のそれぞれ固有のXORキーが使用されています。インプラントの各関数(表4に記載)はXORキーをそれぞれ備えており、C2、URL/HTTP、RSAの全般的な関連操作に使用されます。

キー:

使用対象:

F226E34F0B64528CF0

組み込みRSAキーの復号

371F41ABE4C8880BC1

URL/HTTP関連操作

40A521B0866411BAC4

汎用文字列の復号キー

EFEA221C400E2D1227

C2メッセージ

82EF8E95992055B6B5

C2メッセージ

4F840D589769

Create process関数

6EFEAF1AAA6932

Create file/download関数

59938EF1C8EFBA79B

Delete file/folder関数

722C1B76

Shell handler関数

1F4582D80B

Read file/upload関数

6A39E0FC68D6

Set C2 check-in interval関数

A24B726DFD

Set C2 activity schedule関数

597EB47AAD

Get host/install info関数

表5:XORエンコード/デコードのキー

まとめ

インプラントがバックドアの基本機能を提供するための機能セットを保持していることが解析を通じて明らかになっています。こうした機能の例として、ファイルのダウンロード/アップロード、コマンドのリモート実行、対話型のシェルアクセスなどが挙げられます。

公開されているAPT-28の"x-tunnel"の記述とこのインプラントの関数を比較しても、トンネリング、プロキシ、VPN型の機能は見られません。さらに、資格情報の収集、ネットワークサービスのスキャン、Windowsのレジストリ操作も実行されていません。モジュール性が欠如していることを考えると、更新されたバージョンのみがこれらの機能を提供するものと思われます。一方、このインプラントがダウンロードして実行する後続ツールにこれらの機能が存在することも考えられます。この代替シナリオのほうが可能性は高いかもしれません。

侵入の痕跡(IOC)

SHA256:

b40909ac0b70b7bd82465dfc7761a6b4e0df55b894dd42290e3f72cb4280fa44

C2ビーコンドメイン::

malaytravelgroup[.]com

DGAドメイン::

schooltillhungryprocess[.]com
reasonwithusefulpolicy[.]com
streetunderrelevantpeople[.]com
experiencewithweakkid[.]com
systembeforeniceparent[.]com

ミューテックス::

1b8232f6-6806-4733-901d-62bf3ef33e6c

ハードコードされたユーザーエージェント文字列::

“Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0”

Yaraシグネチャ

rule apt28_backdoor_cls
{
            strings:
            $st1 = "AES_256_poco" ascii
                       $st2 = "TEncryption" ascii
                       $st3 = "shell" ascii
            condition:
                       all of them
}

rule apt28_backdoor_crc32
{
               strings:
                              $xor1 = { 48 8B 07 39 48 0C 75 3A 44 8B 70 08 4C 8B 38 4D 85 C0 74 2E 45 85 E4 74 29 }                                      
               condition:
               $xor1
}

 

付録

 

復号された文字列テーブル:

テーブル1

テーブル2

テーブル3

different
used
important
every
large
available
popular
lonely
basic
known
various
difficult
several
unite
historical
hot
useful
mental
scare
additional
emotional
old
political
similar
healthy
financial
medical
traditional
former
entire
strong
actual
significant
successful
electrical
expensive
pregnant
intelligent
interesting
poor
happy
responsible
cute
helpful
recent
willing
nice
wonderful
impossible
serious
huge
rare
visible
typical
competitive
critical
desperate
immediate
aware
educational
environmental
global
decent
relevant
accurate
capable
dangerous
dramatic
efficient
powerful
foreign
hungry
friendly
psychological
severe
suitable
numerous
sufficient
unusual
anxious
cultural
curious
famous
pure
comprehensive
obvious
careful
impressive
unhappy
acceptable
aggressive
boring
inner
eastern
sudden
reasonable
strict
weak
civil

at
on
in
to
into
from
before
until
till
about
for
of
with
by
after
since
during
between
near
nearby
behind
across
above
over
under
below
along
round
around
past
through

street
company
part
system
number
world
case
work
party
girl
house
woman
life
people
year
day
way
thing
child
group
time
area
problem
place
hand
service
school
guy
country
point
week
relationship
end
word
family
fact
head
month
information
power
change
question
business
development
home
side
night
money
eye
interest
book
teacher
air
court
water
manager
form
food
ca
moment
level
room
car
story
market
effect
idea
opportunity
result
use
study
job
name
report
body
law
face
authority
friend
parent
minute
door
minister
road
rate
line
hour
war
mother
right
office
person
reason
view
term
period
centre
morning
project
research
figure
society
history
city
police
kind
million
community
need
tree
price
team
game
father
kid
student
support
program
health
field
man
example
quality
control
action
process
position
education
age
course
type
manner
order
decision
industry
mind
condition
paper
bank
century
activity
table
sense
building
experience
staff
language
plan
policy

 

表6:C2 DGA文字列

テーブル1

news
nwshp
section
pagead
ads
forum
general
topic
master
explore
features
enterprise
pricing
article
contact
security
about
status
blog
training
help
feedback
terms
activity
pricing
switch

表7:URLパス文字列テーブル

 

 

 

 

Tags: