티스토리 뷰

최종 수정: 2015-11-08

hackability@TenDollar


안녕하세요. Hackability 입니다.


이번에 포스팅 할 내용은 2015 School CTF 의 Reverse 300 문제 입니다.


본 문제에서는 바이너리 파일을 제공합니다.


근데 이상하게 문제 내용을 살펴 보면 딱히 사용자 입력이나 뭔가 키 값에 의한 연산같은것들이 없고 겔럭시들만 출력을 합니다.

그렇다면 문제 내에서 연산은 하는데 노출 시키지 않았을 수 있습니다.

데이터 영역의 문자열 상수들을 살펴 보면서 xref 위치를 살펴 보다가 해당 문자열들을 자꾸 레퍼하는 함수를 보게 되었습니다. (근데 이 함수는 제가 main을 따라갈땐 없던 함수 였음)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int __libc_csu_gala()
{
  int result; // eax@1
 
  sc[0= off_409014;
  sc[3= &byte_40DAC0;
  sc[1= 31337;
  sc[2= 1;
  byte_40DAC0 = off_409004[0][8];
  byte_40DAC1 = off_409010[0][7];
  byte_40DAC2 = off_409008[0][4];
  byte_40DAC3 = off_409004[0][6];
  byte_40DAC4 = off_409004[0][1];
  byte_40DAC5 = off_409008[0][2];
  byte_40DAC6 = 95;
  byte_40DAC7 = off_409004[0][8];
  byte_40DAC8 = off_409004[0][3];
  byte_40DAC9 = off_40900C[0][5];
  byte_40DACA = 95;
  byte_40DACB = off_409004[0][8];
  byte_40DACC = off_409004[0][3];
  byte_40DACD = off_409004[0][4];
  byte_40DACE = off_409010[0][6];
  byte_40DACF = off_409010[0][4];
  byte_40DAD0 = off_409004[0][2];
  byte_40DAD1 = 95;
  byte_40DAD2 = off_409010[0][6];
  result = off_409008[0][3];
  byte_40DAD3 = off_409008[0][3];
  byte_40DAD4 = 0;
  return result;
}
cs

보면 byte에 입력되는 값이 20 글자 이고 95 는 문자열로 언더바 (_) 이기 때문에 이 바이트 시퀀스가 flag일 확률이 높습니다.

따라서 어떤 값이 대입되는지 살펴 보려면 먼저 off 값들을 정리할 필요가 있습니다.

off_00409004 = "Andromeda"
off_00409008 = "Messier"
off_0040900C = "Sombrero"
off_00409010 = "Triangulum"

이정도 정리 해놓고 위와 비교 하여 글자 하나씩 맞추면 flag 는 다음과 같습니다.

aliens_are_around_us

* 추가로 다른 라이트업을 보면 처음에 소스에서 겔럭시 구조를 만드는데 secret_information 필드가 있었고, 마지막 배열의 next 포인터가 null 이 아니라 어떤 값을 가리키고 있어서 그 값을 따라가서 문자열을 조합하면 위처럼 나온다고 합니다.

(gdb) x/10qw 0x60115c0x60115c <sc>:  0x00400a67  0x00000000  0x00007a69  0x000000010x60116c <sc+16>:   0x00601184  0x00000000  0x00000000  0x000000000x60117c <sc+32>:   0x00000000  0x00000000

...(gdb) x/1s 0x006011840x601184 <sc+40>:   "aliens_are_around_us"

이 방식이 제가 푼 방식과 다른점은 저는 정적 분석으로 프로그램 실행 중 할당되는 내용을 안보고 푼 것이고, 라이트 업은 bp를 걸어 가면서 할당되는 값이 어떻게 할당되는지 보면서 넘어가는 방식 이였습니다.

저는 리버싱을 할 때 대부분 정적으로 하는 안좋은 습관이 있는데 정적으로 대략적인 구조만 살펴 보고 bp 잡으면서 동적으로 문제 해결하는것이 더욱 효과적입니다.


댓글