SQL Injection day 1


信息收集
database() / schema()
: 获取当前数据库名mysql> select database(); +------------+ | database() | +------------+ | security | +------------+ 1 row in set (0.04 sec) mysql> select schema(); +----------+ | schema() | +----------+ | security | +----------+ 1 row in set (0.00 sec)
user() / current_user()
: 获取当前执行查询的用户名mysql> select user(); +----------------+ | user() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.01 sec) mysql> select current_user(); +----------------+ | current_user() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.00 sec)
version() / @@version
: 获取SQL服务版本mysql> select version(); +-------------------------+ | version() | +-------------------------+ | 5.5.44-0ubuntu0.14.04.1 | +-------------------------+ 1 row in set (0.00 sec) mysql> select @@version; +-------------------------+ | @@version | +-------------------------+ | 5.5.44-0ubuntu0.14.04.1 | +-------------------------+ 1 row in set (0.00 sec)
@@basedir / @@datadir
: 获取MySQL安装目录 / 获取MySQL数据目录mysql> select @@basedir; +-----------+ | @@basedir | +-----------+ | /usr | +-----------+ 1 row in set (0.00 sec) mysql> select @@datadir; +-----------------+ | @@datadir | +-----------------+ | /var/lib/mysql/ | +-----------------+ 1 row in set (0.00 sec)
@@
用于读取或设置MySQL服务器自身的配置和状态。这些变量控制着数据库的行为,例如版本信息、文件路径、缓存大小等等。
系统变量分为
GLOBAL
(全局级别)和SESSION
(会话级别)。
@variable
用于定义和访问用户自定义的变量,可以使用SET
或SELECT
进行设置。
mysql> SET @my_name = 'may';
Query OK, 0 rows affected (0.01 sec)
mysql> select @my_name;
+----------+
| @my_name |
+----------+
| may |
+----------+
1 row in set (0.00 sec)
mysql> select @my := (select 'may');
+-----------------------+
| @my := (select 'may') |
+-----------------------+
| may |
+-----------------------+
1 row in set (0.00 sec)
mysql> select @my;
+------+
| @my |
+------+
| may |
+------+
1 row in set (0.00 sec)
核心利用函数
1. 字符串操纵函数
LENGTH(str)
: 返回字符串的字节长度。mysql> select length(password) from users where username = 'admin'; +------------------+ | length(password) | +------------------+ | 5 | +------------------+ 1 row in set (0.01 sec)
从攻击者的角度来看,这是盲注的第一步:探测未知数据的长度。例如,猜测数据库名、表名或密码的长度。
SUBSTRING(str, start, length)
: 从字符串str
中,在指定的start
位置开始,提取length
个字符。为了兼容性,MySQL为子字符串函数提供了两个别名:
substr
和mid
;它们本质上指向的是同一个函数。mysql> select SUBSTRING('admin@may.com',1,5); +--------------------------------+ | SUBSTRING('admin@may.com',1,5) | +--------------------------------+ | admin | +--------------------------------+ 1 row in set (0.03 sec) mysql> select SUBSTR('admin@may.com',1,5); +-----------------------------+ | SUBSTR('admin@may.com',1,5) | +-----------------------------+ | admin | +-----------------------------+ 1 row in set (0.00 sec) mysql> select MID('admin@may.com',1,5); +--------------------------+ | MID('admin@may.com',1,5) | +--------------------------+ | admin | +--------------------------+ 1 row in set (0.00 sec)
从攻击者的角度来看,这是逐字符提取数据的核心武器。在确定数据长度后,你可以手动或通过脚本循环——从位置1开始,一次提取一个字符,并与你的猜测进行比较。
ASCII(char) / ORD(char)
: 返回单个字符的ASCII值。mysql> select ASCII('m'); +------------+ | ASCII('m') | +------------+ | 109 | +------------+ 1 row in set (0.03 sec) mysql> select ORD('m'); +----------+ | ORD('m') | +----------+ | 109 | +----------+ 1 row in set (0.01 sec)
ASCII()
与ORD()
并不等价,其区别主要在于对单字节和多字节字符处理时的差异:在处理单字节字符时,它俩是等价的
而在处理中文、日文、emoji等多字节字符时则存在差异
CONCAT(str1, str2, …)
: 将多个字符拼接成一个字符串。mysql> select concat(username,password) from users; +---------------------------+ | concat(username,password) | +---------------------------+ | DumbDumb | | AngelinaI-kill-you | | Dummyp@ssword | | securecrappy | | stupidstupidity | | supermangenious | | batmanmob!le | | adminadmin | | dhakkandumbo | | admin4admin4 | +---------------------------+ 10 rows in set (0.01 sec)
GROUP_CONCAT(column)
: 将多行中指定列的值,连接成一个单一的字符串。mysql> select group_concat(username) from users; +---------------------------------------------------------------------------------------------+ | group_concat(username) | +---------------------------------------------------------------------------------------------+ | Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin,admin1,admin2,admin3,dhakkan,admin4 | +---------------------------------------------------------------------------------------------+ 1 row in set (0.03 sec)
2. 条件逻辑函数
IF(condition, value_if_true, value_if_false)
: 执行一个简单的“如果…那么…否则…”决策。mysql> select id,username,if(id > 5,'vip','regular') from users; +----+----------+----------------------------+ | id | username | if(id > 5,'vip','regular') | +----+----------+----------------------------+ | 1 | Dumb | regular | | 2 | Angelina | regular | | 3 | Dummy | regular | | 4 | secure | regular | | 5 | stupid | regular | | 6 | superman | vip | | 7 | batman | vip | | 8 | admin | vip | | 9 | admin1 | vip | | 10 | admin2 | vip | | 11 | admin3 | vip | | 12 | dhakkan | vip | | 14 | admin4 | vip | +----+----------+----------------------------+ 13 rows in set (0.00 sec)
CASE WHEN … THEN … ELSE … END
: 实现更复杂的多分支条件逻辑,类似于编程语言中的switch-case
或if-elseif-else
。mysql> SELECT -> id,password, -> CASE -> WHEN length(password) > 5 then 'strong-pwd' -> WHEN length(password) < 5 then 'easy-pwd' -> ELSE 'low-pwd' -> END AS strong_check -> FROM users; +----+------------+--------------+ | id | password | strong_check | +----+------------+--------------+ | 1 | Dumb | easy-pwd | | 2 | I-kill-you | strong-pwd | | 3 | p@ssword | strong-pwd | | 4 | crappy | strong-pwd | | 5 | stupidity | strong-pwd | | 6 | genious | strong-pwd | | 7 | mob!le | strong-pwd | | 8 | admin | low-pwd | | 9 | admin1 | strong-pwd | | 10 | admin2 | strong-pwd | | 11 | admin3 | strong-pwd | | 12 | dumbo | low-pwd | | 14 | admin4 | strong-pwd | +----+------------+--------------+ 13 rows in set (0.00 sec)
在这个
CASE
语句的例子中,AS
关键字为由CASE
表达式计算出的结果列,分配了一个别名。
Subscribe to my newsletter
Read articles from may directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
