Writer - hoodbilen

pwntools란?


시스템해킹(pwnable)에 필요한 기능들을 최대한 집대성해 만든 파이썬 모듈이다. 실제로는 프레임워크라고 더 자주 표현한다.

How to install?


$ apt-get update
$ apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential
$ pip install --upgrade pip
$ pip install --upgrade pwntools

추가 정보는 아래 확인.

https://github.com/Gallopsled/pwntools

USE


$ vi test.py
$ python test.py

이런 식으로 작성하고, 실행시킬 수 있다.

process & remote


process함수는 로컬 바이너리에 대해 익스플로잇을 테스팅해볼 때 사용하는 함수이고, remote함수는 원격 서버를 대상으로 실제 익스플로잇을 작동시킬 때 사용하는 함수이다.

from pwn import *
p = process('./test') # local 파일 test를 대상으로 exploit 실행함.
p = remote('warroom.kr', 123456) # warroom.kr의 123456번 포트에 있는 바이너리를 대상으로 exloit 실행함.

send


pwntools에는 send와 관련된 다양한 함수가 있다.

from pwn import *
p = process('./test')

p.send('A') # ./test에 'A'를 입력한다.
p.sendline('A') # ./test에 'A'+'\n'을 입력한다.
p.sendafter('hello', 'A') # ./tets가 'hello'를 출력하면, 'A'를 입력한다.
p.sendlineafter('hello', 'A') # ./test가 'hello'를 출력하면 'A'+'\n'을 입력한다.

send, sendline, sendafter, sendlineafter 을 사용할 때는 process값을 받은 p.를 꼭 붙여주어야 한다.

recv


pwntools에는 recv와 관련된 다양한 함수가 있다.

from pwn import *
p = process('./test')

data = p.recv(1024) # p가 출력하는 데이터중 최대 1024바이트의 데이터를 받아서 data에 저장
data = p.recvn(5) # p가 출력하는 데이터중 정확히 5바이트를 받아서 data에 저장
data = p.recvline() # p가 출력하는 데이터중 개행문자를 만날 때 까지를 data에 저장
data = p.recvuntil('hello') # hello라는 문자열을 p가 출력할 때 까지 받아서 data에 저장
data = p.recvall() # 연결이 끊어지거나 프로세스가 종료될 때까지 받아서 data에 저장

주의해서 봐야할 것은 p.recvp.recvn 의 차이점인데, p.recv()는 최대 n 바이트를 받는 것 이기 때문에, 1024바이트를 다 채워 받지 못해도 에러를 발생시키지 않지만, p.recvn()의 경우 정확히 인자만큼의 데이터를 받지 못하면 계속 대기한다.

recv,recvline,recvn,recvuntil, recvall은 불필요한 문자까지 입력받은 후 send를 할때도 사용할 수 있다. 불필요한 문자를 입력받을 때는 data = 를 제외하고 p.recvline() 처럼 단독으로 사용하면 된다.

packing & unpacking


대부분의 CPU는 little endian을 이용한다. 익스플로잇을 작성하다 보면 어떤 값을 little endian스트링으로 변경하거나, 또는 역의 과정을 거쳐야 하는 경우가 자주 있는데, 이를 쉽게 할 수 있도록 pwntools에서는 함수로 제공한다.

ex)

#test.py
from pwn import *

data32 = 0x41424344
data64 = 0x4142434445464748

print p32(data32)
print p64(data64)

data32 = "ABCD"
data64 = "ABCDEFGH"

print hex(u32(data32))
print hex(u64(data64))
$python test.py
DCBA
HGFEDCBA
0x44434241
0x4847464544434241

log


from pwn import *
context.log_level = 'debug' # 서버 혹은 바이너리와 이 익스플로잇간에 오고가는 모든 데이터를 화면에 hexdump형식으로 출력해줌

debug


from pwn import *
p = process('./test')
gdb.attach(p)

익스플로잇을 실행하는 중간에 debug를 하고 싶을때 원하는 위치에서 위 명령어를 사용하면 새 창에서 해당 프로그램이 gdb로 보여진다. 정확하게 원하는 값이 채워졌는지, 릭이 정확하게 되었는지, 스택주소, 데이터 등을 볼 때 유용하다.

interactive


쉘을 획득한 경우이거나, 익스플로잇의 특정 경우에 직접 입력을 주면서 디버깅을 해보고 싶다면 사용하게 되는 함수. 익스플로잇과 프로세스와의 연결을 stdin, stdout <=> process로 바꿔준다.

pwntools 익스플로잇이 끝났을 때 쉘을 따지 않아도 $ 가 나오는 이유가 이것 때문이다.

from pwn import *
p = process('./test')
p.interactive()

ELF


리눅스에서 작동하는 실행파일 ELF 에는 각종 정보가 기록되어 있다. 그 중 대표적인 것이 GOT, PLT 인데, pwntools를 통해 이런 값들을 쉽게 구해올 수 있다.

from pwn import *
e = ELF('./test')
puts_plt = e.plt['puts'] # ELF ./test에서 puts()의 PLT주소를 찾아서 puts_plt에 넣는다.
read_got = e.got['read'] # ELF ./test에서 read()의 GOT주소를 찾아서 read_got에 넣는다.

해당 문서는 pwntools를 사용하면서 자주 마주치는 함수들에 대해서만 간략히 소개한 문서이다.

자세한 사용법을 알고싶은 사람은 아래 공식 주소를 참고.

https://docs.pwntools.com/en/stable/index.html

'hacking > tool' 카테고리의 다른 글

mac IDA create structure  (0) 2019.08.08

IDA는 이런식으로 Structures 창이 있다. 해당 창에서 구조체를 선언하면 code를 좀더 편하게 볼 수 있다.

구조체를 선언하는 방법은 insert key를 누르는 것이다. 그런데 mac은 자판에 insert key가 없다... 대체로 `Insert -> fn+Enter`라고 했는데 아무리 눌러도 되지를 않는다... 해서 알아보니 mac은 단축키가 따로 존재하더라.

바로 `i`다. 

`i`를 누르면 이런식으로 create할 수 있는 창이 생긴다. 해당 창에서 내가 원하는 구조체 명을 적고 `ok`를 누르면 된다.

이런식으로 구조체의 ends를 누르고 `d`key를 누르면 변수가 선언된다.

선언된 변수에서 `n`key를 누르면 변수 명을 바꿀 수 있다.

선언된 변수에서 `d`key를 누르면 변수 크기를 바꿀 수 있다.

선언된 변수에서 `fn+u`key를 누르면 변수를 삭제할 수 있다.

 

구조체를 다 만들었으면 코드에 삽입해주면 된다.

변경하고 싶은 부분을 클릭하고 `y`를 누르면 해당 부분을 재정의 할 수 있다. 이런식으로 재정의해주면 된다.

'hacking > tool' 카테고리의 다른 글

How to use pwntools  (0) 2019.08.08

+ Recent posts