Tools

pwn 사용법 요약

geunyeong 2020. 3. 19. 22:35


from pwn import *


#
# process( PROGRAM_PATH )
#
p = process('./program.exe')

p.send('hello world') # input 'hello world' through stdin
p.sendafter('world', 'hello world') # input 'hello world' when receive 'world' string
p.sendline('hello world') # input 'hello world\n' through stdin
p.sendlineafter('world', 'hello world') # input 'hello world\n' when receive 'world' string

p.recv(1234) #read 1234 byte data from stdout
p.recvline() # read a line from stdout
p.recvuntil('world') #read a data until 'world' from stdout

p.interactive() # user can input and receive datas directly


#
# remote( IP, PORT )
#
r = remote('127.0.0.1', 4444) # connect to server:port using nc
r.send('hello world') # input 'hello world' through stdin
r.sendline('hello world') # input 'hello world\n' through stdin

r.recv(1234) #read 1234 byte data from stdout
r.recvline() # read a line from stdout
r.recvuntil('world') #read a data until 'world' from stdout

r.interactive() # user can input and receive datas directly


#
# ssh( USERNAME, IP, PORT, PASSWORD )
#
s = ssh('sshuser', '127.0.0.1', port=4444, password='sshpassword')

sp = s.run('whoami') # run process after connect to server
sp.recv()
sp.send(b'\x12\x34\x56\x78')

s['whoami'] # show result that run command complete
s.download_file('/etc/passwd') # download file from connected server


#
# encoding
#

# encode to little endian (packs an 32, 64-bit integer)
p32(b'\x12\x34\x56\x78') # \x78\x56\x34\x12
p32(b'\x12\x34\x56\x78', endian='big')
p64(b'\x12\x34\x56\x78\x9a\xbc\xde\xf0') # \xf0\xde\xbc\x9a\x78\x56\x34\x12

# transit integer to string (packed number 32, 64-bit as a string)
u32('ABCD') # hex(u32('ABCD')) = '0x44434241'
u64('1234') # hex(u64('ABCDEFGH')) = '0x4847464544434241'


#
# ELF( PROGRAM_PATH )
#
e = ELF('./program.exe')
e.checksec() # 적용된 보호기법 보여줌
libc = e.libc # load library file that process links
libc.symbols['__malloc_hook'] # 라이브러리에서 __malloc_hook 심볼의 오프셋
read_plt = e.plt['read'] # read api의 plt 주소
read_got = e.gotp'read'] # read api의 got 주


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


#
# debug
#
p = process('./proagram.exe')
gdb.attach(p) # run gdb with p


#
# shell code
# https://www.lazenca.net/pages/viewpage.action?pageId=14712942
#
context.arch = 'i386'
context.os = 'linux'
context.endian = 'little'
context.word_size = 32
asm('nop') # b'\x90' in i386 arch

context(arch='arm', os='linux', endian='big', word_size=32)
asm('nop') # b'\xe3\xf0\x00' in arm arch

asm('mov eax, 0').encode('hex') # 'b80000000000'
disasm('6a0258cd80ebf9'.decode('hex'))
# 0: 6a 02  push 0x2
# 2: 58     pop eax
# 3: cd 80  int 0x80
# 5: eb f9  jmp 0x0

asm( \
    shellcraft.setreuid() \
    + shellcraft.dupsh(4) \
).encode('hex') # '6a3158cd80...'


#
# dummy
#
cyclic(20) # aaaabaaacaaadaaaeaaa
cyclic_find('faab') # buffer에서 crash 일으키는 offset 발견해줌