說起來,學習Python很大一部分原因是由於對WEB安全的興趣以及對SQLMAP這款工具的好奇,曾經設想學完Python基礎就讀一讀SQLMAP源碼,然而懶病一犯,隨之就大江東去。近來,又重新燃起了讀源碼的想法,耗費幾天時間,基本算是了解一些,在此記錄下來,分享出去。有始但不一定有終,但終究好於不做,慚愧。
我的源碼學習環境如下:
(1)PentesterLab虛擬機;
(2)PyCharm Community Edition 2016.3;
(3)Notepad++
(4)SQLMAP 1.1.1.4#dev
好了,先將幾個重要的函數、變量撩着,main()除外,不足在后續補充完善。
1.cmdLineParser()
位於sqlmap.py中第123行,cmdLineOptions.update(cmdLineParser().__dict__),此函數主要用了optparse模塊來解析腳本傳入的參數,定義在lib\parse\cmdline.py模塊中,使用sqlmap工具的小伙伴們會在此發現很多常見的命令,比如-u -d --random-agent –current-db --dbs --tables --columns等等,在此版本中實際是有194個參數的,這么豐富的功能,有待挖掘啊!
2.initOptions(cmdLineOptions)
位於sqlmap.py中第124行,此函數主要作用是初始化conf、kb這兩個始終貫穿程序的重要變量(自定義字典),定義在lib\core\option.py模塊中,其中conf初始化后有26個鍵值對,kb初始化后有141個鍵值對,同時,此函數最后又調用了_mergeOptions函數,用來合並cmdLineParser()的參數以及conf初始化的參數,合並后conf總共有220個鍵值對。
3.init()
位於sqlmap.py中第141行,此函數主要作用是sqlmap運行的一系列初始化工作,定義在lib\core\option.py模塊中,其中主要的作用包括檢查依賴包、參數輸入合規性檢查、設置代理、加載tamper、解析targeturl、設置請求頭、設置線程數、加載boundaries_xml、加載payloads_xml等。
4.start()
位於sqlmap.py中第151行,此函數主要作用是開始進行注入檢查,判斷是否存在SQL注入漏洞,定義在lib\controller\controller.py模塊中,此函數是重中之重。start()函數中又調用了幾個非常重要的函數,如下。
4.1 setupTargetEnv()
定義在lib\core\target.py模塊中,此函數的主要作用是初始化掃描結果環境,包括創建掃描結果存放目錄、sqllite3數據庫(或者從已有結果中提取數據,對於已掃描的結果不用再掃描)等。
4.2 checkConnection()
位於lib\controller\controller.py中377行,此函數的主要作用是檢查給定的url是否可以訪問。
4.3 checkWaf()
位於lib\controller\controller.py第380行,此函數的主要作用是判斷目標是否有WAF,payload會采用"AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
4.4 checkStability()
位於lib\controller\controller.py第394行,此函數的主要作用是判斷目標target內容是否是會很快變化,其核心是對比第一次訪問目標target內容與延時再次訪問target內容做比較,如果firstPage == secondPage,則認為頁面時穩固的。
4.5 checkDynParam()
位於lib\controller\controller.py第493行,此函數的主要作用是檢查給定url中的參數是否是動態的,如果不是動態的則需要選取其它參數。比如name=root,此處的參數則指name。其核心是給參數name另外一個隨機值,比如name=2394,然后對比兩次返回的頁面,如果相似度高於0.98則認為頁面內容基本沒變,參數不是動態的。
4.6 heuristicCheckSqlInjection()
位於lib\controller\controller.py第516行,此函數的主要作用是一個試探性檢查,payload是name=root)((\\'))."(,(或類似),有可能會爆出后端db信息、xss漏洞、文件上包含漏洞等信息。
4.7 checkSqlInjection()
位於lib\controller\controller.py第528行,真正的SQL注入檢查,重中之重。此函數會結合xml\payloads\下的基於布爾的、基於時間的、基於錯誤的、內聯查詢、對查詢、基於union的注入檢查xml以及boundaries.xml來提取注入語句進行注入漏洞判斷。此處不詳細講解,后期單獨說。
OK,說完start()函數中的幾個關鍵函數調用,其中4.2~4.7均在lib\controller\checks.py模塊中定義,而它們在checks均會調用的一些核心函數如下:
5. Request.queryPage()
根據構造好的payload訪問指定目標web,並對比返回內容與最初頁面內容,包含兩個重要的函數。位於lib\request\connect.py模塊中
5.1 Connect.getPage()
實際訪問web的方法,調用了urllib2.Request方法。
5.2 comparison()
此函數主要作用是比較頁面內容,判斷頁面變化,調用了difflib庫。
6. agent.payload()
定義於lib\core\agent.py模塊中,主要作用是根據xml下的注入表達式生成實際可用的payload,用到了正則、隨機數(字符串)等內容。
7. action()
位於lib\controller\controller.py中639行,主要作用是注入SQL,獲取指定信息,比如數據庫、表、字段、用戶、版本等,定義於lib\controller\action.py模塊。此模塊后期單獨列出分享。
SQLMAP源碼分析第一章節就先到這吧,不足之處、錯誤之處后期深入后再處理。
