본문으로 바로가기

[Protostar] Stack1 풀이, write-up

category Wargame/Protostar 2019. 1. 6. 10:21

Protostar --- Stack1



Stack1의 힌트이다.


If you are unfamiliar with the hexadecimal being displayed, "man ascii" is our friend.

Also Protostar is little endian.


힌트를 해석하면 아래와 같다.


만약 너가 앞으로 보여질 16진수에 친숙하지 않다면 "man ascii" 명령어가 도움이 될것이다.

또한, Protostar는 little endian 방식을 사용한다.



stack1.c의 소스코드는 아래와 같다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
 
  if(argc == 1) {
      errx(1"please specify an argument\n");
  }
 
  modified = 0;
  strcpy(buffer, argv[1]);
 
  if(modified == 0x61626364) {
      printf("you have correctly got the variable to the right value\n");            
  } else {            
      printf("Try again, you got 0x%08x\n", modified);
  }
}
cs



volatile keyword로 4 byte int type 변수 modified를 선언한다.

64 byte char type array buffer를 선언한다.



1
2
3
4
int main(int argc, char **argv)                                                    
{
  volatile int modified;
  char buffer[64];
cs



stack1을 실행할 때 파일의 파라미터가 없다면, "please specify an argument\n"를 출력한다.



1
2
3
    if(argc == 1) {
      errx(1"please specify an argument\n");                                    
      }
cs



modified 변수를 0으로 초기화하고, 첫 번째 인자를 buffer array에 복사한다.



1
2
      modified = 0;                                                                
      strcpy(buffer, argv[1]);
cs



만일 modified가 "0x61626364"이면, "you have correctly got the variable to the right value\n"를 출력한다.

만일 modified가 "0x61626364" 아니면, "Try again, you got modified"를 출력한다.



1
2
3
4
5
6
      if(modified == 0x61626364) {
              printf("you have correctly got the variable to the right value\n");
      } else {
                 printf("Try again, you got 0x%08x\n", modified);
       }
}
cs



stack0과 매우 유사한 형태다. 하지만 stack1의 초점은 modified를 정확히 "0x61626364"로 초기화 해야한다.



만일 파라미터를 가지지 않으면 아래와 같이 나오고, stack0와 같이 너무 작은 값을 입력하여 modified를 변경시키지 못할때, overflow를 발생시켰지만 modified 값이 "0x61626364"로 변경되지 않을때는 아래와 같다.





gdb를 이용해 stack1의 elf 파일이 어떤 stack 구조를 가지고 있는지 확인해보자.





stack0에서 본 stack과 정확히 같은 구조를 가지고 있다.


다만 분석을 위해 parameter를 어디서 얻어오는지 확인해보자.

일반적으로 strcpy() 함수를 호출할 때, copy 할 source를 rsi, copy 될 destination을 rdi로 설정한다.

따라서 rdi는 buffer의 주소 source는 parameter의 주소가 될 것이다.


0x0000000000401184 <+50>: mov    rax,QWORD PTR [rbp-0x60]

0x0000000000401188 <+54>: add    rax,0x8

0x000000000040118c <+58>: mov    rdx,QWORD PTR [rax]

0x000000000040118f <+61>: lea     rax,[rbp-0x50]
0x0000000000401193 <+65>: mov    rsi,rdx
0x0000000000401196 <+68>: mov    rdi,rax

rsi에 대입되는 rdx를 주목해서 보면 된다.




gdb 분석을 바탕으로 stack을 그려보면 아래와 같이 정확히 stack0와 같음을 확인할 수 있다.





modified 변수의 값을 수정하기 위해서 76 byte의 padding이 필요하고 modified를 "0x61626364"로 대입하면 된다.

다만 여기서 little endian 사용하기 때문에 "\x64\x63\x62\x61"로 작성해야한다.





little endian을 고려하지 않고 사용하면 "0x64636261" 처럼 예상과 반대 값이 나오기 때문에 little endian을 고려해서 작성해야 한다.









'Wargame > Protostar' 카테고리의 다른 글

[Protostar] Stack5 풀이, write-up  (0) 2019.01.12
[Protostar] Stack4 풀이, write-up  (0) 2019.01.09
[Protostar] Stack3 풀이, write-up  (1) 2019.01.08
[Protostar] Stack2 풀이, write-up  (0) 2019.01.07
[Protostar] Stack0 풀이, write-up  (0) 2019.01.05