# 14|自动化注入神器(一):sqlmap的设计思路解析 你好,我是王昊天。 从古至今,人们为了方便自己的生活,发明出各种各样的工具。就拿扫地来说,这是我小时候最讨厌的家务活动,因为扫地时扬起的灰尘会让我十分难受,而且有的死角很难被打扫干净。扫地机器人的出现给我们带来了极大的便利,我们只要拥有它,就不需要再亲自扫地了。 在前几节课中,我们学习了SQL注入的原理和方法,相信你已经小试牛刀了。不知道你在做注入测试的时候是否会觉得困难呢?反正我学的时候是遇到了不少困难,比如,绕过技巧多种多样,我们几乎不可能全部记住它们,就算记住了我们一一去尝试也需要很多的时间,费时又伤神。 就像我们刚才说过的,当问题出现时,我们常常会创造出一种工具,来解决对应的问题。那么有没有一款工具,能帮我们自动去进行注入测试呢?答案是肯定的,这个工具就是sqlmap。 这节课呢,我们正式开启sqlmap学习之旅,深入探究这款自动化注入神器的实现原理。**首先我们要对一些知识有所了解,包括如何获取软件的代码,如何搭建软件的运行环境,以及软件文件功能等。接下来,我们会对sqlmap的工作流程做一个整体的介绍,这会为我们后续学习sqlmap打好基础。** ## sqlmap ![图片](https://static001.geekbang.org/resource/image/34/9a/347a42c49613eea753d176b53396ba9a.png?wh=1895x662) 我们先来看看到底什么是sqlmap。 sqlmap是一个帮助我们自动检测sql注入是否存在的测试工具,它会使用不同注入方法进行测试,并将测试结果展示给我们,供我们利用。这些方法都是我们之前学过的内容,包括联合注入、时延注入、布尔盲注、报错注入和堆查询注入。如果你感兴趣,可以去上节课寻找更加详细的介绍。 因为它的持续更新和维护,所以大家普遍认为它既方便又好用,从图片中我们可以看到超过4k的fork数量,以及高频的源码更新。就像一枚硬币的两面,这种优势也会伴随一些问题,比如给我们阅读源代码增加了难度,而我们要想真正去理解、掌握这款工具,就必须要迎难而上,对它的源代码进行剖析。 ![图片](https://static001.geekbang.org/resource/image/2e/ca/2e17e69bf2856256754fc409ab2ebaca.png?wh=1751x480) **代码获取** 我们用如下命令将sqlmap的源代码克隆下来。 ```bash git clone https://github.com/sqlmapproject/sqlmap cd sqlmap ``` 因为该过程需要访问外网,所以克隆的速度会较为缓慢,当然我们可以借助一些代理工具来加速这个过程。 这里我们分析的sqlmap版本是最新的版本1.6,它于2022年初发布,相比于上一代1.5.12版本,只是修复了几个编码异常,并且替换版本信息,并没有什么重大的改动。因此学习两个大版本的代码都是可以的。 ![图片](https://static001.geekbang.org/resource/image/35/80/35e9758f3c123549d2a25488c9224580.png?wh=1296x363)![图片](https://static001.geekbang.org/resource/image/65/e6/65ff8f7d9aca2ac1b79afbf44548fbe6.png?wh=1243x347) 在获取到源代码之后,我们还需要配置软件的运行环境,这样sqlmap才能顺利的运行。下面让我们进入到环境搭建这一步骤。 **环境搭建** 这节课,我们采用的分析环境是python3.10.1,可以利用下面的命令新建一个虚拟的解释环境,这样做有利于运行环境的隔离,防止其他环境因素干扰sqlmap的执行过程。 ```bash python3 -m venv venv ``` **配置文件** 在做完环境搭建之后,sqlmap已经具有运行能力了。但是我们还需要知道哪个文件才是它的配置文件,即哪个文件会对它的运行产生影响。所以呢,接下来我们就来看看,sqlmap中有哪些重要的文件,它们又有哪些功能。 首先我们一起看下sqlmap的配置文件`sqlmap.conf`: ```python # At least one of these options has to be specified to set the source to # get target URLs from. [Target] # Target URL. # Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2 url = # Direct connection to the database. # Examples: # mysql://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME # oracle://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_SID direct = # Parse targets from Burp or WebScarab logs # Valid: Burp proxy (http://portswigger.net/suite/) requests log file path # or WebScarab proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project) # 'conversations/' folder path logFile = # Scan multiple targets enlisted in a given textual file bulkFile = # Load HTTP request from a file # Example (file content): POST /login.jsp HTTP/1.1\nHost: example.com\nUser-Agent: Mozilla/4.0\n\nuserid=joe&password=guessme requestFile = # At least one of these options has to be specified to set the source to # get target URLs from. [Target] # Target URL. # Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2 url = # Direct connection to the database. # Examples: # mysql://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME # oracle://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_SID direct = # Parse targets from Burp or WebScarab logs # Valid: Burp proxy (http://portswigger.net/suite/) requests log file path # or WebScarab proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project) # 'conversations/' folder path logFile = # Scan multiple targets enlisted in a given textual file bulkFile = # Load HTTP request from a file # Example (file content): POST /login.jsp HTTP/1.1\nHost: example.com\nUser-Agent: Mozilla/4.0\n\nuserid=joe&password=guessme requestFile = ...... # Force back-end DBMS operating system to provided value. If this option is # set, the back-end DBMS identification process will be minimized as # needed. # If not set, sqlmap will detect back-end DBMS operating system # automatically by default. # Valid: linux, windows os = ...... ``` 由于配置文件很长,所以这里没有全部展示出来。我们需要知道的是,**配置文件的参数配置可以对sqlmap程序运行的流程产生影响**。举个例子,在配置文件中可以设置OS配置项,sqlmap就无需探测操作系统的类型了,这样就可以帮助我们在一些特定情况下优化sqlmap的执行速度。 看完配置文件之后,我们回忆一下之前学过的内容,在做SQL注入时,都需要经历哪些步骤呢? 我们知道,一般来说SQL注入攻击可以分为三步,首先是寻找注入点,之后要选择闭合参数的位置,最后要根据需求选择合适的payload,来实现我们的注入攻击操作。 sqlmap和手动SQL注入的思想是相似的,程序可以直接从请求的参数中获取到注入点位置的信息,而闭合参数的位置和payload的选择则会因为它们的多样性变得略微复杂,下面就让我们一起来看看与之相关的两个配置文件。 我们先来看sqlmap中闭合参数的配置内容,这里举个例子帮助你来理解什么是闭合参数。以一个典型的SQL注入语句为例: ```python SELECT id FROM users WHERE name = '$name'; ``` 想要对其进行注入,就需要将name参数闭合,这在前两节课中有过较深入的探讨。 对于sqlmap而言,data.xml.boundaries.xml就是用于闭合参数的配置文件,通过该文件我们可以确定闭合元素的字符和位置等等信息,了解该文件有助于我们理解sqlmap真正发送的测试payload的格式,关于payload格式这部分的内容我们会在下一讲具体的讲解。 ```plain