Bug 1119540 (CVE-2018-1160)

Summary: VUL-0: CVE-2018-1160: netatalk: Unauthenticated remote code execution in Netatalk
Product: [Novell Products] SUSE Security Incidents Reporter: David Disseldorp <ddiss>
Component: IncidentsAssignee: Security Team bot <security-team>
Status: RESOLVED FIXED QA Contact: Security Team bot <security-team>
Severity: Critical    
Priority: P3 - Medium CC: ddiss, karol, meissner, pgajdos, rfrohl, samba-maintainers, security-team
Version: unspecified   
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard: CVSSv3:SUSE:CVE-2018-1160:9.8:(AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) maint:released:sle10-sp3:64196
Found By: Other Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description David Disseldorp 2018-12-14 14:07:50 UTC
This bug is tracked via https://bugzilla.samba.org/show_bug.cgi?id=13711

AFAICT we ship Netatalk via the SLES12 SDK and openSUSE.

Release is planned for Thursday 20th of December 2018.


Original mail from Jacob Baines <jbaines@tenable.com>

Hey Ralph,

From my point of view it is pretty serious. I'm able to achieve unauthenticated
remote code execution on the latest version of Netatalk (and older versions as
well but I haven't tracked it all the way back yet). As far as the CVE dance
goes, Tenable (my employer) is a CNA so I can assign the CVE and provide MITRE
the appropriate data. Let me describe the bug first though.

As I'm sure you know, one of the first unauthenticated requests sent to
Netatalk's afpd is the OPEN SESSION request which is handled by
dsi_opensess.c. The bug lies is the following for loop (lines 30-42):

  /* parse options */
  while (i < dsi->cmdlen) {
    switch (dsi->commands[i++]) {
    case DSIOPT_ATTNQUANT:
      memcpy(&dsi->attn_quantum, dsi->commands + i + 1, dsi->commands[i]);
      dsi->attn_quantum = ntohl(dsi->attn_quantum);

    case DSIOPT_SERVQUANT: /* just ignore these */
    default:
      i += dsi->commands[i] + 1; /* forward past length tag + length */
      break;
    }
  }
  
In particular, the memcpy trusts dsi->commands[i] to specify a size that fits
into dsi->attn_quantum. However, when we look up the sizeof attn_quantum in
dsi.h we find that its only a 32-bit int (four bytes). A malicious client can
send a dsi->command[i] larger than 4 bytes to begin overwriting variables in the
dsi struct.

Now obviously, dsi->command[i] is a single char in a char array which limits the
amount of data the attacker can overwrite in the dsi struct to 0xff. So for this
to be useful in an attack there needs to be something within the 0xff bytes that
follow attn_quantum. From dsi.h:

    uint32_t attn_quantum, datasize, server_quantum;
    uint16_t serverID, clientID;
    uint8_t  *commands; /* DSI recieve buffer */
    uint8_t  data[DSI_DATASIZ];    /* DSI reply buffer */

Of particular interest to me is the commands pointer. This is a heap allocated
pointer that is reused for every packet received (and sent?). Using the memcpy,
an attacker can overwrite this point with the address of their choice and then
all subsequent AFP packets will be written to that location. This is more or
less all an attacker needs to achieve remote code execution (write
whatever/wherever).

I generally like to prove RCE if I'm able to. So my question was, what could I
do to take over execution flow? The simple answer is to write into the
preauth_switch and then use the protocol to invoke the function of my choice. I
have a Seagate NAS that uses Netatalk's afp implementation. I'm able to
read/write/delete files off of the NAS via Netatalk's afpd without
authentication using this technique.

However, there is some good news. I cannot successfully exploit this
vulnerability using Ubuntu's netatalk package. The reason being that they've
compiled netatalk's afpd with -fPIE. Since I don't know any addresses ahead of
time (due to ASLR) I can't easily exploit afpd as a remote attacker. Although
there is a chance that someone who is actually good at exploit development could
get around that (or maybe find a pointer leak somewhere).

So to summarize, Netatalk's afpd is vulnerable to unauthenticated remote code
execution due to a bad memcpy in dsi_opensess.c. The vulnerability allows an
attacker to write whatever wherever. I have a very rough RCE PoC written against
a Seagate NAS that uses Netatalk's afpd if that is useful (I can also provide
pcaps). But perhaps the following is enough. Below is a python script that will
overwrite the server_quantum field with 0xdeadbeef. As you probably know, the
server responds to the client's open session request with the server_quantum so
you'll be to see that we actually overwrote the server_quantum value by looking
at the server response (look via wireshark or whatever - the script itself
doesn't parse the response).

import socket
import sys

def print_usage():
    print "Usage: python " + sys.argv[0] + " <ip> <port>"
    sys.exit(0)

if len(sys.argv) != 3:
    print_usage()

ip = sys.argv[1]
try:
    port = int(sys.argv[2])
except:
    print "Invalid port number."
    print_usage()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "[+] Attempting connection to " + ip + ":" + sys.argv[2]
sock.connect((ip, port))
print "[+] Connected!"

data = '\x00\x04\x00\x01\x00\x00\x00\x00'
data += '\x00\x00\x00\x12\x00\x00\x00\x00'
data += '\x01' # attnquant in open sess
data += '\x10' # attnquant size
data += '\xaa\xbb\xcc\xdd' # overwrites attn_quantum (on purpose)
data += '\x00\x00\x00\x00' # overwrites datasize
data += '\xef\xbe\xad\xde' # overwrites server_quantum
data += '\xfa\xce\xfe\xed' # overwrites the server id and client id

sock.sendall(data)

try:
    resp = sock.recv(1024)
    print "Response: '" + resp + "'"
except:
    print "[-] Oh no! We didn't receive a response."

As far as a patch goes, I initially assumed the memcpy was intended to have a
sizeof(dsi->attn_quantum). However, I'm less sure now. The memcpy *implies* that
4 bytes are expected but perhaps that is the mistake? As the protocol isn't well
documented, maybe only 1 byte can be specified? In which case the memcpy is
inappropriate. You would know better than I. At most this feels like a 3 line
change to me though.

Finally, I need to inform you that my employer, Tenable, follows a 90-day
vulnerability disclosure policy. That means, even though we prefer coordinated
disclosure, we'll issue an advisory on January 28th with or without a patch. You
can read the full details of our policy here:
https://static.tenable.com/research/tenable-vulnerability-disclosure-policy.pdf
Also, as I said, I can easily assign a CVE and contact MITRE if needed. I'm
unsure how you coordinate fixes/releases with downstream consumers though.

Thank you for taking the time to read this. If this isn't remotely clear or
whatever then I'm more than happy to flesh out the details We'd greatly
appreciate it if you'd acknowledge receipt of this report. If you have any
questions we'd be happy to address them.
Comment 1 Petr Gajdos 2018-12-17 09:45:09 UTC
Just run the daemon:
$ /usr/sbin/netatalk
or
$ rcnetatalk start

test.py: see comment 0

$ python test.py localhost 548 | hexdump -C | grep 'ad be'
00000050  0c 00 00 00 00 00 04 de  ad be ef 02 04 00 00 00  |................|
$
Comment 2 Petr Gajdos 2018-12-17 10:33:29 UTC
Similar symptom for 42.3, 12 and 11sp2. 10sp2 has the same version as 11sp2.
Comment 3 Petr Gajdos 2018-12-17 11:09:45 UTC
The code snippets specified in comment 0 are also everywhere.
Comment 4 Petr Gajdos 2018-12-17 11:25:38 UTC
All 42.3,12,11sp2,10sp2/netatalk are built with -fpie flag. It is in 42.3,12 specified in CLFAGS inside spec file, by patch in 11sp2,10sp2; welcome to review build process.
Comment 5 Petr Gajdos 2018-12-18 10:23:06 UTC
Is there a fix available?
Comment 6 David Disseldorp 2018-12-18 10:33:17 UTC
Created attachment 792933 [details]
Embargoed patch for master
Comment 7 David Disseldorp 2018-12-18 10:33:47 UTC
Created attachment 792934 [details]
Embargoed patch for 3.1
Comment 8 David Disseldorp 2018-12-18 10:35:37 UTC
(In reply to Petr Gajdos from comment #5)
> Is there a fix available?

I've attached the patches here. If you'd like access to the upstream bug, create a bugzilla.samba.org account with a SUSE address and I'll add you to the cc list.
Comment 9 Petr Gajdos 2018-12-18 13:59:55 UTC
AFTER

$ python test.py localhost 548 | hexdump -C  | grep 'ad be'
$

In the log (set e. g. log file = /var/log/afp.log in /etc/netatalk/afp.conf):
Dec 18 13:11:39.560800 afpd[27282] {dsi_opensess.c:49} (error:DSI): option 1 bad length: 1

Differences for 11sp2:
- start netatalk with rcatalk start
- log can not be set (--without-logfile), the log is written to syslog
Comment 10 Marcus Meissner 2018-12-18 14:04:17 UTC
CRD: 2018-12-20


Please submit
Comment 11 Petr Gajdos 2018-12-18 14:09:00 UTC
(In reply to David Disseldorp from comment #8)
> (In reply to Petr Gajdos from comment #5)
> > Is there a fix available?
> 
> I've attached the patches here. If you'd like access to the upstream bug,
> create a bugzilla.samba.org account with a SUSE address and I'll add you to
> the cc list.

Thanks David. I maintain many packages, so I try to keep subscriptions low as possible. Let us see whether this bug will be an exception, or whether horde of netatalk security bugs crops up.

I will just have two simple questions, if you can help:
1. Is there a CVE assigned already, if yes, could you please add it here?
2. From my former comments, it seems that 2.0 is affected too. Is there any information that would confirm/disprove this assumption?
Comment 12 Petr Gajdos 2018-12-18 14:15:56 UTC
(In reply to Marcus Meissner from comment #10)
> CRD: 2018-12-20
> 
> 
> Please submit

You certainly see that I am working on it. It appears I am perhaps actually finished. I have two questions:
A. See question 1 from comment 11: Is a CVE assigned to this issue?
B. How to set up IBS/OBS project correctly? Packages will be submitted to and submitted from IBS/home:pgajdos:maintenance:netatalk and OBS/home:pgajdos:maintenance:netatalk respectively.
Comment 13 David Disseldorp 2018-12-18 14:30:41 UTC
(In reply to Petr Gajdos from comment #11)
...
> Thanks David. I maintain many packages, so I try to keep subscriptions low
> as possible. Let us see whether this bug will be an exception, or whether
> horde of netatalk security bugs crops up.

Understood.

> I will just have two simple questions, if you can help:
> 1. Is there a CVE assigned already, if yes, could you please add it here?

Yes, CVE-2018-1160.

> 2. From my former comments, it seems that 2.0 is affected too. Is there any
> information that would confirm/disprove this assumption?

The CVE Advisory (I'll attach) mentions "Versions:    Any version Netatalk 2 and newer".
Comment 14 David Disseldorp 2018-12-18 14:33:13 UTC
Created attachment 792950 [details]
proposed CVE Advisory text
Comment 15 Petr Gajdos 2018-12-18 14:34:49 UTC
Thanks David!
Comment 16 Petr Gajdos 2018-12-18 14:37:27 UTC
Marcus: am I right that I can check in patches into IBS without any special setting to IBS/home:pgajdos:maintenance:netatalk and I cannot submit to OBS/ome:pgajdos:maintenance:netatalk anyhow before CRD?
Comment 17 Petr Gajdos 2018-12-18 14:59:29 UTC
I gathered the info from Vita. Packages submitted now against: 12, 11sp2 and 10sp3.

TODO: 42.3 on Thursday
Comment 18 Petr Gajdos 2018-12-18 15:02:05 UTC
(In reply to David Disseldorp from comment #13)
> The CVE Advisory (I'll attach) mentions "Versions:    Any version Netatalk 2
> and newer".

David: Last question to be sure: upstream had not provided patch for 2.x, correct?
Comment 19 Marcus Meissner 2018-12-18 15:07:48 UTC
IBS - no special settings neeed, just regular maintenance branch.

OBS - please do not yet checkin there
Comment 20 David Disseldorp 2018-12-18 15:17:51 UTC
(In reply to Petr Gajdos from comment #18)
> (In reply to David Disseldorp from comment #13)
> > The CVE Advisory (I'll attach) mentions "Versions:    Any version Netatalk 2
> > and newer".
> 
> David: Last question to be sure: upstream had not provided patch for 2.x,
> correct?

Correct. If you'd like to ask for one, I'd recommend asking Ralph in the upstream ticket or via mail.
Comment 22 Petr Gajdos 2018-12-18 20:34:26 UTC
David,

I had requested the account. It seems it is not automated process, so let's see when I get the access.

Anyway, thank you for the proxy.
Comment 24 Swamp Workflow Management 2018-12-19 12:46:49 UTC
An update workflow for this issue was started.
This issue was rated as critical.
Please submit fixed packages until 2018-12-21.
When done, reassign the bug to security-team@suse.de.
https://swamp.suse.de/webswamp/wf/64195
Comment 25 Petr Gajdos 2018-12-20 13:32:12 UTC
Upstream provided the patch for 2.x, unfortunately this is much closer to code in 3.x than to 2.0.3 we maintain, as far as I can see.

Package 42.3/netatalk submitted.

I believe all fixed.
Comment 26 Swamp Workflow Management 2018-12-20 13:50:06 UTC
This is an autogenerated message for OBS integration:
This bug (1119540) was mentioned in
https://build.opensuse.org/request/show/660288 42.3 / netatalk
Comment 28 Robert Frohl 2018-12-20 15:21:50 UTC
upstream bug is public:
https://bugzilla.samba.org/show_bug.cgi?id=13711
Comment 31 Swamp Workflow Management 2018-12-21 11:11:23 UTC
SUSE-SU-2018:4214-1: An update that fixes one vulnerability is now available.

Category: security (important)
Bug References: 1119540
CVE References: CVE-2018-1160
Sources used:
SUSE Linux Enterprise Software Development Kit 11-SP4 (src):    netatalk-2.0.3-249.23.3.1
SUSE Linux Enterprise Debuginfo 11-SP4 (src):    netatalk-2.0.3-249.23.3.1
Comment 32 Swamp Workflow Management 2018-12-21 17:09:24 UTC
SUSE-SU-2018:4217-1: An update that fixes one vulnerability is now available.

Category: security (important)
Bug References: 1119540
CVE References: CVE-2018-1160
Sources used:
SUSE Linux Enterprise Workstation Extension 12-SP4 (src):    netatalk-3.1.0-3.3.1
SUSE Linux Enterprise Workstation Extension 12-SP3 (src):    netatalk-3.1.0-3.3.1
SUSE Linux Enterprise Software Development Kit 12-SP4 (src):    netatalk-3.1.0-3.3.1
SUSE Linux Enterprise Software Development Kit 12-SP3 (src):    netatalk-3.1.0-3.3.1
SUSE Linux Enterprise Desktop 12-SP4 (src):    netatalk-3.1.0-3.3.1
SUSE Linux Enterprise Desktop 12-SP3 (src):    netatalk-3.1.0-3.3.1
Comment 33 Swamp Workflow Management 2018-12-28 20:15:13 UTC
openSUSE-SU-2018:4287-1: An update that fixes one vulnerability is now available.

Category: security (important)
Bug References: 1119540
CVE References: CVE-2018-1160
Sources used:
openSUSE Leap 42.3 (src):    netatalk-3.1.7-8.3.1
Comment 34 Marcus Meissner 2019-01-07 13:53:48 UTC
done