GET /api/techniques/?page=3
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 157,
    "next": "https://search.unprotect.it/api/techniques/?page=4",
    "previous": "https://search.unprotect.it/api/techniques/?page=2",
    "results": [
        {
            "name": "TLS Callback",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "Most debuggers start at the program entry point as defined by the PE header. A TLS callback can be used to execute code before the entry point and therefore run secretly in a debugger.\r\n\r\nThis technique can be used to detect that the process is being debugged and thus terminate the process instead to continue execution.",
            "resources": "https://resources.infosecinstitute.com/debugging-tls-callbacks/#gref\r\nhttps://isc.sans.edu/diary/How+Malware+Defends+Itself+Using+TLS+Callback+Functions/6655",
            "tags": "tls callback",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/69/",
                    "description": "",
                    "plain_code": "#include \"windows.h\"\r\n#include <stdio.h>\r\n\r\nvoid NTAPI __stdcall TLSCallbacks(PVOID DllHandle, DWORD dwReason, PVOID Reserved);\r\n\r\n#ifdef _M_IX86\r\n#pragma comment (linker, \"/INCLUDE:__tls_used\")\r\n#pragma comment (linker, \"/INCLUDE:__tls_callback\")\r\n#else\r\n#pragma comment (linker, \"/INCLUDE:_tls_used\")\r\n#pragma comment (linker, \"/INCLUDE:_tls_callback\")\r\n#endif\r\nEXTERN_C\r\n#ifdef _M_X64\r\n#pragma const_seg (\".CRT$XLB\")\r\nconst\r\n#else\r\n#pragma data_seg (\".CRT$XLB\")\r\n#endif\r\n\r\nPIMAGE_TLS_CALLBACK _tls_callback = TLSCallbacks;\r\n#pragma data_seg ()\r\n#pragma const_seg ()\r\n\r\nvoid NTAPI __stdcall TLSCallbacks(PVOID DllHandle, DWORD dwReason, PVOID Reserved)\r\n{\r\n\tMessageBox(nullptr, \"TLS Callback\", \"\", 0);\r\n\tExitProcess(0);\r\n}\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n\tprintf(\"Main function!\");\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/1/",
                    "name": "detect_tlscallback",
                    "rule": "rule detect_tlscallback {\r\n    meta:\r\n        description = \"Simple rule to detect tls callback as anti-debug.\"\r\n        author = \"Thomas Roccia | @fr0gger_\"\r\n    strings:\r\n        $str1 = \"TLS_CALLBACK\" nocase\r\n        $str2 = \"TLScallback\" nocase\r\n    condition:\r\n        uint32(uint32(0x3C)) == 0x4550 and any of them\r\n}"
                }
            ]
        },
        {
            "name": "Detecting Running Process: EnumProcess API",
            "category": [
                "https://search.unprotect.it/api/categories/3/",
                "https://search.unprotect.it/api/categories/6/",
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "The EnumProcess function can be used to search for a specific process (e.g: ollydbg.exe...).",
            "resources": "https://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/3/",
                    "technique": "https://search.unprotect.it/api/techniques/68/",
                    "description": "",
                    "plain_code": "//source: https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-processes\r\n#include <windows.h>\r\n#include <stdio.h>\r\n#include <tchar.h>\r\n#include <psapi.h>\r\n\r\n// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS\r\n// and compile with -DPSAPI_VERSION=1\r\n\r\nvoid PrintProcessNameAndID( DWORD processID )\r\n{\r\n    TCHAR szProcessName[MAX_PATH] = TEXT(\"<unknown>\");\r\n\r\n    // Get a handle to the process.\r\n\r\n    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |\r\n                                   PROCESS_VM_READ,\r\n                                   FALSE, processID );\r\n\r\n    // Get the process name.\r\n\r\n    if (NULL != hProcess )\r\n    {\r\n        HMODULE hMod;\r\n        DWORD cbNeeded;\r\n\r\n        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), \r\n             &cbNeeded) )\r\n        {\r\n            GetModuleBaseName( hProcess, hMod, szProcessName, \r\n                               sizeof(szProcessName)/sizeof(TCHAR) );\r\n        }\r\n    }\r\n\r\n    // Print the process name and identifier.\r\n\r\n    _tprintf( TEXT(\"%s  (PID: %u)\\n\"), szProcessName, processID );\r\n\r\n    // Release the handle to the process.\r\n\r\n    CloseHandle( hProcess );\r\n}\r\n\r\nint main( void )\r\n{\r\n    // Get the list of process identifiers.\r\n\r\n    DWORD aProcesses[1024], cbNeeded, cProcesses;\r\n    unsigned int i;\r\n\r\n    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )\r\n    {\r\n        return 1;\r\n    }\r\n\r\n\r\n    // Calculate how many process identifiers were returned.\r\n\r\n    cProcesses = cbNeeded / sizeof(DWORD);\r\n\r\n    // Print the name and process identifier for each process.\r\n\r\n    for ( i = 0; i < cProcesses; i++ )\r\n    {\r\n        if( aProcesses[i] != 0 )\r\n        {\r\n            PrintProcessNameAndID( aProcesses[i] );\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}"
                }
            ],
            "detection_rules": []
        },
        {
            "name": "Detecting Window with FindWindow API",
            "category": [
                "https://search.unprotect.it/api/categories/3/",
                "https://search.unprotect.it/api/categories/6/"
            ],
            "description": "The [FindWindowA](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa) / [FindWindowW](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindoww) function can be used to search for windows by name or class.\r\n\r\nIt is also possible to use [EnumWindows](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows) API in conjunction with [GetWindowTextLength](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextlengthw) and [GetWindowText](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextw) to locate a piece of string that could reveal the presence of a known debugger.\r\n\r\n### Some Known Debuggers\r\n\r\n* ImmunityDebugger\r\n* OllyDbg\r\n* IDA\r\n* x64dbg / x32dbg\r\n* WinDbg",
            "resources": "https://securingtomorrow.mcafee.com/mcafee-labs/overview-malware-self-defense-protection/",
            "tags": "WinAPI, FindWindow",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/3/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/67/",
                    "description": "Feel free to edit both `fw_debuggers` and `contains_in_title` to extend the search of known debuggers.",
                    "plain_code": "import ctypes\r\nimport os\r\n\r\nfrom ctypes.wintypes import BOOL, HWND, LPARAM,\\\r\n                            LPWSTR, INT, MAX_PATH,\\\r\n                            LPDWORD, DWORD, HANDLE,\\\r\n                            HMODULE\r\n\r\n\r\ndef found(description, hwnd):\r\n    \"\"\"\r\n    When a Window handle is found it will output to console several information about spotted process.\r\n    :param description: Description of found object.\r\n    :param hwnd: Handle of found object.\r\n    \"\"\"\r\n    lpdwProcessId = ctypes.c_ulong()\r\n\r\n    output = \"-\" * 60 + \"\\r\\n\"\r\n    output += description + \"\\r\\n\"\r\n    output += \"-\" * 60 + \"\\r\\n\"\r\n\r\n    output += f\"Handle: {hwnd}\\r\\n\"\r\n\r\n    _GetWindowThreadProcessId(hwnd, ctypes.byref(lpdwProcessId))\r\n\r\n    if (lpdwProcessId is not None) and (lpdwProcessId.value > 0):\r\n        PROCESS_QUERY_INFORMATION = 0x0400\r\n        PROCESS_VM_READ = 0x0010\r\n\r\n        procHandle = ctypes.windll.kernel32.OpenProcess(\r\n            PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,\r\n            False,\r\n            lpdwProcessId.value\r\n        )\r\n\r\n        if procHandle > 0:\r\n            output += f\"Process Id: {lpdwProcessId.value}\\r\\n\"\r\n\r\n            lpFilename = ctypes.create_unicode_buffer(MAX_PATH)\r\n\r\n            if _GetModuleFileNameEx(procHandle, 0, lpFilename, MAX_PATH) > 0:\r\n                path, process_name = os.path.split(lpFilename.value)\r\n\r\n                output += f\"Process Name: {process_name}\\r\\n\"\r\n                output += f\"Image Path: {path}\\r\\n\"\r\n\r\n            ctypes.windll.kernel32.CloseHandle(procHandle)\r\n\r\n    output += \"-\" * 60 + \"\\r\\n\\r\\n\"\r\n\r\n    print(output)\r\n\r\n\r\ndef enum_window_proc(hwnd, lparam):\r\n    \"\"\"\r\n    EnumWindows API CallBack\r\n    :param hwnd: Current Window Handle\r\n    :param lparam: Not used in our case\r\n    :return: Always True in our case\r\n    \"\"\"\r\n    if hwnd > 0:\r\n        nMaxCount = ctypes.windll.user32.GetWindowTextLengthW(hwnd)+1\r\n\r\n        if nMaxCount > 0:\r\n            lpWindowName = ctypes.create_unicode_buffer(nMaxCount)\r\n\r\n            if _GetWindowText(hwnd, lpWindowName, nMaxCount) > 0:\r\n                for description, in_title in contains_in_title:\r\n                    if in_title in lpWindowName.value:\r\n                        found(description, hwnd)\r\n\r\n    return True\r\n\r\n\r\nif __name__ == '__main__':\r\n    '''\r\n        Description | Window Class Name (lpClassName) | Window Title (lpWindowName)\r\n    '''\r\n    fw_debuggers = [\r\n        (\"OllyDbg\", \"OLLYDBG\", None),\r\n        (\"x64dbg (x64)\", None, \"x64dbg\"),\r\n        (\"x32dbg (x32)\", None, \"x32dbg\"),\r\n        # ......... #\r\n    ]\r\n\r\n    '''\r\n        Description | Text contained in debugger title.\r\n    '''\r\n    contains_in_title = [\r\n        (\"Immunity Debugger\", \"Immunity Debugger\"),\r\n        # ......... #\r\n    ]\r\n\r\n    # Define GetWindowThreadProcessId API\r\n    _GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId\r\n\r\n    _GetWindowThreadProcessId.argtypes = HWND, LPDWORD\r\n    _GetWindowThreadProcessId.restype = DWORD\r\n\r\n    # Define GetModuleFileNameEx API\r\n    _GetModuleFileNameEx = ctypes.windll.psapi.GetModuleFileNameExW\r\n    _GetModuleFileNameEx.argtypes = HANDLE, HMODULE, LPWSTR, DWORD\r\n    _GetModuleFileNameEx.restype = DWORD\r\n\r\n    '''\r\n        Search for Debuggers using the FindWindowW API with ClassName /+ WindowName\r\n    '''\r\n    for description, lpClassName, lpWindowName in fw_debuggers:\r\n        handle = ctypes.windll.user32.FindWindowW(lpClassName, lpWindowName)\r\n\r\n        if handle > 0:\r\n            found(description, handle)\r\n\r\n    '''\r\n        Search for Debuggers using EnumWindows API.\r\n        We first list all Windows titles then search for a debugger title pattern.\r\n        This is useful against debuggers or tools without specific title / classname. \r\n    '''\r\n\r\n    # Define EnumWindows API\r\n    lpEnumFunc = ctypes.WINFUNCTYPE(\r\n        BOOL,\r\n        HWND,\r\n        LPARAM\r\n    )\r\n\r\n    _EnumWindows = ctypes.windll.user32.EnumWindows\r\n\r\n    _EnumWindows.argtypes = [\r\n        lpEnumFunc,\r\n        LPARAM\r\n    ]\r\n\r\n    # Define GetWindowTextW API\r\n    _GetWindowText = ctypes.windll.user32.GetWindowTextW\r\n\r\n    _GetWindowText.argtypes = HWND, LPWSTR, INT\r\n    _GetWindowText.restype = INT\r\n\r\n    # Enumerate Windows through Windows API\r\n    _EnumWindows(lpEnumFunc(enum_window_proc), 0)"
                },
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/1/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/67/",
                    "description": "You can build this snippet as a classic Delphi Console Application and add your own signatures for detecting debuggers and related tools.",
                    "plain_code": "program FindWindowAPI;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\nuses\r\n  System.SysUtils, WinAPI.Windows, Generics.Collections, psAPI;\r\n\r\n{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n  TFindWindowSignature Class\r\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}\r\n\r\ntype\r\n  TFindWindowSignature = class\r\n  private\r\n    FDescription : String;\r\n    FClassName   : String;\r\n    FWindowName  : String;\r\n  public\r\n    {@C}\r\n    constructor Create(ADescription, AClassName, AWindowName : String);\r\n\r\n    {@G}\r\n    property Description : String read FDescription;\r\n    property ClassName   : String read FClassName;\r\n    property WindowName  : String read FWindowName;\r\n  end;\r\n\r\n{-------------------------------------------------------------------------------\r\n  ___constructor\r\n-------------------------------------------------------------------------------}\r\nconstructor TFindWindowSignature.Create(ADescription, AClassName, AWindowName : String);\r\nbegin\r\n  FDescription := ADescription;\r\n  FClassName   := AClassName;\r\n  FWindowName  := AWindowName;\r\nend;\r\n\r\n{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n  Main\r\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}\r\n\r\nvar LFindWindowSignatures  : TObjectList<TFindWindowSignature>;\r\n    LEnumWindowsSignatures : TDictionary<String, String>;\r\n\r\n{-------------------------------------------------------------------------------\r\n  When a Window handle is found it will output to console several information\r\n  about spotted process.\r\n-------------------------------------------------------------------------------}\r\nprocedure Found(ADescription : String; AHandle : THandle);\r\nconst CRLF = #13#10;\r\n\r\nvar AStdout_TXT    : String;\r\n    AProcessId     : Cardinal;\r\n    AProcessHandle : THandle;\r\n    ARet           : DWORD;\r\n    pImagePath     : PWideChar;\r\nbegin\r\n  try\r\n      AStdout_TXT := AStdout_TXT + StringOfChar('-', 60) + CRLF;\r\n      AStdout_TXT := AStdout_TXT + ADescription + CRLF;\r\n      AStdout_TXT := AStdout_TXT + StringOfChar('-', 60) + CRLF;\r\n\r\n      AStdout_TXT := AStdout_TXT + Format('Handle: %d%s', [AHandle, CRLF]);\r\n\r\n      GetWindowThreadProcessId(AHandle, @AProcessId);\r\n\r\n      if (AProcessId > 0) then begin\r\n        AProcessHandle := OpenProcess(\r\n                                        (PROCESS_QUERY_INFORMATION or PROCESS_VM_READ),\r\n                                        False,\r\n                                        AProcessId\r\n        );\r\n\r\n        if (AProcessHandle > 0) then begin\r\n          AStdout_TXT := AStdout_TXT + Format('Process Id: %d%s', [AProcessId, CRLF]);\r\n\r\n          pImagePath := nil;\r\n          try\r\n              GetMem(pImagePath, (MAX_PATH * 2));\r\n              ARet := GetModuleFileNameExW(AProcessHandle, 0, pImagePath, (MAX_PATH * 2));\r\n              if (ARet > 0) then begin\r\n                AStdout_TXT := AStdout_TXT + Format('Process Name: %s%s', [ExtractFileName(String(pImagePath)), CRLF]);\r\n                AStdout_TXT := AStdout_TXT + Format('Image Path: %s%s', [ExtractFilePath(String(pImagePath)), CRLF]);\r\n              end;\r\n          finally\r\n            if Assigned(pImagePath) and (ARet > 0) then\r\n              FreeMem(pImagePath, ARet);\r\n          end;\r\n        end;\r\n      end;\r\n\r\n      AStdout_TXT := AStdout_TXT + StringOfChar('-', 60) + CRLF + CRLF;\r\n\r\n      ///\r\n  finally\r\n    WriteLn(AStdout_TXT);\r\n  end;\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n  Find Debuggers by Window Name or Class Name using FindWindow API\r\n-------------------------------------------------------------------------------}\r\nfunction Locate_FindWindow() : Boolean;\r\nvar AFindWindowSignature : TFindWindowSignature;\r\n    i                    : Integer;\r\n    pClassName           : Pointer;\r\n    pWindowName          : Pointer;\r\n    AHandle              : THandle;\r\nbegin\r\n  result := False;\r\n  ///\r\n\r\n  for i := 0 to LFindWindowSignatures.Count -1 do begin\r\n    AFindWindowSignature := LFindWindowSignatures.Items[i];\r\n    if NOT Assigned(AFindWindowSignature) then\r\n      continue;\r\n    ///\r\n\r\n    pClassName  := nil;\r\n    pWindowName := nil;\r\n\r\n    if NOT AFindWindowSignature.ClassName.isEmpty then\r\n      pClassName := PWideChar(AFindWindowSignature.ClassName);\r\n\r\n    if NOT AFindWindowSignature.WIndowName.isEmpty then\r\n      pWindowName := PWideChar(AFindWindowSignature.WindowName);\r\n\r\n    AHandle := FindWindowW(pClassName, pWindowName);\r\n    if (AHandle > 0) then begin\r\n      Found(AFindWindowSignature.Description, AHandle);\r\n\r\n      ///\r\n      result := True;\r\n    end;\r\n  end;\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n  Find Debuggers by Window Name (via Window Name Pattern) using EnumWindows API\r\n-------------------------------------------------------------------------------}\r\nfunction EnumWindowProc(AHandle : THandle; AParam : LPARAM) : BOOL; stdcall;\r\nvar AMaxCount   : Integer;\r\n    AWindowName : String;\r\n    AOldLen     : Cardinal;\r\n    APattern    : String;\r\n    AKey        : String;\r\nbegin\r\n  result := True;\r\n  ///\r\n\r\n  if (AHandle = 0) then\r\n    Exit();\r\n  ///\r\n\r\n  AMaxCount := GetWindowTextLength(AHandle) + 1;\r\n  if (AMaxCount = 0) then\r\n    Exit();\r\n\r\n  SetLength(AWindowName, AMaxCount); // Other technique instead of using GetMem / FreeMem a new Pointer.\r\n  try\r\n      if (GetWindowTextW(AHandle, PWideChar(AWindowName), AMaxCount) = 0) then\r\n        Exit();\r\n      ///\r\n\r\n      AOldLen := Length(AWindowName);\r\n\r\n      for AKey {Description} in LEnumWindowsSignatures.keys do begin\r\n        if NOT LEnumWindowsSignatures.TryGetValue(AKey, APattern) then\r\n          continue;\r\n\r\n        AWindowName := StringReplace(AWindowName, APattern, '', []);\r\n\r\n        if (Length(AWindowName) <> AOldLen) then begin\r\n          Found(AKey, AHandle);\r\n\r\n          break;\r\n        end;\r\n      end;\r\n  finally\r\n    SetLength(AWindowName, 0);\r\n  end;\r\nend;\r\n\r\nfunction Locate_EnumWindows() : Boolean;\r\nbegin\r\n  EnumWindows(@EnumWindowProc, 0);\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n  Append FindWindow Technique Signature\r\n-------------------------------------------------------------------------------}\r\nprocedure AppendFindWindowSignature(ADescription, AClassName, AWindowName : String);\r\nvar AFindWindowSignature : TFindWindowSignature;\r\nbegin\r\n  if NOT Assigned(LFindWindowSignatures) then\r\n    Exit();\r\n  ///\r\n\r\n  AFindWindowSignature := TFindWindowSignature.Create(ADescription, AClassName, AWindowName);\r\n\r\n  LFindWindowSignatures.Add(AFindWindowSignature);\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n  ___entry\r\n-------------------------------------------------------------------------------}\r\nbegin\r\n  try\r\n    LFindWindowSignatures := TObjectList<TFindWindowSignature>.Create();\r\n    LEnumWindowsSignatures := TDictionary<String, String>.Create();\r\n    try\r\n      {\r\n        Configure debuggers signatures here for FindWindow API technique.\r\n      }\r\n      AppendFindWindowSignature('OllyDbg', 'OLLYDBG', '');\r\n      AppendFindWindowSignature('x64dbg (x64)', '', 'x64dbg');\r\n      AppendFindWindowSignature('x32dbg (x32)', '', 'x32dbg');\r\n\r\n      // ...\r\n      // AppendFindWindowSignature('...', '...', '...');\r\n      // ...\r\n\r\n      {\r\n        Configure debuggeers signatures here for EnumWindows API technique.\r\n      }\r\n      LEnumWindowsSignatures.Add('Immunity Debugger', 'Immunity Debugger');\r\n\r\n      // ...\r\n      // AEnumWindowsSignatures.Add('...', '...');\r\n      // ...\r\n\r\n      {\r\n        Fire !!!\r\n      }\r\n      Locate_FindWindow();\r\n      Locate_EnumWindows();\r\n\r\n      readln;\r\n    finally\r\n      if Assigned(LFindWindowSignatures) then\r\n        FreeAndNil(LFindWindowSignatures);\r\n\r\n      if Assigned(LEnumWindowsSignatures) then\r\n        FreeAndNil(LEnumWindowsSignatures);\r\n    end;\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\n\r\nend."
                }
            ],
            "detection_rules": []
        },
        {
            "name": "GetLocalTime, GetSystemTime, timeGetTime, NtQueryPerformanceCounter",
            "category": [
                "https://search.unprotect.it/api/categories/3/",
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "When a debugger is present, and used to single-step through the code, there is a significant delay between the executions of the individual instructions, when compared to native execution.",
            "resources": "https://www.malwinator.com/2016/01/03/part-2-antidebug/",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "QueryPerformanceCounter",
                    "rule": "rule:\r\n  meta:\r\n    name: check for time delay via QueryPerformanceCounter\r\n    namespace: anti-analysis/anti-debugging/debugger-detection\r\n    author: michael.hunhoff@fireeye.com\r\n    scope: function\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Debugger Detection::Timing/Delay Check QueryPerformanceCounter [B0001.033]\r\n    examples:\r\n      - Practical Malware Analysis Lab 16-03.exe_:0x4011e0\r\n  features:\r\n    - and:\r\n      - count(api(kernel32.QueryPerformanceCounter)): 2 or more"
                }
            ]
        },
        {
            "name": "GetTickCount",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "This is typical timing function which is used to measure time needed to execute some function/instruction set. If the difference is more than fixed threshold, the process exits.",
            "resources": "https://researchcenter.paloaltonetworks.com/2015/10/ticked-off-upatre-malwares-simple-anti-analysis-trick-to-defeat-sandboxes/",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "gettickcount",
                    "rule": "rule:\r\n  meta:\r\n    name: check for time delay via GetTickCount\r\n    namespace: anti-analysis/anti-debugging/debugger-detection\r\n    author: michael.hunhoff@fireeye.com\r\n    scope: function\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Debugger Detection::Timing/Delay Check GetTickCount [B0001.032]\r\n    examples:\r\n      - Practical Malware Analysis Lab 16-03.exe_:0x4013d0\r\n  features:\r\n    - and:\r\n      - count(api(kernel32.GetTickCount)): 2 or more"
                }
            ]
        },
        {
            "name": "RDTSC",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "The Read-Time-Stamp-Counter (RDTSC) instruction can be used by malware to determine how quicky the processor excutes the program's instructions. It returns the count of the number of ticks since the last system reboot as a 64-bit value placed into EDX:EAX.\r\n\r\nIt will execute RDTSC twice and then calculate the difference between low order values and check it with CMP condition. If the difference lays below 0FFFh no debugger is found if it is above or equal then application is debugged.",
            "resources": "https://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide\r\nhttps://www.aldeid.com/wiki/RDTSC-Read-Time-Stamp-Counter",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "NtGlobalFlag",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "The information that the system uses to determine how to create heap structures is stored at an undocumented location in the PEB at offset 0x68. If the value at this location is 0x70, we know that we are running in a debugger.",
            "resources": "https://www.aldeid.com/wiki/PEB-Process-Environment-Block/NtGlobalFlag",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/6/",
                    "technique": "https://search.unprotect.it/api/techniques/63/",
                    "description": "",
                    "plain_code": "#include &lt;Winternl.h&gt;\r\n#include &lt;Windows.h&gt;\r\n#include &lt;tchar.h&gt;\r\n#include &lt;stdio.h&gt;\r\n\r\n/*\r\n*Using ZwQueryInformationProcess we get the PEB Address and \r\n*then we check the NtGlobalFlag to determine the process is being debugged or not.\r\n*/\r\n\r\nint main() {\r\n     \r\n    typedef unsigned long(__stdcall *pfnZwQueryInformationProcess)\r\n    (\r\n        IN  HANDLE,\r\n        IN  unsigned int, \r\n        OUT PVOID, \r\n        IN  ULONG, \r\n        OUT PULONG\r\n    );\r\n    pfnZwQueryInformationProcess ZwQueryInfoProcess = NULL;\r\n     \r\n    HMODULE hNtDll = LoadLibrary(_T(&quot;ntdll.dll&quot;));\r\n    if (hNtDll == NULL) { }\r\n \r\n    ZwQueryInfoProcess = (pfnZwQueryInformationProcess) GetProcAddress(hNtDll,\r\n        &quot;ZwQueryInformationProcess&quot;);\r\n    if (ZwQueryInfoProcess == NULL) { }\r\n    unsigned long status;\r\n \r\n    DWORD pid = GetCurrentProcessId();\r\n    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);\r\n    PROCESS_BASIC_INFORMATION pbi;\r\n    status = ZwQueryInfoProcess(hProcess,\r\n                                ProcessBasicInformation,\r\n                                &amp;pbi,\r\n                                sizeof(pbi),\r\n                                NULL);\r\n                                 \r\n    PPEB peb_addr = pbi.PebBaseAddress;\r\n    DWORD ptr = pbi.PebBaseAddress;\r\n    ptr|=104;\r\n    DWORD *temp = ptr;\r\n    MessageBox(0, *temp ? &quot;Debugger found&quot; : &quot;Debugger not found&quot;,&quot;Status&quot;,0x30);\r\n     \r\n    return 0;\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/1/",
                    "name": "DebuggerCheck__GlobalFlags",
                    "rule": "rule DebuggerCheck__GlobalFlags  {\r\n    meta:\r\n\tdescription = \"Rule to detect NtGlobalFlags debugger check\"\r\n        author = \"Thibault Seret\"\r\n        date = \"2020-09-26\"\r\n    strings:\r\n        $s1 = \"NtGlobalFlags\"\r\n    condition:\r\n        any of them\r\n}"
                },
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "ntglobalflag",
                    "rule": "rule:\r\n  meta:\r\n    name: check for PEB NtGlobalFlag flag\r\n    namespace: anti-analysis/anti-debugging/debugger-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: function\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Debugger Detection::Process Environment Block NtGlobalFlag [B0001.036]\r\n    references:\r\n      - Practical Malware Analysis, Chapter 16, p. 355\r\n      - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/index.htm\r\n    examples:\r\n      - Practical Malware Analysis Lab 16-01.exe_:0x403530\r\n  features:\r\n    - and:\r\n      - basic block:\r\n        - and:\r\n          - match: PEB access\r\n          - or:\r\n            - or:\r\n              - offset/x32: 0x68 = PEB.NtGlobalFlag\r\n              - offset/x64: 0xBC = PEB.NtGlobalFlag\r\n            - and:\r\n              - mnemonic: add\r\n              - or:\r\n                - number/x32: 0x68 = PEB.NtGlobalFlag\r\n                - number/x64: 0xBC = PEB.NtGlobalFlag\r\n      - number: 0x70 = (FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS)"
                }
            ]
        },
        {
            "name": "Heap Flag",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "ProcessHeap is located at 0x18 in the PEB structure. This first heap contains a header with fields used to tell the kernel whether the heap was created within a debugger. These are known as the ForceFlags and Flags fields.",
            "resources": "https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "IsDebugged Flag",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "While a process is running, the location of the PEB can be referenced by the location fs:[30h]. For anti-debugging, malware will use that location to check the BeingDebugged flag, which indicates whether the specified process is being debugged.",
            "resources": "http://malwareanalysis.tech/2016/12/isdebuggerpresent-using-inline-assembly-instead-of-windows-api/",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/1/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/61/",
                    "description": "",
                    "plain_code": "unit UntPEBDebug;\r\n\r\ninterface\r\n\r\nuses Windows;\r\n\r\nconst PROCESS_QUERY_LIMITED_INFORMATION = $1000;\r\n        PROCESS_BASIC_INFORMATION         = 0;\r\n\r\n// https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess\r\nvar _NtQueryInformationProcess : function(\r\n                                            ProcessHandle : THandle;\r\n                                            ProcessInformationClass : DWORD;\r\n                                            ProcessInformation : Pointer;\r\n                                            ProcessInformationLength :\r\n                                            ULONG; ReturnLength : PULONG) : LongInt; stdcall;\r\n\r\n    hNTDLL : THandle;\r\n\r\n\r\n{$IFDEF WIN64}\r\ntype\r\n    PProcessBasicInformation = ^TProcessBasicInformation;\r\n    TProcessBasicInformation = record\r\n    ExitStatus         : Int64;\r\n    PebBaseAddress     : Pointer;\r\n    AffinityMask       : Int64;\r\n    BasePriority       : Int64;\r\n    UniqueProcessId    : Int64;\r\n    InheritedUniquePID : Int64;\r\n    end;\r\n{$ELSE}\r\ntype\r\n    PProcessBasicInformation = ^TProcessBasicInformation;\r\n    TProcessBasicInformation = record\r\n    ExitStatus         : DWORD;\r\n    PebBaseAddress     : Pointer;\r\n    AffinityMask       : DWORD;\r\n    BasePriority       : DWORD;\r\n    UniqueProcessId    : DWORD;\r\n    InheritedUniquePID : DWORD;\r\n    end;\r\n{$ENDIF}\r\n\r\nfunction GetProcessDebugStatus(AProcessID : Cardinal; var ADebugStatus : boolean) : Boolean;\r\nfunction SetProcessDebugStatus(AProcessID : Cardinal; ADebugStatus : Boolean) : Boolean;\r\n\r\nimplementation\r\n\r\n{-------------------------------------------------------------------------------\r\n    Open a process and retrieve the point of debug flag from PEB.\r\n\r\n    If function succeed, don't forget to call close process handle.\r\n-------------------------------------------------------------------------------}\r\nfunction GetDebugFlagPointer(AProcessID : Cardinal; var AProcessHandle : THandle) : Pointer;\r\nvar PBI     : TProcessBasicInformation;\r\n    ARetLen : Cardinal;\r\nbegin\r\n    result := nil;\r\n    ///\r\n\r\n    AProcessHandle := 0;\r\n\r\n    if NOT Assigned(_NtQueryInformationProcess) then\r\n    Exit();\r\n    ///\r\n\r\n    AProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_WRITE or PROCESS_VM_READ, false, AProcessID);\r\n    if (AProcessHandle = 0) then\r\n    Exit;\r\n\r\n    if _NtQueryInformationProcess(AProcessHandle, PROCESS_BASIC_INFORMATION, @PBI, sizeOf(TProcessBasicInformation), @ARetLen) = ERROR_SUCCESS then\r\n    result := Pointer(NativeUInt(PBI.PebBaseAddress) + (SizeOf(Byte) * 2))\r\n    else\r\n    CloseHandle(AProcessHandle);\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n    Retrieve the target process debug status from PEB.\r\n\r\n    ADebugStatus = True  : Target process debug flag is set.\r\n    ADebugStatus = False : Target process debug flag is not set.\r\n-------------------------------------------------------------------------------}\r\nfunction GetProcessDebugStatus(AProcessID : Cardinal; var ADebugStatus : boolean) : Boolean;\r\nvar hProcess         : THandle;\r\n\r\n    pDebugFlagOffset : Pointer;\r\n    pDebugFlag       : pByte;\r\n    ABytesRead       : SIZE_T;\r\nbegin\r\n    result := false;\r\n    ///\r\n\r\n    pDebugFlagOffset := GetDebugFlagPointer(AProcessID, hProcess);\r\n\r\n    if not Assigned(pDebugFlagOffset) then\r\n    Exit();\r\n    ///\r\n    try\r\n    getMem(pDebugFlag, sizeOf(Byte));\r\n    try\r\n        if NOT ReadProcessMemory(hProcess, pDebugFlagOffset, pDebugFlag, sizeOf(Byte), ABytesRead) then\r\n        Exit;\r\n\r\n        ///\r\n        ADebugStatus := (pDebugFlag^ = 1);\r\n    finally\r\n        FreeMem(pDebugFlag);\r\n    end;\r\n\r\n    ///\r\n    result := (ABytesRead = SizeOf(Byte));\r\n    finally\r\n    CloseHandle(hProcess);\r\n    end;\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n    Update target process debug flag.\r\n\r\n    ADebugStatus = True  : Set target process debug flag.\r\n    ADebugStatus = False : Unset target process debug flag.\r\n-------------------------------------------------------------------------------}\r\nfunction SetProcessDebugStatus(AProcessID : Cardinal; ADebugStatus : Boolean) : Boolean;\r\nvar hProcess         : THandle;\r\n\r\n    pDebugFlagOffset : Pointer;\r\n    ADebugFlag       : Byte;\r\n    ABytesWritten    : SIZE_T;\r\nbegin\r\n    result := false;\r\n    ///\r\n\r\n    pDebugFlagOffset := GetDebugFlagPointer(AProcessID, hProcess);\r\n\r\n    if not Assigned(pDebugFlagOffset) then\r\n    Exit();\r\n    ///\r\n    try\r\n    if ADebugStatus then\r\n        ADebugFlag := 1\r\n    else\r\n        ADebugFlag := 0;\r\n\r\n    if NOT WriteProcessMemory(hProcess, pDebugFlagOffset, @ADebugFlag, SizeOf(Byte), ABytesWritten) then\r\n        Exit;\r\n\r\n    ///\r\n    result := (ABytesWritten = SizeOf(Byte));\r\n    finally\r\n    CloseHandle(hProcess);\r\n    end;\r\nend;\r\n\r\ninitialization\r\n    {\r\n    Load NtQueryInformationProcess from NTDLL.dll\r\n    }\r\n    _NtQueryInformationProcess := nil;\r\n\r\n    hNTDLL := LoadLibrary('ntdll.dll');\r\n\r\n    if (hNTDLL <> 0) then\r\n    @_NtQueryInformationProcess := GetProcAddress(hNTDLL, 'NtQueryInformationProcess');\r\n\r\nfinalization\r\n    _NtQueryInformationProcess := nil;\r\n\r\n    if (hNTDLL <> 0) then\r\n    FreeLibrary(hNTDLL);\r\n\r\n\r\nend."
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "debugged_flag",
                    "rule": "rule:\r\n  meta:\r\n    name: check for PEB BeingDebugged flag\r\n    namespace: anti-analysis/anti-debugging/debugger-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Debugger Detection::Process Environment Block BeingDebugged [B0001.035]\r\n    references:\r\n      - Practical Malware Analysis, Chapter 16, p. 353\r\n    examples:\r\n      - Practical Malware Analysis Lab 16-01.exe_:0x403530\r\n  features:\r\n    - and:\r\n      - match: PEB access\r\n      - offset: 2 = PEB.BeingDebugged"
                }
            ]
        },
        {
            "name": "CloseHandle, NtClose",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "When a process is debugged, calling NtClose with an invalid handle will generate a STATUS_INVALID_HANDLE exception.",
            "resources": "https://www.symantec.com/connect/articles/windows-anti-debug-reference",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "CsrGetProcessID",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "This function is undocumented within OpenProcess. It can be used to get the PID of CRSS.exe, which is a SYSTEM process. By default, a process has the SeDebugPrivilege privilege in their access token disabled. However, when the process is loaded by a debugger such as OllyDbg or WinDbg, the SeDebugPrivilege privilege is enabled. If a process is able to open CRSS.exe process, it means that the process SeDebugPrivilege enabled in the access token, and thus, suggesting that the process is being debugged.",
            "resources": "https://www.gironsec.com/blog/2013/12/other-antidebug-tricks/",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "EventPairHandles",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "An EventPair Object is an event constructed by two _KEVENT structures which are conventionally named High and Low. There is a relation between generic Event Objects and Debuggers cause they have to create a custom event called DebugEvent able to handle exceptions. Due to the presence of events owned by the Debugger, every information relative to the events of a normal process differs from a debugged process.",
            "resources": "https://www.evilfingers.com/publications/research_EN/EventPairsHandle.pdf",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/3/",
                    "technique": "https://search.unprotect.it/api/techniques/58/",
                    "description": "",
                    "plain_code": "#define WIN32_LEAN_AND_MEAN\r\n#include <stdio.h>\r\n#include <iostream>\r\n#include <stdlib.h>\r\n#include <windows.h>\r\n#include \"defs.h\"\r\n\r\n\r\n#pragma comment(lib,\"ntdll.lib\")\r\n#pragma comment(lib,\"psapi.lib\")\r\n\r\n\r\nvoid QueryProcessHeapMethod(void)\r\n{\r\n    PDEBUG_BUFFER buffer;\r\n    buffer = RtlCreateQueryDebugBuffer(0,FALSE);\r\n    RtlQueryProcessHeapInformation(buffer);\r\n\r\n    if (buffer->RemoteSectionBase == (PVOID) 0x50000062){\r\n        MessageBoxA(NULL,\"Debugged\",\"Warning\",MB_OK);\r\n    }\r\n    else {\r\n        MessageBoxA(NULL,\"Not Debugged\",\"Warning\",MB_OK);\r\n    }\r\n    if (buffer->EventPairHandle == (PVOID) 0x00002b98) {\r\n        MessageBoxA(NULL,\"Debugged\",\"Warning\",MB_OK);\r\n    }\r\n    else {\r\n        MessageBoxA(NULL,\"Not Debugged\",\"Warning\",MB_OK);\r\n        printf(\"EventPairHandle= %x\",(int)buffer->EventPairHandle);\r\n    }\r\n}\r\nint main()\r\n{\r\n    QueryProcessHeapMethod();\r\n    return (EXIT_SUCCESS);\r\n}"
                }
            ],
            "detection_rules": []
        },
        {
            "name": "OutputDebugString",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "This Windows API is often used by developers for debugging purpose. It will display a text to the attached debugger. This API is also used by Malware to open a communication channel between one or multiple processes.\r\n\r\nIt is possible to use [OutputDebugString](https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringw) in addition of [GetLastError](https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) / [SetLastError](https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setlasterror) to detect debugger presence.",
            "resources": "https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/1/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/57/",
                    "description": "",
                    "plain_code": "program OutputDebugString;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\nuses\r\n  WinAPI.Windows,\r\n  System.SysUtils;\r\n\r\nvar AErrorValue : Byte;\r\n\r\nbegin\r\n  try\r\n    randomize;\r\n\r\n    AErrorValue := Random(High(Byte));\r\n\r\n    SetLastError(AErrorValue);\r\n\r\n    OutputDebugStringW('TEST');\r\n\r\n    if (GetLastError() = AErrorValue) then\r\n      WriteLn('Debugger detected using OutputDebugString() technique.')\r\n    else\r\n      WriteLn('No debugger detected using OutputDebugString() technique.');\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
                },
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/57/",
                    "description": "",
                    "plain_code": "#include <stdio.h>\r\n#include <Windows.h>\r\n\r\nint main()\r\n{\r\n\tSetLastError(0);\r\n\t\r\n        // Send string to the debugger\r\n\tOutputDebugStringA(\"Hello friend\");\r\n\r\n\tif (GetLastError() != 0)\r\n\t{\r\n\t\tprintf(\"Debugger detected!!\\n\");\r\n\t}\r\n        system(\"pause\");\r\n\treturn 0;\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "output_debug_string",
                    "rule": "rule:\r\n  meta:\r\n    name: check for OutputDebugString error\r\n    namespace: anti-analysis/anti-debugging/debugger-detection\r\n    author: michael.hunhoff@fireeye.com\r\n    scope: function\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Debugger Detection::OutputDebugString [B0001.016]\r\n    examples:\r\n      - Practical Malware Analysis Lab 16-02.exe_:0x401020\r\n  features:\r\n    - and:\r\n      - api: kernel32.SetLastError\r\n      - api: kernel32.GetLastError\r\n      - api: kernel32.OutputDebugString"
                }
            ]
        },
        {
            "name": "NtQueryObject",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "This function retrieves object information. By calling this function with the class ObjectTypeInformation will retrieve the specific object type (debug) to detect the debugger.",
            "resources": "https://msdn.microsoft.com/en-us/library/bb432383(v=vs.85).aspx\r\nhttps://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide?fbclid=IwAR0fpYHnQX6C3YyBx3pnZ1m3bOYawc-kUIhZn65T5Bf7pQR26fUuVNYPs_Q#NtQueryObject",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/1/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/56/",
                    "description": "Support both 32/64 bit.",
                    "plain_code": "program NtQueryObject;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\n{$ALIGN ON}\r\n{$MINENUMSIZE 4}\r\n\r\nuses\r\n  WinAPI.Windows, System.SysUtils;\r\n\r\ntype\r\n  TUnicodeString = record\r\n    Length: USHORT;\r\n    MaximumLength: USHORT;\r\n    Buffer: PWideChar;\r\n  end;\r\n\r\n  TObjectInformationClass = (\r\n                                    ObjectBasicInformation    = 0,\r\n                                    ObjectNameInformation     = 1,\r\n                                    ObjectTypeInformation     = 2,\r\n                                    ObjectAllTypesInformation = 3,\r\n                                    ObjectHandleInformation   = 4\r\n  );\r\n\r\n  OBJECT_TYPE_INFORMATION = record\r\n    Name: TUnicodeString;\r\n    ObjectCount: ULONG;\r\n    HandleCount: ULONG;\r\n    Reserved1: array[0..3] of ULONG;\r\n    PeakObjectCount: ULONG;\r\n    PeakHandleCount: ULONG;\r\n    Reserved2: array[0..3] of ULONG;\r\n    InvalidAttributes: ULONG;\r\n    GenericMapping: GENERIC_MAPPING;\r\n    ValidAccess: ULONG;\r\n    Unknown: UCHAR;\r\n    MaintainHandleDatabase: ByteBool;\r\n    Reserved3: array[0..1] of UCHAR;\r\n    PoolType: Byte;\r\n    PagedPoolUsage: ULONG;\r\n    NonPagedPoolUsage: ULONG;\r\n  end;\r\n  POBJECT_TYPE_INFORMATION = ^OBJECT_TYPE_INFORMATION;\r\n  TObjectTypeInformation = OBJECT_TYPE_INFORMATION;\r\n  PObjectTypeInformation = ^TObjectTypeInformation;\r\n\r\n  OBJECT_ALL_TYPE_INFORMATION = record\r\n    NumberOfObjectTypes : ULONG;\r\n    ObjectTypeInformation : array[0..0] of TObjectTypeInformation;\r\n  end;\r\n  POBJECT_ALL_TYPE_INFORMATION = ^OBJECT_ALL_TYPE_INFORMATION;\r\n  TObjectAllTypeInformation = OBJECT_ALL_TYPE_INFORMATION;\r\n  PObjectAllTypeInformation = ^TObjectAllTypeInformation;\r\n\r\n// https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryobject\r\nvar\r\n  _NtQueryObject : function (\r\n                                ObjectHandle : THandle;\r\n                                ObjectInformationClass : TObjectInformationClass;\r\n                                ObjectInformation : PVOID;\r\n                                ObjectInformationLength : ULONG;\r\n                                ReturnLength : PULONG\r\n                              ): ULONG; stdcall;\r\nvar hNTDLL              : THandle;\r\n    ARet                : ULONG;\r\n    ARequiredSize       : ULONG;\r\n    pAllTypeInformation : PObjectAllTypeInformation;\r\n    pTypeInformation    : PObjectTypeInformation;\r\n    i                   : Integer;\r\n    pRow                : PObjectTypeInformation;\r\n    pDummy              : Pointer;\r\n    ADebuggerFound      : Boolean;\r\n\r\nbegin\r\n  try\r\n    ADebuggerFound := False;\r\n\r\n    @_NtQueryObject := nil;\r\n    ///\r\n\r\n    hNTDLL := LoadLibrary('NTDLL.DLL');\r\n    if (hNTDLL = 0) then\r\n      Exit();\r\n    try\r\n      @_NtQueryObject := GetProcAddress(hNTDLL, 'NtQueryObject');\r\n      if NOT Assigned(_NtQueryObject) then\r\n        Exit();\r\n      ///\r\n\r\n      ARet := _NtQueryObject(0, ObjectAllTypesInformation, @ARequiredSize, SizeOf(ULONG), @ARequiredSize);\r\n      if (ARequiredSize <= 0) then\r\n        Exit();\r\n      ///\r\n\r\n      GetMem(pAllTypeInformation, ARequiredSize);\r\n      try\r\n        ARet := _NtQueryObject(0, ObjectAllTypesInformation, pAllTypeInformation, ARequiredSize, nil);\r\n        if (ARet <> 0) then\r\n          Exit();\r\n        ///\r\n\r\n        pRow := @pAllTypeInformation^.ObjectTypeInformation;\r\n\r\n        for I := 0 to pAllTypeInformation^.NumberOfObjectTypes -1 do begin\r\n            if String.Compare(String(pRow^.Name.Buffer), 'DebugObject', True) = 0 then\r\n              ADebuggerFound := (pRow^.ObjectCount > 0);\r\n            ///\r\n\r\n            if ADebuggerFound then\r\n              break;\r\n\r\n            pRow := Pointer (\r\n              (NativeUInt(pRow^.Name.Buffer) + pRow^.Name.Length) and (NOT (SizeOf(Pointer)-1)) + SizeOf(Pointer)\r\n            );\r\n        end;\r\n      finally\r\n        FreeMem(pAllTypeInformation, ARequiredSize);\r\n      end;\r\n    finally\r\n      FreeLibrary(hNTDLL);\r\n    end;\r\n\r\n    if ADebuggerFound then\r\n      WriteLn('A Debugger Was Found!')\r\n    else\r\n      WriteLn('No Debugger Found!');\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
                }
            ],
            "detection_rules": []
        },
        {
            "name": "NtSetInformationThread",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "[NtSetInformationThread](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntsetinformationthread) can be used to hide threads from debuggers using the `ThreadHideFromDebugger` ThreadInfoClass (`0x11` / `17`).\r\n\r\nThe debugger won't be able to capture any information about running threads affected by this property.\r\n\r\nIf a breakpoint is placed inside a thread affected by this property, the debugger will likely crash.",
            "resources": "https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-zwsetinformationthread\r\nhttps://ntquery.wordpress.com/2014/03/29/anti-debug-ntsetinformationthread/",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/1/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/55/",
                    "description": "You can compile this code snippet as a classical Delphi Console Application.",
                    "plain_code": "program ADB_NtSetInformationThread;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\nuses\r\n  WinAPI.Windows, System.SysUtils;\r\n\r\ntype\r\n  // ntddk.h\r\n  TThreadInfoClass = (\r\n                        ThreadBasicInformation,\r\n                        ThreadTimes,\r\n                        ThreadPriority,\r\n                        ThreadBasePriority,\r\n                        ThreadAffinityMask,\r\n                        ThreadImpersonationToken,\r\n                        ThreadDescriptorTableEntry,\r\n                        ThreadEnableAlignmentFaultFixup,\r\n                        ThreadEventPair_Reusable,\r\n                        ThreadQuerySetWin32StartAddress,\r\n                        ThreadZeroTlsCell,\r\n                        ThreadPerformanceCount,\r\n                        ThreadAmILastThread,\r\n                        ThreadIdealProcessor,\r\n                        ThreadPriorityBoost,\r\n                        ThreadSetTlsArrayAddress,\r\n                        ThreadIsIoPending,\r\n                        ThreadHideFromDebugger, {<--}\r\n                        ThreadBreakOnTermination,\r\n                        ThreadSwitchLegacyState,\r\n                        ThreadIsTerminated,\r\n                        ThreadLastSystemCall,\r\n                        ThreadIoPriority,\r\n                        ThreadCycleTime,\r\n                        ThreadPagePriority,\r\n                        ThreadActualBasePriority,\r\n                        ThreadTebInformation,\r\n                        ThreadCSwitchMon,\r\n                        ThreadCSwitchPmu,\r\n                        ThreadWow64Context,\r\n                        ThreadGroupInformation,\r\n                        ThreadUmsInformation,\r\n                        ThreadCounterProfiling,\r\n                        ThreadIdealProcessorEx,\r\n                        ThreadCpuAccountingInformation,\r\n                        ThreadSuspendCount,\r\n                        ThreadActualGroupAffinity,\r\n                        ThreadDynamicCodePolicyInfo,\r\n                        MaxThreadInfoClass\r\n  );\r\n\r\n  var hNtDll    : THandle;\r\n      AThread   : THandle;\r\n      AThreadId : Cardinal;\r\n\r\n      NtSetInformationThread : function(\r\n                                          ThreadHandle : THandle;\r\n                                          ThreadInformationClass : TThreadInfoClass;\r\n                                          ThreadInformation : PVOID;\r\n                                          ThreadInformationLength : ULONG\r\n                                      ) : NTSTATUS; stdcall;\r\n\r\n  const\r\n    STATUS_SUCCESS = $00000000;\r\n\r\n{-------------------------------------------------------------------------------\r\n  Hide Thread From Debugger\r\n-------------------------------------------------------------------------------}\r\nfunction HideThread(AThreadHandle : THandle) : Boolean;\r\nvar AThreadInformation : ULONG;\r\n    AStatus            : NTSTATUS;\r\nbegin\r\n  result := False;\r\n  ///\r\n\r\n  if not assigned(NtSetInformationThread) then\r\n    Exit();\r\n\r\n\r\n\r\n  // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntsetinformationthread\r\n  AStatus := NtSetInformationThread(AThreadHandle, ThreadHideFromDebugger, nil, 0);\r\n\r\n  case AStatus of\r\n    {\r\n      STATUS_INFO_LENGTH_MISMATCH\r\n    }\r\n    NTSTATUS($C0000004) : begin\r\n      WriteLn('Error: Status Info Length Mismatch.');\r\n    end;\r\n\r\n    {\r\n      STATUS_INVALID_PARAMETER\r\n    }\r\n    NTSTATUS($C000000D) : begin\r\n      WriteLn('Error: Invalid Parameter.');\r\n    end;\r\n\r\n    {\r\n      STATUS_SUCCESS\r\n    }\r\n    NTSTATUS($00000000) : begin\r\n      WriteLn(Format('Thread: %d is now successfully hidden from debuggers.', [AThreadHandle]));\r\n\r\n      result := True;\r\n    end;\r\n\r\n    {\r\n      Other Errors\r\n    }\r\n    else begin\r\n      WriteLn('Error: Unknown.');\r\n    end;\r\n  end;\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n  ___thread:example\r\n-------------------------------------------------------------------------------}\r\nprocedure ThreadExample(pParam : PVOID); stdcall;\r\nbegin\r\n  WriteLn('Example Thread Begin.');\r\n\r\n\r\n  {\r\n    If we are attached to a debugger, we trigger a new breakpoint.\r\n\r\n    If thread is set with hidden from debugger, process should crash.\r\n  }\r\n  if IsDebuggerPresent() then begin\r\n    asm\r\n      int 3\r\n    end;\r\n  end;\r\n\r\n  WriteLn('Example Thread Ends.');\r\n\r\n  ///\r\n  ExitThread(0);\r\nend;\r\n\r\n{-------------------------------------------------------------------------------\r\n  ___entry\r\n-------------------------------------------------------------------------------}\r\nbegin\r\n  try\r\n    hNtDll := LoadLibrary('NTDLL.DLL');\r\n    if (hNtDll = 0) then\r\n      Exit();\r\n    try\r\n      @NtSetInformationThread := GetProcAddress(hNtDll, 'NtSetInformationThread');\r\n      if NOT Assigned(NtSetInformationThread) then\r\n        Exit();\r\n\r\n      {\r\n        Create an example thread\r\n      }\r\n      SetLastError(0);\r\n\r\n      AThread := CreateThread(nil, 0, @ThreadExample, nil, CREATE_SUSPENDED, AThreadId);\r\n      if (AThread <> 0) then begin\r\n        WriteLn(Format('Example thread created. Thread Handle: %d , Thread Id: %d', [AThread, AThreadid]));\r\n\r\n        HideThread(AThread);\r\n\r\n        ///\r\n        ResumeThread(AThread);\r\n\r\n        WaitForSingleObject(AThread, INFINITE);\r\n      end else begin\r\n        WriteLn(Format('Could not create example thread with error: .', [GetLastError()]));\r\n      end;\r\n    finally\r\n      FreeLibrary(hNtDll);\r\n    end;\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
                }
            ],
            "detection_rules": []
        },
        {
            "name": "NtQueryInformationProcess",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "This function retrieves information about a specified process. Malware are able to detect if the process is currently being debugged with the information retrieves by the function.",
            "resources": "https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "CheckRemoteDebuggerPresent",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "CheckRemoteDebuggerPresent is a kernel32.dll function that sets (-1)0xffffffff in the DebuggerPresent parameter if a debugger is present.  Internally, it also uses NtQueryInformationProcess with ProcessDebugPort as a ProcessInformationClass parameter.",
            "resources": "https://msdn.microsoft.com/en-us/library/windows/desktop/ms679280(v=vs.85).aspx",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/6/",
                    "technique": "https://search.unprotect.it/api/techniques/53/",
                    "description": "",
                    "plain_code": "#include \"windows.h\"\r\n \r\nint main(void)\r\n{\r\n    BOOL HasDebugPort = FALSE;\r\n \r\n    if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &HasDebugPort))\r\n    {\r\n           ExitProcess(0); // Running in ring-3 debugger\r\n    }\r\n    // Running outside ring-3 debugger\r\n    return 0;"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "capa_debugger_api",
                    "rule": "rule:\r\n  meta:\r\n    name: check for debugger via API\r\n    namespace: anti-analysis/anti-debugging/debugger-detection\r\n    author: michael.hunhoff@fireeye.com\r\n    scope: function\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Debugger Detection::CheckRemoteDebuggerPresent [B0001.002]\r\n      - Anti-Behavioral Analysis::Debugger Detection::WudfIsAnyDebuggerPresent [B0001.031]\r\n    references:\r\n      - https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.cpp\r\n    examples:\r\n      - al-khaser_x86.exe_:0x420000\r\n  features:\r\n    - or:\r\n      - api: kernel32.CheckRemoteDebuggerPresent\r\n      - api: WUDFPlatform.WudfIsAnyDebuggerPresent\r\n      - api: WUDFPlatform.WudfIsKernelDebuggerPresent\r\n      - api: WUDFPlatform.WudfIsUserDebuggerPresent"
                }
            ]
        },
        {
            "name": "IsDebuggerPresent",
            "category": [
                "https://search.unprotect.it/api/categories/3/"
            ],
            "description": "This function checks specific flag in the Process Environment Block (PEB) for the field IsDebugged which will return zero if the process is not running into a debugger or a nonzero if a debugger is attached.\r\n\r\nIf you want to understand the underlying process of [IsDebuggerPresent](https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-isdebuggerpresent) API you can check the code snippet section for the following method: [IsDebugged Flag](https://search.unprotect.it/map/anti-debugging/isdebugged-flag/).",
            "resources": "https://msdn.microsoft.com/en-us/library/windows/desktop/ms680345(v=vs.85).aspx",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/52/",
                    "description": "",
                    "plain_code": "#include <windows.h>\r\n#include <stdio.h>\r\n\r\nint main(int argc, char** argv)\r\n{\r\n\tif (IsDebuggerPresent())\r\n\t{\r\n            printf(\"Debugger detected!!\\n\");\r\n\t}\r\n\telse\r\n\t{\r\n\t    printf(\"No debugger detected!!\\n\");\r\n\t}\r\n\tsystem(\"pause\");\r\n\treturn 0;\r\n}"
                },
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/1/",
                    "author": "https://search.unprotect.it/api/snippet_authors/1/",
                    "technique": "https://search.unprotect.it/api/techniques/52/",
                    "description": "",
                    "plain_code": "program IsDebuggerPresent;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\nuses\r\n  WinAPI.Windows, System.SysUtils;\r\n\r\nbegin\r\n  try\r\n    if IsDebuggerPresent() then\r\n      WriteLn('Process is currently getting debugged.')\r\n    else\r\n      WriteLn('Process is not likely getting debugged.');\r\n\r\n    readln;\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
                }
            ],
            "detection_rules": []
        },
        {
            "name": "Fake Signature",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Every exe file contain metadata that allow users to trust the third party that distribute the program. Malware are able to usurp the metadata in order to fool the user but also the security tools.",
            "resources": "https://www.mcafee.com/us/resources/reports/rp-quarterly-threats-jun-2017.pdf",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Adding antivirus exception",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Another way for a malware is to add an exception into the antivirus.",
            "resources": "https://www.darknet.org.uk/2016/12/malware-writers-using-exclusion-lists-to-linger/",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/3/",
                    "name": "bypass_applocker",
                    "rule": "title: AppLocker Bypass via Regsvr32\r\nstatus: experimental\r\ndescription: AppLocker Bypass via Regsvr32\r\nauthor: Joe Security\r\ndate: 2020-03-04\r\nid: 200059\r\nthreatname:\r\nbehaviorgroup: 5\r\nclassification: 8\r\nmitreattack:\r\n\r\nlogsource:\r\n      category: process_creation\r\n      product: windows\r\ndetection:\r\n      selection:      \r\n          CommandLine:\r\n              - '*regsvr32*/s /u /n /i:http*scrobj*'\r\n      condition: selection\r\nlevel: critical"
                }
            ]
        },
        {
            "name": "Disabling Antivirus",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Some malware can also use specific command to disable the antivirus and to avoid detection.",
            "resources": "https://blog.malwarebytes.com/cybercrime/2015/11/vonteera-adware-uses-certificates-to-disable-anti-malware/",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/1/",
                    "name": "disable_antivirus",
                    "rule": "import \"pe\"\r\n\r\nrule disable_antivirus \r\n{\r\n    meta:\r\n\tauthor = \"x0r\"\r\n\tdescription = \"Disable AntiVirus\"\r\n\r\n    strings:\r\n        $p1 = \"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\DisallowRun\" nocase\r\n        $p2 = \"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\\\\\" nocase\r\n        $p3 = \"SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows Defender\" nocase\r\n\r\n        $c1 = \"RegSetValue\" \r\n\r\n        $r1 = \"AntiVirusDisableNotify\" \r\n        $r2 = \"DontReportInfectionInformation\" \r\n        $r3 = \"DisableAntiSpyware\" \r\n        $r4 = \"RunInvalidSignatures\" \r\n        $r5 = \"AntiVirusOverride\" \r\n        $r6 = \"CheckExeSignatures\"\r\n\r\n        $f1 = \"blackd.exe\" nocase\r\n        $f2 = \"blackice.exe\" nocase\r\n        $f3 = \"lockdown.exe\" nocase\r\n        $f4 = \"lockdown2000.exe\" nocase\r\n        $f5 = \"taskkill.exe\" nocase\r\n        $f6 = \"tskill.exe\" nocase\r\n        $f7 = \"smc.exe\" nocase\r\n        $f8 = \"sniffem.exe\" nocase\r\n        $f9 = \"zapro.exe\" nocase\r\n        $f10 = \"zlclient.exe\" nocase\r\n        $f11 = \"zonealarm.exe\" nocase\r\n\r\n    condition:\r\n        ($c1 and $p1 and 1 of ($f*)) or ($c1 and $p2) or 1 of ($r*) or $p3\r\n}"
                },
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "Check for Sandbox and AV Modules",
                    "rule": "rule:\r\n  meta:\r\n    name: check for sandbox and av modules\r\n    namespace: anti-analysis/anti-av\r\n    author: \"@_re_fox\"\r\n    scope: basic block\r\n    unprotect: U0508\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection [B0009]\r\n      - Anti-Behavioral Analysis::Sandbox Detection [B0007]\r\n    examples:\r\n      - ccbf7cba35bab56563c0fbe4237fdc41:0x0040a4a0\r\n  features:\r\n    - and:\r\n      - api: GetModuleHandle\r\n      - or:\r\n        - string: /avghook(x|a)\\.dll/i\r\n          description: AVG\r\n        - string: /snxhk\\.dll/i \r\n          description: Avast\r\n        - string: /sf2\\.dll/i \r\n          description: Avast\r\n        - string: /sbiedll\\.dll/i\r\n          description: Sandboxie\r\n        - string: /dbghelp\\.dll/i \r\n          description: WindBG\r\n        - string: /api_log\\.dll/i \r\n          description: iDefense Lab\r\n        - string: /dir_watch\\.dll/ \r\n          description: iDefense Lab\r\n        - string: /pstorec\\.dll/i\r\n          description: SunBelt Sandbox\r\n        - string: /vmcheck\\.dll/i\r\n          description: Virtual PC\r\n        - string: /wpespy\\.dll/i\r\n          description: WPE Pro\r\n        - string: /cmdvrt(64|32).dll/i \r\n          description: Comodo Container\r\n        - string: /sxin.dll/i \r\n          description: 360 SOFTWARE\r\n        - string: /dbghelp\\.dll/i\r\n          description: WINE\r\n        - string: /printfhelp\\.dll/i \r\n          description: Unknown Sandbox"
                },
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/3/",
                    "name": "fingerprint_av",
                    "rule": "title: Get antivirus details via WMIC query\r\nstatus: experimental\r\ndescription: Get antivirus details via WMIC query\r\nauthor: Joe Security\r\ndate: 2020-03-27\r\nid: 200069\r\nthreatname:\r\nbehaviorgroup: 5\r\nclassification: 8\r\nmitreattack:\r\n\r\nlogsource:\r\n      category: process_creation\r\n      product: windows\r\ndetection:\r\n      selection:\r\n          CommandLine:\r\n              -'*wmic * path antivirusproduct get displayname*'\r\n      condition: selection\r\nlevel: critical"
                }
            ]
        },
        {
            "name": "File Splitting",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "An old trick consists to split the malicious file into different parts and analyse all of them separately with and AV. The chunk where the detection is still being triggered is actually the part of the file that need to change to evade the antivirus software you are targeting.",
            "resources": "https://dl.packetstormsecurity.net/papers/bypass/bypassing-av.pdf",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Bypassing Static Heuristic",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Dynamic heuristic engines are implemented in the form of hooks (in user-land or kernel-land) or based on emulation. User-land hooks (HIPS) can be easily bypass by malware by patching back the entry point of the hooked function. For kernel-land hook, malware has to run in kernel space by installing a driver or abusing a kernel-level vulnerability.",
            "resources": "https://hydrasky.com/malware-analysis/malware-analysis-bypass-dynamic-heuristic-antivirus/",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "File Format Confusion",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "By looking the structure of the PE and the content of the file, the engine is able to detect if the file is malicious or not. For example, an heuristic engine can try to figure out if a file are using a dual extension (e.g: invoice.doc.exe) and determine the file as being malicious.\r\n\r\nConfusing file format is another trick that can be used to bypass an AV detection specific to a file format.",
            "resources": "https://wikileaks.org/ciav7p1/cms/files/BypassAVDynamics.pdf\r\nhttps://code.google.com/archive/p/corkami/wikis/mix.wiki",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/3/",
                    "name": "spoofed_extension",
                    "rule": "title: Execute DLL with spoofed extension\r\nstatus: experimental\r\ndescription: Execute DLL with spoofed extension\r\nauthor: Joe Security\r\ndate: 2020-03-24\r\nid: 200068\r\nthreatname:\r\nbehaviorgroup: 1\r\nclassification: 8\r\nmitreattack:\r\n\r\nlogsource:\r\n      category: process_creation\r\n      product: windows\r\ndetection:\r\n      selection:      \r\n          CommandLine:\r\n              - '*rundll32*.html,DllRegisterServer*'\r\n              - '*rundll32*.htm,DllRegisterServer*'\r\n              - '*rundll32*.txt,DllRegisterServer*'\r\n              - '*rundll32*.png,DllRegisterServer*'\r\n              - '*rundll32*.jpeg,DllRegisterServer*'\r\n              - '*rundll32*.jpg,DllRegisterServer*'\r\n              - '*regsvr32 c:\\programdata\\\\*.pdf*'\r\n              - '*regsvr32 c:\\programdata\\\\*.txt*'\r\n              - '*regsvr32 c:\\users\\public\\\\*.pdf*'\r\n              - '*regsvr32 c:\\users\\public\\\\*.txt*'\r\n              \r\n      condition: selection\r\nlevel: critical"
                }
            ]
        },
        {
            "name": "Big File",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Because of the imposed file size limit, you can trick the scanner into skipping a file by changing the file’s size to make it larger than the hard-coded size limit. This file size limit applies especially with heuristic engines based on static data (data extracted from the portable executable, or PE, header). This is an old trick still apply in the wild.",
            "resources": "https://securelist.com/old-malware-tricks-to-bypass-detection-in-the-age-of-big-data/78010/",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Fingerprinting Emulator",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Fingerprinting the AV emulator can allow the malware to detect the AV. For example, specific mutex can be used by the AV emulator, trying to detect it allow the sample to detect the AV.",
            "resources": "https://www.blackhat.com/docs/us-16/materials/us-16-Bulazel-AVLeak-Fingerprinting-Antivirus-Emulators-For-Advanced-Malware-Evasion.pdf",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "PE Format Manipulation",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Evading signature can also be performed by modifying the PE structure (changing section names, TimeDateStamp, MajorLinkerVersion/MinorLinkerVersion, Major/Minor OperatingSystemVersion and ImageVersion/MinorImageVersion, AddressOfEntryPoint, Maximum number of sections, File length.",
            "resources": "https://pentest.blog/art-of-anti-detection-2-pe-backdoor-manufacturing/",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Evading Specific Signature",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "Some signatures are specifically designed to catch an exploit or a specific behaviour. By reversing the signature, it is possible to modify the malware to evade the signature. For example, by changing the size of the payload matching, or by changing the file's header.",
            "resources": "https://www.digital.security/en/blog/bypassing-antivirus-detection-pdf-exploit",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Evading Hash Signature",
            "category": [
                "https://search.unprotect.it/api/categories/2/"
            ],
            "description": "AV are able to detect if it's a known malware by calculating the file hash, by changing a simple bit into the binary can sometimes allow the sample to evade hash detection. This technique is unlikely to work anymore.",
            "resources": "https://resources.infosecinstitute.com/antivirus-evasion-tools/",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Connected Printer",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Another way to determine if it's a sandbox, is to detect a potential connected printer or identify the default Windows printers, Adobe, Onenote.",
            "resources": "https://www.slideshare.net/bz98/sandbox-detection-leak-abuse-test-hacktivity-2015",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Detecting USB Drive",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Another way to determine if it's a sandbox, it is to detect a potential USB drive.",
            "resources": "https://www.first.org/resources/papers/conf2017/Countering-Innovative-Sandbox-Evasion-Techniques-Used-by-Malware.pdf",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Detecting Hostname",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Most sandbox are using name like Sandbox, Cuckoo, Maltest, Malware, malsand, ClonePC.... All this hostname can provide the information to the malware.",
            "resources": "https://www.first.org/resources/papers/conf2017/Countering-Innovative-Sandbox-Evasion-Techniques-Used-by-Malware.pdf",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/35/",
                    "description": "",
                    "plain_code": "#include <iostream>\r\n#include <windows.h>\r\n\r\nint WINAPI WinMain ( HINSTANCE, HINSTANCE, LPSTR, int )\r\n{\r\n  char  ComputerName [MAX_COMPUTERNAME_LENGTH + 1];\r\n  DWORD cbComputerName = sizeof ( ComputerName );\r\n\r\n  if ( GetComputerName ( ComputerName, &cbComputerName ))\r\n     { \r\n         MessageBox ( NULL, ComputerName, \"Computer Name:\", MB_OK | MB_ICONINFORMATION ); \r\n     } \r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "sandbox_name",
                    "rule": "rule:\r\n  meta:\r\n    name: check for sandbox username\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: \"@_re_fox\"\r\n    scope: function\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection [B0009]\r\n    examples:\r\n      - ccbf7cba35bab56563c0fbe4237fdc41:0x402B90\r\n    references:\r\n      - https://github.com/LloydLabs/wsb-detect\r\n  features:\r\n    - and:\r\n      - api: GetUserName\r\n      - or:\r\n        - string: /MALTEST/i\r\n          description: Betabot Username Check\r\n        - string: /TEQUILABOOMBOOM/i\r\n          description: VirusTotal Sandbox\r\n        - string: /SANDBOX/i\r\n          description: Gookit Username Check\r\n        - string: /^VIRUS/i\r\n          description: Satan Username Check\r\n        - string: /MALWARE/i\r\n          description: Betabot Username Check\r\n        - string: /SAND\\sBOX/i\r\n          description: Betabot Username Check\r\n        - string: /Test\\sUser/i\r\n          description: Betabot Username Check\r\n        - string: /CurrentUser/i\r\n          description: Gookit Username Check\r\n        - string: /7SILVIA/i\r\n          description: Gookit Username Check\r\n        - string: /FORTINET/i\r\n          description: Shifu Username Check\r\n        - string: /John\\sDoe/i\r\n          description: Emotet Username Check\r\n        - string: /Emily/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /HANSPETER\\-PC/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /HAPUBWS/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /Hong\\sLee/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /IT\\-ADMIN/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /JOHN\\-PC/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /Johnson/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /Miller/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /MUELLER\\-PC/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /Peter\\sWilson/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /SystemIT/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /Timmy/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /WIN7\\-TRAPS/i\r\n          description: Trickbot Downloader Username Check\r\n        - string: /WDAGUtilityAccount/i\r\n          description: Windows Defender Application Guard"
                }
            ]
        },
        {
            "name": "Checking Hard Drive Size",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Not so many user machine are using less than 80Go, by requesting the drive size, malware can determined a virtual environment.",
            "resources": "https://www.botconf.eu/2015/sandbox-detection-for-the-masses-leak-abuse-test/",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/3/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/34/",
                    "description": "Python snippet to detect the drive size with `GetDiskFreeSpaceExW`",
                    "plain_code": "import ctypes\r\nimport math\r\n\r\n# Convert octets\r\ndef convert_size(size_bytes):\r\n    if size_bytes == 0:\r\n        return \"0B\"\r\n    size_name = (\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\")\r\n    i = int(math.floor(math.log(size_bytes, 1024)))\r\n    p = math.pow(1024, i)\r\n    s = round(size_bytes / p, 2)\r\n    return \"%s %s\" % (s, size_name[i])\r\n\r\n\r\n# Get disk size with API GetDiskFreeSpaceExW\r\ndef disk_size(path):\r\n    PULARGE_INTEGER = ctypes.POINTER(ctypes.c_ulonglong)\r\n    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)\r\n    kernel32.GetDiskFreeSpaceExW.argtypes = (ctypes.c_wchar_p,) + (PULARGE_INTEGER,) * 3\r\n\r\n    _, total, free = ctypes.c_ulonglong(), ctypes.c_ulonglong(), ctypes.c_ulonglong()\r\n    success = kernel32.GetDiskFreeSpaceExW(path, ctypes.byref(_), ctypes.byref(total), ctypes.byref(free))\r\n    size = convert_size(total.value)\r\n    print \"The size of the disk is: \", size\r\n\r\n\r\nif __name__ == '__main__':\r\n    disk_size(\"C:/\")"
                }
            ],
            "detection_rules": []
        },
        {
            "name": "Checking Memory Size",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Most of the modern user machine are at least 4Go or more. Machine with less memory size can be detected as a sandbox.",
            "resources": "https://www.botconf.eu/2015/sandbox-detection-for-the-masses-leak-abuse-test/",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Checking Installed Software",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "By determining which software are installed the sandbox can be detected (e.g: Python, Tracer, Debugging Tools, Vmware tools...).",
            "resources": "https://www.theguardian.com/technology/blog/2011/nov/08/sandboxing-malware-failure",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/3/",
                    "technique": "https://search.unprotect.it/api/techniques/32/",
                    "description": "This code snippet will browse the registry to check installed software.",
                    "plain_code": "#include <iostream>\r\n#include <windows.h>\r\n\r\nbool EnumInstalledSoftware(void)\r\n{\r\n    HKEY hUninstKey = NULL;\r\n    HKEY hAppKey = NULL;\r\n    WCHAR sAppKeyName[1024];\r\n    WCHAR sSubKey[1024];\r\n    WCHAR sDisplayName[1024];\r\n    WCHAR *sRoot = L\"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\";\r\n    long lResult = ERROR_SUCCESS;\r\n    DWORD dwType = KEY_ALL_ACCESS;\r\n    DWORD dwBufferSize = 0;\r\n\r\n    if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, sRoot, 0, KEY_READ, &hUninstKey) != ERROR_SUCCESS)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    for(DWORD dwIndex = 0; lResult == ERROR_SUCCESS; dwIndex++)\r\n    {\r\n        dwBufferSize = sizeof(sAppKeyName);\r\n        if((lResult = RegEnumKeyExW(hUninstKey, dwIndex, sAppKeyName,\r\n            &dwBufferSize, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)\r\n        {\r\n            //printf(sSubKey, L\"%s\\\\%s\", sRoot, sAppKeyName);\r\n            if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, sSubKey, 0, KEY_READ, &hAppKey) != ERROR_SUCCESS)\r\n            {\r\n                RegCloseKey(hAppKey);\r\n                RegCloseKey(hUninstKey);\r\n                return false;\r\n            }\r\n\r\n            dwBufferSize = sizeof(sDisplayName);\r\n            if(RegQueryValueExW(hAppKey, L\"DisplayName\", NULL,\r\n                &dwType, (unsigned char*)sDisplayName, &dwBufferSize) == ERROR_SUCCESS)\r\n            {\r\n                wprintf(L\"%s\\n\", sDisplayName);\r\n            }\r\n\r\n            RegCloseKey(hAppKey);\r\n        }\r\n    }\r\n\r\n    RegCloseKey(hUninstKey);\r\n\r\n    return true;\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/1/",
                    "name": "UNPROTECT_Check_installed_software",
                    "rule": "import \"pe\"\r\n\r\nrule check_installed_software {\r\n    meta:\r\n        description = \"Detect check installed software through registry\"\r\n        author = \"Thomas Roccia | @fr0gger_\"\r\n    strings:\r\n        $s1 = \"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\" wide\r\n\r\n    condition:\r\n       uint16(0) == 0x5A4D and $s1 or\r\n       pe.imports(\"Advapi32.dll\", \"RegQueryValueEx\")\r\n}"
                }
            ]
        },
        {
            "name": "Checking Screen Resolution",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Sandbox are not used to work as a normal user environment, so most of the time the screen resolution stay at the minimum 800x600 or lower. No one is actually working on a such small screen. Malware could potentially detect the screen resolution to determine if it's a user machine or a sandbox.",
            "resources": "https://www.botconf.eu/2015/sandbox-detection-for-the-masses-leak-abuse-test/",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/31/",
                    "description": "",
                    "plain_code": "#include \"wtypes.h\"\r\n#include <iostream>\r\nusing namespace std;\r\n\r\n/*\r\n1024x768 can be used for automated Sandbox\r\n800x600 can be used for automated Sandbox\r\n640x480 can be used for automated Sandbox\r\n1024x697\r\n1280x800\r\n1280x960\r\n1680x1050\r\n1916x1066\r\n*/\r\n\r\nvoid GetResolution(int& horiz, int& verti)\r\n{\r\n   RECT desktop;\r\n   const HWND hDesktop = GetDesktopWindow();\r\n   GetWindowRect(hDesktop, &desktop);\r\n   horiz = desktop.right;\r\n   verti = desktop.bottom;\r\n}\r\n\r\nint main()\r\n{\r\n   int horiz = 0;\r\n   int verti = 0;\r\n   GetResolution(horiz, verti);\r\n\r\n   if(horiz < 1024)\r\n   {\r\n      cout << \"[!] Looks like you run in a sandbox!\"<< '\\n';\r\n   }\r\n\r\n   cout << \"[+] Screen resolution: \"<< horiz << \"x\" << verti << '\\n';\r\n   return 0;\r\n}"
                }
            ],
            "detection_rules": []
        },
        {
            "name": "Checking Recent Office Files",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Another way to detect if the malware is running in a real user machine is to check if some recent Office files was opened.",
            "resources": "https://www.zscaler.com/blogs/research/malicious-documents-leveraging-new-anti-vm-anti-sandbox-techniques",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Checking Mouse Activity",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Some Sandbox doesn't have the mouse moving or a fun wallpaper, malware can detect if there is any activities into the sandbox.",
            "resources": "https://blogs.forcepoint.com/security-labs/highly-evasive-code-injection-awaits-user-interaction-delivering-malware",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "mouse_cursor",
                    "rule": "rule:\r\n  meta:\r\n    name: check for unmoving mouse cursor\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: BitsOfBinary\r\n    scope: function\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::User Activity Based Checks [T1497.002]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Human User Check [B0009.012]\r\n    references:\r\n      - https://www.joesecurity.org/blog/5852460122427342172\r\n    examples:\r\n      - 7E17F0F35D50F49407841372F24FBD38:0x4010f6\r\n  features:\r\n    - and:\r\n      - count(api(user32.GetCursorPos)): 2 or more"
                }
            ]
        },
        {
            "name": "Stalling Code",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "This technique is used for delaying execution of the real malicious code. Stalling code is typically executed before any malicious behavior. The attacker’s aim is to delay the execution of the malicious activity long enough so that an automated dynamic analysis system fails to extract the interesting malicious behavior.",
            "resources": "https://www.sans.org/reading-room/whitepapers/malicious/sleeping-sandbox-35797",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        },
        {
            "name": "Onset Delay",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Malware will delay execution to avoid analysis by the sample. For example, a Ping can be perform during a time defined. Unlike extended sleep that will use the Sleep function, onset delay will use another way to delay execution.\r\n\r\nThe purpose of such evasive code is to delay the execution of malicious activity long enough so that automated analysis systems give up on a sample, incorrectly assuming that the program is non-functional, or does not execute any action of interest.",
            "resources": "http://www.syssec-project.eu/m/page-media/3/hasten-ccs11.pdf\r\nhttps://blog.sonicwall.com/2018/02/6-ways-malware-evades-detection/",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/3/",
                    "name": "onset_delay",
                    "rule": "title: Powershell delayed execution via ping command\r\nstatus: experimental\r\ndescription: Powershell delayed execution via ping command\r\nauthor: Joe Security\r\ndate: 2020-03-17\r\nid: 200066\r\nthreatname:\r\nbehaviorgroup: 5\r\nclassification: 8\r\nmitreattack:\r\n\r\nlogsource:\r\n      category: process_creation\r\n      product: windows\r\ndetection:\r\n      selection:      \r\n          CommandLine:\r\n              - '*ping -n * & powershell.exe -executionpolicy bypass -noninteractive -windowstyle hidden*'\r\n      condition: selection\r\nlevel: critical"
                }
            ]
        },
        {
            "name": "VPCEXT",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "The VPCEXT instruction (visual property container extender) is another anti–virtual machine trick used by malware to detect virtual systems. This technique is not documented. If the execution of the instruction does not generate an exception (illegal instruction), then the program is running on a virtual machine.",
            "resources": "https://www.cert.pl/en/news/single/necurs-hybrid-spam-botnet/\r\nhttps://shasaurabh.blogspot.com/2017/07/virtual-machine-detection-techniques.html\r\nhttps://www.codeproject.com/Articles/9823/Detect-if-your-program-is-running-inside-a-Virtual",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/3/",
                    "technique": "https://search.unprotect.it/api/techniques/25/",
                    "description": "",
                    "plain_code": "/*\r\n-----------------------------------------------------------------------------\r\n  * Created by * lallous <lallousx86@yahoo.com> *\r\n  * All rights reserved.\r\n  *\r\n  * Redistribution and use in source and binary forms, with or without\r\n  * modification, are permitted provided that the following conditions\r\n  * are met:\r\n  * 1. Redistributions of source code must retain the above copyright\r\n  *    notice, this list of conditions and the following disclaimer.\r\n  *\r\n  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''\r\nAND\r\n  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r\n  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r\nPURPOSE\r\n  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE\r\nLIABLE\r\n  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r\nCONSEQUENTIAL\r\n  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\r\nGOODS\r\n  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r\n  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r\nSTRICT\r\n  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY\r\nWAY\r\n  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r\nOF\r\n  * SUCH DAMAGE.\r\n  *\r\n-----------------------------------------------------------------------------\r\n*/\r\n\r\n// IsInsideVPC's exception filter\r\nDWORD __forceinline IsInsideVPC_exceptionFilter(LPEXCEPTION_POINTERS ep)\r\n{\r\n   PCONTEXT ctx = ep->ContextRecord;\r\n\r\n   ctx->Ebx = -1; // Not running VPC\r\n   ctx->Eip += 4; // skip past the \"call VPC\" opcodes\r\n   return EXCEPTION_CONTINUE_EXECUTION;\r\n   // we can safely resume execution since we skipped faulty instruction\r\n}\r\n\r\n// high level language friendly version of IsInsideVPC()\r\nbool IsInsideVPC()\r\n{\r\n   bool rc = false;\r\n\r\n   __try\r\n   {\r\n     _asm push ebx\r\n     _asm mov  ebx, 0 // Flag\r\n     _asm mov  eax, 1 // VPC function number\r\n\r\n     // call VPC\r\n     _asm __emit 0Fh\r\n     _asm __emit 3Fh\r\n     _asm __emit 07h\r\n     _asm __emit 0Bh\r\n\r\n     _asm test ebx, ebx\r\n     _asm setz [rc]\r\n     _asm pop ebx\r\n   }\r\n   // The except block shouldn't get triggered if VPC is running!!\r\n   __except(IsInsideVPC_exceptionFilter(GetExceptionInformation()))\r\n   {\r\n   }\r\n\r\n   return rc;\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "VMCPUID",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "VMCPUID is another instruction that allows a malware to detect the virtual environment.",
            "resources": "https://www.cert.pl/en/news/single/necurs-hybrid-spam-botnet/",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "IN",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "An attempt to run such instructions in user-mode will generate an exception. VMWare uses IN instruction in a special port (VX) as an interface between VMM. So, such operation will not generate an exception if executed in user-mode inside a VMWare virtual machine.",
            "resources": "https://sites.google.com/site/bletchleypark2/malware-analysis/malware-technique/anti-vm",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "CPUID",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Checking the CPU ID found within the registry can provide information to what kind of system you are running.",
            "resources": "https://sites.google.com/site/bletchleypark2/malware-analysis/malware-technique/anti-vm",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/6/",
                    "technique": "https://search.unprotect.it/api/techniques/21/",
                    "description": "",
                    "plain_code": "/* Check hypervisor presence bit */\r\nstatic inline int cpuid_hv_bit(){\r\n    int ecx;\r\n    __asm__ volatile(\"cpuid\" \\\r\n        : \"=c\"(ecx) \\\r\n        : \"a\"(0x01));\r\n    return (ecx>>31) & 0x1;\r\n}\r\n/* Get hypervisor name */\r\nstatic inline void cpuid_hv_vendor_00(char * vendor){\r\n    int ebx = 0, ecx = 0, edx = 0;\r\n    __asm__ volatile(\"cpuid\" \\\r\n        : \"=b\"(ebx), \\\r\n        : \"=c\"(ecx), \\\r\n        : \"=d\"(edx) \\\r\n        : \"a\"(0x40000000));\r\n    sprintf(vendor, \"%c%c%c%c\", ebx, (ebx>>8), (ebx>>16), (ebx>>24));\r\n    sprintf(vendor+4, \"%c%c%c%c\", ebx, (ebx>>8), (ebx>>16), (ebx>>24));\r\n    sprintf(vendor+8, \"%c%c%c%c\", ebx, (ebx>>8), (ebx>>16), (ebx>>24));\r\n    vendor[12] = 0x00;\r\n}\r\nvoid cpu_write_hv_vendor(char * vendor){\r\n    cpuid_hv_vendor_00(vendor);\r\n}\r\nint cpu_known_vm_vendors(){\r\n    const int count = 6;\r\n    int i;\r\n    char cpu_hv_vendor[13];\r\n    strings strs[count];\r\n    strs[0] = \"KVMKVMKVM\\0\\0\\0\"; /* KVM */\r\n    strs[1] = \"Microsoft Hv\"; /* Microsoft Hyper-V or Windows Virtual PC */\r\n    strs[2] = \"VMwareVMware\"; /* VMware */\r\n    strs[3] = \"XenVMMXenVMM\"; /* Xen */\r\n    strs[4] = \"prl hyperv\"; */ Parallels */\r\n    strs[5] = \"VBoxVBoxVBox\"; /* VirtualBox */\r\n    cpu_write_hv_vendor(cpu_hv_vendor);\r\n    for (i=0; i < count; i++){\r\n        if (!memcmp(cpu_hv_vendor,strs[i], 12)) return TRUE;\r\n    }\r\n    return FALSE;\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "STR",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Stores the segment selector from the Task Register (TR).",
            "resources": "https://sites.google.com/site/bletchleypark2/malware-analysis/malware-technique/anti-vm",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "SMSW",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Stores the machine status word into the destination operand.",
            "resources": "https://sites.google.com/site/bletchleypark2/malware-analysis/malware-technique/anti-vm",
            "tags": "",
            "snippets": [
                {
                    "language": "https://search.unprotect.it/api/snippet_languages/2/",
                    "author": "https://search.unprotect.it/api/snippet_authors/2/",
                    "technique": "https://search.unprotect.it/api/techniques/19/",
                    "description": "",
                    "plain_code": "#include <iostream>\r\n\r\nusing namespace std;\r\n\r\nvoid smsw()\r\n{\r\n\tunsigned int reax = 0;\r\n\r\n\t__asm\r\n\t{\r\n\t\tmov eax, 0xCCCCCCCC\r\n\t\tsmsw eax\r\n\t\tmov DWORD PTR[reax], eax\r\n\t}\r\n\r\n\tif ((((reax >> 24) & 0xFF) == 0xcc) && (((reax >> 16) & 0xFF) == 0xcc))\r\n\t{\r\n\t    cout << \"VM detected!\" << endl;\r\n\t}\r\n}\r\n\r\nint main()\r\n{\r\n    smsw();\r\n    cout << \"Hello world!\" << endl;\r\n    return 0;\r\n}"
                }
            ],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "SLDT, No Pill",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "The No Pill technique relies on the fact that the LDT structure is assigned to a processor not an Operating System. The LDT location on a host machine will be zero and on a virtual machine will be non-zero.",
            "resources": "https://blog.talosintelligence.com/2009/10/how-does-malware-know-difference.html",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "SIDT, Red Pill",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Red Pill is an anti-VM technique that executes the SIDT instruction to grab the value of the IDTR register. The virtual machine monitor must relocate the guest's IDTR to avoid conflict with the host's IDTR. Since the virtual machine monitor is not notified when the virtual machine runs the SIDT instruction, the IDTR for the virtual machine is returned.",
            "resources": "https://litigationconferences.com/wp-content/uploads/2017/05/Introduction-to-Evasive-Techniques-v1.0.pdf",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "vm_instruction",
                    "rule": "rule:\r\n  meta:\r\n    name: execute anti-VM instructions\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: moritz.raabe@fireeye.com\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection::Instruction Testing [B0009.029]\r\n    examples:\r\n      - Practical Malware Analysis Lab 17-03.exe_:0x401A80\r\n  features:\r\n    - or:\r\n      - mnemonic: sdit\r\n      - mnemonic: sgdt\r\n      - mnemonic: sldt\r\n      - mnemonic: smsw\r\n      - mnemonic: str\r\n      - mnemonic: in\r\n      - mnemonic: cpuid\r\n      - mnemonic: vpcext"
                }
            ]
        },
        {
            "name": "Checking Pipe",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "Cuckoo uses a pipe \\\\\\\\.\\\\pipe\\\\cuckoo for the communication between the host system and the guest system. A malware can request the file to detect the virtual environment.",
            "resources": "https://www.slideshare.net/ThomasRoccia/sandbox-evasion-cheat-sheet",
            "tags": "",
            "snippets": [],
            "detection_rules": [
                {
                    "type": "https://search.unprotect.it/api/detection_rule_categories/2/",
                    "name": "device_pipe",
                    "rule": "rule:\r\n  meta:\r\n    name: check for windows sandbox via device\r\n    namespace: anti-analysis/anti-vm/vm-detection\r\n    author: \"@_re_fox\"\r\n    scope: basic block\r\n    att&ck:\r\n      - Defense Evasion::Virtualization/Sandbox Evasion::System Checks [T1497.001]\r\n    mbc:\r\n      - Anti-Behavioral Analysis::Virtual Machine Detection [B0009]\r\n    references:\r\n      - https://github.com/LloydLabs/wsb-detect\r\n    examples:\r\n      - 773290480d5445f11d3dc1b800728966:0x140001140\r\n  features:\r\n    - and:\r\n      - api: CreateFile\r\n      - string: \\\\.\\GLOBALROOT\\device\\vmsmb"
                }
            ]
        },
        {
            "name": "Detecting Hooked Function",
            "category": [
                "https://search.unprotect.it/api/categories/1/"
            ],
            "description": "To avoid some actions on the system by the malware like deleted a file. Cuckoo will hook some function and performs another action instead of the original one. For example the function DeleteFileW could be hooked to avoid file deletion.",
            "resources": "https://www.slideshare.net/ThomasRoccia/sandbox-evasion-cheat-sheet",
            "tags": "",
            "snippets": [],
            "detection_rules": []
        }
    ]
}