0%

Sqlmap源码-请求参数的检验和解析(一)

前言

我们平时在使用sqlmap的时候,

一般会直接这样使用:sqlmap -u http://sqlilabs:8888/Less-1/?id=1

1
2
3
[10:18:54] [INFO] testing if GET parameter 'id' is dynamic
[10:18:54] [INFO] confirming that GET parameter 'id' is dynamic
[10:18:54] [INFO] GET parameter 'id' is dynamic

这个时候,sqlmap会自动识别到get请求的有可测试参数id那么,sqlmap是如何解析到这个参数的呢?

重点讲解一下target.py下的解析请求参数函数_setRequestParams()

_setRequestParams()函数

函数说明:

1
2
3
4
"""
Check and set the parameters and perform checks on 'data' option for
HTTP method POST.
"""

对请求的参数进行检验和解析.

这个函数是在sqlmap测试前的目标准备时做的工作.

可参考一下,sqlmap 内核分析 I: 基础流程


流程图:

画图真累人…

由于代码量实在有点多,下面只能挑一些重点的来讲


匹配并解析Post数据:

sqlmap支持这五种数据类型

  • XML

  • JSON

  • JSON_LIKE

  • MULTIPART

  • ARRAY_LIKE

正则匹配:

通过正则匹配这五种类型的数据,它们的正则表达式为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Regular expression for XML POST data
XML_RECOGNITION_REGEX = r"(?s)\A\s*<[^>]+>(.+>)?\s*\Z"

# Regular expression used for detecting JSON POST data
JSON_RECOGNITION_REGEX = r'(?s)\A(\s*\[)*\s*\{.*"[^"]+"\s*:\s*("[^"]*"|\d+|true|false|null).*\}\s*(\]\s*)*\Z'

# Regular expression used for detecting JSON-like POST data
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*'[^']+'\s*:\s*('[^']+'|\d+).*\}\s*(\]\s*)*\Z"

# Regular expression used for detecting multipart POST data
MULTIPART_RECOGNITION_REGEX = r"(?i)Content-Disposition:[^;]+;\s*name="

# Regular expression used for detecting Array-like POST data
ARRAY_LIKE_RECOGNITION_REGEX = r"(\A|%s)(\w+)\[\]=.+%s\2\[\]=" % (DEFAULT_GET_POST_DELIMITER, DEFAULT_GET_POST_DELIMITER)

解析:

以解析json数据为例,

关键是这3个正则表达式,分别解析3种模式的数据

简单理解为:

  • 模式"":""

  • 模式"":数字

  • 模式"":true false null类型

然后调用process()去解析出它的参数名整个参数.

解析到的数据会添加到hintNames列表

举2个实例方便理解.

例子1:json数据

比如现在有一段json数据.

经过解析后:

简单的说就是,经过解析处理后,整段的json数据已经分割开来了,变成了一个个可测试的参数

例子2:MULTIPART数据:

比如现在有一段MULTIPART类型的数据.

经过解析后,也变成了一个可测试的参数.

总结:

sqlmap会尽可能找出你的Post数据中所有可测试参数.


URI注入:

通过正则匹配url是否符合uri注入的模式.

正则表达式:r"//[^/]*/([^\.*?]+)\Z"

符合的情况:

  • http://www.site.com/id82

  • http://www.site.com/article

不符合的情况:

  • http://www.qqq.com

  • http://www.site.com/article.php?id=1

如果符合uri注入的模式,会提示你是否尝试进行uri注入

总结:

我之前简单以为url有参数才存在注入的可能性.

其实,url并非一定要带参数才有可能存在注入的,只要跟数据库交互的地方都有可能存在sqli.

refs:同花顺某站一处URI注入


解析cookie:

解析cookie会调用到paramToDict()这个函数(把参数转换为可测试参数字典),这个函数也是个大函数,就不具体讲了.可能要写一篇文章才会详细讲到.

比较重要的点有,一般会用;符号去分割解析cookie里面的参数.

然后形成可测试参数列表.

sqlmap会尽可能找出你的Post数据中所有可测试参数.cookie里的每个参数都不放过.


解析header:

header中可测试的点可能有:

  • user-agent

  • referer

  • host

  • cookie

比如有一段数据:

解析后的header中可测试的参数为


识别csrf-token:

1
2
# Infixes used for automatic recognition of parameters carrying anti-CSRF tokens
CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf", "token")

尝试在header数据中寻找有无cstf-token标记的字眼,如果有认为无法注入.

1
2
elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I):
testSqlInj = False

refs:【技术分享】使用burp macros和sqlmap绕过csrf防护进行sql注入

然而,一些像CSRF、tokens或者简单的的反自动化技术如在一个表单中包含一个隐藏值就能够阻止自动化工具正确的工作


总结:

  • sqlmap支持5种数据类型的Post数据:XMLJSONJSON_LIKEMULTIPARTARRAY_LIKE

  • sqlmap会尽可能找出你的Post数据中所有可测试参数.

  • url并非一定要带参数才有可能存在注入的,只要跟数据库交互的地方都有可能存在注入,可以考虑uri注入

  • header中可以测试的点为:- user-agentrefererhostcookie