-
タグ
タグ
- セキュリティ
- 人材開発・教育
- システム開発
- アプリ開発
- モバイルアプリ
- DX
- AI
- サイバー攻撃
- サイバー犯罪
- 標的型攻撃
- 脆弱性
- 働き方改革
- 企業市民活動
- 攻撃者グループ
- JSOC
- JSOC INSIGHT
- サイバー救急センター
- サイバー救急センターレポート
- LAC Security Insight
- セキュリティ診断レポート
- サイバー・グリッド・ジャパン
- CYBER GRID JOURNAL
- CYBER GRID VIEW
- ラックセキュリティアカデミー
- すごうで
- ランサムウェア
- ゼロトラスト
- ASM
- EDR
- XDR
- SASE
- デジタルアイデンティティ
- インシデントレスポンス
- 情シス向け
- 対談
- CIS Controls
- Tech Crawling
- クラウド
- クラウドインテグレーション
- データベース
- アジャイル開発
- DevSecOps
- OWASP
- CTF
- FalconNest
- セキュリティ診断
- IoT
- EC
- サプライチェーンリスク
- スレットインテリジェンス
- テレワーク
- リモートデスクトップ
- アーキテクト
- プラス・セキュリティ人材
- 障がい者採用
- 官民学・業界連携
- カスタマーストーリー
- 白浜シンポジウム
- CODE BLUE
- 情報モラル
- クラブ活動
- 初心者向け
- 趣味
- カルチャー
- 子育て、生活
- 広報・マーケティング
- コーポレート
- ライター紹介
- IR
ラックの脅威分析チームは、2022年4月頃から、KCPプロトコル※1をC2通信として利用する新たなマルウェア「gokcpdoor」を使用した攻撃活動を日本国内の製造業や学術機関などで確認しています。この攻撃活動は、中国を拠点とする攻撃者グループによるものと見られ、日本国内の組織や海外拠点へ同様の攻撃が行われている可能性がうかがえます。
※1 GitHub - skywind3000/kcp: :zap: KCP - A Fast and Reliable ARQ Protocol
そこで今回は、KCPプロトコルをC2通信として利用するgokcpdoorを利用した一連の攻撃キャンペーンをもとに、背後にある攻撃者像や同様の攻撃に対する検知や防御手法を紹介します。本内容は、2023年10月4日から6日に開催されたセキュリティカンファレンスVirus Bulletin Conference 2023(VB2023)にて、「Let's go door with KCP」というタイトルで詳細を発表しました※2。
※2 Virus Bulletin :: Let's go door with KCP
KCPプロトコルと代表的なライブラリ
KCPプロトコルの概要と代表的なライブラリであるkcp-go※3について解説します。
※3 kcp package - github.com/xtaci/kcp-go - Go Packages
KCPプロトコル
KCPは、2011年にskywind3000氏によって設計・開発された自動再送要求(ARQ)を行うトランスポート層の通信プロトコルです。
KCP自体は下位のデータの転送方式を定義していませんが、KCPを使用する多くの実装では下位のプロトコルとしてUDPを採用しており、UDP上でTCPのような高信頼を確保しながら低遅延の通信を実現しています。このような特徴から、プロキシソフトウェアやオンラインゲーム、ストリーミングサービスなどのリアルタイム性が求められるソフトウェアやサービスで使用されています。
図1は、KCPプロトコルにおける単方向のデータ送信を表したものです。KCPメッセージには、4つのコマンドがあり、このうちIKCP_CMD_PUSHとIKCP_CMD_ACKは、データの送信と確認応答を示すためのコマンドで頻繁に使用されます。残りのIKCP_WASKとIKCP_CMD_WINSは、ウィンドウプローブとウィンドウ更新通知のためのコマンドで、ネットワークや受信者の負荷状況に応じて送信者がデータの転送を停止した際に、通信を再開するにあたり必要なものです。

図2は、単方向からKCPメッセージを送信した際にキャプチャしたパケットデータです。UDPのペイロードとしてKCPメッセージが送受信されており、赤色の箇所がデータの送信、青色の箇所がデータの受信を示しています。この図では、文字列"Message sent by Host-A"を送信しています。また、各データの先頭から5バイト目がコマンドを表しており、赤色の箇所の0x51(81)はIKCP_CMD_PUSH、青色の箇所の0x52(82)はIKCP_CMD_ACKです。

このように、KCPプロトコルに則った通信では平文でデータがやり取りされます。なお、KCPメッセージのデータ構造の詳細については、Appendixの「KCPおよびkcp-goの伝送データ構造」をご参照ください。
kcp-goライブラリ
KCPプロトコルに基づいた通信を提供するGo言語のライブラリの1つとして、kcp-goがあります(図3)。kcp-goは、前方誤り訂正やデータの暗号化などを備えており、これを用いると再送のコストを削減しつつUDP上で暗号化したKCPメッセージを送受信できるようになります。KCPに関するライブラリの中では最も人気が高く、gokcpdoorもC2通信を行うにあたってkcp-goを採用しています。
kcp-goの暗号化処理は、AESやBlowfish、Salsa20などをサポートしており、CFBモードで行われます。また、暗号化時にランダムな値(Nonce)をデータの先頭に付与するため、同じ平文であっても暗号化後のデータが毎回異なります。このため、kcp-goによって暗号化されたUDP通信をキャプチャしたとしても、KCPメッセージを判別することは困難です。

KCPプロトコルを利用するマルウェア
図4は、KCPプロトコルを実装するマルウェアをコンパイルタイムスタンプの情報を基にタイムラインで時系列にまとめたものです。2020年4月頃からマルウェア「Crosswalk」※4にKCPプロトコルが実装されて以降、当該プロトコルを利用するマルウェアを目にする機会が増加しています。
※4 Higaisa or Winnti? APT41 backdoors, old and new(https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/)
一方、マルウェアを利用する攻撃者に焦点を当ててみると、多くのマルウェアがAPT41に関連していることもわかります。実は、これら多くのマルウェアは、KCPプロトコルを実際の攻撃活動に使用しているという報告はほとんどありません。このような状況の中、2022年3月、実際の攻撃活動で確認したgokcpdoorは、kcp-goライブラリを利用してKCPプロトコルでC2通信を行うマルウェアでした。

図5は、gokcpdoorにおけるKCPプロトコルの実装を確認するために、kcp-goライブラリのソースコード(kcp-go/kcp.go)と、gokcpdoorのprogram/kcp.(*KCP).Input関数のデコンパイルした擬似コードを比較したものです。gokcpdoorは、kcp-goのソースコードを利用していることが確認できます。

gokcpdoorの解析
gokcpdoorは、Go言語でコーディングされたバックドア型のマルウェアであり、Linux(ELF)版とWindows(PE)版を確認しています。C2通信は、前述した通り、KCPプロトコルを利用することが大きな特徴です。以降では、gokcpdoorの詳細な解析結果について解説します。
Windows版とLinux版の比較
はじめに、Linux版とWindows版のビルドバージョンを確認すると、いずれのバージョンもgo1.17.5でビルドされています(図6)。また、図7にある通り、コンパイル環境には「gokcpdoor1.0-20220301」という文字列が含まれていることがわかります。このことから当該マルウェアをgokcpdoorと命名しています。


次に、マルウェアの機能性を見てみると、こちらもLinux版とWindows版でどちらもほぼ同じ機能を有しています。ただし、Windows版には「main_WinExec」という名前の特徴的な関数が含まれています(図8)。
この関数は、文字通り、WinExec APIを呼び出すことで指定されたコマンドを実行するためのものであり、図9に示す通り、該当の関数でWinExecのアドレスを解決し、呼び出していることが確認できます。


バックドア機能
gokcpdoorは、Go言語のnet.ResolveUDPAddr関数※5およびnet.ListenUDP関数※6を使用して、ハードコードされたポート番号で待ち受けます(図10)。
※5 net package - net - Go Packages "ResolveUDPAddr"
※6 net package - net - Go Packages "ListenUDP"

開放するポート番号などの情報は、XOR演算およびBase64でエンコードされています。図11に示すLinux版のgokcpdoorサンプルの場合は、図上部のオフセット0x7aefd0(off_7AEFD0)に暗号化されたバイナリがあります。このデータをハードコードされたXORキーでXOR演算後、Base64でデコードを行うと、図下部のように開放アドレスとポートを表す"0.0.0.0:10054"(赤色の枠)と識別子を表す"nId2jUd3Ld1Fxe"(橙色の枠)を確認できます。
なお、識別子は、バックドアのコマンド操作開始時に使う固定文字列であり、これをバックドアに対して最初に送信することで、gokcpdoorがコマンドを受け付ける状態になります。

gokcpdoorがサポートするバックドアコマンドは20種類あり、図12のように実装されています。これらのコマンドには、任意コマンドの実行やダウンロード実行、任意ファイルのアップロード、ポートフォワードなどがあり、バックドアが動作する被害ホストを完全に制御できます。コマンド一覧およびその内容の詳細については、Appendixの「C2コマンド」をご参照ください。

通信データと暗号化処理
図13は、バックドアとC2サーバの間でやり取りされるC2コマンドおよび実行結果が、内部でUDPパケットにカプセル化されるまでの処理過程を示したものです。
C2コマンドなどのデータは、まずBase64エンコードされ、改行コードを末尾に付けた形式で、前述のkcp-goライブラリの送信処理に渡されます。その後、kcp-goライブラリによってKCPメッセージが生成され、そのKCPメッセージを組み込んだkcp-goフォーマットのデータが生成されます。そして暗号化後にUDPパケットのデータとして格納されます。

データの暗号化処理として、gokcpdoorはAES-256を使用します。図14は、gokcpdoorにおいてKCPプロトコルを利用したC2通信の暗号化処理を定義した部分のコードです。このコードでは、PBKDF2-HMAC-SHA1でハードコードされたパスワードとソルトなどから32バイトの鍵を導出し、その導出鍵をAES暗号化のためにNewAESBlockCrypt関数へ渡しています。gokcpdoorの通信データを復号する場合、この導出鍵(もしくは導出時のパラメータ)が必要となります。

類似マルウェア「gokcprat」
gokcpdoorを使用した攻撃活動を調査する過程で、利用しているライブラリやコード、含まれている文字列などが類似する「gokcprat」というマルウェアも確認しています(図15)。
gokcpratは、表1に示す通り、ビルドバージョンやVirus Totalの投稿時期から、gokcpdoorよりも前に開発された可能性が高く、また、コマンドの数がgokcpdoorより少ない特徴があります。また、機能面で見れば、gokcpdoorがポートを開放して外部からの接続を待ち受けるのに対し、gokcpratは外部へコールバック通信を発生させる点が大きく異なります。

比較要素 | gokcpdoor | gokcprat |
---|---|---|
ビルドバージョン | go1.17.5 | go1.16.6 |
サポートOS | Linux, Windows | Linux |
通信手段 | Listen | Reverse |
暗号化方法 | PBKDF2 and AES-256 | PBKDF2 and AES-256 |
コマンド数 | 20種類 | 15種類 |
通信プロトコル | KCP | KCP |
Virus TotalにおけるFirst Submissions | 2022年7月12日 | 2021年11月18日 |
攻撃者グループの考察
図16は、2021年から2022年にかけて確認したgokcpdoorに関連する攻撃手口の一例です。この攻撃者グループは、窃取した認証情報やクライアント証明書などを使用して、SSL-VPN経由で被害者のネットワークに侵入し、端末やサーバにマルウェアやツールセットを設置します。この事例では、gokcpdoorをはじめ、別のマルウェア「ABK downloader」※7やデュアルユースツール(PsExec、MimikatzやWinRAR)などが設置されていました。
※7 An Overhead View of the Royal Road | @nao_sec

攻撃者グループが使用するマルウェア
ABK downloaderは、ダウンローダ型マルウェアで、攻撃者グループTickが使用するマルウェアの1つです。今回の事例で見つかったABK downloaderは、次の動作を行うことを確認しています。
図17は、ABK downloaderの動作概要です。ABK downloaderは、TickやTonto Teamで利用されるマルウェア「OAED Loader」※8にXORで暗号化されて内包されています。このOAED Loaderは、DLLサイドローディングによって実行され、Process Hollowingを利用してABK downloaderをsvchost.exeなどの正規のプロセスにインジェクションし、動作させます。また、文字列「v|xI?1bW」をマーカーとして、以降のバイナリデータをXOR演算し、AKB downloaderを復号します(図18)。
※8 標的型攻撃の実態と対策アプローチ 日本を狙うサイバーエスピオナージの動向2020年度|Macnica Networks、TeamT5


ABK downloaderには、主に次の4つの機能があります。
- Symantec社、TrendMicro社、Qihoo 360社およびMcAfee社のセキュリティ対策製品を検出(図19)
- MACアドレス、システム情報、およびセキュリティソフトの情報を収集し、空白文字なしのUser-Agentを利用してC2サーバにこれらのデータを送信(図20)
- GetLocalTime APIを使用して、"8:00-18:00"の就業時間と考えられる時間帯にのみ動作
- 正規のWebサイトを侵害し、C2サーバやマルウェア置き場として利用


攻撃者グループとマルウェアの関係性
図21は、攻撃者グループとマルウェアの関係性を表したものです。前述したように、KCPプロトコルを使用するマルウェアの多くはAPT41と関連しており、gokcpdoorもその1つであると疑われます。しかしながら、確認した攻撃事例では、Tickが使用するマルウェア(ABK downloaderおよびOAED Loder)と共にgokcpdoorが確認できており、当該マルウェアは、Tickとの関連があると考えられます。
攻撃者グループの帰属の概要については、Appendixの「Diamond Model」を参照してください。

対策
KCPプロトコルやgokcpdoorに関する攻撃キャンペーンへの対策について紹介します。
なお、gokcpdoorやgokcpratのC2通信はAESで暗号化されているため、KCPトラフィックとして検出を行うためには、通信を復号する必要があります。
KCPトラフィックの検出
KCPトラフィックには、KCP特有のメッセージヘッダフィールドが存在しますが、KCPプロトコルを識別するための特徴が少なく、ネットワークトラフィックからKCPだけを検出することは困難です。ネットワークセキュリティ製品などを利用している場合は、「Unknown UDP Traffic」などのアラート種別で検出することがあり、そのような特徴的なアラートを確認する方法が最も現実的です。
また、UDPパケットをキャプチャ可能な環境の場合、UDPペイロードにKCPのコマンドが存在するかを確認することで、KCPの通信を判別できる可能性があります。
例えば、Splunkでは、Splunk Streamを用いてパケットをキャプチャした上で、図22に示すサーチクエリを利用すればログからKCPトラフィックを検出できます。このクエリは、UDPのキャプチャログから、送受信内容の5バイト目がKCPのコマンド(IKCP_CMD_PUSHとIKCP_CMD_ACK)であるものをサーチします。
なお、本クエリを使用する場合は、別途Splunk Steamのデプロイおよびキャプチャ設定が必要となります。設定方法については、Appendix「Splunk Steamの設定方法」を参照してください。

また、Wiresharkにおいて、KCPプロトコルを分析可能なKCP dissectorプラグインを使用することで、不審なUDPトラフィックをKCPトラフィックとして識別することもできます。図23は、CandyMi氏によって開発されたプラグイン※9を使用した例です。
※9 GitHub - cfadmin-cn/kcp_dissector: kcp dissector based on wireshark.

gokcpdoorの検知
gokcpdoorは、マルウェア内に含まれる特徴的な文字列や、バックドアとして動作した際の実行痕跡から、以下の4つの手法で検知できる可能性があります。
- Yaraルールによるスキャン(Appendix「Yaraルール」)
- AutorunsによるAutoStart Extensibility Points(ASEP)のチェック
- Sysmonのプロセス作成イベントおよびネットワーク接続イベントのログのチェック(図24)
- EDR製品のプロセスツリーからのシェルコマンド実行のチェック(図25)


まとめ
gokcpdoorは、C2通信にKCPプロトコルを使用するGo言語でコーディングされたバックドア型のマルウェアです。同じ開発者が作成したと思われるgokcpratの存在も確認しており、いずれも検体内にバージョン情報と考えられる文字列が含まれていることから、攻撃者は、今後も機能を改善した類似検体の開発を継続する可能性があります。
また、昨今、KCPプロトコルを利用するマルウェアを目にする機会が増えており、攻撃者は今後もKCPプロトコルをC2通信の一手段として利用するマルウェアを攻撃に使用することが予想されます。このため、十分に警戒し、EDR製品を利用したエンドポイントの監視やネットワーク機器を利用した通信制御および監視といった、セキュリティ対策を講じていくことが重要です。
ラックの脅威分析チームでは、今後もこの攻撃者グループおよび利用されたマルウェアについて、継続的に調査し、広く情報を提供していきますので、ご活用いただければ幸いです。
松本 拓馬、石川 芳浩
Appendix
KCPおよびkcp-goの伝送データ構造

フィールド | サイズ | 説明 |
---|---|---|
conv | 4bytes | セッション番号 |
cmd | 1byte | コマンド |
frg | 1byte | フラグメント数 |
wnd | 2byte | ウィンドウサイズ |
ts | 4bytes | タイムスタンプ |
sn | 4bytes | シリアル番号 |
una | 4bytes | 受信済みのKCPメッセージ数 |
len | 4bytes | データの長さ |
data | 可変長 | データ |

Field | Size | Description |
---|---|---|
Nonce | 16bytes | ランダムな値 |
CRC32 | 4bytes | CRC32チェックサム |
FEC SEQ ID | 4bytes | FECシーケンスID |
FEC Type | 2bytes | FECタイプ |
Size | 2bytes | データの長さ |
Data | 可変長 | KCPメッセージまたはFECのParity Shard |
C2コマンド
Command | Description |
---|---|
exec | 任意のコマンド実行 |
shell | リバースシェル。コマンドプロンプトを起動し、インタラクティブに操作 |
wget | 指定されたURLから感染端末へファイルのダウンロード |
upload | C2サーバから感染端末にファイルをアップロード |
download | 感染端末からC2サーバにファイルをダウンロード |
dir / ls | カレントディレクトリのファイル一覧を取得 |
mkdir | ディレクトリを作成 |
rm | 任意のパスのファイルおよびフォルダを削除 |
cd | ディレクトリを移動 |
pwd | カレントディレクトリのパスを取得 |
whoami / id | "whoami"または"id"コマンドを実行し、コンピュータ名とユーザ名を取得 |
getos | "wmic os get name"または"uname -a"コマンドを実行し、OS情報を取得 |
ps | 実行中のプロセス一覧を取得 |
ifconfig / ipconfig | ネットワーク設定情報を取得 |
netstat | ネットワークの接続状況を取得 |
portfoward |
|
socks5 |
|
charset | 文字コードを変更(UTF-8のみをサポート) |
back | コマンド操作を終了 |
exitprocess | 自身のプロセスを終了 |
Yaraルール
rule gokcpdoor { meta: description = "Detects gokcpdoor malware" author = "LAC Co., Ltd." strings: $str1 = "gokcpdoor" ascii $str2 = "exec_lin.go" ascii $str3 = "exec_win.go" ascii $str4 = "syscmds/ps_linux.go" ascii $str5 = "syscmds/ps_windows.go" ascii $str6 = "target.go" ascii condition: (4 of ($str*)) and filesize > 2MB }
* 本番システムに導入する前に、適切なテストとチューニングを行うことを推奨します。
Splunk Steamの設定方法


Diamond Model

IOC(Indicator Of Compromised)
Indicator | Indicator | Type | Type | Context |
---|---|---|---|---|
86f02e9f344a8e8009e59ecae934a780 | MD5 | ABK Downloader | ||
d85c9b3d49b1af482c384a4253c16e28ae65a0f5 | SHA1 | |||
61eb25a6e6457087232de7ce7cd7b6cd9926e10674487c9e55b9a3fa54748b4c | SHA256 | |||
Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0) | User-Agent | |||
a6f4a5ec66b7c5f275e793be02885543 | MD5 | gokcpdoor for Linux | ||
bdb3db1013b16cb64b3f8156eae621054fa334bf | SHA1 | |||
2dd8ab1493a97e0a4416e077d6ce1c35c7b2d8749592b319a7e2a8f4cd1cc008 | SHA256 | |||
fa4a45c531a19744e91bbfb9da1b29c0 | MD5 | gokcprat for Linux | ||
f43e693cf6d459506249d1801742a190c3a4b483 | SHA1 | |||
993dbbce860539e1b7a1f91ebacc0ee7f1cd1a6cc37a9c7a2a2647fc64382f56 | SHA256 | |||
103.97.179[.]182 | C2 |
タグ
- セキュリティ
- 人材開発・教育
- システム開発
- アプリ開発
- モバイルアプリ
- DX
- AI
- サイバー攻撃
- サイバー犯罪
- 標的型攻撃
- 脆弱性
- 働き方改革
- 企業市民活動
- 攻撃者グループ
- JSOC
- もっと見る +
- JSOC INSIGHT
- サイバー救急センター
- サイバー救急センターレポート
- LAC Security Insight
- セキュリティ診断レポート
- サイバー・グリッド・ジャパン
- CYBER GRID JOURNAL
- CYBER GRID VIEW
- ラックセキュリティアカデミー
- すごうで
- ランサムウェア
- ゼロトラスト
- ASM
- EDR
- XDR
- SASE
- デジタルアイデンティティ
- インシデントレスポンス
- 情シス向け
- 対談
- CIS Controls
- Tech Crawling
- クラウド
- クラウドインテグレーション
- データベース
- アジャイル開発
- DevSecOps
- OWASP
- CTF
- FalconNest
- セキュリティ診断
- IoT
- EC
- サプライチェーンリスク
- スレットインテリジェンス
- テレワーク
- リモートデスクトップ
- アーキテクト
- プラス・セキュリティ人材
- 障がい者採用
- 官民学・業界連携
- カスタマーストーリー
- 白浜シンポジウム
- CODE BLUE
- 情報モラル
- クラブ活動
- 初心者向け
- 趣味
- カルチャー
- 子育て、生活
- 広報・マーケティング
- コーポレート
- ライター紹介
- IR