因为主要是自己看SQLMap源码有个记录,所以写上来的东西,对我个人来说就是想到什么写什么,比较杂乱,推荐看参考中各位大牛的文章。
==============================================================
- 流程图
- 目录结构
- 流程
- 源码详读
==============================================================
-
流程图
-
目录结构
-
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的相关静态信息。
-
-
流程
-
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中,才会进行 基本流程至此基本结束
-
-
源码详读
- agent.py (reading @2016-12-18
Refs:
http://www.91ri.org/13785.html
http://blog.csdn.net/wangyi_lin/article/details/8555117
来源:oschina
链接:https://my.oschina.net/u/1166442/blog/797053