본문 바로가기
Security/System Hacking

[Dreamhack System Hacking] STAGE 3

by 단월໒꒱ 2022. 1. 23.

[gdb 설치]

1. 디버거

 1) 디버거

   - 버그를 없애기 위해 사용하는 도구

   - 프로그램을 어셈블리 코드 단위로 실행하면서 실행결과를 사용자에게 보여줌

   - 개발자 -> 작성한 코드의 문제점을 명확하게 찾을 수 있게 됨

   - 해커, 리버스 엔지니어 -> 버그 탐색의 효율을 높일 수 있게 되어 취약점 발견이 쉬워짐

 

2. gdb & pwndbg

 1) 실습 예제

 

 

 

주어진 코드를 작성해서 c 파일을 만든 뒤 컴파일 해주고 디버깅을 시작한다.

 

리눅스는 실행파일의 형식으로 ELF를 규정하고 있다고 한다.

ELF는 크게 헤더와 여러 섹션들로 구성

헤더 : 실행에 필요한 여러 정보

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

 

ELF 헤더 중에 진입점이라는 필드 존재

 -> 운영체제는 ELF를 실행할 때 진입점의 값부터 프로그램 실행

 

 

 

 

readelf로 진입점을 확인해본 결과 0x401050인 것을 확인할 수 있다.

 

 2) start

   - 진입점부터 프로그램을 분석 가능

   - 진입점에 중단점 설정하고 실행

 

 

 

강의에서는 이 값이 위의 진입점과 같던데 실제로 해보니 여기서는 조금 다르다.

 

 3) context

   - 주요 메모리들의 상태를 프로그램이 실행되고 있는 맥락(context)라고 함

   - 크게 4개의 영역

      ① registers : 레지스터의 상태를 보여줌

      ② disasm : rip부터 여러 줄에 걸쳐 디스어셈블된 결과를 보여줌

      ③ stack : rsp부터 여러 줄에 걸쳐 스택의 값들을 보여줌

      ④ backtrace : 현재 rip에 도달할 때까지 어떤 함수들이 중첩되어 호출됐는지 보여줌

   - 어셈블리를 실행할 때마다 갱신되어 방금 실행한 어셈블리 명령어가 메모리에 미친 영향을 쉽게 파악할 수 있게 함

 

 

 

 

 4) break(b) : 중단점 설정

 5) continue(c) : 계속 실행

 

 

 

 6) run(r) : 중단점 설정시 단순히 실행 / 중단점 미설정시 프로그램 처음부터 실행

 

 

 

 7) disassemble : 디스어셈블 결과 출력

      - u, nearpc, pd : 디스어셈블 결과 가독성 좋게 출력

 

 8) nexti(ni) : 명령어 실행, 함수 내부로는 들어가지 않음

 

 9) stepi(si) : 명령어 실행, 함수 내부로 들어감

 

 10) finish : 함수의 끝까지 한 번에 실행

 

 11) x : 특정 주소에서 원하는 길이만큼의 데이터를 원하는 형식으로 인코딩하여 볼 수 있음

// rsp부터 80바이트를 8바이트씩 hex 형식으로 출력
pwndbg> x/10gx $rsp
0x7fffffffc228: 0x00007ffff7a05b97      0x0000000000000001
0x7fffffffc238: 0x00007fffffffc308      0x0000000100008000
0x7fffffffc248: 0x00000000004004e7      0x0000000000000000
0x7fffffffc258: 0x71eb993d1f26e436      0x0000000000400400
0x7fffffffc268: 0x00007fffffffc300      0x0000000000000000

// rip부터 10줄의 어셈블리 명령어 출력
pwndbg> x/5i $rip
=> 0x4004e7 <main>:     push   rbp
   0x4004e8 <main+1>:   mov    rbp,rsp
   0x4004eb <main+4>:   sub    rsp,0x10
   0x4004ef <main+8>:   mov    DWORD PTR [rbp-0xc],0x0
   0x4004f6 <main+15>:  mov    DWORD PTR [rbp-0x8],0x1

// 특정 주소의 문자열 출력
pwndbg> x/s 0x400000
0x400000:       "\177ELF\002\001\001"

 

 

 12) telescope(tele) : 메모리 조회, 메모리값이 포인터일 경우 재귀적으로 따라가며 모든 메모리값 출력

 

 

 

 13) vmmap : 가상 메모리의 레이아웃 출력

 

 

 

3. gdb / python

 1) gdb / python

   - gdb를 통해 디버깅할 때 직접 입력할 수 없을 때 사용 ex. 숫자와 알파벳이 아닌 값 입력

  

 2) gdb / python argv

   - run 명령어의 인자로 $()와 함께 파이썬 코드를 입력하면 값 전달 가능

   - 예시

 

pwndbg> r $(python -c 'print "\xff"*100')
Starting program: /home/s0ngsari/a $(python -c 'print "\xff"*100')
argv[1] ????????????????????????????????????????????????????????????????????????????????????????????????????

 

 3) gdb / python input

   - $()와 함께 파이썬 코드 입력하면 값 입력 가능

   - 입력값으로 전달하기 위해 '<<<' 사용

   - 예시

 

r $(python -c 'print "\xff"*100') <<< $(python -c 'print "dreamhack"')
Starting program: /home/s0ngsari/a $(python -c 'print "\xff"*100') <<< $(python -c 'print "dreamhack"')
argv[1] ????????????????????????????????????????????????????????????????????????????????????????????????????
Name: dreamhack

 

 

[pwntools 설치]

1. pwntools

 1) pwntools

   - 파이썬 모듈

   - pwntools 덕분에 익스플로잇 제작이 간단해짐

   - pwntools를 사용한 익스플로잇 스크립트

 

#!/usr/bin/python3
from pwn import *
# Make TCP connection
r = remote("127.0.0.1", 31337)
# Build payload
payload = ""
payload += "Socket script"
payload += "\n"
# Send payload
r.send(payload)
# Print received data
data = r.recv(1024)
print(f"Received: {data}")

 

 

 2) 설치

    - 깃헙에 오픈 소스로 공개되어 있음

    - 아래의 코드를 통해 설치 가능

 

$ apt-get update
$ apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade pwntools

 

2. pwntools API 사용법

 1) process & remote

   - 로컬 프로세스 또는 원격 서버의 서비스를 대상으로 익스플로잇 수행

   - process : 보통 로컬 바이너리를 대상으로 익스플로잇을 테스트하고 디버깅하기 위해 사용

   - remote : 원격 서버를 대상으로 실제 공격하기 위해 사용

 

 

 

 2) send

   - 데이터를 프로세스에 전송

 

 

 

 3) recv

   - 프로세스에서 데이터를 수신

   - recv(n) : 최대 n 바이트를 받음 (그 이하를 받아도 에러 발생 x)

   - recvn(n) : 정확히 n 바이트를 못 받으면 계속 대기

 

 

 

 4) packing & unpacking

   - 어떤 값을 리틀 엔디언의 바이트 배열로 변경하거나 그 역의 과정을 거치는 데 사용

   - 리틀 엔디언 : 메모리 주소가 높은 곳에서 낮은 곳으로 읽음

   - 빅 엔디언 : 메모리 주소가 낮은 곳에서 높은 곳으로 읽음

 

 

 

5) interactive

   - 셸을 획득했거나, 익스플로잇의 특정 상황에 직접 입력을 주면서 출력을 확인하고 싶을 때 사용

 

 

 

 6) ELF

   - ELF 헤더의 여러 중요 정보 수집

 

 

 

7) context.log

   - 익스플로잇 과정에서 출력할 정보의 중요도

   - context.log_level : 로그 레벨 조절 가능

 

 

 

8) context.arch

   - 익스플로잇 대상의 아키텍처 정보 지정

 

 

 

 9) shellcraft

   - 다양한 셸 코드 제공

 

 

 

 10) asm

   - 어셈블리 코드를 기계어로 어셈블

   - 대상 아키텍처가 중요하므로 아키텍처 미리 지정해야 함

 

 

 

 

 

 

STAGE 3도 클리어

댓글