System Hacking

pwndbg를 이용한 ELF 동적 분석 방법

jir4vvit 2020. 8. 29. 20:35

참고 : dreamhack.io
환경 : ubuntu 16.04.7

 

 

바이너리를 분석할 때, 바이너리가 실행되며 변화하는 상태를 관찰하기 위해 동적 디버깅이 필요한 경우가 있다.

리눅스의 실행파일인 ELF 파일을 동적으로 디버깅하는 방법에 대해 알아보자.

 

이 포스팅에서 사용할 ELF 디버거는 gdb를 기반으로 만들어진 pwndbg이다.

 


 

디버깅할 파일의 소스코드이다.

example0.c

해당 소스코드를 사진에 제시된 방법으로 컴파일 해보자..

 

컴파일 완료

그럼 ELF 실행파일이 생겼을 것이다. (꿀팁을 주자면 실행파일은 녹색으로 이름이 되어있다 ㅎㅎ)

 

file

진짜 ELF 파일이다 ㅇㅇ

 


이제 디버깅을 해보자.

 

dbg 기반으로 만들어진 pwndbg을 사용하였다.

솔직히 dbg는 가독성이 떨어지는데 그에 비해 pwndbg는 알록달록해서 가독성이 높다. 

-q 옵션을 사용해 주면 앞에 기다란 ... 문자들을 빼준다.. (없이 하면 주르르르륵 너무 많은 정보가 나옴)

 

 

disassemble 명령을 사용하여 main을 디스어셈블 형태로 봐보자..

기존 gdb에서는 disas 라고만 쳐도 되는데 pwndbg에서는 저렇게 쳐야되더라.

 


 

사진에 표시해놓은 0x08048437에 break point를 걸고 디버깅을 해보자

 

break(b)를 사용하여 원하는 메모리 위치에 브레이크 포인트를 걸면 되고, 어디다가 브레이크가 걸렸는지는 info 명령을 통해 확인할 수 있다.

 

그리고 이제 run(r) 명령으로 실행시키면..!

내가 브레이크를 건 곳까지 실행이 되게 된다. 해당 명령을 nexti(ni) 명령을 통해 한 줄 수행하고 eax 상태를 봐보자.

참고로 eax에는 val1 + val2가 저장되어 있다. 예상대로 3이 저장되어있다.

 


이제 printf 부분에 브레이크 포인트를 걸고 실행해보자.

 

브레이크를 걸고 브레이크가 제대로 걸린 것을 확인하였다.

 

 

프로세스가 멈추어있는 상태에서 프로세스를 이어서 실행시켜주는 명령어는 continue(c) 이다.

이어서 실행시켜보자.

 

 

x 명령어는 출력 타입을 지정해줄 수 있다.

위 사진은 esp 레지스터의 메모리를 word 타입으로 2개만큼(x/2wx) 출려해본 사진이다.

 

x86 아키텍처의 호출 규약에 의해, printf 함수가 호출되는 시점의 스택 메모리에 함수의 인자들이 순서대로 저장되어 있는 것을 볼 수 있다.

 

위 사진은 첫번째 인자의 주소 0x080484e0을 문자열 형태로(x/s) 출력한 결과이다.

 

 

 

 

 

밑에 STACK이랑 등등 다 있는데 윗부분만 잘라서 캡처하였다.

ni 명령을 이용해 printf 함수를 실행한 결과이다.

printf 함수가 실행되어 "1 + 2 = 3" 문자열이 출력되었다.