| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 3 Tier Architecture
- AWS 보안 아키텍처 분석
- terraform
- dreamhack
- 네트워크
- 드림핵
- C
- network
- 운영체제
- AWS
- Amazon S3
- python
- reversing.kr
- AWS Active Directory
- IAM Federation
- operating system
- AWS IAM Role
- AWS 인프라 분석
- 리버싱
- AWS 인프라 아키텍처
- 침입 차단 시스템(IPS)
- programmers
- reversing
- TryHackMe
- AWS 침해 사고 사례 분석
- AWS 보안 사고 사례 모음
- Today
- Total
lhywk 님의 블로그
[Dreamhack] rev-basic-4 본문
문제
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 알아내세요.
문제 풀이

입력값이 정확하면 Correct 아니면 Wrong을 출력하는 프로그램이에요.
IDA를 통해 분석을 해볼게요.

sub_1400011C0은 printf, sub_140001220은 scanf로 대응 되겠네요.
if 조건문에 sub_140001000 함수에서 반환값을 보고 Correct와 Wrong을 출력하고있어요.
sub_140001000을 분석해봐야겠네요.

반복문으로 0x1C(28)번 반복하고 내부에서 연산을 수행하고 있어요.
return 1이 되게 만들어야 되므로 내부 연산이 byte_140003000과 일치해야 해요.

byte_140003000의 배열의 값을 확인합니다.
이제 역연산 코드를 작성하기 전에 로직을 한번 볼게요.
(unsigned __int8)(16 * *(_BYTE *)(a1 + i))에서 16 * *(_BYTE *)(a1 + i)은 16 * a1[i]로 대응됩니다.
그리고 unsigned __int8로 캐스팅하여 1바이트만 남게 하고 있어요.
(int)*(unsigned __int8 *)(a1 + i) >> 4)은 a1[i] >> 4로 대응되요. 그리고 이 두 연산을 |로 OR 연산처리를 합니다.

연산을 수행하는 해당 어셈블리만 볼게요.
sar eax, 4로 4비트를 오른쪽을 shift 해요.
shl ecx, 4로 4비트를 왼쪽으로 shift하고 0xF0과 and 연산을 한다음 이 둘을 or 연산합니다.
아까 배열을 확인했을때 첫 번째 값은 0x24였어요. 이걸로 연산을 한번 따라가볼게요.
sar eax, 4 -> 4비트를 오른쪽으로 shift ( 상위 4비트의 값을 하위 자리로 이동! )
0010 0100 >> 4 0000 0010
shl ecx,4 -> 4비트를 왼쪽으로 shift ( 하위 4비트의 값을 상위 자리로 이동! )
0100 0000
and ecx, 0F0h -> 상위 4비트만 남기기
0100 0000
or eax, ecx -> 상위 4비트와 하위 4비트를 합친다!
0100 0010
결과적으로 0x42가 됩니다. 이 연산은 니블 스왑이에요.
1byte = 8bits 이에요.
여기서 니블이란 개념은 8bits를 4bits, 4bits로 나눈 것이에요.
그래서 이 연산은 0x24를 앞 상위 니블, 하위 니블을 스왑하여 0x42로 바꾸는 것이에요.
아스키코드로는 'B'가 되겠네요. 첫번째 입력 값은 B에요.
그런데 아까 코드에서는 어셈블리랑 달랐어요.
(unsigned __int8)(16 * *(_BYTE *)(a1 + i)) 특히 이 코드가 어셈블리에선
shl ecx,4
and ecx, 0F0h
이렇게 구현 되어 있었어요.
16을 곱하는건 << 4와 같은 의미에요.
그리고 (unsigned __int8)로 8비트로 캐스팅 하고 있어요.
해당 캐스팅 연산은 & 0xF0을 하여 하위 4비트를 마스킹 하는 어셈블리로 대체 된거에요.
data = bytearray([0x24, 0x27, 0x13, 0xC6, 0xC6, 0x13, 0x16, 0xE6, 0x47, 0xF5, 0x26, 0x96, 0x47, 0xF5, 0x46, 0x27, 0x13, 0x26, 0x26, 0xC6, 0x56, 0xF5, 0xC3, 0xC3, 0xF5, 0xE3, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00])
for i in range(28):
tmp = (data[i] << 4) & 0xF0 | data[i] >> 4
print(chr(tmp), end='')
분석이 전부 끝났고 역연산 코드를 파이썬으로 그대로 구현합니다.
'Reversing > Dreamhack' 카테고리의 다른 글
| [Dreamhack] rev-basic-8 (0) | 2025.12.23 |
|---|---|
| [Dreamhack] rev-basic-6 (0) | 2025.12.17 |
| [Dreamhack] WinDbg Exercise 2 (0) | 2025.12.15 |
| [Dreamhack] WinDbg Exercise 1 (0) | 2025.12.15 |
| [Dreamhack] rev-basic-3 (0) | 2025.12.13 |