Pixiv - KiraraShss
707 words
4 minutes
Windows Binary Exploitation筆記
使用工具
- VM
- 分析工具 : PEBear, DLL Export Viewer
- 組語除錯工具 : WinREPL
- C++ ROP Gadget : rp++
- Debugger : x64dbg, Windbg Preview
Windbg操作
|: Process Status~: Thread Status- 顯示記憶體內容 :
d{b|d|q|u}+Ln(顯示N個) - 以某種資料結構解讀 :
dt (module)!_name+rn(recursive) - 對記憶體寫入 : 數值
e{b|d|q}, 字串e{a|u|za|zu}(z : 指以NULL做結尾) - 暫存器 :
r,r [reg] = [val] - 取值 :
poi - 反組譯 :
u,uf - 斷點 :
bp [addr] .if [cond]{} .else{gc} - 列出載入的模組 :
lm - 執行 :
go, Step in :t, Step over :p - Mapping :
!address - 查看權限 :
!vprot - 查看Error Code :
!error Value [Flags], Flags=Win32, NTSTATUS… - 查看Symbol :
x module!symbol
呼叫慣例
- 流程控制 :
call/ret - 參數 : 使用 CX, DX, R8, R9, stack
- Prologue, Epilogue : 保存/恢復上一個frame的RBP
Buffer Overflow
列舉一些危險的函數
gets()scanf()stcpy()sprintf()memcpy()strcat()
會覆蓋到在stack frame以下的saved RIP
Dynamic Library
- Dynamic-Link library
- ntdll : Native API
- kernelbase : kerel32中部分函數(偏核心)
- kernel32 : Win32API
- msvcrt : Windows Libc
IAT
- Import Address Table
- 類似Linux GOT
保護機制
- DEP : NX
- Security Cookie : 類似Linux Stack Canary
- ASLR : library的基址在開機時就決定了, 同一隻DLL在不同Process使用CoW機制
- CFG : Link時建立function table, 執行期間建立bitmap, 避免indirect jump
- 只檢查通往的函數, 不會檢查如何過來這個函數
- CFG-SupressExports mode : 禁止其他合法DLL函數, 不過還是可以利用相同image
- ACG : 禁止創造RWX segment
- Child Process Policy : 禁止fork出新的process
Shellcode
-
System call number經常修改
- 呼叫API -> 需要找出API的位址
-
_TEB : Thread Environment Block
- 執行緒資訊
- _NT_TIB : Exception List, Stack
- PEB位址
- 由FS/GS指向
-
_PEB : Process Environment Block
- _PEB_LDR_DATA
- _LDR_DATA_TABLE_ENTRY
- InMemoryOrderModuleList : Binary->ntdll->kernel32->kernelbase
- ProcessHeap
- Image Base
-
獲取DLL位址 : 使用GS
- PEB : GS+0x60
- PEB->Ldr : PEB+0x18
- InMemoryOrderModuleList : 獲得kernel32.dll基址 (Ldr+0x20)
- Binary->ntdll->kernel32
- 使用
mov rdi, qword ptr [rdi]爬Linked List - 從List Node獲得基址 : kernel32+0x20
-
獲取函數地址 : 利用RVA
- 需要Export Table
NT HeaderRVA :[kernel32 + 0x3c]NT header: kernel32+RVAExport DirectoryRVA :[nt_header +4+0x14+0x70]Export Directory: kernel32+RVAName pointer tableRVA :[Export Directory Table + 0x20]Name pointer Table: Export Directory Table+RVAFunction NameRVA :[Name Pointer Table + index * 4]- 對於每個Index, 爬出Name pointer Table保存的Function Name, 找WinExec
Ordinal TableRVA :[Export Directory Table RVA+ 0x24]Ordinal Table: kernel32+RVAOrdinal:Ordinal Table+ index * 2Export Address TableRVA :[Export Directory Table + 0x1c]Export Address Table: kernel32+RVAWinExecRVA :Export Address Table+Ordinal* 4WinExec: kernel32+RVA
-
呼叫函數
- RCX : cmd.exe
- RSP對齊0x10 (避免踩到movaps)
- 呼叫WinExec
Return to Library
- 用以克制DEP
- 由於ASLR, 需要洩漏記憶體資訊(相對offset不變)
- IAT, stack上殘留值, heap上的結構體
File Operation
- Linux FD = Windows File HANDLE
open()=CreateFile()/OpenFile()read()=ReadFile()write()=WriteFile()
Lab1
- flag1 : 設定RIP跳轉到打印flag處
- flag2 : 設定RIP跳轉到該函數
- flag3 : 在XOR處設定Contidional Breakpoint, 使原本存放亂數的RAX變成0
Lab2
- 換行符號與Linux上不同 :
\r\n - cyclic找crash offset
- 覆蓋RIP
Lab3
- 利用一次任意讀取洩漏IAT上的地址
- 計算offset獲得
kernel32.dll基址 - 利用BOF呼叫
WinExec()
Windows Binary Exploitation筆記
https://blog.cyberangel.work/posts/winpwn/ Last updated on 2024-11-22,377 days ago
Some content may be outdated