Pwntools는 python으로 작성된 exploit 작성을 간단하게 하기위해 만든 CTF framework, exploit 개발 라이브러리이다.
64-bit Ubuntu에 가장 적합하고, python 2.7이 필요하다. (python 2.7 문법을 알아야 할 듯)
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
git clone https://github.com/Gallopsled/pwntools
pip install --upgrade --editable ./pwntools
-pwntool에 빨리 친숙해지도록 python module structure 사용
-pwnlib 일반적인 python moduel
- pwn CTF 시 사용
-많은 submodule의 함수들과 함께 상위 레벨의 pwnlib에서 모든 것을 import 함.
=> import pwn 또는 from pwn import *을 하면, exploit을 작성할 때 필요한 모든 것에 접근할 수 있다.
-pwnlib.term.init() 호출 : terminal을 raw-mode로 전환해서 그렇지 않은 것처럼 보이도록 기능을 구현
- pwnlib.context.log_level : “info”로 세팅
- sys.argv : sys.argv로 값을 분석하고, 분석에 성공한 것은 제거 (?)
- pwnlib.util.packing 할 필요없이 import pwnlib.util
- pwnlib.shellcraft 은 아직 안정적이지 않음
Ubuntu Xenial (16.04) 는 대부분 아키테쳐를 위한 official 패키지를 가지고 있어서 이 과정 필요X
$ apt-get install python-dev
from pwn import *
* process, sockets, serial ports과 모든 종류의 일들과 소통기 위한 표준 인터페이스에 노출될 수 있도록 한다.
Ex. Remote connection : pwnlib.tubes.remote
* pwnlib.tubes.process : process와 interacting
* Process와 interact 가능
interactive 함수가 있어서 이전에는 직접 interactive 함수를 구현했어야 했는데,
def interactive(s):
while True:
cmd = raw_input(‘$ ’)
s.send(cmd + ‘\n’)
print s.recv(1024)
pwntool에서는 interactive 함수로 이 코드에서 하는 기능을 구현할 수 있어서 interact할 수 있다.
* pwnlib.tubes.ssh : SSH module => local/setuid exploit에 사용
>>> shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
>>> shell['whoami']'bandit0'
>>> shell.download_file('/etc/motd')
>>> sh = shell.run('sh')
>>> sh.sendline('sleep 3; echo hello world;')
>>> sh.recvline(timeout=1)
>>> sh.recvline(timeout=5)'hello world\n'>>> shell.close()
ssh 함수로 user, server, password, port를 인자로 주면 local server에 연결이 되서 shell 변수로 interact해서 받은 결과(명령의 결과)를 출력할 수 있다.
또 run 함수로 ‘sh’를 실행시켜서 sh 변수로 받게 하면, sh.sendline으로 명령을 보내면, 실행된 명령을 recvline으로 받을 수 있다.
Struct module을 사용해서 주소를 sequence of bytes로 변환했었는데,
p32, u32, u8 함수 인자로 주소를 넣으면 p32 = lambda x : struck.pack(‘<I’, x)로 하지 않아도 된다.
>>> asm('nop', arch='arm')'\x00\xf0 \xe3'
(위의 코드는 안 됐다…architecture 관련 binutils 설치를 했는데도 안 된다.)
* context : 운영체제, 문자 길이, endian을 context로 세팅할 수 있다.
>>> context.arch = 'i386'
>>> context.os = 'linux'
>>> context.endian = 'little'
>>> context.word_size = 32
* 한 번에 값을 세팅할 수 있다.
>>> asm('nop')'\x90'
>>> context(arch='arm', os='linux', endian='big', word_size=32)
>>> asm('nop')'\xe3 \xf0\x00' 8. Setting Logging Verbosity
* context 로 표준 pwntools 로깅의 내용을 제어할 수 있다.
>>> context.log_level = 'debug'
이렇게 세팅하면 tube 함수로 받고 보내는 데이터를 화면에 출력한다.
* pwnlib.asm module : disassemble -> assemble로 변환 가능
>>> asm('mov eax, 0').encode('hex')
'b800000000'
disasm 함수 : Shellcode를 disassemble한 것을 출력할 수 있다.
>>> print disasm('6a0258cd80ebf9'.decode('hex'))
0: 6a 02 push 0x2
2: 58 pop eax
3: cd 80 int 0x80
5: eb f9 jmp 0x0
* pwnlib.shellcraft : shellcode를 직접 작성하지 않아도 된다! Shellcode를 로딩해줌
>>> asm(shellcraft.setreuid() + shellcraft.dupsh(4)).encode('hex')
'6a3158cd80...'
* pwnlib.util.fiddling : dummy를 작성하지 않고 이 함수 사용하면 된다.
>>> print cyclic(20)
aaaabaaacaaadaaaeaaa
* pwnlib.cyclic : buffer에서 crash일으키는 offset 발견해준다.
>>> # Assume EIP = 0x62616166 ('faab' which is pack(0x62616166)) at crash time
>>> print cyclic_find('faab')
120
* pwnlib.elf : adress, symbols, got, plt 함수로 원하는 함수나 원하는 주소 찾을 수 있다.
>>> e = ELF('/bin/cat')>>> print hex(e.address)
0x400000
>>> print hex(e.symbols['write'])
0x401680
>>> print hex(e.got['write'])
0x60b070
>>> print hex(e.plt['write'])
0x401680
* 패치를 해서 파일을 저장할 수 있다.
>>> e = ELF('/bin/cat')
>>> e.read(e.address, 4)'\x7fELF'
>>> e.asm(e.address, 'ret')
>>> e.save('/tmp/quiet-cat')
>>> disasm(file('/tmp/quiet-cat','rb').read(1))'
0: c3 ret'
VMware Workstation Pro에 Ubuntu 18.04 LTS 설치 (0) | 2020.02.04 |
---|---|
Pwntools 설치 (feat. lrzsz) (0) | 2019.09.22 |
Ubuntu SSH 연결을 위한 설정 (xshell) (0) | 2019.09.22 |
IDA Pro 7.0 사용법 (3) | 2019.07.28 |
[Pwntools] 중요하고 자주 쓰이는 모듈, 함수 정리 (0) | 2019.07.26 |