# **Pwntools學習筆記** ###### Date: `2023/01/01` ## :memo: 何謂 pwntools ? * pwntools是一個CTF框架和漏洞利用開發套件。 * ==用Python開發==。 * 旨在讓使用者簡單快速的編寫exploit(漏洞利用)。 ## :memo: 匯入 pwntools 套件 ```python= from pwn import * ``` ## :memo: pwntools 連接方式 ### 1.透過 nc 連接 (明文傳送) **格式**:連線名稱 = `remote(‘IP address‘, port)` **範例**:conn = `remote(‘140.110.112.195‘, 2400)` ### 2.透過 ssh 連接 (密文傳送) **格式**:連線名稱 = `ssh(host=‘IP address‘, user=‘XXX’, port=???, password=‘XXXXX’)` **範例**:`shell = ssh(host='192.168.14.144', user='root', port=2222, password='123456')` ## :memo: pwntools 傳送及接收數據函數 ### 傳送: * `send(payload)`:發送payload(需為字串) * `sendline(payload)`:發送payload,並換行(末尾\n) * `sendafter(some_string, payload)`:接收到 some_string 後, 發送 payload * `sendlineafter(some_string, payload)`:接收到 some_string 後, 發送 payload並換行 * **範例:**`conn.sendline(ans.encode())` # 將ans轉換成Byte 字串傳送至連接端 ### 接收: * `recvn(N)`:接受 N 個字元 * `recvline()`:接收一行資料 * `recvlines(N)`:接收 N 行資料 * `recvuntil(some_string)`:接收到 some_string 為止 **範例:** * `conn.recvline()`:從連接端接收一行資料 * `conn.recvlines(7)`:從連接端接收七行資料 * `conn.recvuntil(b’answer: ’)`:從連接端接收資料,直到 ’answer: ’字串 ## :memo: pwntools 連接送出答案後,取得flag方法 1. `interactive()`:與 shell 互動,輸入 logout 離開連接端 shell **範例:**`conn.interactive()`:回到 shell,可取得 flag 2. 用 `recvline()`:接收 flag 後再印出 **範例:** `aaa = conn.recvline()`:將接收的 flag 存到 aaa 變數 `print(aaa.decode())`:將 aaa 變數轉成字元字串再輸出至螢幕上 3. 最後加上```close()```關閉連結 **範例:** ```conn.close()```:關閉連結 :::warning :bulb:透過 python 的 `remote()` 函數連線,傳送接收資料皆為本機程式與連接端之間傳遞,不會於螢幕上顯示過程 ::: ## :memo: 練習題1:count ### 題目: * 題目說1就輸入1,說2就輸入2,以此類推。 ![](https://i.imgur.com/shUTTkS.png) ### 我的程式碼: ```python= from pwn import * r = remote('140.110.112.214', 2403) r.recvlines(3) for i in range(100): r.recvlines(2) r.sendline(str(i+1).encode()) r.interactive() r.close() ``` ### 解題心得: * 透過題目給的網址進行nc連線,開一個python檔,完成程式碼執行後,發現有錯誤,檢查後發現原來是程式碼中的網址輸入錯誤導致!修正後即成功獲得標籤(倒數第三行)。 ## :memo: 練習題2:3rd ### 題目: * 從題目給的數據中找出第三大的數。 ![](https://i.imgur.com/eSPuht5.png) ### 我的程式碼: ```python= from pwn import * r = remote('140.110.112.214', 2400) r.recvlines(7) r.recvuntil(b'numbers : ') l = r.recvline() num = [int(x) for x in l.split()] num.sort(reverse=True) print(num[2]) r.recvuntil(b'answer : ') r.sendline(str(num[2]).encode()) print(r.recvline().decode()) r.interactive() r.close() ``` ### 解題心得: * 把題目給的數據存到一個list裡面,再透過排序即可找到第三大的數字為何! ## :memo: 練習題3:beautify ### 題目: * 把題目給的字串中'-'或'_'轉換成' ',並且整句轉為小寫。 ![](https://i.imgur.com/I4VeFYp.png) ### 我的程式碼: ```python= from pwn import * r = remote('140.110.112.214', 2401,level='debug') r.recvlines(8) r.recvuntil(b'sentence : ') s = r.recvline() s = s.replace(b'-',b' ') s = s.replace(b'_',b' ') s = s.lower() r.sendlineafter(b'answer : ',s) r.interactive() r.close() ``` ### 解題心得: * 一開始字串前面忘記加上'b'導致出現type error,以後要記得將字串前面加上'b'轉成byte字串。 * 在port後面加上```level='debug'```可以在執行時顯示過程,方便除錯。 ## :memo: 練習題4:calender ### 題目: * 判斷閏年 ![](https://i.imgur.com/NFSSbj6.png) ### 我的程式碼: ```python= from pwn import * a=remote('140.110.112.214',2402,level='debug') a.recvlines(9) for i in range(100): a.recvline() a.recvuntil(b'year : ') b=a.recvn(4) b=int(b) if b%4 == 0: if b%100 == 0: if b%400 == 0: a.sendlineafter(b'answer : ','leap') else: a.sendlineafter(b'answer : ','ordinary') else: a.sendlineafter(b'answer : ','leap') else: a.sendlineafter(b'answer : ','ordinary') a.interactive() a.close() ``` ### 解題心得: * 判斷閏年題目之前用C++寫過,所以這題比較容易! ## :memo: 練習題 5 money: ### 題目: * 計算本金加上利率的結果。 ![](https://i.imgur.com/LDR5dRl.png) ### 我的程式碼: ```python= from pwn import * r = remote('140.110.112.214', 2407,level='debug') r.recvlines(8) for i in range(100): r.recvline() r.recvuntil(b'money : ') o = r.recvline() o = int(o) r.recvuntil(b'interest : ') p = r.recvline() print(p) p = p[:-2] print(p) p = int(p) o = o+o*(p/100) o = int(o) r.sendlineafter(b'answer : ',str(o)) r.interactive() r.close() ``` ### 解題心得: * 送出的結果要是字串。 * p有可能為小數,要轉整數。 * p接收時接收到換行和%,所以要去掉! ## :memo: 練習題 6 id: ### 題目: * 規則⼀ : 開頭會是⼤寫的英⽂文字⺟ A-Z * 規則⼆ : 後面接著 9 個數字 * 規則三 : 9 個數字的總和要是 3 的倍數 ![](https://i.imgur.com/KGMKwBC.png) ### 我的程式碼: ```python= from pwn import * r = remote('140.110.112.214', 2406,level='debug') r.recvlines(14) for i in range(100): r.recvline() r.recvn(5) o = r.recvline() o = o[:-1] ans = True if 'A'<=chr(o[0])<='Z': ans = True else: ans = False print(chr(o[0]), ans) if len(o)!=10: ans = False o = o[1:] sum = 0 for i in o: i = int(i) sum+= i if sum % 3!=0: ans = False if ans == True: p = b'valid' else: p = b'invalid' r.sendlineafter(b'answer : ',p) r.interactive() r.close() ``` ### 解題心得: * 在寫這題後我學習到要判斷一個數字是否介在A到Z之間要用```chr```轉字元,不能用```str```,因為把一個文字母的ASCII碼轉成字元才能做比較! ## :memo: 練習題7:tros ### 題目: * 把題目給的字串依照Z到A排序,一百筆測資。 ![](https://i.imgur.com/2VKzaS1.png) ### 我的程式碼: ```python= from pwn import * r = remote('140.110.112.214', 2409,level='debug') r.recvlines(5) for i in range(100): r.recvline() r.recvn(7) o = r.recvline() o = o[:-1] l = [] for y in o: l.append(y) l.sort(reverse=True) r.recvn(9) for j in l: r.send(chr(j)) r.sendline() r.interactive() r.close() ``` ### 解題心得: * 利用ASCII碼由大到小排序儲存到一個List,在依序由排序過的list中取出答案。