본문 바로가기

Reverse Engineering/Wargame

Dreamhack : rev-basic-5

문제 링크

https://dreamhack.io/wargame/challenges/19

 

rev-basic-5

Reversing Basic Challenge #5 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출

dreamhack.io

 

 

풀이

 

그림 1

 

위 그림 1에서 빨간 박스는 해당 문제의 주요 로직을 나타낸다. 

 

그림 2

 

디컴파일하여 위 그림 2와 같이 확인이 가능하다. 그림 1의 어셈블리 연산에서도 확인이 가능했지만, 사용자 입력 값 배열의 앞, 뒤 원소를 더한 값이 아래 그림 3의 chall05의 원소들과 같아야 한다. 

 

그림 3

 

chall05_byte = [
    0xAD, 0xD8, 0xCB, 0xCB, 0x9D, 0x97, 0xCB, 0xC4, 0x92, 0xA1, 0xD2, 0xD7, 
    0xD2, 0xD6, 0xA8, 0xA5, 0xDC, 0xC7, 0xAD, 0xA3, 0xA1, 0x98, 0x4C, 
    0x00
]

 

위 그림 2에서 i = 23 일 때까지( chall05[23] ) 반복문이 도는 것을 알 수 있다. 즉 위 그림 3에서 실질적으로 사용되는 원소는 위 chall05_byte 배열과 같고, 사용자 입력(input) 배열의 각 원소들의 합을 아래에 같이 간략히 나타내보았다. 

 

input[0] + input[1] = 0xAD
input[1] + input[2] = 0xD8
...
...
input[21] + input[22] = 0x98
input[22] + input[23] = 0x4C
input[23] + input[24] = 0x00

 

input[23] 이 0x00 임을 알고 있으므로, input[22] = chall05_byte[22] - 0x00과 같다. 이런식으로 역으로 연산을 진행해 나가면 된다. 

 

chall05_byte = [0xAD, 0xD8, 0xCB, 0xCB, 0x9D, 0x97, 0xCB, 0xC4, 0x92, 0xA1, 
        0xD2, 0xD7, 0xD2, 0xD6, 0xA8, 0xA5, 0xDC, 0xC7, 0xAD, 0xA3, 
        0xA1, 0x98, 0x4C, 0x00, 0x00]

input_list = [0] * 25  

for i in range(23, 0, -1):  
    input_list[i-1] = chall05_byte[i-1] - input_list[i]


print(list(map(hex, input_list)))
print(''.join(list(map(chr, input_list))))

 

연산 로직에 기반하여 위와 같이 코드를 작성했다. (처음에는 사용자 입력 값 길이를 25까지 생각했어서 배열의 길이를 25로 잡았었지만, 아래 그림 4에서 볼 수 있듯이 메모리 주소에 값이 할당되지 않은 곳은 00으로 되어 있어 사용자 입력 배열의 길이를 23으로 잡아도 무방하다)

 

그림 4