ゾンビ狩りクラブ

Linux, Server, Network, Security 関連などをゆるーくテキトーに載せてます

pwntools tubeメソッドまとめ

python3でのpwntoolsのtubeメソッドをまとめたメモ

Index

1. 読み込み系

受信したデータは、一旦バッファに書き込まれそこから読み出す。
受信したデータは、bytes型 (b'') で返される。
また、すべてのメソッド名の recv 部分は、read に置き換えられる(recv は read のエイリアスになっている)。

例えば、以下の2つは同一である。

  • recvlines()
  • readlines()

buffer の挙動は以下になる。

# test.py
from pwn import *

p = process('cat')

p.send("Hello")
p.recv(1)

print(p.buffer.get())
% python3 test.py
[+] Starting program '/bin/cat': Done
b'ello'
[*] Stopped program '/bin/cat'

recv(self, numb=4096, timeout=default)

受取可能なnumbバイトまで受け取り、即座に受信したデータを返す。
コネクションが閉じた場合、exceptions.EOFError が上がる。

  • numb
    読み込むバイト数
  • timeout
    タイムアウト(秒)

unrecv(self, data)

バッファの先頭に data を入れる。

  • data (bytes)
    バッファに入れるデータ
# test.py
from pwn import *

p = process('cat')

p.send("Michael Jackson")

print(p.recv(7))

p.unrecv(b"Samuel L.")

print(p.recv())
% python3 test.py
[+] Starting program '/bin/cat': Done
b'Michael'
b'Samuel L. Jackson'
[*] Stopped program '/bin/cat'

recvpred(self, pred, timeout=default)

pred の評価が偽の間、1バイトずつデータを受信する。

  • pred (callable)
    条件で論理値を返す関数
  • timeout
    タイムアウト(秒)

例えば、以下のような関数を指定した場合、"Hello"をいう文字列の間データを受信する。

# test.py
from pwn import *

def pred(data):
    print(data)
    if data.decode('utf-8') == "Hello":
        return True
    else:
        return False

p = process('cat')

p.sendline('Hello John')

rec = p.recvpred(pred)

print(rec.decode("utf-8"))
% python3 test.py
[+] Starting program '/bin/cat': Done
b''
b'H'
b'He'
b'Hel'
b'Hell'
b'Hello'
Hello
[*] Stopped program '/bin/cat'

recvn(self, numb, timeout=default)

numbバイトを正確にデータを受信する(データを受信するかタイムアウトになるまで値を返さない)。

  • numb
    読み込むバイト数
  • timeout
    タイムアウト(秒)

recvuntil(self, delims, drop=False, timeout=default)

delims のいずれかが現れるまでデータを受信する。

  • delims (bytes,str,tuple)
    デリミタ
  • drop (bool)
    trueの場合、戻り値に delims を含めない
  • timeout
    タイムアウト(秒)

recvlines(self, numlines=2**20, keepends=False, timeout=default)

munlines 行までデータを受信する。
戻り値は、リストで返される。

  • numlines (int)
    読み込む行数
  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)

recvline(self, keepends=True, timeout=default)

改行文字まで(一行)データを受信する。

  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)

recvline_pred(self, pred, keepends=False, timeout=default)

pred の評価が真の行まで受け取り、真になった最初の行を返す。

  • pred (callable)
    論理値を返す関数
  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)
# test.py
from pwn import *

def pred(data):
    if "Occupation" in data.decode('utf-8'):
        return True
    else:
        return False

p = process('cat')

s = """Name: Elvis Presley
Born: January 8, 1935
Occupation: Singer, actor
Resting place: Graceland
"""

p.send(s)

rec = p.recvline_pred(pred)
print(rec)
% python3 test.py
[+] Starting program '/bin/cat': Done
b'Occupation: Singer, actor'
[*] Stopped program '/bin/cat'

recvline_contains(self, items, keepends=False, timeout=default)

items のいずれかが含まれる最初の行まで受け取り、マッチした最初の行を返す。

  • items (bytes,str,tuple)
    調べる文字列か文字列のリスト
  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)
# test.py
from pwn import *

p = process('cat')

s = """Name: Elvis Presley
Born: January 8, 1935
Occupation: Singer, actor
Resting place: Graceland
"""

p.send(s)

rec = p.recvline_contains(["Born", "place"])
print(rec)
% python3 test.py
[+] Starting program '/bin/cat': Done
b'Born: January 8, 1935'
[*] Stopped program '/bin/cat'

recvline_startswith(self, delims, keepends=False, timeout=default)

delims のいずれかで始まる行までを受け取り、マッチした最初の行を返す。

  • delims (bytes,str,tuple)
    デリミタ
  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)

recvline_endswith(self, delims, keepends=False, timeout=default)

delims のいずれかで終わる行までを受け取り、マッチした最初の行を返す。

  • delims (bytes,str,tuple)
    デリミタ
  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)

recvregex(self, regex, exact=False, timeout=default)

regex で指定された正規表現にマッチするまでデータを受信する。

  • regex
    マッチさせる正規表現
  • exact (bool)
    True の場合、're.RegexObject.search' 関数の代わりに 're.RegexObject.match' 関数を使用する。
  • timeout
    タイムアウト(秒)
# test.py
from pwn import *

p = process('cat')

s = """Name: Elvis Presley
Born: January 8, 1935
Occupation: Singer, actor
Resting place: Graceland
"""

p.send(s)

rec = p.recvregex(r"\d{4}", timeout=0.1)
print(rec)
% python3 test.py
[+] Starting program '/bin/cat': Done
b'Name: Elvis Presley\nBorn: January 8, 1935'
[*] Stopped program '/bin/cat'

recvline_regex(self, regex, exact=False, keepends=False, timeout=default)

regex で指定された正規表現にマッチするまで読み込み、マッチした最初の行を返す。

  • regex
    マッチさせる正規表現
  • exact (bool)
    True の場合、're.RegexObject.search' 関数の代わりに 're.RegexObject.match' 関数を使用する。
  • keepends (bool)
    戻り値に改行を含めるかどうか
  • timeout
    タイムアウト(秒)

recvrepeat(self, timeout=default)

タイムアウトかEOFに達するまでデータを受信する。

  • timeout
    タイムアウト(秒)

recvall(self, timeout=Timeout.forever)

EOFに達するまでデータを受信する。

  • timeout
    タイムアウト(秒)

2. 書き込み系

send(self, data)

データを送信する。

  • data
    送信するデータ

sendline(self, line='')

データに改行を追加し、送信する。
send(data + t.newline) と同等

  • line
    改行を追加して送信するデータ

sendlines(self, lines=[])

リストの各データに改行を追加し、送信する。

  • lines (list)
    送信するデータ
# test.py
from pwn import *

p = process('cat')

p.sendlines(["Michael", "Jackson"])

print(p.recv())
% python3 test.py
[+] Starting program '/bin/cat': Done
b'Michael\nJackson\n'
[*] Stopped program '/bin/cat'

3. 送信と受信のコンビネーション系

sendafter(self, delim, data, timeout=default)

recvuntil(delim, timeout) で受信した後に send(data) で送信する。

sendlineafter(self, delim, data, timeout=default)

recvuntil(delim, timeout) で受信した後に sendline(data) で送信する。

sendthen(self, delim, data, timeout=default)

send(data) で送信した後に recvuntil(delim, timeout) で受信する。

sendlinethen(self, delim, data, timeout=default)

sendline(data) で送信した後に recvuntil(delim, timeout) で重心する。

4. インタラクティブ系

interactive(self, prompt=term.text.bold_red('$') + ' ')

書き込み、読み込みをインタラクティブに行う。

from pwn import *

p = process('/bin/sh')

p.interactive()
% python3 test.py
[+] Starting program '/bin/sh': Done
[*] Switching to interactive mode
$ uname
Linux
$ exit
[*] Got EOF while reading in interactive
$
[*] Program '/bin/sh' stopped with exit code 0
[*] Got EOF while sending in interactive
Traceback (most recent call last):
  File "/home/r00t/tools/python3-pwntools/pwnlib/tubes/process.py", line 611, in close
    fd.close()
BrokenPipeError: [Errno 32] Broken pipe

5. 変換系

以下のそれぞれが変換してから、送信する。

def p64(self, *a, **kw): return self.send(packing.p64(*a, **kw))

def p32(self, *a, **kw): return self.send(packing.p32(*a, **kw))

def p16(self, *a, **kw): return self.send(packing.p16(*a, **kw))

def p8(self, *a, **kw): return self.send(packing.p8(*a, **kw))

def pack(self, *a, **kw): return self.send(packing.pack(*a, **kw))

def unpack(self, *a, **kw): return packing.unpack(self.recvn(context.bytes), *a, **kw)

def flat(self, *a, **kw): return self.send(packing.flat(*a, **kw))