Pwntools
Eitt af því sem ítrekað kemur upp í gagnaglímum er að við þurfum að eiga samskipti við forrit, hvort sem það er keyrandi á tölvunni okkar eða á vefþjóni. Oft á tíðum er ferlið þannig að forritið býst við inntaki frá okkur, svarar einhverju, við gefum annað inntak, og svo koll af kolli. Í einhverjum tilfellum getum við leyst verkefni, sem fela í sér slík samskipti, í höndunum, en í langflestum tilfellum er einfaldara að sjálfvirknivæða þessi samskipti. Það gerir okkur kleift að staðla samskiptin, prófa mismunandi breytingar á skipulagðan hátt og þrautaleita (e. brute force) lausnir, svo dæmi séu tekin.
Hvað er Pwntools?
Pwntools er forritasafn, skrifað fyrir Python, sem hægt er að nota til að sjálfvirknivæða slík samskipti. Það býður upp á að opna tengingu yfir net eða við forrit og gerir okkur kleift að eiga samskipti yfir tenginguna.
Til að nota forritasafnið þarf að sækja pwntools af PyPI (The Python Package Index), t.d. með
pip install pwntools
Á fylgiþjóninum er búið að setja upp pwntools pakkann og því hægt að nota það í Python hvar sem er.
Vissir þú?
Pwntools var upprunalega þróað sem lítið safn af hjálparföllum af Gallopsled CTF-liðinu árið 2013 til að auðvelda þeim að leysa gagnaglímur hratt og örugglega. Forritasafnið sló svo rækilega í gegn hjá netöryggissamfélaginu að það er í dag nær staðalbúnaður hjá öllum sem taka þátt í keppnum af þessu tagi eða vinna við að greina veikleika í forritum!
Tengingar
Til að stofna tengingu yfir netið notum við remote(address, port) sem tekur við hýsisnafni eða vistfangi, auk tengis. Fallið skilar svo hlut sem hægt er að nota til að lesa og senda gögn.
Til að keyra upp forrit notum við process sem getur, m.a., tekið slóðina á forritinu sem viðfang. Forritið er þá keyrt og fallið skilar hlut sem hægt er að nota til að eiga samskipti við það.
Hlutirnir sem skilað er úr þessum tveimur föllum bjóða upp á sömu föll, en þau algengustu eru eftirfarandi.
| Aðferð | Lýsing |
|---|---|
conn.recv(n) |
Les nákvæmlega n mörg bæti. |
conn.recvline() |
Les gögn frá netþjóninum þar til ný lína er lesin (\n). |
conn.recvuntil(b"mynstur") |
Les gögn þar til bætarunan b"mynstur" sést. Þetta er hægt að nota til að bíða eftir ákveðnum kvaðningum (e. prompts) eins og sláðu inn tölu:. |
conn.recvall() |
Les öll gögn sem berast þar til forritið lokar tengingunni. |
conn.send(b"gogn") |
Sendir hrá bæti til netþjónsins. |
conn.sendline(b"gogn") |
Sendir bæti og bætir sjálfkrafa við nýrri línu (\n) aftan á gögnin (líkir eftir því að ýtt hafi verið á Enter). |
conn.sendlineafter(b":", b"gogn") |
Bíður fyrst eftir ákveðinni bætarunu, :, og sendir síðan gögn ásamt nýrri línu. |
conn.interactive() |
Gefur okkur gagnvirka skel (e. interactive shell) sem gerir okkur kleift að eiga bein samskipti við forritið eða þjónustuna. |
Sýnidæmi: reiknivélin úr Linux-æfingagögnunum
Í ~/examples/pwntools-calculator er lítið forrit sem birtir tíu einföld reikningsdæmi og bíður eftir svari við hverju þeirra. Prófum fyrst að ræsa forritið handvirkt.
cd ~/examples/pwntools-calculator
./calculator
Við getum svo notað pwntools til að lesa dæmin og senda svörin sjálfkrafa. Eftirfarandi skrifta notar process til að ræsa forritið og reikna dæmin út frá frálaginu.
from pwn import *
# Ef calculator er í sömu möppu og þessi skrifta.
p = process("./calculator")
for umferd in range(10):
# Bíðum eftir byrjun reikningsdæmisins.
p.recvuntil(b"Calculate: ")
# Lesum t.d. b"17 + 25\n" og skiptum því í þrjá hluta.
vinstri, virki, haegri = p.recvline().decode().split()
vinstri = int(vinstri)
haegri = int(haegri)
if virki == "+":
svar = vinstri + haegri
elif virki == "-":
svar = vinstri - haegri
elif virki == "*":
svar = vinstri * haegri
else:
raise ValueError(f"Óþekktur virki: {virki}")
# Forritið bíður nú eftir „Answer: “. Sendum svarið og Enter.
p.recvuntil(b"Answer: ")
p.sendline(str(svar).encode())
# Lesum staðfestinguna áður en við höldum í næstu umferð.
print(p.recvline().decode().strip())
# Lesum lokaskilaboðin þegar forritið hefur lokið.
print(p.recvall().decode())
Hér notum við recvuntil til að bíða eftir ákveðnum texta, recvline til að lesa heilt reikningsdæmi og sendline til að senda svarið sem bæti.
Á nákvæmlega sama hátt má nota Pwntools til að eiga samskipti við sama forrit yfir netið með remote. Þá er nóg að skipta út process fyrir remote. Hægt er að tengjast sama forriti yfir TCP á skoli.ggc.tf á tengi 31000. Til að láta Pwntools eiga samskipti við það er nóg að skipta út process("./calculator") fyrir remote("skoli.ggc.tf", 31000).