rev-basic의 마지막 문제다.

늘 하던대로 우선 비교함수식을 찾으려고 디버거에서 문자열검색을 했는데 "I_am_KEY"라는 문자열이 있다. 일단 이런게 있구나라 생각하고 비교함수를 확인해보자.
 

지금까지와는 뭔가 느낌이 다른게 머리가 아프다. 그래도 대충 큰 것만 확인해보자면, strlen을 호출해서 입력 문자열의 길이를 확인한다. 그리고 실행하면서 확인해본 결과 스택[rsp+40]에는 입력 문자열, 스택[rsp+24]에는 입력 문자열 배열의 크기가 저장된다.
 
그리고 디버거를 따라가며 확인해보니 문자열 길이가 맞지 않으면 바로 ret으로 넘어가고, 문자열 길이를 맞춰서 가보면 마지막엔 [7FF628904000]과 비교한다.

00007FF628904000  7E 7D 9A 8B 25 2D D5 3D 03 2B 38 98 27 9F 4F BC  ~}..%-Õ=.+8.'.O¼  
00007FF628904010  2A 79 00 7D C4 2A 4F 58 00 00 00 00 00 00 00 00  *y.}Ä*OX........

 
이번에는 정신건강에 이로운 IDA로 디컴파일을 해보자

우선 이 sub_140001000비교함수를 디컴파일해봤다. 여기서 v3에 입력된 문자열의 길이를 저장하고 문자열 길이부터 확인한다. (v3+1)%8 == 0이 아니면 추가 비교 없이 "Wrong"을 출력하고 종료된다. 프로그램에 직접적으로 한글자씩 맞추는걸 막은 것 같다.
문자열 길이 확인 후에는 sub_1400010A0함수를 호출한다. 이 함수도 확인해보자.

여기서 아까 위에서 확인했던 "I_am_KEY"문자열을 사용한다.
 
대충 설명하자면 input[(j + 1) & 7]에 ~~4020[key[j] ^ input[j & 7]]값을 더하고 rotate right를 5만큼 해서 저장한다. 초기값은 input[0]이다.
말로보면 간단한데 이거 역산식짜다가 머리가 터질뻔했다.
 

def rol(x, n):
    shiftBit = x << n
    shiftBit &= 255
    carryBit = x >> 8 - n
    return shiftBit | carryBit

def ror(x, n):
    shiftBit = x >> n
    carryBit = x << (8 - n)
    carryBit &= 255
    return shiftBit | carryBit

key = 'I_am_KEY'
enc = '7E 7D 9A 8B 25 2D D5 3D 03 2B 38 98 27 9F 4F BC 2A 79 00 7D C4 2A 4F 58' #7FF628904000

#byte_140004020
tmp = '63 7C 77 7B F2 6B 6F C5 30 01 67 2B FE D7 AB 76 CA 82 C9 7D FA 59 47 F0 AD D4 A2 AF 9C A4 72 C0 B7 FD 93 26 36 3F F7 CC 34 A5 E5 F1 71 D8 31 15 04 C7 23 C3 18 96 05 9A 07 12 80 E2 EB 27 B2 75 09 83 2C 1A 1B 6E 5A A0 52 3B D6 B3 29 E3 2F 84 53 D1 00 ED 20 FC B1 5B 6A CB BE 39 4A 4C 58 CF D0 EF AA FB 43 4D 33 85 45 F9 02 7F 50 3C 9F A8 51 A3 40 8F 92 9D 38 F5 BC B6 DA 21 10 FF F3 D2 CD 0C 13 EC 5F 97 44 17 C4 A7 7E 3D 64 5D 19 73 60 81 4F DC 22 2A 90 88 46 EE B8 14 DE 5E 0B DB E0 32 3A 0A 49 06 24 5C C2 D3 AC 62 91 95 E4 79 E7 C8 37 6D 8D D5 4E A9 6C 56 F4 EA 65 7A AE 08 BA 78 25 2E 1C A6 B4 C6 E8 DD 74 1F 4B BD 8B 8A 70 3E B5 66 48 03 F6 0E 61 35 57 B9 86 C1 1D 9E E1 F8 98 11 69 D9 8E 94 9B 1E 87 E9 CE 55 28 DF 8C A1 89 0D BF E6 42 68 41 99 2D 0F B0 54 BB 16 CF 32 25 34 56 3D FF FF 30 CD DA CB A9 C2 00 00'


enc = enc.split(' ')
tmp = tmp.split(' ')


res = []
chars = []

for i in range(len(enc)):
    res.append(int(enc[i], 16))

for i in range(len(tmp)):
    chars.append(int(tmp[i], 16))


for k in reversed(range(3)):
    for i in range(16):
        for j in reversed(range(8)):
            res[k * 8 + ((j + 1) & 7)] = (rol(res[k * 8 + ((j + 1) & 7)], 5) - chars[ord(key[j]) ^ res[k * 8 + (j & 7)]]) & 0xFF

flag = ''
for i in range(len(res)):
    flag += chr(res[i])

print(flag)

중간에 쓸데없는것 같이 보이는 for문이 많은 이유는 파이썬의 타입에러 때문이다.. 후... c로 하면 더 복잡하니 악으로 깡으로 버틴다.
 
결론만 말하자면 예전에 풀었던 몇 번이더라.. rev-basic-5였었나... 이 문제와 같이 마지막에서 부터 하나씩 내려오는 식으로 문제를 풀어야한다.
 
각 인덱스에 k * 8을 더해준 이유는 파이썬에서는 sub_140001000비교함수와 같이 인덱스를 직접적으로 못건들기 때문에 계산식 안에서 처리해줬다.

 
늙어서 눈이 침침해진건지 계산식을 계속 잘못봐서 이거 왜안되지를 3시간동안 반복하다가 겨우 오류 찾았는데 그 다음엔 key인덱스 잘못잡아서 또 한 30분 헤멨다.. 왜이럴까
 
여담으로 수식 외에도 이게 인덱스를 계속 왔다갔다 하는거다 보니 out of range error가 계속 발생했다. 그래서 그냥 byte_140004020을 00 00부분까지 싹다 긁어왔더니 그때부턴 에러가 안나오더라

'Security > Reversing' 카테고리의 다른 글

[wargame.kr] DLL with notepad  (0) 2022.07.13
Secure Mail  (0) 2022.07.13
Dreamhack rev-basic-8  (0) 2022.07.05
Dreamhack rev-basic-7  (0) 2022.06.21
Dreamhack rev-basic-6  (0) 2022.06.01

이번 문제는 지금까지 잘 풀어왔다면 굉장히 쉬운 문제다.
비교함수를 확인해보자.

대충 보면 암호문의 길이는 0x15고 imul연산과 and연산이 보인다.
[imul a, b, c] 연산은 [a = b * c]와 같다. 따라서 이 비교함수연산을 그대로 대입해보면
(input[i]*0xFB)&(0xFF) == enc[i]이다.
 
이를 역산식으로 만들면
input[i] == (enc[i]&(0xFF)) / (0xFB)
인데 파이썬에서 나눗셈은 무조건 float를 결과값으로 가진다. 타입변환이 귀찮기 때문에 브루트포스로 대입해서 비교하는 식으로 코드를 작성했다.
 

enc = 'AC F3 0C 25 A3 10 B7 25 16 C6 B7 BC 07 25 02 D5 C6 11 07 C5 00'
enc = enc.split(' ')

res = ''

for i in range(21): #0x15 == 21
    for j in range(32, 127): #printable ascii code
        if (j*0xFB)&(0xFF) == int(enc[i],16):
            print(chr(j), end='')

'Security > Reversing' 카테고리의 다른 글

Secure Mail  (0) 2022.07.13
Dreamhack rev-basic-9  (0) 2022.07.05
Dreamhack rev-basic-7  (0) 2022.06.21
Dreamhack rev-basic-6  (0) 2022.06.01
Dreamhack rev-basic-5  (0) 2022.05.28

+ Recent posts