프로그램을 실행해 보았다.
이런 값이 나오네.
gdb로 돌려보자.
ㅇㅋ NX 걸려있다. 스택 실행권한 없다.
이제 어떤 함수가 있는지 보자.
main문만 잘 보면 될것 같다.
볼까
아 랜덤함수가 눈에 들어온다.
아마도 rand 값이랑 일치하는 값을 찾아줘야 할 것 같다.
IDA로 한번 더 볼까?
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
int v4; // [rsp+0h] [rbp-10h]
int v5; // [rsp+4h] [rbp-Ch]
unsigned __int64 v6; // [rsp+8h] [rbp-8h]
v6 = __readfsqword(0x28u);
setbuf(_bss_start, 0LL);
v4 = 0;
v3 = time(0LL);
srand(v3);
v5 = rand();
puts("============================");
puts(asc_400948);
puts("============================");
printf("Input Key : ");
__isoc99_scanf("%d", &v4);
if ( v5 == v4 )
{
puts("Correct!");
system("cat /home/random/flag");
exit(0);
}
puts("Nah...");
exit(0);
}
오케이 정확히 맞았다.
이제 뭘 해야하는지 알았으니, 저 random 값을 어떻게 가져올지를 고민해보자.
seed값이 주어지지않는다면 or seed 값이 노출된다면 rand값은 진짜로 랜덤은 아니다. PRNG 이다.
일단 보이는 유일한 취약점은 scanf 이다.
random 함수의 취약점은 진짜 랜덤이 아니라는 점이다. 그렇다면 random을 자체로 실행해서 출력해줄 수 있다면 v5의 값을 알아낼 수 있을 것이다.
RTL 사용해주면 되려나…?
일단 열심히 검색하다가 보니, 파이썬으로도 OS상의 시간값을 가져올 수 있다고 한다.
그러면 굳이 내부에서 실행한 값을 leak 해오지 않더라도 값을 구할 수 있다.
seed 값을 알고, 해당 libc 상의 random 과 동일하게 구동된다면 말이다.
이걸 해주는 모듈이 ctypes 다.
오늘 처음 알았는데 많이 배워간다.
한번 해봤다.
from pwn import *
from ctypes import *
lib = CDLL('libc.so.6')
lib.srand(lib.time("\0"))
rand = lib.rand()
p=remote("ctf.j0n9hyun.xyz",3014)
p.recvuntil("Input Key : ")
print("rand is : "+str(rand))
p.sendline(str(rand))
p.interactive()
HackCTF{5087686686858549173307745189}
'WriteUp > HackCTF' 카테고리의 다른 글
RTL_Core (0) | 2020.08.31 |
---|---|
Forensics : 잔상 (0) | 2020.08.22 |
Pwnable : 1996 (0) | 2020.08.22 |
Forensic : Terrorist (0) | 2020.08.14 |
Forensic : Magic PNG (0) | 2020.08.14 |