https://dreamhack.io/wargame/challenges/836
Analysis
main function
int __fastcall main(int argc, const char **argv, const char **envp)
{
char s1[9]; // [rsp+6h] [rbp-3Ah] BYREF
char s[9]; // [rsp+Fh] [rbp-31h] BYREF
unsigned int v6; // [rsp+18h] [rbp-28h] BYREF
unsigned int v7; // [rsp+1Ch] [rbp-24h] BYREF
char *s2; // [rsp+20h] [rbp-20h]
int fd; // [rsp+2Ch] [rbp-14h]
void *buf; // [rsp+30h] [rbp-10h]
unsigned int v11; // [rsp+38h] [rbp-8h]
int i; // [rsp+3Ch] [rbp-4h]
v7 = 0;
v6 = 0;
v11 = 0;
initialize(argc, argv, envp);
buf = malloc(0x45uLL);
fd = open("./flag", 0);
read(fd, buf, 0x45uLL);
close(fd);
get_rand_num(&v6);
printf("Random number: %#x\n", v6);
printf("Input? ");
__isoc99_scanf("%d", &v7);
v11 = v6 ^ v7;
snprintf(s, 9uLL, "%08x", v6 ^ v7);
for ( i = 0; i <= 7; ++i )
s1[i] = s[7 - i];
printf("Result: %s\n", s1);
s2 = "a0b4c1d7";
if ( !strcmp(s1, "a0b4c1d7") )
{
puts("Congrats!");
puts((const char *)buf);
}
else
{
puts("Try again");
}
return 0;
}
코드 분석
1. flag 파일을 열어서 buf에다 flag를 저장하게 된다.
2. v6에 렌덤 값을 받아온다.
3. v6 ^ v7을 한 값을 s에다 넣는다.
4. s1에 s를 뒤집어서 넣는다.
5. s1을 "a0b4c1d7"과 비교해서 맞으면 플래그를 출력한다.
이런 로직을 가지고 있습니다.
실행했을 때 이렇게 나오게 됩니다.
일단 Random number가 항상 바뀌기 때문에 pwntools를 이용하여 Random number를 가져와 연산을 할 것입니다.
pwntools 설치 방법 (제 블로그 아닙니다)
pwntools를 설치 한 뒤에 서버와 연결해 Random number를 가져오는 코드를 짜줄 것입니다.
from pwn import *
r = remote('host3.dreamhack.games', 20174)
r.recvuntil(b': ')
Random_number = int(r.recvuntil(b'\n')[:-1], 16)
print(f'Random number : {hex(Random_number)}')
그리고 a0b4c1d7 값을 거꾸로 해주는 코드를 짜주겠습니다.
s2 = int('a0b4c1d7'[::-1], 16)
그리고 [Dreamhack] Easy Assembly 여기서 소개했었던 XOR 연산의 특성을 이용하여 input 값을 구할 것입니다.
v7 = Random_number ^ s2
이게 가능한 이유는 v7과 v6 = Random number가 16진수 숫자로 표현되서 가능합니다.
서버에 v7을 보내 Flag를 받아내보겠습니다.
Exploit
from pwn import *
r = remote('host3.dreamhack.games', 20174)
r.recvuntil(b': ')
Random_number = int(r.recvuntil(b'\n')[:-1], 16)
print(f'Random number : {hex(Random_number)}')
s2 = int('a0b4c1d7'[::-1], 16)
v7 = Random_number ^ s2
print(f'Input : {hex(v7)}')
r.sendlineafter(b'? ', str(v7).encode())
r.recvuntil(b'!\n')
flag = r.recvuntil(b'\n')[:-1].decode()
print(f'FLAG : {flag}')
'Reverse engineering' 카테고리의 다른 글
[Dreamhack] rev-basic-1 (1) | 2024.07.03 |
---|---|
[Dreamhack] rev-basic-0 (0) | 2024.07.03 |
[Dreamhack] Easy Assembly (0) | 2024.07.03 |