woonadz :)

[DreamHack] basic_rev_5 문제 풀이_reversing_nabi 본문

IT/DreamHack

[DreamHack] basic_rev_5 문제 풀이_reversing_nabi

C_scorch 2023. 4. 13. 08:36
반응형

문제

DreamHack의 basic reversing 시리즈는 전체적인 로직은 같고, 입력값을 기반으로 serial과 비교하는 부분의 로직이 다르기 때문에 그 부분부터 설명한다.

 

문자열 참조를 통해 Input 값을 받아 serial 일치 여부를 판단하는 함수가 있는 곳으로 이동했다.

 

rsp 값을 옮긴 rax 레지스터의 값과 18을 비교하는 것으로 보아 serial은 24자리라는 것을 추측할 수 있다.

 

사용자 입력값을 eax 레지스터에 옮긴다.

 

16진수 기준으로 0부터 17까지 증가하는 rsp 레지스터의 값을 ecx 레지스터에 옮기고 +1 을 한다.

 

사용자의 다음 입력값을 ECX 레지스터로 옮긴다.

 

사용자의 입력값을 더한다. (abcdefg라면 a+b, b+c, c+d 순)

 

특정 주소에서 값을 가져와 그 값을 ECX 레지스터에 넣고 EAX 레지스터와 비교한다.

메모리에서 비교되는 값은 다음과 같다.

00007FF762043000 AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5 .ØËË..ËÄ.¡Ò×ÒÖ¨¥

00007FF762043010 DC C7 AD A3 A1 98 4C 00                                              ÜÇ.£¡.L.

 

위 식들을 방정식으로 표현하면 다음과 같다.

M = memory 값

A = 사용자 i번째 입력값

B = 사용자 i+1번째 입력값

A + B = M

A를 구한다고 가정하면

A = M-B가 된다.

이를 재귀함수를 이용해 구현해보려고 했다.

 

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

global result
result = ''

def decrypt(num, usr):
    if usr == -1:
        for j in range(32,127):
            for z in range(32,127):
                if j + z == encrypted[num]:
                    stand = z
                    global result
                    result += chr(j)
                    return decrypt(++num,stand)
    else:
        for z in range(32,127):
                if usr + z == encrypted[num]:
                    stand = z
                    result += chr(usr)
                    return decrypt(++num,stand)

print(decrypt(0,-1))

하지만 다음과 같은 오류가 발생했고 해당 오류는 재귀함수를 너무 깊이 들어가 런타임 오류가 발생한 것 이다.

따라서 하향식으로 다시 코드를 짰다. 가장 마지막 HEX 값이 0인 것을 이용해 계산한다.

 

편의를 위해 다음과 같이 재정의하겠다.

A[i] = 사용자 i번째 입력값

A[i+1] = 사용자 i+1번째 입력값

마지막 HEX 값이 0 이라는 것은

A[22] + A[23] = 0 이라는 것이고,

A[21]+A[22] = 4C라는 것이다.

사용자가 입력 가능한 아스키 범위는 모두 0 초과의 정수이기 때문에 A[22] = 0, A[23] = 0이고,

A[21] 은 4C가 된다.

그렇게되면

A[20]+A[21] = 98

A[20] = 98 - A[21]이기 때문에

결과적으로

A[i] = M[i+1] - A[i+1]

A[i-1] = M[i] - A[i]

A[i-2] = M[i-1] - A[i-1]

….

이 성립되게 된다.

코드로 작성하면 다음과 같다.

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

front = 0
result = ''

for i in range(23,-1,-1):
    front = encrypted[i]-front
    result += (chr(front))

result = result[::-1]
print(result)

답을 얻었다.

반응형