Write-up/HackCTF

[HackCTF] Handray

새달아 2022. 1. 14. 17:51

확장자가 file인 파일... 아마 ELF파일인 것 같으니 리눅스에서 열어보자.

64bit ELF파일이구나! 그렇다면 바로 실행시키면 어떤 동작을 하는지 알 수 있겠지?

flag를 뛰어넘었습니다... 일단 뭔지 모르겠다. 값을 넣어봐도 안넣어봐도 똑같네...

일단 ida로 확인해보자.

...? printf 하나만 달랑있다. 좀 당황스럽지만 어셈블리로 다시 보자.

첫번째 분기점에서 jnz를 jz로 바꾸면 다른 분기로 넘어갈 수 있는데 jnz로 되어있어 무조건 "flag를 뛰어넘었습니다."가 출력되는 것 같다. 정상적인 값이 나오게 하려면 다른 분기점에서 어떻게 작동하는지 알면 실행시키지 않아도 flag를 얻을 수 있다.

 

다른 분기점에서의 작동을 보면...

1. 0부터 0x1E까지 반복하는 반복문이다.
2. [rbp+var_8]과 [rax*4]는 배열의 인덱스처럼 쓰인다.
3. 배열은 string과 array가 있는데, 해당 인덱스의 값을 서로 더하여 string배열에 다시 저장하는 것을 반복한다.

그렇다면... string과 array에 어떤 값들이 있는지 살펴보면 쉽게 풀 수 있다!

string에서는 이러한 값들이 저장되어 있고,

array 배열에는 이러한 값들이 저장되어 있다.

  • string은 1바이트씩 이니까 char형, array는 4바이트씩이니까 int형으로 유추...
  • 위에 array의 인덱스가 [rax*4]인 이유도, int형은 4바이트씩 메모리를 잡기때문에 4바이트 단위로 인덱스가 증가함.

이 내용을 코드로 옮겨서 실행하면...

#include <stdio.h>

int main()
{
	int i;
	int array[32] = {0x7, 0x4, 0x3, 0x1, 0x4, 0x6, 0x3, 0x1, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x3, 0x4, 0x5, 0x2, 0x5, 0x2, 0x2, 0x2, 0x2, 0x2};
	char key[34] = "A]`j?NCz?eiHb:R^CkdA.jaP+F+..jb!}";
	char flag[34];
	
	for(i = 0; i < 31; i++)
	{
		flag[i] = key[i] + array[i];
	}
	flag[31] = key[31];
	flag[32] = key[32];
	flag[33] = key[33];
	
	
	printf("%s", flag);
	
	return 0;
}

쨘! 이렇게 flag를 획득할 수 있다.