Exploit-DB #39569
Description: OpenSSH 7.2p1 - (Authenticated) xauth Command Injection
Type: remote
Platform: multiple
Date: 2016-03-16
Author: tintinweb

Exploit:
'''
Author:     <github.com/tintinweb>
Ref:        https://github.com/tintinweb/pub/tree/master/pocs/cve-2016-3115
Version:    0.2
Date:       Mar 3rd, 2016

Tag:        openssh xauth command injection may lead to forced-command and /bin/false bypass

Overview
--------

Name:           openssh
Vendor:         OpenBSD
References:     * http://www.openssh.com/[1]

Version:        7.2p1 [2]
Latest Version: 7.2p1
Other Versions: <= 7.2p1 (all versions; dating back ~20 years)
Platform(s):    linux
Technology:     c

Vuln Classes:   CWE-93 - Improper Neutralization of CRLF Sequences ('CRLF Injection')
Origin:         remote
Min. Privs.:    post auth

CVE:            CVE-2016-3115



Description
---------

quote website [1]

> OpenSSH is the premier connectivity tool for remote login with the SSH protocol. It encrypts all traffic to eliminate eavesdropping, connection hijacking, and other attacks. In addition, OpenSSH provides a large suite of secure tunneling capabilities, several authentication methods, and sophisticated configuration options.
Summary
-------

An authenticated user may inject arbitrary xauth commands by sending an
x11 channel request that includes a newline character in the x11 cookie.
The newline acts as a command separator to the xauth binary. This attack requires
the server to have 'X11Forwarding yes' enabled. Disabling it, mitigates this vector.

By injecting xauth commands one gains limited* read/write arbitrary files,
information leakage or xauth-connect capabilities. These capabilities can be
leveraged by an authenticated restricted user - e.g. one with the login shell
configured as /bin/false or one with configured forced-commands - to bypass
account restriction. This is generally not expected.

The injected xauth commands are performed with the effective permissions of the
logged in user as the sshd already dropped its privileges.

Quick-Info:

* requires: X11Forwarding yes
* bypasses /bin/false and forced-commands
** OpenSSH does not treat /bin/false like /bin/nologin (in contrast to Dropbear)
* does not bypass /bin/nologin (as there is special treatment for this)

Capabilities (xauth):

* Xauth
	* write file: limited chars, xauthdb format
	* read file: limit lines cut at first \s
	* infoleak: environment
	* connect to other devices (may allow port probing)


PoC see ref github.
Patch see ref github.


Details
-------

// see annotated code below

    * server_input_channel_req (serverloop.c)
     *- session_input_channel_req:2299 (session.c [2])
      *- session_x11_req:2181

    * do_exec_pty or do_exec_no_pty
     *- do_child
      *- do_rc_files (session.c:1335 [2])

Upon receiving an `x11-req` type channel request sshd parses the channel request
parameters `auth_proto` and `auth_data` from the client ssh packet where
`auth_proto` contains the x11 authentication method used (e.g. `MIT-MAGIC-COOKIE-1`)
and `auth_data` contains the actual x11 auth cookie. This information is stored
in a session specific datastore. When calling `execute` on that session, sshd will
call `do_rc_files` which tries to figure out if this is an x11 call by evaluating
if `auth_proto` and `auth_data` (and `display`) are set. If that is the case AND
there is no system `/sshrc` existent on the server AND it no user-specific `$HOME/.ssh/rc`
is set, then `do_rc_files` will run `xauth -q -` and pass commands via `stdin`.
Note that `auth_data` nor `auth_proto` was sanitized or validated, it just contains
user-tainted data. Since `xauth` commands are passed via `stdin` and `\n` is a
command-separator to the `xauth` binary, this allows a client to inject arbitrary
`xauth` commands.

Sidenote #1: in case sshd takes the `$HOME/.ssh/rc` branch, it will pass the tainted
input as arguments to that script.
Sidenote #2: client code also seems to not sanitize `auth_data`, `auth_proto`. [3]

This is an excerpt of the `man xauth` [4] to outline the capabilities of this xauth
command injection:

	SYNOPSIS
       	xauth [ -f authfile ] [ -vqibn ] [ command arg ... ]

		add displayname protocolname hexkey
		generate displayname protocolname [trusted|untrusted] [timeout seconds] [group group-id] [data hexdata]
		[n]extract filename displayname...
		[n]list [displayname...]
		[n]merge [filename...]
		remove displayname...
		source filename
		info
		exit
		quit
		version
		help
		?
		
Interesting commands are:
	
	info	 - leaks environment information / path
			~# xauth info
			xauth:  file /root/.Xauthority does not exist
			Authority file:       /root/.Xauthority
			File new:             yes
			File locked:          no
			Number of entries:    0
			Changes honored:      yes
			Changes made:         no
			Current input:        (argv):1
	
	source	 - arbitrary file read (cut on first `\s`)
			# xauth source /etc/shadow
			xauth:  file /root/.Xauthority does not exist
			xauth: /etc/shadow:1:  unknown command "smithj:Ep6mckrOLChF.:10063:0:99999:7:::"
						
	extract  - arbitrary file write
			 * limited characters
	         * in xauth.db format
	         * since it is not compressed it can be combined with `xauth add` to
	           first store data in the database and then export it to an arbitrary
	           location e.g. to plant a shell or do other things.
	
	generate - connect to <ip>:<port> (port probing, connect back and pot. exploit
			   vulnerabilities in X.org
	
	
Source
------

Inline annotations are prefixed with `//#!`


/*
 * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
 * first in this order).
 */
static void
do_rc_files(Session *s, const char *shell)
{
...
		snprintf(cmd, sizeof cmd, "%s -q -",				
		    options.xauth_location);
		f = popen(cmd, "w");							//#! run xauth -q -
		if (f) {
			fprintf(f, "remove %s\n",					//#! remove <user_tainted_data> - injecting \n auth_display injects xauth command
			    s->a