rev-basic-5 문제도 마찬가지로 문자열을 역참조해서
문자열을 암호화시키는 함수를 찾을 수 있다. 위 링크 참조하기 바람.
암호화시키는 함수만 들여다보면 아래와 같다.
sub_140001000 ... movsxd rax, [rsp+18h+var_18] mov rcx, [rsp+18h+arg_0] movzx eax, byte ptr [rcx+rax] mov ecx, [rsp+18h+var_18] inc ecx movsxd rcx, ecx mov rdx, [rsp+18h+arg_0] movzx ecx, byte ptr [rdx+rcx] add eax, ecx movsxd rcx, [rsp+18h+var_18] lea rdx, byte_140003000 movzx ecx, byte ptr [rdx+rcx] cmp eax, ecx ...
movsxd rax, [rsp+18h+var_18] mov rcx, [rsp+18h+arg_0] movzx eax, byte ptr [rcx+rax]
받은 문자열 중 0번째 문자값을 EAX 레지스터에 저장시킨다.
mov ecx, [rsp+18h+var_18] inc ecx movsxd rcx, ecx mov rdx, [rsp+18h+arg_0] movzx ecx, byte ptr [rdx+rcx]
받은 문자열의 인덱스를 나타내는 ECX 레지스터를 1만큼 증가시킨다.
따라서 1번째 문자값이 ECX 레지스터에 저장된다.
add eax, ecx
EAX 값 = EAX 값 + ECX 값
즉, EAX값은 0번째 문자값과 1번째 문자값을 더한 값이다.
movsxd rcx, [rsp+18h+var_18] lea rdx, byte_140003000 movzx ecx, byte ptr [rdx+rcx] cmp eax, ecx
그리고 EAX값과 암호화된 문자열 중 0번째 문자값이랑 비교한다.
암호화된 문자열은(byte_140003000)은 아래와 같았다.
\xAD\xD8\xCB\xCB\x9D\x97\xCB\xC4\x92\xA1\xD2\xD7\xD2\xD6\xA8\xA5\xDC\xC7\xAD\xA3\xA1\x98\x4C\x00
아래와 같이 한문자씩 계속 비교한다고 보면 된다.
0xAD != (0번째 문자) + (1번째 문자) 0xD8 != (1번째 문자) + (2번째 문자) 0xCB != (2번째 문자) + (3번째 문자) ... 0x00 != (23번째 문자) + (24번째 문자)
0x00 != (23번째 문자) + (24번째 문자)에서 힌트를 얻을 수 있다.
문자 코드 범위가 무조건 0이상이어야 하므로
23번째 문자와 24번째 문자값이 둘다 0이다.
0x4c != (22번째 문자) + (23번째 문자)에서
23번째 문자값이 0이므로
22번째 문자값=0x4c(L)
0x98 != (21번째 문자) + (22번째 문자)에서
22번째 문자값이 0x4c이므로
21번째 문자값=0x98-0x4c=0x4c(L)
0xA1 != (20번째 문자) + (21번째 문자)에서
21번째 문자값이 0x4c이므로
20번째 문자값=0xA1-0x4c=0x55(U)
…
이렇게 쭉- 암호화된 문자열을 역순으로 하나씩 계산해서
복호화시킬 수 있다.
enc_str = b'\xAD\xD8\xCB\xCB\x9D\x97\xCB\xC4\x92\xA1\xD2\xD7\xD2\xD6\xA8\xA5\xDC\xC7\xAD\xA3\xA1\x98\x4C\x00' dec_str = "" last = enc_str[len(enc_str) - 1]; for i in range(1, len(enc_str)): j = enc_str[len(enc_str) - i - 1] - last; last = j; dec_str = dec_str + chr(j) print(dec_str[::-1])
ubuntu@WSL:~/CTF/dreamhack.io/chall5$ python3 chall5.py All_l1fe_3nds_w1th_NULL