[Tutorial] rev_basic_3

@yd1ng· May 12, 2025 · 2 min read

1. 파일 준비

$ unzip "prob (1).zip"     # 바이너리 추출
$ chmod +x prob            # 실행 권한 부여

2. 문자열로 구조 파악

$ strings prob | grep -A1 -B1 flag
Enter flag:
Wrong length.
Wrong flag.
Correct! Flag accepted.
  • 프로그램은 길이(73 바이트)를 먼저 확인한 뒤, 각 바이트를 검사해 맞으면 성공 메시지를 출력한다.

3. 핵심 흐름 (main)

디스어셈블 결과 요약:

단계 동작
scanf("%72s", buf) 플래그 입력
strlen(buf) == 0x49 73 바이트 길이 체크
루프 i = 0‥72 encrypt_byte(buf[i], i) 결과가 테이블 arr1[i]와 일치해야 함
모두 통과 "Correct! Flag accepted." 출력

암호화 함수 encrypt_byte를 뒤집으면 원본 플래그가 복원된다.


4. 암호화 함수 분석

encrypt_byte(char, idx) 의 실제 연산 순서(8‑비트 연산 기준):

  1. XORx ^= idx
  2. XORx ^= 0xA5
  3. 회전(ROL)x = rol(x, (idx mod 7) + 1)
  4. 가산x = (x + idx + 0x11) mod 256
  5. 비트 반전x = bit_reverse(x)
    (8 비트를 좌우 뒤집기: 0babc……cba0b)

최종 결과가 테이블 arr1[idx]와 같아야 한다.


5. arr1 테이블 추출

.data 섹션은 가상 주소 0x4000, 파일 오프셋 0x3000.
arr1의 주소가 0x4020이므로 파일 오프셋 0x3020에서 73 바이트를 읽어온다.

$ dd if=prob bs=1 skip=$((0x3020)) count=0x49 2>/dev/null | xxd
00000000: 779a 9203 74d2 21d3 fe06 5ad1 8f2a e35c  w...t.!...Z..*.\
...

6. 복원 스크립트

역함수 구현보다 전수 검색(0–255)이 간단하다.
아래 파이썬 스크립트는 encrypt_byte를 그대로 구현한 뒤, 각 인덱스마다 일치하는 원본 바이트를 찾아낸다.

# 암호화 보조 함수
def rol(b, k):
    k %= 8
    return ((b << k) | (b >> (8 - k))) & 0xFF

def bit_reverse(b):
    out = 0
    for i in range(8):
        out |= ((b >> i) & 1) << (7 - i)
    return out

def encrypt_byte(x, idx):
    x ^= idx & 0xFF
    x ^= 0xA5
    x = rol(x, (idx % 7) + 1)
    x = (x + idx + 0x11) & 0xFF
    return bit_reverse(x)

# arr1 바이트 배열 (생략) ── 실제 코드엔 73바이트 hex 작성
arr1 = bytes.fromhex(
    "779a920374d221d3fe065ad18f2ae35c..."
)

flag = bytearray()
for i, target in enumerate(arr1):
    for b in range(256):
        if encrypt_byte(b, i) == target:
            flag.append(b)
            break

print(flag.decode())   # → Kuality{4d528416fb8283c439d996ac1d38f6ef155f2194428549e4e0977cfe34bfe1a3}

실행 결과:

Kuality{4d528416fb8283c439d996ac1d38f6ef155f2194428549e4e0977cfe34bfe1a3}

7. 실행 검증

$ ./prob
Enter flag:
Kuality{4d528416fb8283c439d996ac1d38f6ef155f2194428549e4e0977cfe34bfe1a3}
Correct! Flag accepted.

8. 결론

  • encrypt_byteXOR‑회전‑가산‑비트뒤집기 순으로 단일 바이트를 변환한다.
  • 테이블 값이 노출되어 있어, 역산(또는 브루트포스)으로 손쉽게 원본 바이트를 찾을 수 있었다.
  • 위 과정을 통해 플래그 Kuality{4d528416fb8283c439d996ac1d38f6ef155f2194428549e4e0977cfe34bfe1a3}를 얻었으며, 실제 프로그램 실행에서도 정답으로 인식됨을 확인했다.
@yd1ng
안녕하세요. 양진영입니다.
© copyright 2025. yd1ng all rights reserved.