資安基礎惡補 - 網路篇 - 用 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 變更失敗!")




留言
張貼留言