內置的sys模塊使我們能訪問到由Python解釋器使用或維護的對象,其中包括標志、版本、整型數的最大尺寸、可用的模塊、hook路徑、標准錯誤/輸入/輸出的位置,以及調用解釋器的命令行參數。比如,我們或許想要在運行時解析命令行參數。比如,漏洞掃描器:如果我們想把一個文本文件的文件名作為命令參數傳遞進來該怎麼辦?sys.argv列表中含有所有的命令行參數。第一個sys.argv[0]元素中的是Python腳本名稱,列表中的其余參數則記錄了之後所有的命令行參數。如果我們只傳遞一個額外的參數,sys.argv中應該包含兩個元素,也就是sys.argv列表的長度為2。
import sys
if len(sys.argv) == 2:
filename = sys.argv[1]
print(f"[+] Reading Vulnerabilities From: {
filename}" )
運行這段代碼,我們看到代碼成功地解析了命令行參數,如下圖所示:
內置的OS模塊提供了豐富的適用於Mac、NT或Posix的操作系統的函數。這個模塊允許程序獨立地與操作系統環境、文件系統、用戶數據庫以及權限進行交互。上面的例子中,把一個文本文件名(vuln-banners.txt)作為參數傳遞進來,先檢查一下該文件是否存在、當前用戶是否有權限讀取該文件,或許很有價值。如果其中任一條件不滿足,就向用戶顯示一條相應的錯誤信息是很有幫助的。示例代碼如下:
import os, sys
if len(sys.argv) == 2: # 只傳遞一個文件名參數
filename = sys.argv[1] # 獲取文件名,並賦值給filename
if not os.path.isfile(filename): # 判斷文件是否存在
print(f'[-] {
filename} does not exist.')
exit(0)
if not os.access(filename, os.R_OK): # 判斷文件是否有訪問權限
print(f'[-] {
filename} access denied.')
exit(0)
print(f'[+] Reading Vulnerables From: {
filename}')
為驗證代碼,先嘗試讀取一個不存在的文件,腳本提示錯誤信息後,創建一個特定的文件名並成功讀取其中的內容。最後,限制權限,腳本則正確地提示拒絕訪問(access-denied)
+] Reading Vulnerablities From: vuln-banners.txt
(base) [email protected]-Air hacker_python % python test.py vuln-banne.txt
[-] vuln-banne.txt does not exist.
(base) [email protected]-Air hacker_python % python test.py vuln-banners.txt
[+] Reading Vulnerables From: vuln-banners.txt
(base) [email protected]-Air hacker_python % python test.py vuln-banners.txt
[-] vuln-banners.txt access denied.
現在整合這兩個模塊的應用,示例代碼如下:
import socket
import os
import sys
# 定義返回banner函數,參數為(ip,port)
def retBanner(ip, port):
try:
socket.setdefaulttimeout(2)
s = socket.socket()
s.connect((ip, port))
banner = s.recv(1024)
return banner
except:
return
# 定義測試漏洞函數,參數為banner,filename
def checkVulns(banner, filename):
with open(filename, 'r') as f:
for line in f.readlines():
if line.strip('\r\n') in banner:
print(f'[+] Server is vulnerable: {
banner.strip("\n")}')
def main():
if len(sys.argv) == 2:
filename = sys.argv[1]
if not os.path.isfile(filename):
print(f'[-] {
filename} does not exist.')
exit(0)
if not os.access(filename, os.R_OK):
print(f'[-] {
filename} access denied.')
exit(0)
else:
print('[-] Usage: ' + str(sys.argv[0]) + ' <vuln filename>')
exit(0)
portLst = [21, 22, 25, 80, 110, 443]
for i in range(147, 150):
ip = '192.168.31.' + str(i)
for port in portLst:
banner = retBanner((ip, port))
if banner:
print('[+] '+ ip + ': ' + banner)
checkVulns(banner, filename)
if __name__ == '__main__':
main()