mita2 database life

主にMySQLに関するメモです

MySQL mysql コマンドからシェルを呼び出せなくする小技

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 を強制する方法は、省略。。。)