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!

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다