SH1R0_HACKER

stack 2 본문

System2/Protostar

stack 2

SH1R0_HACKER 2020. 10. 18. 15:50

 

stack2.c

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
  char *variable;

  variable = getenv("GREENIE");

  if(variable == NULL) {
      errx(1, "please set the GREENIE environment variable\n");
  }

  modified = 0;

  strcpy(buffer, variable);

  if(modified == 0x0d0a0d0a) {
      printf("you have correctly modified the variable\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }

}

 

이 프로그램은 실행하면 GREENIE 환경 변수가 없다며 프로그램이 종료된다.

코드를 분석해보면 modified (4byte), variable (4byte), buffer (64byte)를 선언한다.

getenv 함수는 variable에 시스템 환경 변수 GREENIE에 저장된 값을 가져온다.

variable == NULL 이라면 오류를 띄우고 종료한다.

 

GREENIE 환경변수를 만들고 modified를 0x0d0a0d0a로 만들어주어야 할 것 같다.


[ 취약점 파악 및 분석 ]

아래는 어셈블리어 해석이다.

   0x08048494 <+0>:     push   ebp
   0x08048495 <+1>:     mov    ebp,esp
   0x08048497 <+3>:     and    esp,0xfffffff0
   0x0804849a <+6>:     sub    esp,0x60
   0x0804849d <+9>:     mov    DWORD PTR [esp],0x80485e0
   0x080484a4 <+16>:    call   0x804837c <getenv@plt>
   // esp 레지스터에 0x80485e0를 전달하고 getenv 함수를 실행한다.
   // x/s 0x80485e0 : "GREENIE"
   0x080484a9 <+21>:    mov    DWORD PTR [esp+0x5c],eax
   0x080484ad <+25>:    cmp    DWORD PTR [esp+0x5c],0x0
   // [esp+0x5c] 메모리와 0을 비교한다. (환경변수에서 아무것도 안가지고오면 0)
   // variable 변수 : esp+0x5c
   0x080484b2 <+30>:    jne    0x80484c8 <main+52>
   0x080484b4 <+32>:    mov    DWORD PTR [esp+0x4],0x80485e8
   0x080484bc <+40>:    mov    DWORD PTR [esp],0x1
   0x080484c3 <+47>:    call   0x80483bc <errx@plt>
   // x/s 0x80485e8 "please set the GREENIE environment variable\n"
   0x080484c8 <+52>:    mov    DWORD PTR [esp+0x58],0x0
   // [esp+0x58]에 0을 넣는다.
   // modified 변수 : esp+0x58
   0x080484d0 <+60>:    mov    eax,DWORD PTR [esp+0x5c]
   0x080484d4 <+64>:    mov    DWORD PTR [esp+0x4],eax
   0x080484d8 <+68>:    lea    eax,[esp+0x18]
   // buffer 변수 : esp+0x18
   0x080484dc <+72>:    mov    DWORD PTR [esp],eax
   0x080484df <+75>:    call   0x804839c <strcpy@plt>
   0x080484e4 <+80>:    mov    eax,DWORD PTR [esp+0x58]
   0x080484e8 <+84>:    cmp    eax,0xd0a0d0a
   // modified 변수와 0x0d0a0d0a를 비교한다.
   0x080484ed <+89>:    jne    0x80484fd <main+105>
   0x080484ef <+91>:    mov    DWORD PTR [esp],0x8048618
   0x080484f6 <+98>:    call   0x80483cc <puts@plt>
   // x/s 0x8048618 "you have correctly modified the variable\n"
   0x080484fb <+103>:   jmp    0x8048512 <main+126>
   0x080484fd <+105>:   mov    edx,DWORD PTR [esp+0x58]
   0x08048501 <+109>:   mov    eax,0x8048641
   0x08048506 <+114>:   mov    DWORD PTR [esp+0x4],edx
   0x0804850a <+118>:   mov    DWORD PTR [esp],eax
   0x0804850d <+121>:   call   0x80483ac <printf@plt>
   // x/s 0x8048641 "Try again, you got 0x%08x\n"
   0x08048512 <+126>:   leave  
   0x08048513 <+127>:   ret 

 

variable의 위치 : esp+0x5c

modified의 위치 : esp+0x58

buffer의 위치 : esp+0x18


[ 취약점 파악 및 분석 ]

우선 프로그램을 실행시키기 위해선 "GREENIE" 라는 환경변수가 필요하다.

이 환경변수가 스택을 다 채우고 modified 변수를 0x0d0a0d0a로 만들어 버리게 하면 된다.

먼저 buffer와 modified의 거리부터 알아보자.

길이가 대략적으로 100보다 작을거라고 생각하고 길이 100의 패턴을 만든다.

그 후 export (환경변수명)='(패턴 값)' 형태로 입력하여 환경변수를 만들어준다.

그러면 이제 프로그램은 GREENIE 환경변수를 참고하여 실행된다.

브레이크 포인트를 main+84에 걸어준다.

modified 변수와 0x0d0a0d0a를 비교하는 부분이다.

 

레지스터에 저장된 패턴값을 보면 EAX : 0x41644141 ('AAdA') 부분을 볼 수 있다.

현재 브레이크 포인트인 main+84번은 modified 변수를 eax에 넣고 비교하기 직전이다.

따라서 현재 eax에 들어있는 값이 modified에 들어있는 패턴값으로 볼 수 있다.

 

즉, GREENIE 환경변수에 설정한 패턴 100개가 buffer (64byte)를 모두 채우고

modified(4byte)로 넘어온 부분이 'AAdA' 라는 것이다.

 

이 부분을 오프셋 명령어의 인자값에 입력하면

사진 삭제

사진 설명을 입력하세요.

buffer변수와 modified변수의 거리는 64바이트라는 결과를 얻을 수 있다.


[ Exploit ]

 

이제 buffer변수와 modified변수의 거리도 알았으니 공격을 해보자.

대표사진 삭제

사진 설명을 입력하세요.

0x0d0a0d0a를 ASCII 코드로 변환하여 입력하려면 문자열이 아닌 개행, 줄바꿈이기 때문에 문자열이 아닌

파이썬을 통해 값을 입력해야 한다.

$ 표시와 () 를 사용하면 파이썬 실행 결과를 커맨드라인에 문자열로 넣을 수 있다.

형태 : $(python -c '코드')

 

메모리 입출력 방식이 리틀 엔디안이기 때문에 0x0a0d0a0d 순으로 입력하면 된다.

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

stack5  (0) 2020.10.18
stack 4  (0) 2020.10.18
stack 3  (0) 2020.10.18
stack 1  (0) 2020.10.18
Stack 0  (0) 2020.10.18