시스템해킹_2주차

2022. 9. 22. 23:4622-2학기 (SISS)/시스템해킹

https://dreamhack.io/lecture/roadmaps/2

 

System Hacking

시스템 해킹을 공부하기 위한 로드맵입니다.

dreamhack.io

2주차 (9/12 ~ 9/18) : STAGE 3, 4


STAGE 3 : Tool Installation


[Tool : gdb]

1. 서론

컴퓨터 과학에서는 실수로 발생한 프로그램의 결함을 버그 (bug)라고 한다.

그런데 이미 완성된 코드에서 버그를 찾는 것은 어렵다. 그래서 이런 어려움을 해소하고자 디버거 (Debugger)라는 도구가 개발되었다. 디버거는 버그를 없애기 위해 사용되는 도구로, 프로그램을 어셈블리 코드 단위로 실행하면서, 실행결과를 사용자에게 보여준다.

그런데 이러한 디버거의 효용을 개발자만 얻는 것이 아니라, 해커, 리버스 엔지니어 등 모두가 이 도구를 사용할 수 있게 되고 버그 탐색의 효율을 높일 수 있게 됐다. 따라서 버그 발견이 쉬어짐으로써, 해커들은 취약점을 발견하기 쉬워졌다.

이번 강의에서 리눅스의 대표적인 디버거인 gdb에 대해 배울 것이다.

2. gdb & pwndbg

1) gdb

gdb(GNU debugger)는 리눅스의 대표적인 디버거이다. 오픈 소스로 개발되어 무료로 설치할 수 있고, 역사가 오래된만큼 다양한 플러그인들이 개발되어 있다.

gdb의 플러그인 중에서 바이너리 분석 용도로 널리 사용되는 플러그인에는 gef, peda, pwngdb, pwndbg 등이 있다. 

 

2) start

리눅스는 실행파일의 형식으로 ELF를 규정하고 있다. ELF는 헤더와 여러 섹션들로 구성되어 있다. 

-헤더 : 실행에 필요한 여러 정보가 적혀 있다.

-섹션 : 컴파일된 기계어 코드, 프로그램 문자열을 비롯한 여러 데이터가 포함되어 있다. 

 

ELF의 헤더 중에 진입점(EP)이라는 필드가 있는데, 운영체제는 ELF를 실행할 때 진입점의 값부터 프로그램을 실행한다.

gdb의 start 명령어는 진입점부터 프로그램을 분석할 수 있게 해주는 gdb의 명령어이다.

 

3) context

프로그램은 실행되면서 레지스터를 비롯한 여러 메모리에 접근한다. 따라서 디버거를 이용하여 프로그램의 실행 과정을 자세히 관찰하려면 컴퓨터의 각종 메모리를 한눈에 파악할 수 있는 것이 좋다.

pwndbg는 주요 메모리들의 상태를 프로그램이 실행되고 있는 맥락(Context)라고 부르며, 이를 가독성 있게 표현할 수 있는 인터페이스를 갖추고 있다.

- 맥락(context)  

  1. register : 레지스터의 상태를 보여준다.
  2. disasm : rip부터 여러 줄에 걸쳐 디스어셈블된 결과를 보여준다.
  3. stack : rsp부터 여러 줄에 걸쳐 스택의 값들을 보여준다.
  4. backtrace : 현재 rip에 도달할 때까지 어떤 함수들이 중첩되어 호출됐는지 보여준다.

4) break & contimue / run

- break : 특정 주소에 중단점(breakpoint)을 설정하는 기능이다.

- continue : 중단된 프로그램을 계속 실행시키는 기능이다. 

-> break로 원하는 함수에 중단점을 설정하고, 프로그램을 계속 실행하면 해당 함수까지 실행한 다음 중단된다. 이러면 중단된 지점부터 다시 세밀하게 분석할 수 있다.

 

- run : 실행하는 기능이다.

5) disassembly

gdb는 기계어를 디스어셈블(Disassemble)하는 기능을 기본적으로 탑재하고 있다. 또 pwndbg에는 디스어셈블된 결과를 가독성 좋게 출력해주는 기능이 있다.

6) navigate - ni / navigate - si / finish

관찰하고자 하는 함수의 중단점에 도달했으면, 그 지점부터는 명령어를 한 줄씩 자세히 분석해야 하는데, 이때 명령어 ni와 si를 사용한다.

- ni : 어셈블리 명령어를 한 줄 실행한다.

        서브루틴의 내부로 들어가지 않는다.

- si : 어셈블리 명령어를 한 줄 실행한다.

        서브루틴의 내부로 들어간다.

- finish : 함수 내부에 필요한 부분을 모두 분석했는데, 함수의 규모가 커서 ni로는 원래 실행 흐름으로 돌아가기 어려울 때               finish 명령어를 사용하여 함수의 끝까지 한 번에 실행할 수 있다.

7) examine

x라는 명령어를 이용하여 특정 주소에서 원하는 길이만큼의 데이터를 원하는 형식으로 인코딩하여 볼 수 있다.

8) telescope / vmmap

- telescope : pwndbg가 제공하는 강력한 메모리 덤프 기능이다. 특정 주소의 메모리 값들을 보여주는 것에서 그치지 않고,                     메모리가 참고하고 있는 주소를 재귀적으로 탐색하여 값을 보여준다.

- vmmap : 가상 메모리의 레이아웃을 보여준다. 파일이 매핑된 영역일 경우에는 해당 파일의 경로까지 보여준다.

9) gdb / python

숫자와 알파벳이 아닌 값을 입력해야 하는 상황에는 이용자가 직접 입력할 수 없는 값이기 때문에 파이썬으로 입력값을 생성하고 이를 사용해야 한다. 

10) gdb / python argv

run 명령어의 인자로 $()와 함께 파이썬 코드를 입력하면 값을 전달할 수 있다. 

입력값을 전달하기 위해서는 '<<<'문자를 사용한다.

 

3. 마치며


[Tool : pwntools]

 1. 서론

1) pwntools의 등장 배경

간단한 프로그램에 대해서는 파이썬과 파이프를 이용한 익스플로잇과 같은 방법으로 공격 페이로드를 생성한다. 그러나 익스플로잇이 조금만 복잡해져도 위와 같은 방식은 사용하기 어려워진다.

그래서 해커들은 익스플로잇 스크립트와 바이너리를 제작하였다.

이렇게 여러 개의 익스플로잇 스크립트를 작성하다 보면 자주 사용하는 함수들이 있는데, 이런 함수들을 반복적으로 구현하는 것은 비효율적이다. 그래서 시 해커들은 pwntools라는 파이썬 모듈을 제작하였다. 이제는 익스플로잇의 대부분이 pwntools를 이용하여 제작 및 공유되므로 시스템 해킹 공부를 하면, 이 모듈의 사용법을 알아둬야 한다.

 

2. pwntools API 사용법

1) process / remote / send / recv

  • process 함수 : 익스플로잇을 로컬 바이너리를 대상으로 할 때 사용하는 함수이다. 익스플로잇을 테스트하고 디버깅하기 위해 사용된다.
  • remote 함수 : 원격 서버를 대상으로 할 때 사용하는 함수이다. 대상 서버를 실제로 공격하기 위해 사용된다.
  • send : 데이터를 프로세스에 전송하기 위해 사용된다.
  • recv : 프로세스에서 데이터를 받기 위해 사용된다. 

2) packing / unpacking / interactive / ELF

  • packing & unpacking : 익스플로잇을 작성하다 보면 어떤 값을 리틀 엔디언의 바이트 배열로 변경하거나, 또는 역의 과정을 거쳐야 하는 경우가 있는데, pwntools에서 사용하는 관련 함수들이다.
  • interactive : 셸을 획득하거나, 익스플로잇의 특정 상황에 직접 입력을 주면서 출력을 확인하고 싶을 때 사용하는 함수이다. 호출하고 나면 터미널로 프로세스에 데이터를 입력하고, 프로세스의 출력을 확인할 수 있다.
  • ELF : ELF 헤더에는 익스플로잇에 사용될 수 있는 각종 정보가 기록되어 있다.

3) context / shellcraft

  • context.log : 디버그의 편의를 돕는 로깅 기능이 있다. context.log_level 변수로 로그 레벨을 조절할 수 있다.
  • context.arch : 셸코드를 생성하거나 코드를 어셈블, 디스어셈블하는 기능들은 공격 대상의 아키텍쳐에 영향을 받는다. 그래서 아키텍쳐 정보를 프로그래머가 지정할 수 있게 해준다.
  • shellcraft : 셸 코드가 실행될 때 메모리의 상태를 반영하지 못하거나, 구성 가능한 문자의 종류에 제한이 있는 등 여러 제약 조건이 존재하는 상황에서 직접 셸 코드를 작성하도록 해준다.

4) asm

  • asm : 어셈블 기능을 제공한다.

3. 마치며


STAGE 4 : Shellcode

[Exploit Tech : Shellcode]

1. 서론

해킹 분야에서 상대 시스템을 공격하는 것을 익스플룃(Exploit)이라고 부른다.

시스템해킹의 익스플로잇과 관련된 총 9가지 공격기법 중 셸코드를 배울 것이다.

- 셸코드(Shellcode) : 익스플로잇을 위해 제작된 어셈블리 코드 조각을 말한다. 일반적으로 셸을 획득하기 위한 목적으로                                      셸코드를 사용한다.

-> 파일 읽고 쓰기, 셸 획득과 관련된 셸코드를 작성해볼 것이다.

 

2. orw 셸코드

1) orw 셸코드 작성

- orw 셸코드 : 파일을 열고 읽은 뒤 화면에 출력해주는 셸코드이다.

2) orw 셸코드 - open & read & write

3) orw 셸코드 컴파일

셸코드는 아스키로 작성된 어셈블리 코드이기 때문에 기계어로 치환하면 CPU가 이해할 수는 있으나 ELF 형식이 아니기 때문에 리눅스에서 실행될 수 없다. 그렇기 때문에 gcc 컴파일을 통해서 ELF형식으로 변형해야 한다.

어셈블리 코드를 컴파일하는 방법에는 셸코드를 실행할 수 있는 스켈레톤 코드를 c언어로 작성하고, 거기에 셸코드를 탑재하는 방법이 있다. (스켈레톤 코드 : 핵심 내용은 비어있고 기본 구조만 갖춘 코드를 의미한다)

4) orw 셸코드 실행

공격 대상이 되는 시스템에서 셸코드를 실행할 수 있다면, 상대 서버의 자료를 유추해낼 수 있다.

5) orw 셸코드 디버깅 

pwndbg 플러그인은 syscall을 호출할 때, 인자를 분석해준다.

write 시스템 콜은 읽어낸 데이터를 출력해준다.

-> 디버깅 결과, write 시스템 콜을 수행할 때 플래그와 함께 출력되는 값을 유출해 내는 것을 메모리 릭(Memory Leak)이라고 부른다. 메모리 릭은 앞으로 배워나갈 보호기법들을 무력화시키는 핵심 역할을 한다.

 

3. execve 셸코드

1) execve 셸코드란

  • 셸(Shell, 껍질) : 운영체제에 명령을 내리기 위해 사용되는 사용자의 인터페이스이다. 셸을 획득하면 시스템을 제어할                            수 있게 되기 때문에 통상적으로 셸 획득을 시스템 해킹의 성공으로 여긴다.
  • execve 셸코드 : 임의의 프로그램을 실행하는 셸코드이다. 이를 이용하면 서버의 셸을 획득할 수 있다.

2) execve 셸코드 작성

  • execve 셸코드 : execve 시스템 콜만으로 구성된다.
  • argv : 실행파일에 넘겨줄 인자를 의미한다.
  • envp : 환경변수를 의미한다.
  • 리눅스에서 기본 실행 프로그램들은 /bin/디렉토리에 저장되어 있다.

4. 결론

셸 코드 작성법을 알면 다른 공격 기법들과 연계하여 강력한 공격 수단으로 활용할 수 있다.


[혼자실습] shell_basic

'22-2학기 (SISS) > 시스템해킹' 카테고리의 다른 글

시스템 해킹_4주차  (1) 2022.09.30
시스템해킹_3주차  (1) 2022.09.23
시스템해킹_1주차  (0) 2022.09.11