| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- AWS 보안 아키텍처 분석
- AWS
- 드림핵
- 네트워크
- AWS 침해사고 사례 분석
- AWS 사고 사례 분석
- TryHackMe
- terraform
- AWS 보안 사고 사례 모음
- network
- 침입 차단 시스템(IPS)
- 프로그래머스
- AWS IAM Role
- programmers
- AWS 아키텍처 분석
- AWS 인프라 분석
- operating system
- AWS 침해 사고 사례 분석
- reversing.kr
- AWS 인프라 아키텍처
- reversing
- 리버싱
- 운영체제
- python
- IAM Federation
- Amazon S3
- C
- AWS Active Directory
- AWS 3 Tier Architecture
- dreamhack
- Today
- Total
lhywk 님의 블로그
[Dreamhack] Simple Crack Me 2 본문
문제
이 문제는 사용자에게 문자열을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
문제 풀이
해당 문제의 바이너리는 elf입니다.
실행시켜 보겠습니다.

123이라는 임의값을 입력했더니 your input length is wrong x(라는 문자열이 출력됐습니다.
입력 값이 맞으면 올바른 출력 문자열이 나오겠네요.
IDA를 통해 분석 해보겠습니다.

your input length is wrong x(이라는 문자열을 봤으니 그 문자열을 참조하는 곳으로 가보겠습니다.

x 단축키로 해당 문자열을 참조하고 있는 주소로 갑니다.

디컴파일한 코드입니다.
코드를 분석해보겠습니다.
먼저 scanf로 우리의 입력값을 s1으로 받습니다.
if 문 안에 sub_4011B6 함수가 있는데 문자열의 길이를 검증하는 거 같습니다.
그 다음 조건 문 내에
sub_4011EF, sub_401263, sub_4012B0 3개의 함수가 있습니다.
그리고 최종적으로 이 함수를 거친 s1의 값을 s2의 값과 32바이트만큼 비교해 맞다면 Correct 출력입니다.

32글자를 입력했더니 이번엔 your input is wrong x( 라는 문자열이 출력되어 입력값은 32자임을 알아냈습니다.
큰 틀의 코드 분석은 끝났습니다.
sub_4011B6 함수부터 분석해보겠습니다.
sub_4011B6

해당 함수를 디컴파일 하면 입력값의 문자열의 길이를 리턴하고 있습니다.
sub_4011EF

매개변수로 받은 a2의 문자열 길이를 result 변수에 대입합니다.
그리고 64비트 정수로 v4에 대입합니다.
반복문을 32번 돌고
내부 코드는

이런식으로 구성되어 있습니다.
이 코드를 쉽게 변경 해보면

이렇게 구성해볼수 있습니다.
sub_401263

해당 함수는 매개변수로 입력값, a2를 받습니다.
result 변수에 a2의 값을 대입하고 반복문을 32번 돕니다.
내부 코드를 보면

이런식으로 구성되어 있습니다.
이 코드도 쉽게 변경 해보면

이런식으로 구성할 수 있습니다.
sub_4012B0

해당 함수도 매개변수로 a1 입력값과 a2를 받습니다.
반복문을 32번 반복하고 내부코드를 보겠습니다.

해당 코드를 쉽게 변경 해보겠습니다.

이렇게 구성할수 있습니다.
모든 함수의 분석이 끝났고 문제 풀이 과정을 생각해보겠습니다.

순서는 위 그림과 같습니다.
이를 풀어내기 위해선 이 흐름도의 연산을 역으로 수행하면 됩니다.
이때 xor 연산을 하는 sub_4011EF는 그대로 처리하면 되지만
sub_401263함수와 sub_4012B0 함수는 각각 더하는 함수, 빼는 함수기 때문에 이 연산은 역으로 처리해야 합니다.
s2의 값을 확인해보겠습니다.

402008에 실제 값의 주소가 시작합니다.
이를 따라가 보겠습니다.

402008부터 402028까지 총 32바이트의 배열 값이 존재합니다.


매개변수로 들어가는 배열의 값들을 확인합니다.
해당 값들을 export로 가져오고 이제 파이썬으로 역연산 코드를 작성해보겠습니다.
data = bytearray([0xF8, 0xE0, 0xE6, 0x9E, 0x7F, 0x32, 0x68, 0x31, 0x05, 0xDC,
0xA1, 0xAA, 0xAA, 0x09, 0xB3, 0xD8, 0x41, 0xF0, 0x36, 0x8C,
0xCE, 0xC7, 0xAC, 0x66, 0x91, 0x4C, 0x32, 0xFF, 0x05, 0xE0,
0xD9, 0x91, 0x00])
param1 = bytearray([0x11, 0x33, 0x55, 0x77, 0x99, 0xBB, 0xDD])
param2 = bytearray([0xEF, 0xBE, 0xAD, 0xDE])
param3 = bytearray([0xDE, 0xAD, 0xBE, 0xEF])
def len_check(string):
return len(string)
def xor_op(data, param1):
result = len_check(param1)
for i in range(32):
data[i] = data[i] ^ param1[i % result]
def inc_op(data, param):
result = param
for i in range(32):
data[i] = (data[i] + param) & 0xFF
def dec_op(data, param):
result = param
for i in range(32):
data[i] = (data[i] - param) & 0xFF
xor_op(data, param1)
dec_op(data, 243)
inc_op(data, 77)
xor_op(data, param2)
inc_op(data, 90)
dec_op(data, 31)
xor_op(data, param3)
for i in data:
print(chr(i), end='')
아까 분석했던 코드를 4가지 함수로 전부 구현해줍니다.
inc_op 함수와 dec_op 함수는 & 0xFF 연산을 하여 1바이트 만을 남깁니다.
아까 말한것처럼 역연산을 할때 xor 연산은 그대로 가지만 dec와 inc는 반대로 써서 역으로 올라갑니다.

플래그를 획득합니다.
'Reversing > Dreamhack' 카테고리의 다른 글
| [Dreamhack] Check Function Argument (0) | 2025.12.26 |
|---|---|
| [Dreamhack] Simple Patch Me (0) | 2025.12.24 |
| [Dreamhack] Simple Crack Me (0) | 2025.12.23 |
| [Dreamhack] rev-basic-8 (0) | 2025.12.23 |
| [Dreamhack] rev-basic-6 (0) | 2025.12.17 |