# Pwntools ![image](https://hackmd.io/_uploads/Sk_s2Hja0.png) (這裡)[https://github.com/Gallopsled/pwntools?tab=readme-ov-file] > 請問 markdown 的 「超連結語法」 是一種 usb 語法嗎 我每次都打反 ### example ```python= from pwn import * import sys import time context.log_level = "debug" context.terminal = ["tmux", "splitw", "-h"] context.arch = "amd64" if len(sys.argv) == 1: r = process("./binary") if args.GDB: gdb.attach(r,"set max-visualize-chunk-size 0x50") elif len(sys.argv) == 3: r = remote(sys.argv[1], sys.argv[2]) else: print("Usage: python3 {} [GDB | REMOTE_IP PORT]".format(sys.argv[0])) sys.exit(1) ``` ### import ```python= from pwn import * ``` ### context ```python= context.os = "linux" context.arch = "amd64" context.log_level = 'debug' ``` > `context.log_level = 'debug'` 可以看到詳細的 `debug` 狀態 > 可以直接使用下面這個,會直接幫你設定好 ```python= context.binary = './challenge-binary' ``` ### ELF ```python= e = ELF('/bin/cat') ``` > 開一個 ELF File,並且交由變數 `e` 管理 > 常使用於 `libc.so.x`,我們可以很簡單的去 Parse 這個 Dynamic Library,然後找到好用的 gadget (e.g. `bin/sh`) ```python= e.address = elf file init address ``` > 這邊可以把 leak 出來的 libc base address assign 給 `address` 這個 member variable ```python= write_address = e.symbols['write'] read_address = e.symbols['read'] ``` > 設定好 address 後,因為符號與整個檔案的相對位置不會改變,所以可以使用 `symbols[symbolname]`,去找你想要的 symbol address ### process ```python= p = process("/path/2/ur/binary") p = remote('ip','port') ``` > `p = process("/path/2/ur/binary")` 把 binary 跑起來,並且交由變數 `p` 管理 > `p = remote('ip','port')` 遠端連線到指定 ip:port ```python= p.send("ur_payload") p.sendline("ur_payload") ``` > 傳送 `ur_payload` 給 process > `send` & `sendline` 差別在於最後有沒有換行(`\n`) ```python= p.sendlineafter(">",b'ur_payload') p.sendlineafter(">",str(ur_payload)) ``` > 在接收到 `>` 後傳送 `ur_payload` 給 process :::warning TODO: `b'a'` and `str(a)` 的差別 (一個是 send byte,一個是 send string) ::: ```python= recv = p.recv() recv = p.recv(N) p.recvline() p.recvuntil(b'w') p.interactive() ``` > `p.recv()` 接收 process 的 data,並且把 data 交由變數 `recv` 管理 > `p.recv(N)` 設定接收 N 個 Bytes > `p.recvline()` 接收一整行 > `p.recvuntil(b'w')` 接收 data 直到 `w`,假如 Process 發送的資料是 `hello,world`,那我們會接收到 `hello,w` > `p.interactive()` 讓我們可以直接與 process interactive ### ### pack and unpack ```python= >>> p8(0) b'\x00' >>> p32(0xdeadbeef) b'\xef\xbe\xad\xde' >>> p32(0xdeadbeef, endian='big') b'\xde\xad\xbe\xef' ``` > `p32` 就是把 data pack 成 32-bits 小端的資料型態 > `u32` 就是 `p32` 的 逆運算 > 如果要 pack 成 64-bits 就使用 `p64` & `u64` ### gdb attach 每次寫完 expolit 都自己爛掉,我都要額外 attach 上去看哪裡有問題 = = ```python= gdb.attach(p) # p 是你要 attach 上的 binary 實例 ``` 然後也可以下 `pause()`,然後 `gdb -p pid` attach 上去