IDA Python(~ Appcall 編 ~)

0x1 はじめに

IDAPython - くじらとたぬき ではIDA Pythonを用いていくつか例を記述してみた.

今回はAppcall を用いた例について, 覚書を記しておく.

0x2 Appcall とは

Appcall is a mechanism to call functions inside the debugged program from the debugger or your
script as if it were a built-in function.
Such a mechanism can be used for debugging, fuzzing and testing applications.
Appcall mechanism highly depends on the type information of the function to be called. For that
reason it is necessary to have a correct function prototype before doing an Appcall, otherwise
different or incorrect results may be returned

関数をスクリプトでいい感じに実行できるという機能.
ファジングとか難読化の解析などが想定される. 地味に解析やってるときに便利そう.(IDAでデバッグするかどうかは別として...)

0x3 実行例

シンプルな以下のプログラムを作成する.

その1(MessageBoxA)

Script command(Shift F2)から以下のコードを入力.

Appcall.MessageBoxA(0, "hoge", "hogehoge", 0)

f:id:kmdnet:20200116203603p:plain

MessageBoxが実行されるのを確認.

その2(add_func 関数を呼び出す)

同様に以下のコードを入力. (※ add_func関数はsub_F75E8Cに相当する)

proto = "int sub_F75E8C(int a, int b);"
func = Appcall.proto(0xF75E8C, proto);
ret = func(Appcall.int64(2), Appcall.int64(3));
print(ret)

f:id:kmdnet:20200116203954p:plain

add_func 関数が実行されるのを確認.

0x4 所感

使いどころはいろいろありそう.

0x5 参考

https://hex-rays.com/products/ida/support/tutorials/debugging_appcall.pdf

Windows の遠隔管理ツールについて

0x1 はじめに

Windowsを遠隔管理できるツールについてのメモ

0x2 検証環境

各ツールでプロセス(calc.exe)を実行し, Sysmon +ProcExp を利用してそれぞれの結果を検証することをゴールとする.

前処理(必要に応じて)

  • PSVersionを 5.1.14409.1005に変更
  • 識別されていないネットワークをプライベートネットワークに変更する.
    • グループポリシーを変更(Security Settings -> Network List Manager Policies -> Unidentified NetworkでLocation typeをPrivateに変更)
  • FWを無効化

0x3 検証

WMI(Windows Management Instrumentation)

  • 実行コマンド
> wmic /node:192.168.56.106 /user:IEUser /password:Passw0rd! process call create calc
  • 結果 f:id:kmdnet:20191116134243p:plain
Integrity Levels(calc.exe) High
Session 0
ParentImage C:\Windows\System32\wbem\WmiPrvSE.exe
ParentCommandLine C:\Windows\system32\wbem\wmiprvse.exe -secured -Embedding
Integrity Levels(WmiPrvSE.exe) System
ParentImage(Parent) C:\Windows\System32\svchost.exe
ParentCommandLine(Parent) C:\Windows\system32\svchost.exe -k DcomLaunch
Integrity Levels(svchost.exe) System

WinRM

コマンド

  • Win 7(192.168.56.106)
> winrm qc
  • Win 8(接続元)
# 追加
> Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.56.106"
# 確認
> Get-Item WSMan:\localhost\Client\TrustedHosts
   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client

Type            Name                           SourceOfValue   Value
----            ----                           -------------   -----
System.String   TrustedHosts                                   192.168.56.106
# 情報収集
> winrm id -r:192.168.56.106
IdentifyResponse
    ProtocolVersion = http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
    ProductVendor = Microsoft Corporation
    ProductVersion = OS: 6.1.7601 SP: 1.0 Stack: 3.0
    SecurityProfiles
        SecurityProfileName = http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/spnego-kerberos

WinRS(Windows Remote Shell)

  • コマンド
> winrs -r:192.168.56.106 calc
  • 結果

f:id:kmdnet:20191116212530p:plain

Integrity Levels(calc.exe) High
Session 0
ParentImage C:\Windows\System32\cmd.exe
ParentCommandLine C:\Windows\system32\cmd.exe /C calc
Integrity Levels(WmiPrvSE.exe) High
ParentImage(Parent) C:\Windows\System32\winrshost.exe
ParentCommandLine(Parent) C:\Windows\system32\WinrsHost.exe -Embedding
Integrity Levels(winrshost.exe) High
ParentImage(PParent) C:\Windows\System32\svchost.exe
ParentCommandLine(PParent) C:\Windows\system32\svchost.exe -k DcomLaunch
Integrity Levels(svchost.exe) System

PsExec

  • 実行コマンド
> PsExec.exe \\192.168.56.106 -u IEUser -p Passw0rd! calc
  • 結果 f:id:kmdnet:20191117190805p:plain
Integrity Levels(calc.exe) High
Session 0
ParentImage C:\Windows\PSEXESVC.exe
ParentCommandLine C:\Windows\PSEXESVC.exe
Integrity Levels(PSEXESVC.exe) System
ParentImage(Parent) C:\Windows\System32\services.exe
ParentCommandLine(Parent) CC:\Windows\System32\services.exe
Integrity Levels(services.exe) System

0x4 まとめ

- ParentImage Integrity Levels(calc.exe) Session
WMI C:\Windows\System32\wbem\WmiPrvSE.exe High 0
WinRS C:\Windows\System32\winrshost.exe(cmd.exe) High 0
PsExec C:\Windows\PSEXESVC.exe High 0

0x5 所感

EDR等の監視の参考にでも.

0x6 参考文献

jpcertcc.github.io

マネージドコード(CLR)を呼び出す

0x1 はじめに

C(++)からマネージドコード(CLR)を呼び出す手法を示す.

0x2 ソースコード

  • test.cs

0x3 実行

 csc /target:library .\test.cs 

0x4 備考

ここからメイン(?)

GUID

  • CLSID_CLRMetaHost : {9280188D-0E8E-4867-B30C-7FA83884E8DE}
  • IID_ICLRMetaHost : {D332DB9E-B9B3-4125-8207-A14884F53216}
  • IID_ICLRRuntimeInfo : {BD39D1D2-BA2F-486A-89B0-B4B0CB466891}
  • CLSID_CLRRuntimeHost : {90F1A06E-7712-4762-86B5-7A5EBA6BDB02}
  • IID_ICLRRuntimeHost : {90F1A06C-7712-4762-86B5-7A5EBA6BDB02}

ppv

  • pMetaHost->GetRuntime : [edx+0Ch]
  • pRuntimeInfo->GetInterface : [edx+24h]
  • pRuntimeHost->Start : [ecx+0Ch]
  • pRuntimeHost->ExecuteInDefaultAppDomain : [edx+2Ch]

0x5 参考文献

MSBuildのインラインタスクについて

1. はじめに

MSBuildのインラインタスクを用いることによってコード実行が可能となる.

2. 手法

以下のxmlファイルを作成して, msbuildで実行するだけ(簡単!)

3. 実行結果

PS C:\Users\test\Desktop\work> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe test.xml
Microsoft (R) Build Engine バージョン 4.8.3752.0
[Microsoft .NET Framework、バージョン 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

2019/08/05 22:33:32 にビルドを開始しました。
test


ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:00.79

4. 参考文献

MSBuild インライン タスク - Visual Studio | Microsoft Docs

検証環境構築(L3スイッチ+ルータ(セキュリティ製品)+VLAN)

はじめに

セキュリティ製品の検証環境構築の簡単なメモ.
L3スイッチ(Cisco) + ルータ(セキュリティ製品を想定)でVLAN環境を作る.
今回はPacket Tracerを用いた. www.netacad.com

検証環境構築

パターン1

L3スイッチでVLANを分けて, トランクポートで接続するパターン

f:id:kmdnet:20190707235117p:plain

スイッチ

  • Switch>ena
  • Switch#conf t
    // Create VLAN
  • Switch(config)#vlan 10
  • Switch(config-vlan)#exit
  • Switch(config)#vlan 20
  • Switch(config-vlan)#exit
    // Assign VLAN
  • Switch(config)#interface range fastEthernet 0/1-10
  • Switch(config-if-range)#switchport mode access
  • Switch(config-if-range)#switchport access vlan 10
  • Switch(config-if-range)#exit
  • Switch(config)#interface range fastEthernet 0/11-20
  • Switch(config-if-range)#switchport mode access
  • Switch(config-if-range)#switchport access vlan 20
  • Switch(config-if-range)#exit
    // 0/24 → trunk port
  • Switch(config)#int fastEthernet 0/24
  • Switch(config-if)#switchport mode trunk

ルータ

  • Router>enable
  • Router#conf t
  • Router(config)#interface fastEthernet 0/0.1
  • Router(config-subif)#encapsulation dot1Q 10
  • Router(config-subif)#ip address 192.168.10.1 255.255.255.0
  • Router(config)#interface fastEthernet 0/0.2
  • Router(config-subif)#encapsulation dot1Q 20
  • Router(config-subif)#ip address 192.168.20.1 255.255.255.0
  • Router(config-subif)#exit
  • Router(config)#interface fastEthernet 0/0
  • Router(config-if)#no shutdown

疎通確認

C:\>ipconfig /all

FastEthernet0 Connection:(default port)

   Connection-specific DNS Suffix..: 
   Physical Address................: 00D0.BC33.622B
   Link-local IPv6 Address.........: FE80::2D0:BCFF:FE33:622B
   IP Address......................: 192.168.10.101
   Subnet Mask.....................: 255.255.255.0
   Default Gateway.................: 192.168.10.1
   DNS Servers.....................: 0.0.0.0
   DHCP Servers....................: 0.0.0.0
   DHCPv6 Client DUID..............: 00-01-00-01-ED-E8-A9-A3-00-D0-BC-33-62-2B

Bluetooth Connection:

   Connection-specific DNS Suffix..: 
   Physical Address................: 0010.1163.B814
   Link-local IPv6 Address.........: ::
   IP Address......................: 0.0.0.0
   Subnet Mask.....................: 0.0.0.0
   Default Gateway.................: 0.0.0.0
   DNS Servers.....................: 0.0.0.0
   DHCP Servers....................: 0.0.0.0
   DHCPv6 Client DUID..............: 00-01-00-01-ED-E8-A9-A3-00-D0-BC-33-62-2B


C:\>ping 192.168.10.102

Pinging 192.168.10.102 with 32 bytes of data:

Reply from 192.168.10.102: bytes=32 time=1ms TTL=128
Reply from 192.168.10.102: bytes=32 time<1ms TTL=128
Reply from 192.168.10.102: bytes=32 time=11ms TTL=128
Reply from 192.168.10.102: bytes=32 time=3ms TTL=128

Ping statistics for 192.168.10.102:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 11ms, Average = 3ms

パターン2

いろいろあってトランクポートを用いない場合()

f:id:kmdnet:20190708221445p:plain

スイッチ

  • enable
  • conf t
    // Create VLAN
  • Switch(config)#vlan 10
  • Switch(config-vlan)#exit
  • Switch(config)#vlan 20
  • Switch(config-vlan)#exit
    // Assign VLAN
  • Switch(config)#interface range fastEthernet 0/1-10
  • Switch(config-if-range)#switchport mode access
  • Switch(config-if-range)#switchport access vlan 10
  • Switch(config-if-range)#exit
  • Switch(config)#interface range fastEthernet 0/11-20
  • Switch(config-if-range)#switchport mode access
  • Switch(config-if-range)#switchport access vlan 20
  • Switch(config-if-range)#exit
    // 0/23, 0/24 → Access port
  • Switch(config)#interface fastEthernet 0/23
  • Switch(config-if)#switchport mode access
  • Switch(config-if)#switchport access vlan 10
  • Switch(config-if)#exit
  • Switch(config)#interface fastEthernet 0/24
  • Switch(config-if)#switchport mode access
  • Switch(config-if)#switchport access vlan 20
  • Switch(config-if)#exit

ルータ

  • Router>ena
  • Router#conf t
  • Router(config)#interface fastEthernet 0/0
  • Router(config-if)#ip address 192.168.10.1 255.255.255.0
  • Router(config-if)#no shutdown
  • Router(config-if)#exit
  • Router(config)#interface fastEthernet 0/1
  • Router(config-if)#ip address 192.168.20.1 255.255.255.0
  • Router(config-if)#no shutdown
  • Router(config-if)#exit

おまけ

VLAN単位でポートミラーリングを行いたい場合.
- Switch>ena
- Switch#conf t
- Switch(config)#monitor session 1 destination interface fastEthernet 0/22

所感

今回はルータ側の処理も記述したが, 本来はセキュリティ製品側で設定する.
限られた資源で環境構築するときに:)

Process Hollowing

1. はじめに

Process Injectionの手法の一つにProcess Hollowingがある.
今回はProcess Hollowingについて調べてみた覚書.

2. 手法

2.1. 検証環境

Windows 7/10

・Dest(Destination) : インジェクションされるプロセス

・Src(Source): インジェクションするPEファイル

以下それぞれのプロセスに対する操作をDest, Srcで示す.

2.2. インジェクションフロー概要

1) Destのプロセスを待機状態(CREATE_SUSPENDED)で作成する(via CreateProcess)

2) DestのPEBを得る(via ntdll!NtQueryInformationProcess)
ここでImageBaseを得る

3) SrcのPEヘッダーをparse
ここでNumberOfSections, Section headerを得る

4) DestをImageBaseを基準としてUnmap(空洞化)する(via ntdll!NtUnmapViewOfSection)

5) DestをImageBaseからOptionalHeader.SizeOfImageだけメモリを確保(via VirtualAllocEx)

6) DestにSrcのヘッダーをOptionalHeader.SizeOfHeadersだけ書き込む(via WriteProcessMemory)

7) DestにSrcのSectionの数(NumberOfSections)だけセクションを書き込む(via WriteProcessMemory)

8) DestとSrcのImageBaseのアドレスが異なる場合, Srcの".reloc"セクションの情報をもとにベースの再配置を行う.

9) (Dest)PEBのImageBaseAddress + SrcのAddressOfEntryPointをEAXに設定->プロセスを再開する(via GetThreadContext -> SetThreadContext -> ResumeThread)

2.3. 補足

2.3.1 PEB(Process Environment Block)について

PEBは以下の構造体で定義される(winternl.h).


typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged;
    BYTE Reserved2[1];
    PVOID Reserved3[2];
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PVOID Reserved4[3];
    PVOID AtlThunkSListPtr;
    PVOID Reserved5;
    ULONG Reserved6;
    PVOID Reserved7;
    ULONG Reserved8;
    ULONG AtlThunkSListPtr32;
    PVOID Reserved9[45];
    BYTE Reserved10[96];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE Reserved11[128];
    PVOID Reserved12[1];
    ULONG SessionId;
} PEB, *PPEB;

ここでReserved3[1]はImageBaseAddressに対応する.

 

2.3.2 ベースの再配置について

 relocation tableには以下の2つの構造体から定義される(winnt.h).

※TYPE_OFFSETは筆者が作成した構造体.


typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
//  WORD    TypeOffset[1];
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

typedef struct _TYPE_OFFSET {
	WORD offset : 12;
	WORD Type : 4;
}TYPE_OFFSET, *PTYPE_OFFSET;

 

上記の構造体は以下の図のように配置されている.

f:id:kmdnet:20190528210522p:plain

TYPE_OFFSETの数は

(IMAGE_BASE_RELOCATION.SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(TYPE_OFFSET)

で求められる.

2.4. 実行結果

恒例の電卓(calc.exe)に対してProcess Hollowingを用いて, プロセスインジェクションした結果.

f:id:kmdnet:20190523220741p:plain

3. 所感

Process Hollowing : プロセスの空洞化(そのまま)

4. 参考文献

https://www.endgame.com/blog/technical-blog/ten-process-injection-techniques-technical-survey-common-and-trending-process

https://github.com/m0n0ph1/Process-Hollowing

Windows Serviceのデバッグ

概略

Windows Serviceのデバッグを行いたい場合のためのメモ

自己責任で(VM推奨)

デバッグした後は元の環境に戻す(重要)

環境

Windows 7 x86 (VirtualBox)



手法 その1

サービスの初期状態からデバッグできるようにする

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Optionにプログラム名のレジストリキーを作成する.


    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution
    String Value
    Value name : Debugger
    Value data : <debugger path> -server npipe:pipe=<Session Name>

今回の場合は以下のようにした.


    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution
    String Value
    Value name : Debugger
    Value data : C:\Debuggers\x86\ntsd.exe -server npipe:pipe=hoge

セッション分離

Windows Vista以降はセッションが分離されているため上記の方法をとる.

それより前のOSだと直接WinDbgを指定してやれば良いらしい(未確認).

f:id:kmdnet:20180522162816p:plain

Let's Debug!

WinDbg → Connect to Remote Session(Ctrl+R)


npipe:server=localhost,pipe=hoge

タイムアウト時間の調整

サービスのタイムアウト時間を伸ばさないとすぐ終了してしまう. デフォルトで30000ミリ秒(30秒).


C:\Windows\System32>sc start MySrv
[SC] StartService FAILED 1053:

The service did not respond to the start or control request in a timely fashion.

f:id:kmdnet:20180522160852p:plain

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Controlでデフォルトのタイムアウト時間を伸ばす. → 再起動


    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
    DWORD
    Value Name : ServicesPipeTimeout
    Value data : 86400000(Decimal)

※ 86400000(Decimal) = 24hours

※ 全てのサービスに影響するためデバッグ後は修正する



手法 その2(svchostと依存関係がある場合)

svchost.exeと依存関係がある場合, 孤立させる必要がある.

今回はBITS(Background Intelligent Transfer Service)を対象にする.


C:\Windows\System32>sc qc bits
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: bits
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 2   AUTO_START  (DELAYED)
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\System32\svchost.exe -k netsvcs
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Background Intelligent Transfer Service
        DEPENDENCIES       : RpcSs
                           : EventSystem
        SERVICE_START_NAME : LocalSystem

見る箇所はBINARY_PATH_NAMEのグループ名(netsvcs). ちなみにsvchost -k (group).

新しいグループ(TempGrp)を作成する.


    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost 
    REG_MULTI_SZ
    Value Name : TempGrp
    Value data : 孤立させたいサービスのValue data

※ 作成したグループのValue dataにnetsvcsのValue dataを指定する.

f:id:kmdnet:20180522212132p:plain

元々のグループのsub keyを作成したグループにコピーする.

今回の場合はnetsvcsなのでAuthenticationCapabilities, CoInitializeSecurityParamを新しいグループにコピーすれば良い.

f:id:kmdnet:20180522213303p:plain

サービスのパスを修正する.


C:\Windows\System32>sc config BITS binPath= "C:\Windows\system32\svchost.exe -k TempGrp"
[SC] ChangeServiceConfig SUCCESS

※ 細かい所だけどbinPathはクオーテーションで囲む, binPath=の後のスペースは必要. ハマりやすい所なので注意.

必要に応じてサービスの再起動を行う. あとは手法 その1と同じ.



手法 その3(非推奨)

MSDNによると非推奨.

svchostを複製する.

%SystemRoot%\System32にsvchost.exeをコピーしてsvchost2.exeを作成する.


C:\Windows\System32>sc config BITS binPath= "C:\Windows\System32\svchost2.exe -k netsvcs"
[SC] ChangeServiceConfig SUCCESS

必要に応じてサービスの再起動を行う. あとは手法 その1と同じ.

所感

個人的には手法1と3(適当)

参考文献

Debugging a Service Application | Microsoft Docs