本文講述的是TDD 方法開發網絡安全測試工具:代理掃描器(第一集),旨在服務社會,供安全研究人員學習使用,請勿用于其他非法用途,違者后果自負。
什么是 TDD 以及 我為什么推薦 TDD
做過一些軟件開發的朋友們可能會知道這個東西 TDD(Test-Driven Development),誠然我自己之前的開發也并不是 TDD,而是傳統的開發,寫文檔,開發,寫文檔的“瀑布”開發。當然自己也是開始嘗試進行一些系統的 Web 開發訓練的時候深深體會到了 TDD 開發的優勢,想到了 紅黑聯盟這邊還有一個坑沒填,那就來結合現在的經驗談一下這個事情吧!Test-Driven Development 顧名思義,就是利用測試來驅動(督促)開發進展中文名也就是測試驅動開發,簡稱 TDD。是一種敏捷開發模式。當然這么說大家會覺得非常抽象。那我就通俗的來解釋一下,可能有不恰當的地方,希望讀者在評論區指出:眾所周知瀑布式開發一般來說寫代碼-寫文檔-寫代碼-寫文檔-… 。每一個周期與周期之間唯一的銜接就是文檔;但是 TDD 是測試驅動的,就是先有測試用例 (testCase),然后再有代碼(聽起來是不是非常的奇怪),其實想想非常的常見,不就是現有需求后代碼么?沒錯啊,TDD 可以說是把這個大需求,直接反映在測試上,然后根據測試用例來開發代碼,寫出滿足測試用例的最少的代碼。
優勢
這樣做有什么好處呢?時刻檢查自己的代碼是不是符合自己的目標,如果符合要求可以通過,如果不符合,則不能通過。除此之外,仔細想想,在未完成開發的時候,你可以隨時停下你的開發,下次只需要運行測試用例,查看哪里沒有通過,就可以繼續之前的代碼進行開發。當然,這只是其中的兩條顯而易見的好處。
缺點
理所當然的,作為一個滲透測試人員,需要一些短平快的腳本的時候,是根本不需要使用 TDD 方法去寫代碼的,顯然啊,TDD 方法開發的代碼量其實要比原來的開發要大(主要體現在有時候需要寫大量的測試代碼),這算是 TDD 一個缺點。不過按照我個人的體驗來說,TDD 方法去開發工具的時候,效率不止是提高了一點,就算寫了大量的測試代碼,但是仍然是效率高于原來。
滲透工具(HTTP 代理掃描)從 0 開始:
提到 HTTP 代理大家都還是挺熟悉的。那么既然要學習滲透工具開發,不妨就來做一個這樣的實用的小玩意。在學習 Python 之余堅持完成了,還可以平時自己使用一波,還是挺不錯的。那么關于 HTTP 代理呢?大家應該都并不是特別陌生,我們經常會使用到 HTTP/HTTPS 代理去完成隱藏自己的真實 IP(隱藏自己真實信息這個的可行性我們暫且不談),那么大家會發現,我們經常上網尋找一些公開的代理網站,(比如快代理啊,xici之類的)
開發環境與重要模塊
1. Python2.7+
2. Pylint 用于檢查代碼規范
3. unittest 用于 TDD 測試驅動開發
說實話,基本 Python 基礎知識和 unittest 的基本使用方法我就不介紹了,如果你在閱讀這篇文章,就說明你至少還有有一些 Python 基礎的。
哦,除此之外,建議在寫代碼的時候使用 Google 開源項目代碼規范 (Python) 。
0×00 Start Up!
(嗨呀,首先是不是要寫 Hello World 啊?)當然,既然我們想要使用 TDD 的方法來開發,我們首先當然需要寫一個測試用例。(暫且撇開測試套件什么的,我們就最簡單的做一個測試用例)。那么要寫測試用例了,我們首先得知道,我們想要做出的功能是怎么樣的?嗯…既然是代理掃描器嘛,首先我們得知道怎么去掃描 HTTP 代理,其實并不用說的太玄乎,有個最簡單的辦法就是,我們就去把它當代理用,如果成功了,那么就說明這個 IP 的端口開啟了代理模式,如果失敗了,那就說明這個端口并不能作為代理來使用。那么事情就簡單了,我們想要的第一個功能就是使用 Python 完成檢測目標 IP:PORT 是否是可用代理。那么就動手吧!
當然我們需要先建立一個文件,根據功能,就叫 check_proxy.py 吧!在新建文件之后,我們需要開始編寫測試用例了。(什么?為什么不是編寫代碼?)畢竟我們嘗試的是 TDD 方法開發工具,顯然首先寫個函數什么的顯然并不是符合我們的初衷。那么,我們就開始吧!
#!/usr/bin/env python#coding:utf-8"""Author: --Purpose: check proxy availableCreated: 2016/10/31"""import unittest########################################################################class CheckProxyTest(unittest.case.TestCase):"""Test CheckProxy"""passif __name__ == '__main__':unittest.main()
在創建了這個段代碼之后,顯然,大家看到我 import unittest 應該就知道接下來要編寫測試用例了吧。那么 unittest 應該怎么使用我覺得我不用向大家解釋太多,直接看代碼更加直觀。在有了測試文件類之后呢,我們并不著急編寫我們的 CheckProxy 的功能代碼。我們不妨設想一下我們這個類的功能:姑且就是我們輸入一個 IP:PORT 這個形式,運行模塊,如果可以用作代理,返回結果表明這個地址可以用作 HTTP 還是 HTTPS 代理,那么我們就規定一下返回的格式吧:
{'result':True,'proxy':{'http':'xxx.xxx.xxx.xx:port','https':'xxx.xxx.xxx.xx:port'}}如果沒有 HTTPS 代理的功能的話那就是:{'result':True,'proxy':{'http':'xxx.xxx.xxx.xx:port',}}當然這是理想情況,如果不是代理呢?{'result':False,'proxy':None}
嗯這樣的話,我們就可以根據這個來寫第一個測試用例了:我們刪除 pass 然后添加 def test_xxxxx 方法:
def test_check_ip(self):'''result should be{'result':True,{C} 'proxy':{'http':'xxx.xxx.xxx.xx:port','https':'xxx.xxx.xxx.xx:port'}}'''
#創建想要測試的實例
master = CheckProxy('78.6.5.45:8080')result = master.test()##對結果進行測試#測試結果必須是個 dict 類型self.assertIsInstance(result, dict)#必須有一個 result 和 proxy 的鍵self.assertTrue(result.has_key('result'))self.assertTrue(result.has_key('proxy'))#result 鍵對應的值必須是一個 bool 類型self.assertIsInstance(result['result'], bool)#斷言測試 result['proxy'] 的類型if result['result']:self.assertIsInstance(result['proxy'], dict)else:self.assertIsNone(result['proxy'])看文倉www.92to.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20161219/73811.html
文章列表