Advertisement
Fare9

Rootkits Arsenal C shellcode improvement

Jun 22nd, 2019
479
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.97 KB | None | 0 0
  1. #include <Windows.h>
  2.  
  3. #pragma section(".code", execute,read,write)
  4. /*
  5. *   If we Merge text section on this one, we will have
  6. *   a lot of Visual Studio code inside of this part of
  7. *   the code, something not good for a shellcode, so
  8. *   just merge data that we want to save.
  9. */
  10. //#pragma comment(linker,"/MERGE:.text=.code")
  11. #pragma comment(linker,"/MERGE:.data=.code")
  12. // Section permissions
  13. #pragma comment(linker,"/SECTION:.code,ERW")
  14. // .code section starts here
  15. #pragma code_seg(push, ".code")
  16.  
  17. #define VAR_DWORD(name) __asm _emit 0x04 __asm _emit 0x04 \
  18.                         __asm _emit 0x04 __asm _emit 0x04
  19.  
  20. #define STR_DEF_04(name, a1, a2, a3, a4) __asm _emit a1 __asm _emit a2 \
  21.                                          __asm _emit a3 __asm _emit a4
  22.  
  23. #define SZ_FORMAT_STR   4
  24. #define SZ_LIB_NAME     16
  25.  
  26.  
  27.  
  28. typedef int(*printfPtr)(const char * restrict, ...);
  29. typedef HMODULE (*LoadLibraryAPtr)(LPCSTR lpLibFileName);
  30. typedef FARPROC (*GetProcAddressPtr)(HMODULE hModule,LPCSTR lpProcName);
  31.  
  32. #pragma pack(1)
  33. typedef struct _USER_MODE_ADDRESS_RESOLUTION
  34. {
  35.     unsigned char LoadLibraryA[SZ_LIB_NAME];
  36.     unsigned char GetProcAddress[SZ_LIB_NAME];
  37. } USER_MODE_ADDRESS_RESOLUTION;
  38. #pragma pack(0)
  39.  
  40.  
  41. #pragma pack(1)
  42. typedef struct _ADDRESS_TABLE
  43. {
  44.     // address resolution
  45.     USER_MODE_ADDRESS_RESOLUTION routines;
  46.  
  47.     // application specific
  48.     unsigned char MSVCR90dll[SZ_LIB_NAME];
  49.     unsigned char printfName[SZ_LIB_NAME];
  50.     printfPtr printf; // printf ptr
  51.     unsigned char formatStr[SZ_FORMAT_STR];
  52.     unsigned long globalInteger;
  53.  
  54. } ADDRESS_TABLE;
  55. #pragma pack()
  56.  
  57.  
  58. unsigned long get_kernel32_base();
  59. unsigned long address_table_storage();
  60. int compare(char *p1, char *p2);
  61. BOOL walk_export_list(unsigned long dll_base, DWORD *function_ptr, char *func_name);
  62.  
  63.  
  64. /*
  65. *   We set main function as the first one, so we will have
  66. *   code section starts by main function, we can create
  67. *   the virtual memory, and jump to the offset 0 of that
  68. *   allocated memory to run the shellcode
  69. */
  70.  
  71. void main()
  72. {
  73.     LoadLibraryAPtr loadlibraryA;
  74.     GetProcAddressPtr getprocaddress;
  75.     HMODULE msvcr90_dll_handle;
  76.  
  77.     unsigned long kernel32base = get_kernel32_base();
  78.  
  79.     ADDRESS_TABLE *address_table = (ADDRESS_TABLE*)address_table_storage();
  80.        
  81.     if (!walk_export_list(kernel32base, &loadlibraryA, address_table->routines.LoadLibraryA))
  82.         return;
  83.  
  84.     msvcr90_dll_handle = loadlibraryA(address_table->MSVCR90dll);
  85.  
  86.     if (!walk_export_list(kernel32base, &getprocaddress, address_table->routines.GetProcAddress))
  87.         return;
  88.  
  89.     address_table->printf = (printfPtr)getprocaddress(msvcr90_dll_handle, address_table->printfName);
  90.  
  91.     if (address_table->printf == NULL)
  92.         return;
  93. }
  94.  
  95.  
  96. unsigned long get_kernel32_base()
  97. {
  98.     unsigned long kernel32_address;
  99.     _asm
  100.     {
  101.         xor ebx, ebx; // ebx = 0
  102.         mov ebx, fs:[0x30]; // get PEB from TEB
  103.         mov ebx, [ebx + 0x0C]; // get LDR from PEB
  104.         mov ebx, [ebx + 0x14]; // get InMemoryOrderModuleList from LDR struct
  105.         mov ebx, [ebx]; // flink (point to ntdll ModuleList)
  106.         mov ebx, [ebx]; // flink (point to kernel32 ModuleList)
  107.         mov ebx, [ebx + 0x10];  // point to dll base (InMemoryOrderList + 0x10 = DllBase)
  108.         mov kernel32_address, ebx;
  109.     }
  110.  
  111.     return (kernel32_address);
  112. }
  113.  
  114.  
  115. unsigned long address_table_storage()
  116. {
  117.     unsigned int table_address;
  118.     __asm
  119.     {
  120.         call end_of_data; // save pointer to data on stack
  121.  
  122.         STR_DEF_04(LoadLibraryA, 'L', 'o', 'a', 'd');
  123.         STR_DEF_04(LoadLibraryA, 'L', 'i', 'b', 'r');
  124.         STR_DEF_04(LoadLibraryA, 'a', 'r', 'y', 'A');
  125.         STR_DEF_04(LoadLibraryA, '\0', '\0', '\0', '\0');
  126.  
  127.         STR_DEF_04(GetProcAddress, 'G', 'e', 't', 'P');
  128.         STR_DEF_04(GetProcAddress, 'r', 'o', 'c', 'A');
  129.         STR_DEF_04(GetProcAddress, 'd', 'd', 'r', 'e');
  130.         STR_DEF_04(GetProcAddress, 's', 's', '\0', '\0');
  131.  
  132.         STR_DEF_04(MSVCR90dll, 'c', 'r', 't', 'd');
  133.         STR_DEF_04(MSVCR90dll, 'l', 'l', '.', 'd');
  134.         STR_DEF_04(MSVCR90dll, 'l', 'l', '\0', '\0');
  135.         STR_DEF_04(MSVCR90dll, '\0', '\0', '\0', '\0');
  136.  
  137.         STR_DEF_04(printfName, 'p', 'r', 'i', 'n');
  138.         STR_DEF_04(printfName, 't', 'f', '\0', '\0');
  139.         STR_DEF_04(printfName, '\0', '\0', '\0', '\0');
  140.         STR_DEF_04(printfName, '\0', '\0', '\0', '\0');
  141.  
  142.         VAR_DWORD(printf);
  143.  
  144.         STR_DEF_04(formatStr, '%', 'X', '\n', '\0');
  145.  
  146.         VAR_DWORD(globalInteger);
  147.  
  148.     end_of_data:
  149.  
  150.         pop eax;
  151.         mov table_address, eax;
  152.     }
  153.  
  154.     return (table_address);
  155. }
  156.  
  157.  
  158. int compare(char *p1, char *p2)
  159. {
  160.     register const unsigned char *s1 = (const unsigned char *)p1;
  161.     register const unsigned char *s2 = (const unsigned char *)p2;
  162.     unsigned char c1, c2;
  163.  
  164.     do
  165.     {
  166.         c1 = (unsigned char)*s1++;
  167.         c2 = (unsigned char)*s2++;
  168.         if (c1 == 0)
  169.             return c1 - c2;
  170.     } while (c1 == c2);
  171.  
  172.     return c1 - c2;
  173.  
  174. }
  175.  
  176.  
  177. BOOL walk_export_list(unsigned long dll_base, DWORD *function_ptr, char *func_name)
  178. {
  179.     IMAGE_DOS_HEADER* image_dos_header = (IMAGE_DOS_HEADER*)dll_base;
  180.     IMAGE_NT_HEADERS* image_nt_headers = (IMAGE_NT_HEADERS*)(dll_base + image_dos_header->e_lfanew);
  181.     IMAGE_DATA_DIRECTORY* image_data_directory = &(image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
  182.  
  183.     DWORD descriptor_start_rva = image_data_directory->VirtualAddress;
  184.  
  185.     IMAGE_EXPORT_DIRECTORY* export_directory = (PIMAGE_EXPORT_DIRECTORY)(dll_base + descriptor_start_rva);
  186.  
  187.     char *dll_name = (char*)(dll_base + export_directory->Name);
  188.     DWORD* address_of_names = (DWORD*)(dll_base + export_directory->AddressOfNames);
  189.     DWORD* address_of_functions = (DWORD*)(dll_base + export_directory->AddressOfFunctions);
  190.     WORD* address_of_ordinals = (WORD*)(dll_base + export_directory->AddressOfNameOrdinals);
  191.  
  192.     SIZE_T index, j;
  193.  
  194.     for (index = 0; index < export_directory->NumberOfNames; index++)
  195.     {
  196.         char* name;
  197.         DWORD name_rva;
  198.         WORD ordinal;
  199.  
  200.         name_rva = address_of_names[index];
  201.  
  202.         if (name_rva == 0)
  203.             continue;
  204.  
  205.         name = (char *)(dll_base + name_rva);
  206.  
  207.         if (compare(name, func_name) == 0)
  208.         {
  209.             ordinal = address_of_ordinals[index];
  210.             (*function_ptr) = (dll_base + address_of_functions[ordinal]);
  211.             return TRUE;
  212.         }
  213.  
  214.     }
  215.  
  216.     return FALSE;
  217. }
  218.  
  219. // .code section finish here
  220. #pragma code_seg(pop)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement