CTF & Wargame(REVERSING)

[dreamhack] level2 many-shuffle 문제 풀이

KWAKBUMJUN 2025. 2. 21. 20:46

일단 해당 문제 파일에 있는 바이너리를 실행해보면

 

위와 같은 결과를 확인할 수 있다. 해당 바이너리에서는 랜덤한 문자열을 생성하고 Shuffled String 이라는 문자열을 출력한 뒤에 사용자에게 입력을 받는다. 하지만 입력받은 값이 특정한 값이 아니라면 Wrong이라는 문자열을 출력한다.

 

IDA로 파일을 분석해보자

main 함수를 디컴파일하면 

위와 같은 정보를 얻을 수 있다. 해당 코드를 하나하나 살펴보면, 

1. [A-Z]{16}에 해당하는 무작위 문자열 생성 후 s에 저장한다.

2. 변수 s에 저장된 값을 dest라는 변수에 복사한다.

3. dest와 s를 번갈아가면서 byte_4020 값에 따라 셔플을 진행한다.

4. 그리고 셔플을 진행한 값을 출력한다. 

5. 사용자에게 문자를 입력받은 뒤에  !strcmp(s, s2) 조건을 만족시키면 flag를 출력한다.

 

위의 코드를 살펴보니, 3번 과정에서 셔플한 문자열을 복호화 하면 flag를 얻을 수 있을 것 같다.

 

역연산을 진행하려면 byte_4020에 어떤 값이 있는지 찾아야 한다. 해당 값을 ida에서 쉽게 찾을 수 있다. 위의 코드에서 byte_4020을 클릭하면

위와 같은 값들이 byte_4020에 저장된 것을 볼 수 있는데, 해당 값들은 edit --> export data --> C unsigned char array(decimal)을 통해 decimal 값으로 추출할 수 있다. 혹은 위의 값들을 hex string으로 추출하여 복호화 하는 과정에서 byte 타입으로 변환해도 된다.

 

이제 byte_4020의 값들을 알아냈으니 복호화 코드를 작성해보자.

from pwn import *

a = "0B08030401000E0D0F090C060205070A0F04080B06070D020C03050E0A000109040C0E050D06090A01000B0F020703080A080F030406000B010D090705020C0E0B06090F02010A0E030C0D000504080709040B05060F080003010A0D020E0C070A0E0907080D030B0C0F02000405060105040D010002090B0C07080A060E0F03040805020A0F0B0700010C030E06090D0D0E0F0B00020A04070609010503080C0E0203050A010700090D0C0B04060F08030B0E0A06040701020D0F000C0905080D0F01020C0A03070906080500040B0E000E040D06010A05030C070B0F0208090B0208070503090D040F0001060C0E0A0B0108000C0D040E0A060F0709050302"
a = bytes.fromhex(a)

# p = process("./many-shuffle")
p = remote("host1.dreamhack.games", 9912)
context.log_level = "debug"

p.recvuntil(b"String: ")
dest = p.recv(16) + b"\x00"*16
s = b"\x00"*64

dest = bytearray(dest)
s = bytearray(s)

for j in range(15, -1, -1):
    for k in range(16):
        if (j & 1) != 0:
            s[k+32] = dest[a[16*j+k]]
        else:
            dest[k] = s[a[16*j+k]+32]

p.recvuntil(b"String?: ")
p.sendline(dest[:16])

p.interactive()

위의 코드의 핵심은 역연산을 수행하기 때문에 제일 처음 반복문인 j를 16부터 반대로 연산하도록 작성한 것이다. 그리고 dest와 s를 번갈아가며 셔플하는 과정 또한 반대로 진행하면 역연산이 성공적으로 수행될 것이다.

 

flag : DH{7db43cb3498cbe8f2fa1416975bbdca04da997cddf20177be2d141edc2abc23c}