在原有基础上进行了安全加固,或者说必须采用特殊调用方式才行。
特点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 }