Iriton's log

[Dreamhack] Beginner: simple-operation 본문

Reversing/Wargame

[Dreamhack] Beginner: simple-operation

Iriton 2024. 4. 2. 22:05
 

simple-operation

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

dreamhack.io

 

풀이

코드의 흐름을 먼저 보자.

17-20: flag 파일을 열어서 파일 디스크립터를 fd 변수에 담는다. 45바이트만큼 읽어서 buf 변수에 받고 다시 닫는다.

21: 난수를 v6에 저장한다.

24: v7에는 사용자 입력값을 받는다.

25: v6 ^ v7 은 XOR 연산을 의미한다.

26: snprintf 함수는 출력 결과를 문자열 버퍼에 저장하는 함수이다. 버퍼의 크기를 지정하여 버퍼 오버플로우를 방지하는데 여기서는 9uLL로 지정했다. 9는 버퍼의 크기이고, uLL은 unsigned long long 타입임을 나타낸다. 추가로 %08x는 16진수로 출력하고 최소 8자리를 출력하며 부족한 자릿수는 0으로 채운다는 걸 의미한다.

27-28: 그 결과가 담긴 s 문자열을 s1에 거꾸로 담는다.

31: 그 결과가 a0b4c1d7과 일치하는지 판별한다.

 

즉, 랜덤값과 입력값을 XOR 연산한 결과가 a0b4c1d7과 일치하게 만들면 된다.

 

 

예전에는 이런 문제를 보면 역함수를 c언어로 직접 짰는데 pwn 모듈을 알게 되어서 오늘 한 번 사용해 보려고 한다.

 

pwn 모듈은 원격으로 호스트에 접속할 수 있다.

코드로 설명을 하겠다.

 

from pwn import *

# 지정 호스트의 지정 포트로 원격 접속
r = remote("host3.dreamhack.games", <포트번호>)

# 서버에서 rand 값 받기
r.recvuntil(b"number: ")
rand = r.recvn(10)

print("rand : ", rand)

# 16진수로 변환한 후 XOR 연산
x = int(rand, 16) ^ 0x7d1c4b0a
# 문자열로 변환 후 바이트 형식으로 인코딩
x = str(x).encode()

# Input?이란 문자열이 나올 때 값을 전송
r.sendlineafter(b"Input? ", x)

# 프로그램 제어(입출력 등)를 사용자에게 넘김
r.interactive()

recvuntil 함수는 해당 문자가 나올 때까지 기다리는 걸 의미한다.

recvn함수는 지정된 크기만큼만 서버에서 값을 받아온다. 여기서 16진수(0x~)로 출력되기 때문에 10으로 지정했다.

받아온 난수를 7d1c4b0a와 연산했는데 여기서 연산 후 거꾸로 계산하기 귀찮으니까 주어진 16진수( a0b4c1d7)를 거꾸로 한 거다.

Input?이란 문자열이 나올 때까지 기다렸다가 나오면 연산결과를 서버에 보낸다. 올바른 결과값이라면 flag가 출력될 것이다.

 

 

앞으로 더 복잡한 문제를 풀어야 하니까 코드를 직접 짜려면 파이썬 공부를 더 해야 할 거 같다.

IDA로 코드 플로우 도 중요해서 C 기초도 까먹지 않기.

'Reversing > Wargame' 카테고리의 다른 글

[CodeEngn] Basic RCE - L07  (0) 2024.05.07
[CodeEngn] Basic RCE - L03  (0) 2024.05.07
[Dreamhack] Reversing Basic Challenge #1  (0) 2024.03.27
[Dreamhack] Reversing Basic Challenge #0  (0) 2024.03.27
[CodeEngn] Basic RCE - L16  (1) 2023.11.21
Comments