1. 程式人生 > >黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

 

聽說不想扯淡的程式猿,不是一隻好猿。所以今天來扯扯淡,不貼程式碼,只講設計思想。

0×00 起 – 初始設計

我們的目標是設計一枚通用的弱密碼掃描器,基本功能是針對不同型別的弱密碼,可方便的擴充套件,比如新增SSH、SVN、phpmyadmin的弱密碼掃描功能。我們設定啟動方法是命令列,可以通過命令列指定掃描物件,以及掃描哪些弱密碼。

既然是要求可擴充套件,那我們首先來編寫一個通用的框架,然後通過新增POC的方法來實現擴充套件。在這個框架中,我們需要處理的事情包括:

初始化掃描物件(格式化URL、從檔案或資料庫中讀取URL)
載入弱密碼掃描指令碼(載入一種或者多種掃描指令碼)

同時為了易用性,框架還要提供一些額外的功能:

提供一些公用的函式(如埠掃描、URL去格式化以及格式化等)
顯示當前可用的POC以及POC的相關資訊

我們預期的呼叫方法應該是這樣:

python base.py -p ssh_weak,mysql_weak -t test.txt --run

這樣,讓我們畫個簡圖:

黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

 

具體講解一下:

base.py是掃描器的入口檔案

poc處理流程:init_poc()將輸入 ssh_weak,mysql_weak格式化,通過load_poc()載入到記憶體中。

target處理流程: init_target()將輸入 test.txt 內容讀取到記憶體中,同時應該支援直接指定引數,以及從資料庫中讀取引數。

POC管理: show_poc_info()呼叫load_poc(),載入所有POC,並print poc_info。

poc_base.py是所有POC的父類,POC通過繼承poc_base,來實現常用函式的繼承,以及POC引擎。

0×10 承 – 功能抽象

通過上述描述,我們得到了一個簡單的框架,通過這個框架提供的功能,我們來試著寫一個標準的POC:

from poc_base import PocBase
class MyPOC(PocBase):
 poc_info = {
 'author': 'Friday',
 'title': 'svn_weak',
 }
 def svn_burst(self, url, user, password):
 pass
 def save(): # 向資料庫或檔案中儲存結果
 pass
 
 def verify(self, target):
 count = 0
 for url in target:
 for user in ['root', 'work']:
 for passwd in ['test', '123456']: 
 count += 1
 if port_open(22) and svn_burst():
 print "Success"
 save() 
 if count % 10 == 0:
 print "當前進度:%d" % count

有幾個地方可以優化:

資料儲存模組,每次掃描完儲存一次,太浪費資源,有什麼解決方法?
資料儲存模組,是否能整合到框架中?
掃描數量較大的時候,應該有掃描成功的提醒,以及掃描進度的提醒,是否能整合到框架中?

這其實是一個問題,資料定時儲存(掃描過程中多次儲存)和進度提醒功能,如何整合到框架中?本來的邏輯是,呼叫一次POC,掃描多個URL,然後直接由POC輸出結果。如果想實現資料儲存和進度提醒,看起來要把更多的控制權交到框架手中。所以,將POC的功能簡化到判斷某一個URL是否存在弱密碼,返回true or false。將POC的呼叫許可權,交到Poc_Base中,多次呼叫POC,虛擬碼如下:

class Poc_Base(object):
 count = 0
 progress = 100 # 進度提醒的單位
 
 @ overide
 def verify():
 pass
 def run():
 for url in url_list:
 count += 1
 if count % progress == 0:
 save() # 資料儲存
 print "progress %d " % (count) # 進度提醒
 if self.verify():
 print "success"

經過優化之後,POC的基本模式,更簡單了:

from poc_base import PocBase
class MyPOC(PocBase):
 poc_info = {
 'author': 'Friday',
 'title': 'svn_weak',
 }
 def svn_burst(self, url, user, password):
 pass
 def verify(self, url):
 for user in ['root', 'work']:
 for passwd in ['test', '123456']: 
 if port_open(22) and svn_burst():
 return True

在beebeeto提交過POC的同學,應該驚呼了“除了結果自動儲存的模組,這不和beebeeto的框架一樣麼!”,是的,在一開始寫框架的時候,參考了beebeeto-frame,後來獨立編寫完成/優化完成後,發現殊途同歸了 : )

0×20 轉 – 效能提升

在實現基本功能之後,我又開始蠢蠢欲動了。作為一個有尊(xing)嚴(neng)的框架,怎麼能滿足於一條線的模式!所以,為了效率,我們要在框架層面新增協程和多程序支援,讓多核CPU每個都能跑到100%是我們的目標!

但應該怎麼新增程序和協程的支援呢?有之前新增資料儲存和進度提醒的經驗,實現不難想象。難點在於,在新增程序和協程支援的時候,不影響正常的資料儲存和進度提醒。虛擬碼如下:

class Poc_Base(object):
 gevent_num = 100 # 協程數
 process_num = 4 # 程序數
 count = [0] * process_num # 每個程序,單獨計數
 progress = 100 # 進度提醒的單位 
 @ overide def verify(): pass
 def verify_count():
 count[progress_number] += 1 if count[progress_number] % progress == 0:
 save() # 資料儲存
 print "progress %d " % (count[progress_number]) # 進度提醒
 if self.verify(): print "success"
 # 協程排程函式,分配任務到協程
 def run_in_gevent(url_list): # url_list 每個程序分配到一定量的url
 pool = Pool(self.gevent_num) for target in url_list:
 pool.add(gevent.spawn(self.verify_count, url))
 pool.join() # 程序排程函式,分配任務到各個程序
 def run():
 url_each_process = len(url_list)/process_num for process_number in range(process_num):
 multiprocessing.Process(target=run_in_gevent, args=(url_list[*:*],)).start()
 multiprocessing.join()

這樣,我們就能在跑POC的時候,用到高階的協程和程序了。

0×30 合

實際執行過程中,協程開了150,程序開了2(8核CPU),可以把兩個核的CPU都跑到90+%。

執行截圖:

黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

 

黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

 

黑客程式設計,基於Python+協程+多程序的弱密碼掃描器!

 

雖然一開始說,不會貼程式碼,但還是貼了不少虛擬碼。內容並不深奧,如果你看過beebeeto-frame和beehive的原始碼,覺得這是簡化版的beehive,是高度定製版的beebeeto-frame,我也會覺得很開心: ) ,學習借鑑就是開源軟體對於我的意義。

因為涉及公司的一些制度,不方便公開原始碼,但感興趣的同學,或者想自己實現一個簡單的掃描器的同學,可以參考上文提到的兩種開源軟體