본문 바로가기
CTF/Dreamhack

[Dreamhack] rev-basic-5

by 8희 2024. 4. 28.

https://dreamhack.io/wargame/challenges/19

 

rev-basic-5

Reversing Basic Challenge #5 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출

dreamhack.io

 


 

cmd 창에서 파일을 실행해보면 input 값을 입력하라고 하고,

잘못된 값을 입력하면 Wrong이라는 메시지가 출력된다.

 

 

문자열 찾기 기능을 이용해서 Input 문자열이 있는 주소로 이동했다.

 

 

이동한 곳을 확인해봤다.

사용자의 입력 값을 chall5.7FF79EAF1000 함수에서 비교한 뒤에

비교 결과에 따라  Correct나 wrong을 출력한다.

 

해당 함수로 들어가보자.

 

 

cmp rax, 18

rax에 인덱스 길이가 24가 될 때까지 복사한다. 

 

movzx eax, byte ptr ds:[rcx+rax]

입력한 문자열에서 첫 번째 값(인덱스 값)을 eax에 저장한다.

바로 뒤에서 ecx에 해당 인덱스 값을 복사한다. 

 

inc ecx

ecx 값을 증가시킨다.

 

mov rdx, qword ptr ss:[rsp+20]

입력한 문자열 주소를 rdx에 저장한다.

 

mov ecx byte ptr ds:[rdx+rcx]

두 번째 입력한 문자열에서 두 번째 값(인덱스 + 1)을 ecx에 저장한다.

 

add eax, ecx

eax와 ecx를 더한다. 

즉, 앞 문자와 뒷 문자를 더한 값을 eax에 저장한다.

 

lea rdx, qword ptr ds:[7FF6F4343000]

[ 7FF6F4343000 ] 주소를 rdx에 저장한다.

해당 주소는 암호화된 문자열을의 주소를 의미한다.

 

movzx ecx, byte ptr ds:[rdx+rcx]

[ 7FF6F4343000 ] 주소의 i번째 값을 저장한다.

 

cmp eax, ecx

eax와 ecx를 비교한다.

즉, 암호화된 문자와 연산 결과를 비교한다.

 

 

[ 7FF6F4343000 ] 주소에 저장된 값은 이와 같다.

마지막 암호문이 00이므로 마지막 평문도 00일 것이다.

따라서 뒤에서부터 암호를 풀어 평문을 구해야 한다.

 

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]
latest = 0
flag = []

for i in range(23, -1, -1):
    latest = encrypted[i] - latest
    flag.append(chr(latest))

flag.reverse()
print(''.join(flag))

 

코드는 이와 같다.

 

 

플래그를 구했다!

'CTF > Dreamhack' 카테고리의 다른 글

[Dreamhack] rev-basic-7  (0) 2024.05.05
[Dreamhack] rev-basic-6  (0) 2024.04.28
[Dreamhack] Reversing Basic Challenge #4  (0) 2024.04.10
[Dreamhack] Reversing Basic Challenge #3  (0) 2024.04.06
[Dreamhack] Reversing Basic Challenge #2  (0) 2024.03.30