logo资料库

SQLMap源代码分析.docx

第1页 / 共22页
第2页 / 共22页
第3页 / 共22页
第4页 / 共22页
第5页 / 共22页
第6页 / 共22页
第7页 / 共22页
第8页 / 共22页
资料共22页,剩余部分请下载后查看
SQLMAP源码分析Part1:流程篇
0x00 概述
0x01 流程图
0x02 调试方法
0x03 流程
3.1 初始化
3.2 start
3.2.1 checkWaf
3.2.2 heuristicCheckSqlInjection
3.2.3 checkSqlInjection
3.2.4 Payload生成条件
3.2.5 Action
3.2.6 HashDB
0x04 结束
SQLMAP 源码分析 Part1:流程篇 0x00 概述 1.drops 之前的文档 SQLMAP 进阶使用介绍过 SQLMAP 的高级使用方法, 网上也有几篇介绍过 SQLMAP 源码的文章曾是土木人,都写的非常好, 建议大家都看一下。 2.我准备分几篇文章详细的介绍下 SQLMAP 的源码,让想了解的朋友 们熟悉一下 SQLMAP 的原理和一些手工注入的语句,今天先开始第一 篇:流程篇。 3.之前最好了解 SQMAP 各个选项的意思,可以参考 sqlmap 用户手册 和 SQLMAP 目录 doc/README.pdf 4.内容中如有错误或者没有写清楚的地方,欢迎指正交流。有部分内 容是参考上面介绍的几篇文章的,在此一并说明,感谢他们。 0x01 流程图
0x02 调试方法 1.我用的 IDE 是 PyCharm。 2.在菜单栏 Run->Edit Configurations。点击左侧的“+”,选择 Python,Script 中选择 sqlmap.py 的路径,Script parameters 中填 入注入时的命令,如下图。
3.打开 sqlmap.py,开始函数是 main 函数,在 main 函数处下断点。 4.右键 Debug 'sqlmap',然后程序就自动跳到我们下断点的 main() 函数处,后面可以继续添加断点进行调试。如下图,左边红色的代表 跳转到下一个断点处,上面红色的表示跳到下一句代码处 5.另外,如果要在代码中加中文注释,需要在开始处添加以下语句: #coding:utf-8。
0x03 流程 3.1 初始化 我这里用的版本是:1.0-dev-nongit-20150614 miin()函数开始 73 行: 1 2 paths.SQLMAP_ROOT_PATH = modulePath() setPaths() 进入 common.py 中的 setPaths()函数后,就可以看到这个函数是定义 SQLMAP 路 径和文件的,类似于: 1 2 3 4 5 paths.SQLMAP_EXTRAS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "extra") paths.SQLMAP_PROCS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "procs") paths.SQLMAP_SHELL_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "shell") paths.SQLMAP_TAMPER_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "tamper") paths.SQLMAP_WAF_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "waf") 接下来的 78 行函数 initOptions(cmdLineOptions),包含了三个函数,作用如流 程图所示,设置 conf,KB,参数. conf 会保存用户输入的一些参数,比如 url, 端口 kb 会保存注入时的一些参数,其中有两个是比较特殊的 kb.chars.start 和 kb.chars.stop,这两个是随机字符串,后面会有介绍。 1 2 3 _setConfAttributes() _setKnowledgeBaseAttributes() _mergeOptions(inputOptions, overrideOptions) 3.2 start 102 行的 start 函数,算是检测开始的地方.start()函数位于 controller.py 中。 1 2 3 4 5 if conf.direct: initTargetEnv() setupTargetEnv() action() return True
首先这四句,意思是,如果你使用-d 选项,那么 sqlmap 就会直接进入 action() 函数,连接数据库,语句类似为: 1 2 3 4 5 6 python sqlmap.py -d "mysql://admin:admin@192.168.21.17:3306/testdb" -f --banner --dbs --user #!python if conf.url and not any((conf.forms, conf.crawlDepth)): kb.targets.add((conf.url, conf.method, conf.data, conf.cookie, None)) 上面代码会把 url,methos,data,cookie 加入到 kb.targets,这些参数就是我们 输入的 接下来从 274 行的 for 循环中,可以进入检测环节 1 for targetUrl, targetMethod, targetData, targetCookie, targetHeaders in kb.targets: 此循环先初始化一些一些变量,然后判断之前是否注入过,如果没有注入过, testSqlInj=True,否则 testSqlInj=false。后面会进行判断是否检测过。 1 def setupTargetEnv():
2 3 4 5 6 7 _createTargetDirs() _setRequestParams() _setHashDB() _resumeHashDBValues() _setResultsFile() _setAuthCred() 372 行 setupTargetEnv()函数中包含了 5 个函数,这些函数作用是 1.创建输出结果目录 2.解析请求参数 3.设置 session 信息,就是 session.sqlite。 4.恢复 session 的数据,继续扫描。 5.存储扫描结果。 6.添加认证信息 其中比较重要的就是 session.sqlite,这个文件在 sqlmap 的输出目录中,测试 的结果都会保存在这个文件里。 3.2.1 checkWaf identifyWaf() checkWaf() if conf.identifyWaf: 1 2 3 377 行 checkWaf()是检测是否有 WAF,检测方法是 NMAP 的 http-waf-detect.nse, 比如页面为 index.php?id=1,那现在添加一个随机变量 index.php?id=1&aaa=2, 设置 paoyload 类似为 AND 1=1 UNION ALL SELECT 1,2,3,table_name FROM information_schema.tables WHERE 2>1-- ../../../etc/passwd,如果 没有 WAF,页面不会变化,如果有 WAF,因为 payload 中有很多敏感字符,大多 数时候页面都会发生改变。 接下来的 conf.identifyWaf 代表 sqlmap 的参数--identify-waf,如果指定了此参数, 就会进入 identifyWaf()函数,主要检测的 waf 都在 sqlmap 的 waf 目录下。
当然检测的方法都比较简单,都是查看返回的数据库包种是否包含了某些特征字 符。如: _product__ = "360 Web Application Firewall (360)" def detect(get_page): retval = False for vector in WAF_ATTACK_VECTORS: page, headers, code = get_page(get=vector) retval = re.search(r"wangzhan\.360\.cn", headers.get("X-Powered-By-360wzb", ""), re.I) is not None if retval: break return retval if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \ and (kb.injection.place is None or kb.injection.parameter is None): 回到 start 函数,385 行会判断是否注入过,如果还没有测试过参数是否可以注 入,则进入 if 语句中。如果之前测试过,则不会进入此语句。
分享到:
收藏