資安基礎惡補 - 網路篇 - 用 Python 3.5 實踐 MAC Changer
Python 3 實踐 MAC Changer
還記得我們在 上一篇 鋪的哏嗎?
今天我們就來用 Python 實作 Mac Changer 看看!
先備知識 - Python
基於 Python 3.5 後的版本實踐,我們會需要認識一些新版本的函式。
subprocess.run(3.5版本以後加入)
import subprocess subprocess.run(["ls", "-l", "/dev/null"], capture_output=True)
像是上述這個例子,經過逐步拆解,大致上會是這樣:
1. 使用 subprocess.run 執行系統指令
2. ["ls", "-l", "/dev/null"] 如同在終端機執行以下指令
ls -l /dev/null
意思是列出 /dev/null 這個文件的詳細資訊, capture_output=True 代表擷取標準輸出、標準輸入,但是因為這行程式並沒有儲存輸出,所以不會顯示結果(如下圖)。
如果拿掉 capture_output=True 就會跑出結果了(如下圖),讀者們可以試試看!
除此之外,如果想要保持原有設定,並把結果儲存到文字中,可以這樣寫:
import subprocess result = subprocess.run(["ls", "-l", "/dev/null"], capture_output=True, text=True) print(result.stdout)
結果輸出會像是下圖:
subprocess.check_output()(3.1版本以後加入)
check_output() 「自動啟用了 check=True」,如果命令執行失敗(回傳碼 !== 0),它會拋出錯誤,而非靜默失敗。另外,有個好用的地方,就是我們可以使用這個函式來獲取輸出的結果。
argparse(3.2版本以後加入)
argparse 基本上就是一個用來解析命令列模組(CLI Arguments)的 Python 內建模組,讓我們的 Python script 可以支援不同的輸入選項,例如:
python test.py --interface eth0 --mac 00:11:22:33:44:55
我們在這邊看到了「--interface eth0」、「--mac 00:11:22:33:44:55」等參數,前者代表要帶的指定參數,後者則是要帶的參數值。
在大致了解使用情境後,我們來看一下經典範例:
import argparse parser = argparse.ArgumentParser( prog="Mac Changer", description="用來改變 Mac 地址的工具", epilog="Text at the bottom of help") parser.add_argument("-i","--interface", dest="interface", help="介面") parser.add_argument("-m","--mac", dest="new_mac", help="想換成的新mac帳號") args = parser.parse_args() # 此處的 args 裡面有之前寫的那些參數 print(arg.new_mac)
所以,今天假設我們下了以下指令:
python3 test.py -h
就會印出參數使用說明:
說到這,需要補充一下舊版使用 optparse 要如何更新成 argparse 的參考文件:
https://docs.python.org/zh-tw/3/howto/argparse-optparse.html#upgrading-optparse-code
先備知識 - Linux
接下來,我們來聊聊與 Mac Changer 相關的 Linux 指令:
ifconfig
可以用來看看我們目前的網路介面以及對應的 ip address、MAC address 等:
eth0
代表我們的有線網路,IP 是 172.16.108.129,而
lo
代表 本機 Loopback,IP 是 127.0.0.1。
接下來,我們進入重頭戲,修改 MAC Address!
STEP1: ifconfig eth0 down
#!/usr/bin/env python import argparse import subprocess import re def get_args(): parser = argparse.ArgumentParser( prog="Mac Changer", description="用來改變 Mac 地址的工具", epilog="Text at the bottom of help" ) parser.add_argument("-i", "--interface", dest="interface", required=True, help="介面") parser.add_argument("-m", "--mac", dest="new_mac_adr", required=True, help="想換成的新 MAC Address") return parser.parse_args() def change_MAC(interface, new_mac_adr): print(f"[+] 轉換 {interface} 介面的 MAC Address 成 {new_mac_adr}") subprocess.run(["ifconfig", interface, "down"], check=True) subprocess.run(["ifconfig", interface, "hw", "ether", new_mac_adr], check=True) subprocess.run(["ifconfig", interface, "up"], check=True) # 轉換後再確認一次 MAC return get_MAC(interface) def get_MAC(interface): try: search_result = subprocess.check_output(["ifconfig", interface], text=True) # 確保是字串 mac_adr_search_result = re.search(r"\w\w:\w\w:\w\w:\w\w:\w\w:\w\w", search_result) if mac_adr_search_result: return mac_adr_search_result.group(0) else: print("[-] 無法讀取 MAC Address") return None except subprocess.CalledProcessError: print(f"[-] 無法執行 ifconfig,請確認 {interface} 是否正確") return None args = get_args() cur_MAC = get_MAC(args.interface) if cur_MAC: print(f"目前的 MAC 是:{cur_MAC}") else: print("[-] 無法獲取目前的 MAC Address,請確認網卡介面是否正確!") exit(1) # 執行 MAC 變更 new_MAC = change_MAC(args.interface, args.new_mac_adr) if new_MAC and new_MAC == args.new_mac_adr: print(f"[+] MAC Address 成功更改為:{new_MAC}") else: print("[-] MAC Address 變更失敗!")
留言
張貼留言