SQL(2)
一.时间盲注
有回显时用Union带出数据,只显示是否时可用布尔盲注得出数据,那如果没有任何输出时?
比如无论查询什么,都显示success,同一个回应,无法直接从服务器注入出任何数据,但是我们可以利用MySQL内置的延时函数sleep,人为的制造出差异
为了测试sql执行的延时,需要使用BP这款软件,输入username='or sleep(1)#
(注:or前面的为false时才会执行后面的)
运用到注入时可以使用if函数来进行条件判断,当if第一个参数为真时进行延时,输入username='or if(1=1,sleep(1),1)#
第一个条件为真时,延时
(注:if里含3个函数,第一个参数为真时,返回第二个参数,为假时,返回第三个参数)
例:username='or if(substr(password,1,1),sleep(1),1)#
sleep为一种延时函数,有5种函数
五种:sleep(),benchmark(t,exp),笛卡尔积,GET_LOCK() RLIKE正则
以下是对这几个 MySQL 特性的详解:
[111]、SLEEP()函数
1. 作用:
- 使 MySQL 服务器暂停执行指定的时间(以秒为单位)。
2. 语法:
- SLEEP(duration) ,其中 duration 是要暂停的时间长度,为整数。
3. 示例:
- SELECT SLEEP(5); :这条 SQL 语句会使数据库暂停执行 5 秒钟后再返回结果。
[222]、BENCHMARK()函数
1. 作用:
- 重复执行表达式一定次数,可用于测试性能,但不是真正意义上的延时函数。它可以用来衡量特定表达式的执行时间,但会消耗大量的系统资源。
2. 语法:
- BENCHMARK(count, expression) ,其中 count 是重复执行的次数, expression 是要执行的表达式。
3. 示例:
- SELECT BENCHMARK(1000000,NOW()); :这里会执行 NOW() 函数 1000000 次。可以通过比较执行前后的时间来了解函数的性能消耗。
[333]、笛卡尔积
1. 作用:
- 笛卡尔积是两个或多个表之间的一种组合结果集的方式,它会将一个表中的每一行与另一个表中的每一行进行组合,生成所有可能的组合结果。
2. 语法:
- 当使用多个表进行查询而没有指定连接条件时,就会产生笛卡尔积。例如, SELECT * FROM table1, table2; 。
3. 示例:
- 假设有两个表 table1 和 table2 ,分别有 3 行和 4 行数据。如果进行笛卡尔积操作,结果集将有 3 * 4 = 12 行数据。
- 笛卡尔积通常不是期望的结果,在实际查询中应该使用适当的连接条件来避免产生不必要的笛卡尔积,以提高查询性能和结果的准确性。
[444]、GET_LOCK()函数
1. 作用:
- 用于获取一个命名的锁,以实现同步机制,防止多个并发连接同时执行特定的代码块。
2. 语法:
- GET_LOCK(str,timeout) ,其中 str 是锁的名称, timeout 是等待获取锁的超时时间(以秒为单位)。如果在超时时间内无法获取锁,函数将返回 0;如果成功获取锁,返回 1。
3. 示例:
- SELECT GET_LOCK('my_lock',10); :尝试获取名为 my_lock 的锁,等待时间为 10 秒。如果成功获取锁,可以在后续的代码中执行需要同步的操作,完成后使用 RELEASE_LOCK() 函数释放锁。
[555]、RLIKE 正则表达式匹配
1. 作用:
- RLIKE (或 REGEXP )用于在 MySQL 中进行正则表达式匹配,以判断一个字符串是否与指定的正则表达式模式相匹配。
2. 语法:
- column_name RLIKE regex_pattern ,其中 column_name 是要进行匹配的列名, regex_pattern 是正则表达式模式。
3. 示例:
- SELECT * FROM my_table WHERE column_name RLIKE '^[a-z]+$'; :这条 SQL 语句将从 my_table 表中选择所有 column_name 列的值为纯小写字母组成的字符串的行。
- 正则表达式可以用于各种复杂的字符串匹配场景,例如匹配特定格式的电话号码、邮箱地址等。但在使用正则表达式时,需要注意性能问题,特别是对于大型数据集,复杂的正则表达式可能会导致查询性能下降。
二.报错注入
在某些情况下,服务器会返回SQL执行错误信息,我们可以利用这个错误信息进行有回显的注入,比如服务器不会返回查询结果,但如果发生SQL执行错误,会将错误输出
有很多可以使MySQL报错的函数
以ExtractValue举例
ExtractValue是一个使用xpath从xml中提取元素的函数,原型为ExtractValue(xml_data, xpath_expression)。其中,xml_data 是包含 XML 内容的列或表达式,xpath_expression 是用于指定要提取节点的 XPath 表达式。
例如,如果有一个存储 XML 数据的列 xml_col,要提取其中某个特定节点的值,可以使用如下语句:SELECT ExtractValue(xml_col, '/root/node_name');
正常的用法
select extractvalue('〈a〉〈b〉text〈/b〉〈/a〉','/a/b')
如果xpath参数有语法错误,整个参数就会被回显在错误信息中
select extractvalue('〈a〉〈b〉bbbb〈/b〉〈/a〉','~text')
我们可以利用一特性,将需要回显的信息插入到xpath参数中,在最前面插入一个'~',波浪号,使其发生语法错误,可以实现Union直接回显一样的效果,
12种报错函数
1. extractvalue() :可用于从 XML 文档中提取特定节点的值。通过构造恶意输入,可以使其产生错误信息并返回部分数据库内容。
- 示例: SELECT extractvalue(NULL,concat(0x3a,(SELECT database())));
2. updatexml() :用于更新 XML 文档中的特定节点。同样可以被利用进行报错注入。
- 示例: SELECT updatexml(NULL,concat(0x3a,(SELECT user())),NULL);
3. floor() :与随机数生成函数结合,可通过产生错误来暴露信息。
- 例如: SELECT FLOOR(RAND(0)*2)+(SELECT IF((SELECT COUNT(*) FROM information_schema.tables)>0,1,0));
4. exp() :指数函数,可用于报错注入场景。
- 示例: SELECT exp((SELECT (CASE WHEN (SELECT COUNT(*) FROM information_schema.tables)>0 THEN 1 ELSE 0 END)));
5. geometrycollection() :在特定情况下可被利用进行报错注入。
- 例如: SELECT ST_GeometryFromText('GEOMETRYCOLLECTION('||(SELECT (CASE WHEN (1=1) THEN 'POINT(1 1)' ELSE NULL END))||')');
6. polygon() :与几何相关的函数,可用于报错注入。
- 示例: SELECT ST_PolygonFromText('POLYGON((0 0,0 1,1 1,1 0,0 0),(0.5 0.5,0.5 0.6,0.6 0.6,0.6 0.5,0.5 0.5))')||(SELECT (CASE WHEN (1=1) THEN 'POINT(1 1)' ELSE NULL END));
7. multipoint() :多点几何函数,可能被用于报错注入。
- 例如: SELECT ST_MultiPointFromText('MULTIPOINT((0 0),(1 1))')||(SELECT (CASE WHEN (1=1) THEN 'POINT(1 1)' ELSE NULL END));
8. linestring() :线串几何函数,可用于报错注入。
- 示例: SELECT ST_LineFromText('LINESTRING(0 0,1 1)')||(SELECT (CASE WHEN (1=1) THEN 'POINT(1 1)' ELSE NULL END));
9. name_const() :可用于构造报错注入语句。
- 例如: SELECT * FROM users WHERE id=(SELECT name_const((SELECT user()),1)) OR 1=1;
10. cast() :类型转换函数,可在报错注入中发挥作用。
- 示例: SELECT CAST((SELECT user()) AS SIGNED);
11. concat() :字符串连接函数,常用于构造报错注入的输入。
- 例如: SELECT CONCAT('Error: ', (SELECT database()));
12. substring() :子字符串提取函数,可用于报错注入以获取特定部分的信息。
- 示例: SELECT SUBSTRING((SELECT user()),1,5);
三.注入点
根据用户插入数据的位置不同,可以有不同的SQL注入点,比较常见的有where,比如查询判断用户名之类的,还有一种是order by,会让用户选择以哪一列目标进行排序,在order by和where后会有一点区别,Union只能用在HAVING和order by之间,limit也是一样的作用
INSERT注入(insert)
UPDATE注入(update)
DELETE注入(delete)
一、ORDER BY 子句
如果应用程序允许用户指定排序字段,例如 SELECT * FROM table ORDER BY column_name ,攻击者可以通过修改 column_name 的值来进行 SQL 注入。例如,输入 column_name;(SELECT * FROM sensitive_table)-- ,可能会导致数据库执行恶意查询并返回敏感信息。
二、LIMIT 子句
在分页查询中,LIMIT 子句用于限制返回的记录数。如果应用程序允许用户指定 LIMIT 的参数,攻击者可以通过修改这些参数来进行 SQL 注入。例如, SELECT * FROM table LIMIT offset, count ,攻击者可以将 offset 或 count 的值修改为恶意的 SQL 表达式,如 offset;(SELECT * FROM sensitive_table)-- 。
三、INSERT 语句
如果应用程序允许用户输入数据并将其插入到数据库中,例如 INSERT INTO table (column1, column2) VALUES (value1, value2) ,攻击者可以通过修改 value1 和 value2 的值来进行 SQL 注入。例如,输入 value1'; DROP TABLE other_table;-- 可能会删除其他表。
四、UPDATE 语句
当应用程序允许用户更新数据库中的数据时,例如 UPDATE table SET column1 = value1 WHERE condition ,攻击者可以通过修改 value1 的值或者 condition 的值来进行 SQL 注入。例如,将 value1 设置为 '; DROP TABLE another_table;-- 可能会删除另一个表。