Iriton's log
[Dreamhack] Beginner: simple-operation 본문
풀이
코드의 흐름을 먼저 보자.
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 |