RTFSC——SQLMap源码(慢慢更给自己)

半世苍凉 提交于 2020-02-28 19:23:16

 因为主要是自己看SQLMap源码有个记录,所以写上来的东西,对我个人来说就是想到什么写什么,比较杂乱,推荐看参考中各位大牛的文章。

==============================================================

  1. 流程图
  2. 目录结构
  3. 流程
  4. 源码详读

==============================================================

  1. 流程图

  2. 目录结构

    1. sqlmap-master
      ├── doc
      ├── extra
      ├── ISSUE_TEMPLATE.md
      ├── lib
      ├── plugins
      ├── procs
      ├── README.md
      ├── shell
      ├── sqlmapapi.py
      ├── sqlmap.conf
      ├── sqlmap.py
      ├── tamper
      ├── thirdparty
      ├── txt
      ├── udf
      ├── waf
      └── xml

              doc: 一些文档,Readme.pdf 内容跟wiki内容大部分一致,值得一看

              extra: 一些外部工具 

              lib: 核心源码实现

              plugins:插件。generic子文件为通用的一些相关插件、 dbms子文件夹具体到各种特定数据库相关的一些插件(连接器、枚举、指纹、文件系统、语法、接管相关)会在exploit SQL injection中用到。

              procs: 几种特定数据库预设的一些具有一定功能的SQL代码段。

              shell: 被转码的一些shell,使用/extra/cloak/cloak.py可以转回源码

              tamper: 存放众多tamper脚本

              thirdparty: 第三方脚本

              txt: 一些文本类型的内容,爆破用的字典、目录、表等,UA信息。

              udf: mysql 和 postgresql的一些UDF文件(多平台、多架构)

              waf: 识别waf用到的一些指纹信息等。

            xml: banner子文件夹,一些用于识别的banner信息;payload子文件夹,各种injection技术的payload信息;boundaries、errors、livetests、queries的相关静态信息。

  3. 流程

    1. 
      sqlmap.py
      
      #函数入口
      =============sqlmap.py=============
      main()
      	checkEnvironment()
      	#运行环境监察
      	setPaths(modulePath())
      	#设置一些路径信息,并检查一些文件的可用性
      	banner()
      	#打印一些banner信息
      	
      	cmdLineOptions.update(cmdLineParser().__dict__)
      	#解析命令行参数到cmdLineOptions这个属性字典
      	initOptions(cmdLineOptions)
      	#初始化conf、kb属性字典,并用cmdLineOption中的设置项填充conf
      		
      		
      	init()
      	#一系列的初始化工作(包含对conf、kb的填充)	
      	
      	start()
      =============controller.py=============
      #此中存在大量需要用户指定才会触发的处理流程,所以我略过一些操作,只挑一些提
      start()
          if conf.url and not any((conf.forms, conf.crawlDepth)):
              kb.targets.add((conf.url, conf.method, conf.data, conf.cookie, None))	
      	#将target的一些信息添加到kb
      	
      	for targetUrl, targetMethod, targetData, targetCookie, targetHeaders in kb.targets
      	#开始循环对每个url进行处理和造作
      	#将一些kb.target信息设置到conf中
      	
      	initTargetEnv()
          #初始化target environment,初始化并设置一些参数
      	parseTargetUrl()
      	#解析URL,将信息设置到conf中
      	
      	#从kb中判断是否进行过injection,并设置testSqlInj
      	
      	setupTargetEnv()
      	#设置target Env
      	#创建目标结果目录
      	#解析并设置请求的参数
      	#设置session.sqlite
      	#从session.sqlite中恢复数据
      	#存储结果
      	#添加认证信息
      	
      	if not checkConnection(suppressOutput=conf.forms) or not checkString() or not checkRegexp()
      	#测试连接有效性、测试响应中返回字符串、测试响应中正则的匹配
      	
      	checkWaf()
      	#使用预设的语句,测试是否存在WAF
      	
      	identifyWaf()
      	#识别WAF
      	
      	checkNullConnection()
      	#测试NUllConnection
      	
      	
          skip = (place == PLACE.USER_AGENT and conf.level < 3)
          skip |= (place == PLACE.REFERER and conf.level < 3)	
      	...
      	#根据level、risk设置一些测试位置
      	
      	checkDynParam(place, parameter, value)
      	#检测参数的动态性
      	
      	heuristicCheckSqlInjection(place, parameter)
      	#进行启发式注入测试,简单测试是否存在注入、XSS、文件包含
      	
      	checkSqlInjection(place, parameter, value)
      
      =============checks.py=============
      checkSqlInjection(place, parameter, value)
      
      	injection = InjectionDict()
      	#用于存放注入过程中一些信息
      	
      	tests = getSortedInjectionTests()
      	#tests 中为各种要测试的payload
      	#内容来自/sqlmap/xml/payloads/下,最初不会对其排序,只是从conf中读到当前环境
      	
      	#开始循环执行各test
      	#接下来的如果只指定了-u参数,因为injection内容多为空,第一层循环会会跳过大段内容。
      	#这些内容与 dbms technique reduceTest 等相关,这些内容会因为循环过程中检测到一定结果,并且由用户输入一些东西之后,被启用
      	
      	if conf.dbms is None:
      		...
      	#开始进行dbms的识别
      	kb.heuristicDbms = heuristicCheckDbms(injection)
      	#如果dbms 未识别 也未指定,则进行boolen-based 简单测试,对dbms进行识别
      	#如果检测出来,会由用户决定是否跳过其他DBMS的tests、是否包含所有关于该数据库的测试,从而大幅减少tests的数量。
      	
      	if stype == PAYLOAD.TECHNIQUE.UNION:
      	#判断是否是union注入,然后根据用户命令行参数指定一些union注入参数。这只是其中一条判定处理,
      	#接下来进行一系列判定和处理
      
      	agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
      	#开始进行生成payload
      	
      	comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
          fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place no
      	for boundary in boundaries:
      	#对boundary 的一些处理,跳过level 不符合的条目,确定clause、where可用,解析boundary 前后缀等一些值
      	#关于这些字段的意义,可以看boundaroes.xml开头的注释
      	#略略略,作者注释写的好清晰。
      	
          if fstPayload:
              boundPayload = agent.prefixQuery(fstPayload, prefix, where, clause)	
      	#拼接payload、prefix、suffix、comment为reePayload
      	
      	for method, check in test.response.items():
      	#开始执行test 请求,判断是否payload注入成功,此处是分技术的 此处method #容易起歧义,与--technique弄混,注意此处对应于test.response中的method,而--technique对应于request中
      	#B: Boolean-based blind SQL injection(布尔型注入)
      	#E: Error-based SQL injection(报错型注入)
      	#U: UNION query SQL injection(可联合查询注入)
      	#T: Time-based blind SQL injection(基于时间延迟注入)
      	
      	#此处对应的是PAYLOAD类 的 Method,而--technique指定的参数对应于PAYLOAD类的SQLINJECTION
      	
      	#保存结果
      	#注入成功,结果写入injection中
      	#对应的host写入kb中
      
      	#跳回conntroller.py
      =============controller.py=============
      
      	#一些无注入参数的提示。
      	#如果有相关参数。将结果写入文件;写入session.sqlite(相关字段在enums.py -> class HASHDB_KEYS);打印一些信息。
      	#如果存在多注入参数,则提示选择
      	#提示注入确认
      	
      	action()
      	#对存在漏洞的参数,进行exploit SQL injection 和一些深入的操作。
      =============action.py=============
      	action()
      	#在识别数据库或指定数据库的基础上
      	#该函数具体执行什么操作需要由用户进行由命令行参数进行制定
      	#只有指定了,被解析进conf中,才会进行
      	
      	
      	基本流程至此基本结束
  4. 源码详读

    1. agent.py (reading @2016-12-18

Refs:

http://www.91ri.org/13785.html

http://blog.csdn.net/wangyi_lin/article/details/8555117

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!