CTF/리버싱

[SharkyCTF] SIMPLE - 리버싱 / 어셈블리어 / IDA

SecurityMan 2022. 8. 27. 11:00

 

문제 제목처럼 간단한 어셈블리 리버싱 문제

 

문제의 목표는 프로그램이 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 변수에 넣어주면 된다.

 

 

코드를 실행하면 바로 플래그가 나온다.

반응형