문제 제목처럼 간단한 어셈블리 리버싱 문제
문제의 목표는 프로그램이 1 을 리턴하도록 하는 적절한 입력값을 찾는 것이다.
BITS 64
SECTION .rodata
some_array db 10,2,30,15,3,7,4,2,1,24,5,11,24,4,14,13,5,6,19,20,23,9,10,2,30,15,3,7,4,2,1,24
the_second_array db 0x57,0x40,0xa3,0x78,0x7d,0x67,0x55,0x40,0x1e,0xae,0x5b,0x11,0x5d,0x40,0xaa,0x17,0x58,0x4f,0x7e,0x4d,0x4e,0x42,0x5d,0x51,0x57,0x5f,0x5f,0x12,0x1d,0x5a,0x4f,0xbf
len_second_array equ $ - the_second_array
SECTION .text
GLOBAL main
main:
mov rdx, [rsp]
cmp rdx, 2
jne exit
mov rsi, [rsp+0x10]
mov rdx, rsi
mov rcx, 0
l1:
cmp byte [rdx], 0
je follow_the_label
inc rcx
inc rdx
jmp l1
follow_the_label:
mov al, byte [rsi+rcx-1]
mov rdi, some_array
mov rdi, [rdi+rcx-1]
add al, dil
xor rax, 42
mov r10, the_second_array
add r10, rcx
dec r10
cmp al, byte [r10]
jne exit
dec rcx
cmp rcx, 0
jne follow_the_label
win:
mov rdi, 1
mov rax, 60
syscall
exit:
mov rdi, 0
mov rax, 60
syscall
문제파일로 main.asm 파일이 주어지는데 내용은 위와 같다.
내용을 대충 살펴보면
some_array / the_second_array 두 개의 배열이 있고
뭔가 이 두 배열을 가지고 XOR 도 하면서
요리조리 만져서 어떤 값을 만들어 내는것 같다.
여기까지만 봐도 어셈블리어는 머리아프니
그냥 컴파일을 해준다.
칼리 리눅스에서
nasm -f elf64 main.asm -o main.o
gcc -o main main.o
이렇게 입력하면 asm 파일을 nasm을 통해 목적파일로 만들고
gcc로 컴파일 해줄 수 있다.
nasm과 gcc는 칼리 리눅스에 내장되어 있다.
IDA 라는 디스어셈블러를 이용해 main 파일을 살펴본다.
main 함수를 보면
if 문 아래쪽에 있는 while 문에서 뭔가 계산을 하는데
some_array에 있는 값을 가져와 v9 에 저장된 값과 더한 뒤,
그걸 42와 XOR 한 값이 the_second_array 에 있는값과 같은지 비교하고 있다.
v9 가 아마 사용자의 입력이 들어가는 부분이지 않을까 싶다.
v9 를 구하려면 간단하게 역으로 계산해주면 된다.
the_second_array 에서 한글자씩 가져와서 42와 XOR 해주고,
그다음 some_array 에 있는 글자를 빼주면 되는것이다.
some_array = [10,2,30,15,3,7,4,2,1,24,5,11,24,4,14,13,5,6,19,20,23,9,10,2,30,15,3,7,4,2,1,24]
the_second_array = [0x57,0x40,0xa3,0x78,0x7d,0x67,0x55,0x40,0x1e,0xae,0x5b,0x11,0x5d,0x40,0xaa,0x17,0x58,0x4f,0x7e,0x4d,0x4e,0x42,0x5d,0x51,0x57,0x5f,0x5f,0x12,0x1d,0x5a,0x4f,0xbf]
flag = ''
for i in range(len(the_second_array)):
flag += chr(int(the_second_array[i] ^ 42) - int(some_array[i]))
print(flag)
파이썬 코드로 아주 간단하게 짤 수 있다.
some_array 와 the_second_array 두 배열을 만들어 asm 파일에 저장되어있던 값을 그대로 복사해준다.
플래그를 저장할 flag 변수를 하나 생성해주고
for 문으로 the_second_array 의 길이만큼 반복해서
(the_second_array ^ 42) - some_array[i] 한 값을 차례로 flag 변수에 넣어주면 된다.
코드를 실행하면 바로 플래그가 나온다.
'CTF > 리버싱' 카테고리의 다른 글
[2020CCE] My Friend - 리버싱 / IDA / Python (56) | 2022.11.01 |
---|---|
[2020CCE] Simple Botnet - 리버싱 / IDA (60) | 2022.10.11 |
[SharkyCTF] Z3ROBOTWAVES - 리버싱 / IDA (44) | 2022.08.16 |
[HouseplantCTF] thedanzman - 리버싱 / Python / ROT13 / Base64 (48) | 2022.06.17 |
[HouseplantCTF] SQUEEZY - 리버싱 / Python / Base64 / XOR (64) | 2022.06.15 |