콘텐츠로 건너뛰기

rev-basic-7

https://h4ck.kr/2023/06/19/rev-basic-3/

rev-basic-7 문제도 마찬가지로 문자열을 역참조해서
문자열을 암호화시키는 함수를 찾을 수 있다. 위 게시물 참조하기 바람.

암호화시키는 함수만 들여다보면 아래와 같다.

sub_140001000      
...
   mov     eax, [rsp+18h+var_18]
   and     eax, 7
   movsxd  rcx, [rsp+18h+var_18]
   mov     [rsp+18h+var_10], rcx
   mov     rdx, [rsp+18h+arg_0]
   movzx   ecx, al
   mov     rax, [rsp+18h+var_10]
   movzx   eax, byte ptr [rdx+rax]
   rol     al, cl
   movzx   eax, al
   xor     eax, [rsp+18h+var_18]
   movsxd  rcx, [rsp+18h+var_18]
   lea     rdx, byte_140003000
   movzx   ecx, byte ptr [rdx+rcx]
   cmp     eax, ecx
...

mov     eax, [rsp+18h+var_18]
and     eax, 7

반복문에서의 카운트 변수,
초기로 가정했을때는 0을 7과 AND 연산을 하여
EAX에 저장한다.


movsxd  rcx, [rsp+18h+var_18]
mov     [rsp+18h+var_10], rcx
mov     rdx, [rsp+18h+arg_0]

rdx 레지스터는 입력받은 문자열을 가리킨다.


movzx   ecx, al
mov     rax, [rsp+18h+var_10]
movzx   eax, byte ptr [rdx+rax]
rol     al, cl

0을 7과 AND 연산한 값인 0을 ecx로 옮긴다.

eax는 입력받은 문자열의 카운트 변수 인덱스에 있는 하나의 문자를 가리키므로
eax = 입력받은 문자열[0]이 되겠다.

eax의 하위 부분을 나타내는 8비트 레지스터는 al,
ecx의 하위 부분을 나타내는 8비트 레지스터는 cl이라고 한다.

al 레지스터는 cl값인 0만큼 왼쪽으로 회전시키는 연산을 한값이 된다.


movzx   eax, al
xor     eax, [rsp+18h+var_18]

eax는 al레지스터 값으로 저장하고
eax는 카운트 변수값인 0을 xor해서 다시 저장한다.


movsxd  rcx, [rsp+18h+var_18]
lea     rdx, byte_140003000
movzx   ecx, byte ptr [rdx+rcx]
cmp     eax, ecx

그리고 EAX 값과 ECX값인 ‘암호화된 문자열[0]’과 서로 비교한다.


암호화된 문자열은(byte_140003000)은 아래와 같았다.

\x52\xDF\xB3\x60\xF1\x8B\x1C\xB5\x57\xD1\x9F\x38\x4B\x29\xD9\x26\x7F\xC9\xA3\xE9\x53\x18\x4F\xB8\x6A\xCB\x87\x58\x5B\x39\x1E

아래와 같이 한문자씩 계속 비교한다고 보면 된다.

암호화된 문자열[n] != rol(입력받은 문자열[n], n & 7) ^ n

0x52 != rol(입력받은 0번째 문자값, 0 & 7) ^ 0
0xDF != rol(입력받은 1번째 문자값, 1 & 7) ^ 1
0xB3 != rol(입력받은 2번째 문자값, 2 & 7) ^ 2
...

a = b ^ c일때, b = a ^ c로 구할 수 있고
rol(a, b) = c일때, a값은 ror(c, b)로 구할 수 있다.

0x52 = rol(입력받은 0번째 문자값, 0 & 7) ^ 0
rol(입력받은 0번째 문자값, 0 & 7) = 0x52 ^ 0
입력받은 0번째 문자값 = ror(0x52 ^ 0, 0 & 7)

0xDF = rol(입력받은 1번째 문자값, 1 & 7) ^ 1
rol(입력받은 1번째 문자값, 1 & 7) = 0x52 ^ 1
입력받은 1번째 문자값 = ror(0x52 ^ 1, 1 & 7)

0xB3 = rol(입력받은 2번째 문자값, 2 & 7) ^ 2
rol(입력받은 2번째 문자값, 2 & 7) = 0x52 ^ 2
입력받은 2번째 문자값 = ror(0x52 ^ 2, 2 & 7)
...

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

enc_str = b'\x52\xDF\xB3\x60\xF1\x8B\x1C\xB5\x57\xD1\x9F\x38\x4B\x29\xD9\x26\x7F\xC9\xA3\xE9\x53\x18\x4F\xB8\x6A\xCB\x87\x58\x5B\x39\x1E'
dec_str = ""

for i in range(len(enc_str)):
    dec_str = dec_str + chr(ror(enc_str[i] ^ i, i & 7))

print(dec_str)
ubuntu@WSL:~/CTF/dreamhack.io/chall7$ python3 chall7.py
Roll_the_left!_Roll_the_right!
태그:

답글 남기기