mysql コマンドでは ! や system によって、シェルを呼び出すことができます。
mysql> \! uname Linux mysql> system uname Linux
実装はシンプルで、標準ライブラリの system 関数が利用されています。
static int
com_shell(String *buffer MY_ATTRIBUTE((unused)),
char *line MY_ATTRIBUTE((unused)))
{
char *shell_cmd;
/* Skip space from line begin */
while (my_isspace(charset_info, *line))
line++;
if (!(shell_cmd = strchr(line, ' ')))
{
put_info("Usage: \\! shell-command", INFO_ERROR);
return -1;
}
/*
The output of the shell command does not
get directed to the pager or the outfile
*/
if (system(shell_cmd) == -1)
{
put_info(strerror(errno), INFO_ERROR, errno);
return -1;
}
return 0;
}
system を使えなくする
LD_PRELOAD を使って、標準ライブラリの system 関数を差し替えてしまいましょう。
ダミーの system 関数を作ります。
#include <stdlib.h>
#include <stdio.h>
int system(const char *command) {
fprintf(stderr, "system command is prohibited\n");
return 0;
}
$ gcc -g -Wall -fPIC -shared -o nosystem.so nosystem.c
$ LD_PRELOAD=$PWD/nosystem.so mysql mysql> \! uname system command is prohibited mysql> system uname system command is prohibited
使えなくなりました。めでたしめでたし(LD_PRELOAD を強制する方法は、省略。。。)