日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

w3af解析

發布時間:2023/11/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 w3af解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. w3af簡介

w3afis a Web Application Attack and Audit Framework.即Web應用攻擊和審計框架。w3af用python編寫,依賴的庫主要有2類,分別如下:

<1> Core requirements:

Python 2.6

fpconst-0.7.2:用于處理IEEE 754浮點數;

nltk:自然語言處理工具包;

SOAPpy:SOAP是簡單對象訪問協議,是一種交換數據的協議規范,基于XML;

pyPdf:處理PDF文檔,提取信息,分割/合并頁面等;

Python bindings for the libxml2 library:libxml2是C庫,這里是個python中間件

Python OpenSSL:實現SSL與TLS的套件,https;

json.py:json是一種輕量級的數據交換格式;

scapy:可以用來發送、嗅探、解析和偽造網絡數據包;

pysvn:支持subversion操作;

python sqlite3:精簡的嵌入式開源數據庫,使用一個文件存儲整個數據庫,沒有獨立的維護進程,全部由應用程序進行維護,使用特別方便;

yappi:支持配置每個線程的CPU時間(https://code.google.com/p/yappi/)

<2> Graphical user interface requirements:

graphviz:可視化圖表graph;

pygtk 2.0:生成GUI;

gtk 2.12:跨平臺的圖形工具包

2. w3af 架構

主要分3部分

<1>內核

The core, which coordinates the whole process and provides libraries for using in plugins.

<2>UI(console和GUI)The user interfaces, which allow the user to configure and start scans

<3>插件The plugins, which find links and vulnerabilities

3.黑盒測試–web應用掃描過程

<1> 識別所有的鏈接,表單,查詢字條串參數;Identify all links, forms, query string parameters.

<2> 對于每個輸入(表單),發送構造的畸形字符串,然后分析輸出;Send specially crafted strings to each input and analyze the output

<3>生成報告Generate a report with the findings

4. w3af工作過程

<1> 調用crawl plugins(如web spider)尋找所有的Links,forms,query string parameters. 通過這一步驟,將創建一個form和Links映射。

<2> 調用audit plugins(比如sqli)發送畸形數據,來盡可能的觸發漏洞。

<3> 通過output plugins將發現的漏洞、調試和錯誤信息反饋給用戶。

5.源碼初窺

文件:w3af/core/controllers/w3afCore.py<1> 類w3afCore:這是整個框架的核心,它調用所有的插件,處理異常,協調所有的工作,創建線程……

scan_start_hook(self)

功能:創建目錄、線程和“消費者”,用來執行一次w3af掃描。

調用:在core初始化,重新啟動掃描(清除前一個掃描的所有結果和狀態)

start(self)功能:UI調用該方法來啟動整個掃描過程

_safe_message_print(self,msg)功能:當磁盤空間耗盡,程序不能再向磁盤寫入日志信息時,會引發異常,該函數就是來處理這種異常。像backtrack這種LiveCD經常出現這種異常。

worker_pool(self)功能:返回一個類Pool的實例

cleanup(self)功能:GUI 調用該方法,當一個掃描被終止,并且用戶想啟動一個新的掃描時,kb所有的數據被刪除。

stop(self)功能:當用戶停止掃描時,UI層調用。

quit(self)功能:退出s3af

pause(self)功能:對于一個掃描,暫停或者取消暫停

verify_environment(self)功能:檢查用戶配置的所有參數是否正確。

scan_end_hook(self)功能:對應scan_start_hook()

exploit_phase_prerequisites()pass

_home_directory(self)功能:處理和創建/管理主目錄相關的工作

_tmp_directory(self)功能:創建tmp目錄,存儲大量資料,/tmp/w3af/<pid>/

6. 進階計劃

讀了幾個源碼文件,感覺具體到某一個文件源碼,看明白沒什么困難,但是看完之后基本上沒有收獲,所以下一步準備修改源碼再編譯,希望能有所收獲。






0.引言

本文深入分析了w3af_console啟動過程,詳細說明了函數調用關系,有助于理解w3af框架。下面是w3af_console入口函數_main()

def _main():_configure_output_manager()sys.exit(main())

1._configure_output_manager深入分析

w3af_console執行的第一個函數_configure_output_manager()分析,執行的結果是創建的console對象保存在全局變量om.out中,om.out在main()函數中會用到,如console.sh()。下面用'->'表示調用或繼承關系,一步一步的分析到源頭。

->(file:w3af_console) _configure_output_manager() ->(file:w3af_console) om.out.set_output_plugins( ['console'] ) ps: om就是out_manager module; out是類out_manager的一個全局對象,定義在\w3af\core\controllers\out_manager.py中 ->(file:\w3af\core\controllers\out_manager.py) set_output_plugins( ['console'] ) ->(file:\w3af\core\controllers\out_manager.py) _add_output_plugins( 'console') ->(file:\w3af\core\controllers\out_manager.py) plugin = factory('w3af.plugins.output.' + OutputPluginName) plugin.set_options(self._plugin_options[OutputPluginName]) self._output_plugin_instances.append(plugin) ->(file:\w3af\core\controllers\misc\factory.py) <pre style="padding-left: 30px;" class="lang:python decode:true">factory('w3af.plugins.output.console')#主要過程__import__('w3af.plugins.output.console')class_name = module_name.split('.')[-1] #class_name='console'module_inst = sys.modules['w3af.plugins.output.console']a_class = getattr(module_inst, 'console') # a_class 現在等價于console類return a_class()</pre> <strong>(到此就返回一個console對象,下面是幾個類的繼承關系)</strong> ->(file:\w3af\plugins\output\console.py) class console(OutputPlugin): ...->(file:\w3af\core\controllers\plugins\output_plugin.py) class OutputPlugin(Plugin): """ This is the base class for data output, all output plugins should inherit from it and implement the following methods : 1. debug( message, verbose ) 2. information( message, verbose ) 3. error( message, verbose ) 4. vulnerability( message, verbose ) """->(file:\w3af\core\controllers\plugins\plugins.py) class Plugin(Configurable): ...->(file:\w3af\core\controllers\configurable.py) class Configurable(object): #This is mostly "an interface"

2.main函數深入分析

假定啟動w3af的命令為

./w3af_console -s script_file

2.1 ConsoleUI

main()函數中首先解析script_file,生成commands_to_run[],根據commands,初始化一個ConsoleUI對象console,這是用戶操作的UI. 有兩個關鍵操作,self.handlers初始化和self.initRoot()

#_handlers是一個字典,鍵盤輸入字符是key,函數是value self._handlers = {'\t': self._onTab,'\r': self._onEnter,term.KEY_BACKSPACE: self._onBackspace,term.KEY_LEFT: self._onLeft,term.KEY_RIGHT: self._onRight,term.KEY_UP: self._onUp,term.KEY_DOWN: self._onDown,'^C': self._backOrExit,'^D': self._backOrExit,'^L': self._clearScreen,'^W': self._delWord,'^H': self._onBackspace,'^A': self._toLineStart,'^E': self._toLineEnd}def __initRoot(self, do_upd):"""Root menu init routine."""cons_upd = ConsoleUIUpdater(force=do_upd)cons_upd.update()# Core initializationself._w3af = w3afCore()self._w3af.plugins.set_plugins(['console'], 'output') #關鍵...#一直遞歸下去,在類w3af_core_plugins(實例是上面的self._w3af.plugins)發現調用的是self._set_plugin_generic(self, 'output', ['console'])self._plugins_names_dict['output'] = ['console']</pre>

(ps: file:\w3af\core\ui\console\console_ui.py

ConsoleUI class represents the console.It handles the keys pressed and delegate the completion and execution tasks to the current menu.)

2.2 accept_disclaimer

創建完console實例后,console調用accept_disclaimer方法,它輸出w3af的免責條款,如果用戶接受,就可以繼續使用,否則退出。

2.3 sh

最后調用console.sh(),進行主循環,創建一個w3af shell,執行w3af的命令。

->(file:\w3af\core\ui\console\console_ui.py)刪除異常處理語句等,sh()完成的主要工作如下

def sh(self,name="w3af",callback=None)self._context = rootMenu(name, self, self._w3af)self._showPrompt()self._active = Trueterm.setRawInputMode(True)self._executePending()while self._active:#主循環,等待用戶輸入,解析命令及參數c = term.getch()self._handleKey(c) #根據字典self._handlers調用相關方法

2.4 rootMenu

對于sh()的第一條語句:

self._context = rootMenu(name, self, self._w3af)

初始化一個rootMenu類的實例_context,顧名思義,包括plugins,target,exploit等根菜單;rootMenu初始化的關鍵代碼如下->(file:\w3af\core\ui\console\rootMenu.py)

class rootMenu(menu):def __init__(self, name, console, core, parent=None):menu.__init__(self, name, console, core, parent)self._load_help('root')# At first, there is no scan threadself._scan_thread = NonemapDict(self.addChild, {'plugins': pluginsMenu,'target': (ConfigMenu, self._w3af.target),'misc-settings': (ConfigMenu, MiscSettings()),'http-settings': (ConfigMenu, self._w3af.uri_opener.settings),'profiles': profilesMenu,'bug-report': bug_report_menu,'exploit': exploit,'kb': kbMenu})def mapDict(fun, dct):for p in dct:fun(p, dct[p])def addChild(self, name, constructor):if type(constructor) in (tuple, list):constructor, params = constructor[0], constructor[1:]else:params = []self._children[name] = constructor(name, self._console, self._w3af, self, *params)</pre>

對于字典的第一項'plugins': pluginsMenu,mapDict()執行過程如下self.addchild('plugins',pluginsMenu)-->self.children['plugins']=pluginsMenu('plugins', self.console, self._w3af, self,[])

-->(file:\w3af\core\ui\console\plugins.py)類pluginsMenuinit中首先得到plugins目錄下的插件類型types(除去attack,tests,.gits的所有目錄名)

types=['audit','auth','bruteforce','crawl','evasion','grep','infrastructure','mangle','output'] for t in types: self.addChild(t, pluginsTypeMenu) self._children['audit']=pluginsTypeMenu('audit',...)

-->(file:\w3af\core\ui\console\plugins.py)類pluginsTypeMenuinit中將plugins/plugin_types/目錄下所有插件讀入到plugins[]中最后保存到一個插件字典中self.plugins={}self.plugins[plugin_name]=plugin_option_num

2.5 _showPrompt

功能輸出提示符[plugins...]>>>

->(file:\w3af\core\ui\console\console_ui.py) term.write(self._context.get_path() + ">>> ")->(file:\w3af\core\ui\console\menu.py) get_path()

2.6 _executePending

調用executePending(),它順序讀取console初始化時的輸入參數commands指令curCmd
paste(curCmd)將指令在終端stdout顯示出來,同時保存至self.line[]
onEnter()依次:執行指令,初始化當前行position=0和line=[],在新一行輸出">>>";
(ps:在當前類中找不到方法,去父類中找,如rootMenu中沒有execute,在其父類menu中找)

->(file:\w3af\core\ui\console\console_ui.py)

def _executePending(self):while (self._commands):curCmd, self._commands = self._commands[0], self._commands[1:]self._paste(curCmd)self._onEnter() def _paste(self, text):tail = self._line[self._position:]for c in text:self._line.insert(self._position, c)self._position += 1term.write(text)term.write(''.join(tail))term.moveBack(len(tail))def _onEnter(self):self._execute() #關鍵self._initPrompt()self._showPrompt()def _execute(self):line = self._getLineStr()term.setRawInputMode(False)om.out.console('')if len(line) and not line.isspace():self._get_history().remember(self._line)params = self.in_raw_line_mode() and line or self._parseLine(line)menu = self._context.execute(params)if menu:if callable(menu):menu = menu()elif menu != self._context:# Remember this for the back commandself._trace.append(self._context)if menu is not None:self._context = menuterm.setRawInputMode(True)</pre>

從上述代碼發現函數調用路線如下

self._executePending()->self._onEnter()->self._execute()->self._context.execute()

self._context是類rootMenu的對象,但是rootMenu類中沒有execute()方法,那么去其父類menu中查找。

2.7 menu.execute

(file:\w3af\core\ui\console\menu.py)

execute方法完整注釋如下

#class menu def execute(self, tokens):if len(tokens) == 0:return self command, params = tokens[0], tokens[1:]handler = self.get_handler(command)# hander 可能是:# _cmd_back(), _cmd_exit(), _cmd_keys(), _cmd_help(), _cmd_print()# 子類中按需要增加了各自特殊_cmd__XXX,如ConfigMenu類中增加了_cmd_set(),_cmd_view()..if handler: # 遞歸出口return handler(params)children = self.get_children() '''return self._children, it's a dict在menu的子類rootMenu中對self._children進行了初始化,代碼見2.4 rootMenu'''if command in children: # in children.keys()child = children[command]#child可能是一個pluginsMenu, ConfigMenuchild.set_child_call(True)#set_child_call函數處理 set命令,如w3af>>> target set target http://w3af.org/try:return child.execute(params) # 按上例,params = set target http://w3af.org/# 由于child也是繼承自menu類,所以execute是同一個方法# 下次調用execute時在handler中找到了_cmd_set()方法# 直接執行_cmd_set(' target http://w3af.org/'),不再向下遞歸finally:child.set_child_call(False)raise BaseFrameworkException("Unknown command '%s'" % command)</pre>

對于上面的最終執行函數handler(),僅分析一個set命令:類ConfigMenu的_cmd_set()方法。

2.8 _cmd_set

(file: \w3af\core\ui\console\config.py)

_cmd_set()的主干如下

#去掉的異常處理等 def _cmd_set(self, params):name = params[0]value = ' '.join(params[1:])self._options[name].set_value(value)self._unsaved_options[name] = valueif value not in self._memory[name]:self._memory[name].append(value)if self._child_call:self._cmd_save([])</pre>

比如命令 w3af>>> target set target http://w3af.org/

從execute()方法執行到_cmd_set()方法時

params=['target','http://w3af.org/']

即name='target', value='http://w3af.org/'

下面關鍵的就是self._options

2.9 w3af_core_target

(file:\w3af\core\ui\console\config.py)

class ConfigMenu(menu) def __init__(self, name, console, w3af, parent, configurable): self._configurable = configurable self._options = self._configurable.get_options()

通過回滾,找到'target'插件對象創建的時刻就是在rootMenu對象創建時,去前文找mapDict()。核對參數發現當時傳入的configurable是self._w3af.target(file:\w3af\core\ui\console\rootMenu.py)

->(file:\w3af\core\controllers\w3afCore.py)class w3afCore的init中有target的創建self.target = w3af_core_target()->(file:\w3af\core\controllers\core_helpers\target.py)

get_options()涉及到的細節過多,跟w3af_console主干沒有太多關系,因此不再深挖下去,以后再做分析。

3. 總結

w3af啟動時,首先添加console插件,配置一個output_manager全局對象om.out,這是創建ConsoleUI,與用戶交互的基礎。然后在main函數中創建ConsoleUI對象,執行初始化,進入最重要的環節,生成一個w3af shell,創建rootMenu,讀取命令行參數script,進行相關設置,最后進行死循環while self._active,等待用戶輸入,解析輸入,如果是正確的命令,就(有些需要調用插件)執行相應操作,至此用戶才能跟w3af進行正常交互,w3af啟動成功。





本文以menu切換,插件加載與啟動為主線,分析w3af源代碼中函數調用和各類之間的繼承與組合關系,閱讀之前請先有一個DFS(深度優先遍歷)的準備。

一、menu切換

1.menu類繼承關系

object

|—menu

—|—rootMenu

—|—pluginsMenu

——|—pluginsTypeMenu

—|—ConfigMenu

—|—profilesMenu

—|—bug_report_menu

—|—kbMenu

—|—exploit

2.w3af>>plugins執行過程

輸入plugins+回車之后,指令從ConsoleUI類的sh()方法依次執行:

self._onEnter()->self._execute()->self._context.execute()

為了分析清楚類之間的關系,下文統一將self替換成類的名字,如果實例對象對分析過程有影響,會特別標出對象名字。

sef._context,在sh()中初始化時是rootMenu類的實例,顧名思義,context是一個上下文,它會隨著程序的執行而變化,具體的說它會隨著w3af shell提示符的變化而變化,從回車之后,一步一步深入分析下去,過程如下。

ConsoleUI._onEnter()->ConsoleUI._execute()->rootMenu.execute()

2.1 rootMenu.execute()

ConsoleUI._context就是類rootMenu的對象,rootMenu是menu類的子類,rootMenu沒有重新定義execute方法,所以最后執行的是menu.execute(‘plugins’)

childrenmenu.get_children()#返回一個字典menu._children

child = children['plugins']#返回一個類pluginsMenu對象,它在rootMenu對象創建時完成的創建

reutn child.execute([])#即pluginsMenu.execute([])

由于參數為空,轉向執行父類的execute函數,menu.execute([]),在該函數中,由于參數為空,終止遞歸,return self,此處也就是pluginsMenu對象。

2.2 ConsoleUI._execute()

返回上一層 ConsoleUI._execute(),接著執行:

menu = pluginsMenu? #這是2.1返回的一個對象,menu在此是一個臨時變量

ConsoleUI._trace.append(ConsoleUI._context) #保存路徑

if menu is not None:

self._context = menu? #完成上下文切換

2.3 ConsoleUI._onEnter()

再返回上一層ConsoleUI._execute(),接著執行:

ConsoleUI._initPrompt()ConsoleUI._showPrompt()#重新顯示shell提示符:w3af/plugins>>>

3.w3af/plugins>>>back執行過程

輸入back+回車之后,指令從ConsoleUI類的sh()方法依次執行:

ConsoleUI._onEnter()->ConsoleUI._execute()->pluginsMenu.execute()

3.1 pluginsMenu.execute()

目前ConsoleUI._context就是類pluginsMenu的對象,pluginsMenu是menu類的子類,由于back不是一個插件類型,所以最后執行的是menu.execute(‘back’),其執行過程如下:

return pluginsMenu._cmd_back()

return pluginsMenu._console.back()

return ConsoleUI.back()

return ConsoleUI._trace.pop()

從第2節能夠知道_trace在尾部append的是rootMenu對象,所以此處彈出的也是rootMenu對象。

3.2 ConsoleUI._execute()

返回上一層 ConsoleUI._execute(),接著執行:

menu = rootMenu? #這是2.1返回的一個對象,menu在此是一個臨時變量

if menu is not None:

self._context = menu? #完成上下文切換

3.3 ConsoleUI._onEnter()

再返回上一層ConsoleUI._execute(),接著執行:

ConsoleUI._initPrompt()ConsoleUI._showPrompt()#重新顯示shell提示符:w3af>>>

二、加載插件

加載爬蟲插件web spider的命令是:

w3af新版本命令:w3af/plugins>>>crawl web_spider

w3af舊版本命令:w3af/plugins>>>discovery webSpider

1.命令解析

crawl/discovery代表插件類型,w3af的插件類型就是w3af/plugins目錄下的目錄名(除去attack,tests),包括audit,crawl,auth,output等。它對應于類pluginsTypeMenu.

web_spider/webSpider代表具體的插件名字,位于w3af/plugins/插件類型/目錄下。

2.獲取所有的可用插件

從w3af_console啟動,到獲取每一種類型的所有插件的過程如下

1)ConsoleUI的_init_()中 self._w3af = w3afCore()

2)ConsoleUI的sh()中調用rootMenu(…,self._w3af,…)

3)rootMenu的_init_()中生成pluginsMenu對象

4)pluginsMenu的_init_()中調用w3af.plugins.get_plugin_types(),返回所有的插件類型types

5)對于每一個插件類型type,生成一個pluginsTypeMenu對象

6)pluginsTypeMenu的_init_()中調用w3af.plugins.get_plugin_list(name),返回一種插件的所有插件名字

7)對于一種插件的所有具體插件,pluginsTypeMenu的_init_()中調用self._w3af.plugins.get_plugin_inst(self._name, p).get_options()返回一個具體插件的使用選項說明

ps: w3af.plugins是類w3af_core_plugins對象

3.w3af/plugins>>>crawl web_spider

此時的上下文是pluginsMenu(參考一.3)

ConsoleUI._onEnter()->ConsoleUI._execute()->pluginsMenu.execute(['crawl','web_spider'])

3.1 pluginsMenu.execute(['crawl','web_spider'])

1)pluginsMenu.execute(['crawl','web_spider'])

2)menu.execute(['crawl','web_spider'])

commands=’crawl’

params=['web_spider']

#由上一節可知,每一個插件類型已經生成pluginsTypeMenu對象,此外查找crawl對應的pluginsTypeMenu

3)pluginsTypeMenu.execute(['web_spider'])

4)pluingsTypeMenu._enablePlugins(‘web_spider’)

5)w3afCore.w3af_core_plugins.set_plugins([...,'web_spider'],’crawl’)

6)w3af_core_plugins._set_plugins_generic(‘crawl’,’web_spider’) #加入字典_plugins_names_dict

至此,web_spider插件加載成功。

3.2 返回過程省略

三、啟動插件

w3af>>start執行后,如何創建web_spider插件類實例,并啟動插件呢?

1. 創建web_spider實例

首先,當前的上下文_context是rootMenu。函數調用過程如下

1)rootMenu._cmd_start()

2)rootMenu._real_start()

3)rootMenu._w3af.plugins.init_plugins()

即w3af_core_plugins.init_plugins()

4)w3af_core_plugins.plugin_factory()

5)w3af_core_plugins.create_instances()

6)w3af_core_plugins.get_plugin_inst()

w3af創建插件實例

Python

def get_plugin_inst(self, plugin_type, plugin_name):""":return: An instance of a plugin."""plugin_inst = factory('w3af.plugins.%s.%s' % (plugin_type, plugin_name))plugin_inst.set_url_opener(self._w3af_core.uri_opener)plugin_inst.set_worker_pool(self._w3af_core.worker_pool)if plugin_name in self._plugins_options[plugin_type].keys():custom_options = self._plugins_options[plugin_type][plugin_name]plugin_inst.set_options(custom_options)# This will init some plugins like mangle and outputif plugin_type == 'attack' and not self.initialized:self.init_plugins()return plugin_inst

defget_plugin_inst(self,plugin_type,plugin_name):

"""

:return: An instance of a plugin.

"""

plugin_inst=factory('w3af.plugins.%s.%s'%(plugin_type,plugin_name))

plugin_inst.set_url_opener(self._w3af_core.uri_opener)

plugin_inst.set_worker_pool(self._w3af_core.worker_pool)

ifplugin_nameinself._plugins_options[plugin_type].keys():

custom_options=self._plugins_options[plugin_type][plugin_name]

plugin_inst.set_options(custom_options)

# This will init some plugins like mangle and output

ifplugin_type=='attack'andnotself.initialized:

self.init_plugins()

returnplugin_inst

7)factory類,就是import web_spider 插件,同時保證插件中的類名字和文件名字完全相同;web_spider類的繼承關系為 object–>Configurable–>plugin–>CrawlPlugin–>web_spider

2. 運行插件

1)rootMenu._cmd_start()

2)rootMenu._real_start()

3)rootMenu._w3af.start()即w3afCore.start(),具體過程暫不分析。

四、小結

本文用DFS的方式,跟蹤分析了w3af_console的menu切換,插件加載與啟動的過程,理清了函數調用關系,初步弄懂了各類之間的關聯。遺留的問題,線程池與w3afCore.start().


總結

以上是生活随笔為你收集整理的w3af解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。