pwntools === :::info 時間:9/26 19:00~21:00 地點:蘭潭校區 學活中心三樓 第三會議室 主題:pwntools > [name=Curious] ::: :::success 報名:[連結](https://forms.gle/F7o34NW6HG26qwtD8) 簽到:[連結]() 簡報:[連結](https://drive.google.com/file/d/1hotAmJ-0IMFZ0HmvG0VXWtyUt4s_VQmh/view?usp=share_link) Lab:[連結](http://172.104.90.38) Flag Format:`NCYU_HACKERS{.*}` 回饋:[連結](https://forms.gle/Aj4CC2QykH6H3KsLA) ::: <!-- 以下區域開放共筆 --> ## 先備知識 ### ASCII #### 字元和數字相互轉換 - 用`chr(num)`把數字轉成字元 - 用`ord(char)`把字元轉成數字 #### 數字只包含0~127 :::spoiler Welcome 先使用VScode ```python= a = "78 67 89 85 95 72 65 67 75 69 82 83 123 87 51 108 67 48 77" #初始字串 a = "78 67 89 85 95 72 65 67 75 69 82 83 123 87 51 108 67 48 77 69 95 49 49 50 95 49 125" # 分割成各個數字字串的 list a = a.split() # 把 list 中的元素轉成 int a = [int(num) for num in a] # 把 int 轉成 ASCII 對應的 char a = [chr(num) for num in a] # 把 list 中所有 char 合併成一個 str a = ''.join(a) print(a) ``` ```python # 講師想秀一行解決 a = '78 67 89 85 95 72 65 67 75 69 82 83 123 87 51 108 67 48 77 69 95 49 49 50 95 49 125' a = ''.join([chr(int(num)) for num in a.split()]) print(a) ``` ::: ### python #### 執行方法 如何執行Python? 三種方法:執行檔案、Interactive Shell、Interactive Shell Pro VScode(直接在VScode的terminal執行), ipython3, python3 還可以? 在Linux上用vim的指令建立一個python檔案`vim test.py`,在command line輸入`python3 test.py`,就可以執行惹 如果不會vim的指令,可以自己上網查 #### Python 資料型別 int:整數 str:字串 bytes:位元組 > 可以用`type(obj)`來確認物件的型別 ```python= In [1]:type(1) Out[1]:int In [2]:type("Hello") #由字元組成 Out[2]:str In [3]:type(b"Hello") #由數字組成,但顯示時如果該數字轉成字元可視就會以字元顯示 Out[3]:bytes ``` #### Python 資料轉換 - int -> str - int -> bytes - int -> hex - int -> ASCII ```python= In [1]:str(3) Out[1]:'3' In [2]:bytes([3]) Out[2]:b'\x03' In [3]:hex(12) Out[3]:'0xc' In [4]:chr(97) Out[4]:'a' ``` - str -> int - bytes -> int - hex -> int - ASCII -> int ```python= In [1]:int('3') Out[1]:3 In [2]:b'\x03'[0] Out[2]:3 In [3]:int('0xc', 16) Out[3]:12 In [4]:ord('a') Out[4]:97 ``` - str -> bytes - hex -> bytes - int -> bytes - int -> str -> bytes > `encode()` string -> bytes > `decode()` bytes -> string ```python= In [1]:'Hello'.encode() Out[1]:b'Hello' In [2]:bytes.fromhex('437572696f7573') Out[2]:b'Curious' In [3]:bytes([7]) Out[3]:b'\x07' #這裡儲存起來的數字是7 In [4]:str(7).encode() Out[4]:b'7' #這裡儲存起來的數字是55(查閱ASCII) ``` - bytes -> str - bytes -> hex - bytes -> int - bytes -> str -> int > `encode()` string -> bytes > `decode()` bytes -> string ```python= In [1]:b'Hello'.decode() Out[1]:'Hello' In [2]:b'Curious'.hex() Out[2]:'437572696f7573' In [3]:b'\x07'[0] Out[3]:7 In [4]:int(b'7') Out[4]:7 ``` ## PPC 介紹 - 指令 `nc <IP/Domain> <Port>` 通常拿來和指定的 IP 或 Domain 上的 Port 建立連線,透過 terminal 上的 stdin 和 stdout 來和 server 互動 >stdin -> 0 stdout -> 1 stderror -> 2 - 指令 `socat TCP-LISTEN:<Port>,fork EXEC:"<cmd>"` 將指定指令的服務綁到本機(127.0.0.1)的 Port 上,當這個 Port 收到 TCP 請求後,執⾏指定的 cmd ## pwntools ### 安裝說明 [感謝Curious的贊助](https://hackmd.io/@akvo-fajro/Pwntools_Installation_Guide) ### pwntools基本用法 ```python= from pwn import * r = remote('172.104.90.38', 10000) # Do something with r (remote object) r.interactive() ``` ### Remote object 方法總結 ## Send Data: - `r.send(payload)` 送出payload - `r.sendline(payload)` 送出payload並換行 - `r.sendafter(p1, p2)` 接收到p1之後送出p2 - `r.sendlineafter(p1, p2` 接收到p1之後送出p2並換行 ## Recv Data: - `r.recv(n)` 接收n個bytes - `r.recvuntil(payload)` 接收到payload為止 - `r.recvline()` 接收一行(但換行為止) - `r.recvlines(n)` 接收n行 ## Other: - `r.interactive()` 切換到互動模式 - `r.close()` 關閉連線 :::spoiler PPC Lab-Welcome Solve Script : ```python= from pwn import * r = remote('172.104.90.38', 10001) r.recvlines(8) # str.strip()/bytes.strip() 是用來把 str/bytes 前後的空白和 bytes 清除掉的 # str.split(str)/bytes.split(bytes) 會去匹配指定的 str/bytes,然後以匹配到的作為分割點 num_list = r.recvline().strip().split(b' : ')[1].decode() num_list = [int(num) for num in num_list.split()] num_list.sort() nth = int(r.recvline().strip().split(b' : ')[1]) r.sendlineafter(b'Answer >', str(num_list[-nth]).encode()) r.interactive() ``` ::: :::spoiler PPC Lab - Count Solve Script : ```python= from pwn import * r = remote('172.104.90.38', 10002) r.recvlines(2) for i in range(100): print(i) r.recvline() r.sendlineafter(b'> ', str(i + 1).encode()) r.interactive() ``` ::: ### remote object error - 卡死 通常是因為 recv 相關的參數錯誤,導致 server 已經發完訊息,但 Pwntools 還在監聽 - EOF 通常是因為程式錯誤,server 那邊把連線斷掉 <!--共筆結束--> <!-- 如果你能夠把它變得更好看再修改code --> <!-- 否則我會去找你 :D --> <style> .navbar-brand::after{content: " x NCYU_HACERS"; } </style>