Mysql:让 mysqld 服务器可以执行操作系统命令(2,安全加固版——特殊调用版):lib_mysqludf_sys

发布时间 2023-12-13 10:14:03作者: jinzhenshui

在原有基础上进行了安全加固,或者说必须采用特殊调用方式才行。

特点1:删除了所有的可调用函数:

sys_get;
sys_set;
sys_exec;
sys_eval;

特点2:根据sys_eval函数,新增写了一个shell函数:改名了!

网上的大部分攻击采用的sys_exec、sys_eval都没有了

shell;

 

特点3:shell的并不能调用任意的命令(字符串)了

命令名必须匹配 【.*mysql_event_.*】的特征

 

特点4:shell的输出内容,限制为1024行

多了就会被截断!防止内存消耗过度造成mysqld崩溃!

 

特点5:其实不是特点,而是因特点3、4而采取的技巧措施。

防小白、防不住大牛@  我不说,你应该也明白什么意思  :-)

echo ?; cmd

?=; cmd

?=; cmd 2>/dev/null

?=;cmd 2>&1

?=;cmd 1> file 2>file

 

 1 my_bool shell_init(
 2     UDF_INIT *initid
 3 ,    UDF_ARGS *args
 4 ,    char *message
 5 ){
 6     unsigned int i=0;
 7     if(args->arg_count == 1
 8     && args->arg_type[i]==STRING_RESULT){
 9         return 0;
10     } else {
11         strcpy(
12             message
13         ,    "Expected exactly one string type parameter"
14         );
15         return 1;
16     }
17 }
18 
19 void shell_deinit(
20     UDF_INIT *initid
21 ){
22 }
23 
24 char* shell(
25     UDF_INIT *initid
26 ,    UDF_ARGS *args
27 ,    char* result
28 ,    unsigned long* length
29 ,    char *is_null
30 ,    char *error
31 ){
32 
33     FILE *pipe;
34     char line[1024];
35     unsigned long outlen, linelen;
36 
37     result = malloc(1);
38     outlen = 0;
39 
40     if (strstr(args->args[0],"mysql_event_")) {
41         pipe = popen(args->args[0], "r");
42         if (pipe!=NULL){
43             int i=0;
44             while (fgets(line, sizeof(line), pipe) != NULL) {
45                 if(++i <= 1024){
46                     linelen = strlen(line);
47                     result = realloc(result, outlen + linelen);
48                     strncpy(result + outlen, line, linelen);
49                     outlen += linelen;
50                 }else{
51                     char msg[]="warn: beyond output limit: 1024 rows!";
52                     linelen = strlen(msg);
53                     result = realloc(result, outlen + linelen);
54                     strncpy(result + outlen, msg, linelen);
55                     outlen += linelen;
56                     break;
57                 }
58             }
59             pclose(pipe);
60         }else{
61             char msg[]="Warn: no output! This command maybe raise error!";
62             linelen=strlen(msg);
63             result = realloc(result, outlen + linelen);
64             strcat(result,msg);
65             outlen += linelen;
66         }
67     }else {
68         char msg[]="This command is not valid, it's name must match '.*mysql_event_.*'!";
69         linelen = strlen(msg) + 1;
70         result = realloc(result, outlen + linelen);
71         strcpy(result, msg);
72         outlen += linelen;
73     }
74 
75 
76     if (!(*result) || result == NULL) {
77         *is_null = 1;
78     } else {
79         result[outlen] = 0x00;
80         *length = strlen(result);
81     }
82 
83     return result;
84 }