슬기로운 해커 생활

Reverse engineering

[Dreamhack] simple-operation

Tjdmin1 2024. 7. 3. 14:10

https://dreamhack.io/wargame/challenges/836

 

simple-operation

Description 우리의 친구 아모가 미션을 주었습니다. "내가 원하는 결과가 나오도록 값을 입력해 줘!" 주어진 바이너리를 분석하고 알맞은 값을 입력하면 플래그가 출력됩니다. 플래그는 flag 파일에

dreamhack.io

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 설치 방법 (제 블로그 아닙니다)

 

[Pwn-tools] Pwntools Installation

오늘은 Memo용으로 Pwntools 설치 방법을 적어두려한다... > Pwntools는 CTF Framework이자, Exploit을 쉽게 작성할 수 있도록 도와주는 라이브러리이다. 설치방법은 Gihub 홈페이지에서 제공한다. 아래와 같다

velog.io

 

pwntools github

 

GitHub - Gallopsled/pwntools: CTF framework and exploit development library

CTF framework and exploit development library. Contribute to Gallopsled/pwntools development by creating an account on GitHub.

github.com

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