{
	"id": "08a823e6-cfa7-401d-a025-33e485b056cf",
	"created_at": "2026-04-06T00:16:18.347197Z",
	"updated_at": "2026-04-10T13:12:22.588195Z",
	"deleted_at": null,
	"sha1_hash": "316c1c936f78837e7148812ecb761adb7345a925",
	"title": "Using Qiling Framework to Unpack TA505 packed samples",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 502993,
	"plain_text": "Using Qiling Framework to Unpack TA505 packed samples\r\nBy mpeintner\r\nPublished: 2020-12-14 · Archived: 2026-04-05 18:21:22 UTC\r\nIntroduction\r\nThreat Actors make use of packers when distributing their malware as they remain an effective way to evade\r\ndetection and to make them more difficult to analyze. Manual analysis can defeat these protections and help to\r\ndevelop tools that allow the unpacking of the malware. To develop these tools, it is necessary to know how the\r\nprocess of unpacking for those malware samples is done in order to replicate their functionality. This can be a\r\ncostly task, and the modification of the unpacking algorithm by the Threat Actor would entail to study the\r\nmalware and modify the tools again.\r\nAt Blueliv, an Outpost24 company, we track Threat Actors like TA505, who also make use of packers in their\r\nmalware distribution campaigns. Regarding TA505, there are currently tools like TAFOF-Unpacker able to\r\nsuccessfully unpack their samples replicating the unpacking algorithm process.\r\nIn this blogpost, we are going to show how to unpack TA505 packed samples using the Qiling Framework\r\nemulator version 1.2, which will allow us to do so, without needing to study and replicate all the implementation\r\ndetails of the unpacking algorithm.\r\nTA505 Packer\r\nOur goal is to dump the unpacked payload from TA505 packed samples using emulation. As we said before, this\r\napproach allows us to circumvent the study of every implementation detail of the unpacking algorithm. However,\r\nwe still need to manually analyze the packer to find a way of getting the unpacked content and dump it.\r\nIn the case of TA505 packer, we could differentiate 3 stages.\r\nFirst stage\r\nThis stage consists of executing useless instructions and loops in order to obfuscate and/or slow down the\r\nanalysis. It also makes use of some anti-emulation techniques to avoid being studied by this kind of software.\r\nUse of useless loops to slow down emulation tasks:\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 1 of 16\n\nFigure 1. Anti-Emulation used in sample\r\ne4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e\r\nDummy functions in different samples:\r\nFigure 2. Dummy function used in sample\r\ne4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 2 of 16\n\nFigure 3. Dummy function used in sample\r\nbb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee\r\nFigure 4. Dummy function used in sample\r\n4b0eafcb1ec03ff3faccd2c0f465f5ac5824145d00e08035f57067a40cd179d2\r\nGetLastError() Anti-Emulation technique\r\nWe can see that between different samples, the dummy and useless functions vary. However, the anti-emulation\r\ntechnique remains the same in all of them, being present in the GetLastError() function. From the Official\r\nWindows API documentation:\r\n“Retrieves the calling thread’s last-error code value. The last-error code is maintained on a per-thread\r\nbasis. Multiple threads do not overwrite each other’s last-error code.”\r\nThis technique is used with different expected return values across different malware samples (using different API\r\ncalls before the GetLastError() occurs), for example:\r\nSetClipboardData:\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 3 of 16\n\nFigure 5. Anti-Emulation used in sample\r\nad320839e01df160c5feb0e89131521719a65ab11c952f33e03d802ecee3f51f\r\nGetWindowContextHelpId:\r\nFigure 6. Anti-Emulation used in sample\r\ne4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e\r\nFigure 7. Anti-Emulation used in sample\r\n4b0eafcb1ec03ff3faccd2c0f465f5ac5824145d00e08035f57067a40cd179d2\r\nFigure 8. Anti-Emulation used in sample\r\nbb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 4 of 16\n\nFor instance, last figure shows the malware calls GetLastError() and the only instruction executed before this\r\none that could have set an error value is the execution of the API call GetWindowsContextHelpId(). From the\r\nOfficial Windows API Documentation:\r\n“Retrieves the Help context identifier, if any, associated with the specified window.”\r\nGiven that the window handle used in this function is invalid, the sample expects this last call to set error value\r\nto 0x578 (ERROR_INVALID_WINDOW_HANDLE), (which is what would happen in a non-emulated\r\nenvironment), and then continues execution. We will have to code this behavior so that the emulation can\r\ndetonate the actual sample, because the emulator is not able to predict the value corresponding to GetLastError()\r\nby itself, since it does not have the real running context of an operating system.\r\nSecond stage\r\nUnpacks an encrypted shellcode in a newly allocated memory in the heap and transfers execution to it. This\r\nshellcode contains the actual Stub of the packer. This stage may also contain junk and useless code to difficult the\r\nmalware analysis.\r\nFigure 9. Unpacking Packer Stub bb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee\r\nThird stage\r\nThis is the TA505 Packer Stub (piece of code containing the decryption routine), that will act as a loader for the\r\nfinal payload, which is written in heap memory and executed. It starts by storing some strings in the stack that will\r\nuse to find the Windows APIs needed to unpack itself: VirtualAlloc, VirtualProtect, LoadLibraryA,\r\nVirtualFree and VirtualQuery.\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 5 of 16\n\nFigure 10. TA505 packers store strings in the stack to resolve Windows API functions.\r\nIt relies on a self-modifying unpacking technique, trying to acquire a block of writeable, executable memory,\r\nunpacking (decrypting and writing) code to the newly allocated memory and finally, transferring execution to the\r\nunpacked code in the newly allocated memory.\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 6 of 16\n\nFigure 11. Packer Stub bb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee\r\nAs it is shown in the last screenshot. The Stub calls VirtualFree() after having written the decrypted payload in\r\nthe newly allocated memory. Our strategy should consider saving the allocated blocks of memory and dump them\r\nonce VirtualFree() is executed (at this point we have seen that the malware is just about to start running the\r\nunpacked payload and it’s in the state which is going to be executed; it is safe to dump now). Before\r\nVirtualFree() happens, we can see the unpacked layer in the last allocated block of memory that we’ve named\r\nallocated2.\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 7 of 16\n\nFigure 12. Unpacked payload bb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee\r\nWe should be able, with emulation, to guide the execution until this point and then dump right away the contents\r\nof the last allocated code to get the next unpacked layer. This is what we are going to try with Qiling\r\nFramework v1.2. Executing the sample using Qiling Framework would allow it to be unpacked automatically,\r\nand we would only have to put hooks into specific Windows API functions to get the unpacked binary.\r\nQiling Framework\r\nQiling Framework is an advanced open source binary emulation Framework, with binary instrumentation and\r\nAPI emulation being its main focus and priority. It is designed as a cross-platform binary instrumentation and\r\nbinary emulation framework and has support for multi-architecture. Code interception and arbitrary code injection\r\nbefore or during a binary execution are one of its powerful features, as well as being able to patch a binary during\r\nexecution.\r\nThe advantage of using the Qiling Framework for this purpose is that changes made to the unpacking algorithm\r\nwill not prevent the samples from being unpacked. This is because we are obviously not implementing the\r\ndecryption algorithm itself, but emulating it instead. However, we also find some obstacles when using emulators,\r\nas packers can also make use of anti-emulation techniques. In this case we would need to understand how the\r\npacker detects the emulator in order to bypass the countermeasures.\r\nFor what we have seen during the analysis of the packer. We would need to:\r\n1. Bypass anti-emulation techniques to execute the Packer Stub\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 8 of 16\n\n2. Store dynamically allocated blocks of memory information (address and size)\r\n3. Dump the unpacked PE once it is ready. (For example, before VirtualFree() gets executed)\r\nBypass anti-emulation techniques\r\nBypass GetLastError() anti-emulation technique\r\nTA505 packer makes use of GetLastError() call to avoid unpacking if it is running in an emulated environment.\r\nTo bypass this measure, we need to find out which API call is meant to set the expected error code in the packer,\r\nthis will usually happen just before the actual call to GetLastError(). Once found, we should add a hook to this\r\nAPI call and force the return of the expected error code. This way, when GetLastError() gets emulated, it will\r\nreceive the value we want, and continue the execution.\r\nMost of the analyzed samples, make use of the call GetWindowContextHelpId() in an “obfuscated” way. They\r\nload the string “SetWindowContextHelpId” and replace the first letter with a “G” before making the call.\r\nFigure 13. bb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee calling\r\nGetWindowContextHelpId as part of its anti-emulation technique\r\nOther samples may use different approaches, but all based on the GetLastError() technique. For example, the\r\nsample e4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e makes use of the API call\r\nSetClassLongA(). From the Official Windows API Documentation:\r\n“Replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the\r\nWNDCLASSEX structure for the class to which the specified window belongs.”\r\nWhen being used like in these samples, the expected behavior (as it is using an invalid Window Handle) is to get\r\nan error 0x578 (ERROR_INVALID_WINDOW_HANDLE).\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 9 of 16\n\nFigure 14. e4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e anti-emulation techniques\r\nbefore unpacking the Packer Stub\r\nOnce identified those API calls, we can reimplement them with Qiling to make sure they set the proper error codes\r\nso that the next call to GetLastError() jumps to the correct branch of the code. Qiling Framework allows us to\r\nreimplement these API calls easily:\r\nGetWindowContextHelpId() hook implementation:\r\nDWORD GetWindowContextHelpId( HWND Arg1 );\r\n@winsdkapi(cc=STDCALL, dllname=”user32_dll”) def hook_GetWindowContextHelpId(ql, address, params):\r\nERROR_INVALID_WINDOW_HANDLE = 0x578 ql.os.last_error = ERROR_INVALID_WINDOW_HANDLE\r\nreturn 0\r\nSetClassLongA() hook implementation:\r\nDWORD SetClassLongA( HWND hWnd, int nIndex, LONG dwNewLong );\r\n@winsdkapi(cc=STDCALL, dllname=”user32_dll”) def hook_SetClassLongA(ql, address, params):\r\nERROR_INVALID_WINDOW_HANDLE = 0x578 ql.os.last_error = ERROR_INVALID_WINDOW_HANDLE\r\nreturn 0\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 10 of 16\n\nWe have to set API hooks before calling “ql.run()“.\r\nql.set_api(“GetWindowContextHelpId”, hook_GetWindowContextHelpId) ql.set_api(“SetClassLongA”,\r\nhook_SetClassLongA)\r\nQiling Framework emulator is constantly evolving. However, there might be some API calls still not present in\r\nthe code. In those cases, we will have to reimplement them, although we could also just give to the caller what he\r\nexpects in order to bypass the different anti-emulation techniques (not emulating the actual Windows call, but\r\nleaving what the sample needs, like the error code in this case, instead).\r\nThis is the case of some API calls that need to be “emulated” so that the malware can continue with its execution.\r\nFor instance, the following Figure shows a packed sample where the interesting “GetLastError()” anti-emulation\r\ntechnique is inside an if statement. We need to make sure that the sample takes the correct conditional path. To do\r\nso, we need to reimplement “ImageList_Add()” as by the time of writing this Blogpost, this is not emulated by\r\ndefault by Qiling.\r\nFigure 15. bb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee anti-emulation techniques\r\nbefore unpacking Packer Stub\r\nImageList_Add() hook implementation:\r\nint ImageList_Add( HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask );\r\n@winsdkapi(cc=STDCALL, dllname=”comctl32_dll”) def hook_ImageList_Add(ql, address, params): ret =\r\n0xFFFFFFFF return ret\r\nThe same happens in sample bb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee with\r\n__wgetmainargs:\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 11 of 16\n\n__wgetmainargs() hook implementation:\r\nint __wgetmainargs ( int *_Argc, wchar_t ***_Argv, wchar_t ***_Env, int _DoWildCard, _startupinfo *\r\n_StartInfo )\r\n@winsdkapi(cc=STDCALL, dllname=”msvcrt_dll”) def hook___wgetmainargs(ql, address, params): return 0\r\nThe sample 74c5ae5e64d0a850eb0ebe3cbca4c6b92918a8365f2f78306643be9cffc32def also makes use of some\r\nAPI calls that need to be reimplemented to get the malware to execute the unpacking Stub.\r\nCoReleaseMarshalData() hook implementation:\r\nHRESULT CoReleaseMarshalData( LPSTREAM pStm );\r\n@winsdkapi(cc=STDCALL, dllname=”ole32_dll”) def hook_CoReleaseMarshalData(ql, addrss, params):\r\nE_INVALIDARG = 0x80070057 return E_INVALIDARG\r\nNOTE: During the development of this tool, we found out that the hooks for CoReleaseMarshalData and\r\nImageListAdd where not working. Apparently, these functions are properly declared in Qiling Framework\r\nversion 1.2, but when we try to run our tool we got a “Windows API implementation error“. This is because\r\nQiling is missing some references in its const.py file. More precisely, it is missing the references for:\r\n“HBITMAP”: “HANDLE”, “HIMAGELIST”: “HANDLE”, “LPSTREAM” : “POINTER”\r\nA pull request to the Qiling project has already been accepted and commited to the development branch which\r\nsolves this issue.\r\nShellExecuteA() hook implementation:\r\nHINSTANCE ShellExecuteA( HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters,\r\nLPCSTR lpDirectory INT nShowCmd );\r\n@winsdkapi(cc=STDCALL, dllname=”shell32_dll”) def hook_ShellExecuteA(ql, address, params): return 0\r\nCreateEventA() hook implementation:\r\nHANDLE CreateEventA( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL\r\nbInitialState, LPCSTR lpName );\r\n@winsdkapi(cc=STDCALL, dllname=”kernel32_dll”) def hook_CreateEventA(ql, address, params): return 0\r\nVirtualQuery hook implementation:\r\nVirtualQuery also seems to give problems when running those samples. The easiest way to make these samples\r\ncontinue with their execution is reimplementing this API call too so that it gives the sample what it wants. In the\r\ncase of TA505 Packer, the unpacking Stub just checks if the return value of this call is a positive value. We can\r\nconsider then:\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 12 of 16\n\nSIZE_T VirtualQuery( LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength\r\n);\r\n@ winsdkapi(cc=STDCALL, dllname=”kernel32_dll”) def hook_VirtualQuery(ql, address, params): return\r\nparams[‘dwLength’]\r\nBypass useless loops to slow down emulation tasks\r\nSome TA505 Packed samples make use of another anti-emulation technique. They execute long useless loops that\r\nmakes emulation take forever (as these loops execute fast in non-emulated environments). Long loops with calls\r\nto Windows Api calls can also be used as an anti-sandbox technique. This can be seen in the following figure:\r\nFigure 16. Anti-Emulation technique used in\r\ne4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e\r\nTo bypass this with Qiling in an “automated” way, we could obviously manually patch the binary or use Qiling\r\nsearch pattern to add this functionality in our unpacking script.\r\ndef patch_binary(ql): patches = [] ”’ Original 81 7D B4 40 42 0F 00 cmp [ebp+var_4C], 1000000 Patch: 81 7D B4\r\n00 00 00 00 cmp [ebp+var_4C], 0 ”’ patch_ = { ‘original’: b’\\x81\\x7D\\xB4\\x40\\x42\\x0F\\x00′, ‘patch’:\r\nb’\\x81\\x7D\\xB4\\x00\\x00\\x00\\x00′ } patches.append(patch_) for patch in patches: antiemu_loop_addr =\r\nql.mem.search(patch[‘original’]) if antiemu_loop_addr: ql.nprint(D_INFO, ‘Found Anti-Emulation loop at addr:\r\n{}’.format(hex(antiemu_loop_addr[0]))) try: ql.patch(antiemu_loop_addr[0], patch[‘patch’]) ql.nprint(D_INFO,\r\n‘Successfully patched!’) return except Exception as err: ql.nprint(D_INFO, ‘Unable to patch binary:\r\n{}’.format(err))\r\nStore dynamically allocated blocks of memory information (address and size)\r\nAs we said previously, the unpacked malware will be written into a new allocated block of memory. It will use\r\nVirtuAlloc() and VirtualAllocEx() to allocate space for the unpacking Stub and the payload. We will need to\r\nkeep track of these allocations in order to be able to dump them when VirtualFree() gets called. We could\r\nreimplement VirtualAlloc() and VirtualAllocEx() for the unpacking in this way:\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 13 of 16\n\nLPVOID VirtualAllocEx( HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType,\r\nDWORD flProtect );\r\n@winsdkapi(cc=STDCALL, dllname=”kernel32_dll”) def hook_VirtualAllocEx(ql, address, params): dw_size =\r\nparams[“dwSize”] addr = ql.os.heap.alloc(dw_size) fl_protect = params[“flProtect”] if fl_protect in [0x1, 0x2,\r\n0x4, 0x8,0x10, 0x20, 0x40, 0x80]: ql.nprint(D_INFO, “VirtualAllocEx start: {} – size: {}”.format(hex(addr),\r\nhex(dw_size))) mem_regions.append({“start”: addr, “size”: dw_size}) return addr\r\nLPVOID VirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );\r\n@winsdkapi(cc=STDCALL, dllname=”kernel32_dll”) def hook_VirtualAlloc(ql, address, params): dw_size =\r\nparams[“dwSize”] addr = ql.os.heap.alloc(dw_size) fl_protect = params[“flProtect”] if fl_protect in [0x1, 0x2,\r\n0x4, 0x8,0x10, 0x20, 0x40, 0x80]: ql.nprint(D_INFO, “VirtualAlloc start: {} – size: {}”.format(hex(addr),\r\nhex(dw_size))) mem_regions.append({“start”: addr, “size”: dw_size}) return addr\r\nDump the unpacked PE once it is ready\r\nNow the last thing left to do is to dump the contents of the last allocated block once we reach the execution of\r\nVirtualFree():\r\ndef dump_memory_region(ql, address, size): ql.nprint(D_INFO, “Read memory region at address: {} – size:\r\n{}”.format(hex(address), hex(size))) try: excuted_mem = ql.mem.read(address, size) except Exception as err:\r\nlog.warning(‘Unable to read memory region at address: {}. Error: {}’.format(hex(address), err)) return\r\nql.nprint(D_INFO, “Dump memory region at address: {} – size: {}”.format(hex(address), hex(size))) with\r\nopen(“unpacked_”+hex(address)+”.bin”, “wb”) as f: f.write(excuted_mem) # write extracted code to a binary file\r\nBOOL VirtualFree( LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType );\r\n@winapi(cc=STDCALL, params={ “lpAddress”: POINTER, “dwSize”: SIZE_T, “dwFreeType”: DWORD }) def\r\nhook_VirtualFree(ql, address, params): global mem_regions lpAddress = params[“lpAddress”] ql.nprint(D_INFO,\r\n“VirtualFree called for address: {}”.format(hex(lpAddress))) ql.nprint(D_INFO, “Memory regions stored:\r\n{}”.format(mem_regions)) try: if mem_regions: unpacked_layer = mem_regions[-1] # Unpacked layer is in the\r\nlast allocated block start = unpacked_layer[“start”] size = unpacked_layer[“size”] dump_memory_region(ql, start,\r\nsize) except Exception as err: ql.nprint(D_INFO, ‘Unable to dump memory region: {}’.format(err))\r\nql.os.heap.free(lpAddress) ql.emu_stop() return 1\r\nProof of Concept\r\nYou can find our proof of concept in our repository.\r\nIOC\r\nSHA256 Packed samples:\r\nSHA256 Unpacked samples:\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 14 of 16\n\nMalware: AZORULT\r\ne4eb1a831a8cc7402c8e0a898effd3fb966a9ee1a22bce9ddc3e44e574fe8c5e\r\n103084a964d0b150e1268c8a1a9d8c2545f7f0721e78a1b98b74304320aeb547\r\nMalware: GELUP\r\nbb5054f0ec4e6980f65fb9329a0b5acec1ed936053c3ef0938b5fa02a9daf7ee\r\n6d15cd4cadac81ee44013d1ad32c18a27ccd38671dee051fb58b5786bc0fa7d3\r\nMalware: SILENCE\r\n4b0eafcb1ec03ff3faccd2c0f465f5ac5824145d00e08035f57067a40cd179d2\r\nb9a0bde76d0bc7cc497c9cd17670d86813c97a9f8bed09ea99d4bf531adafb27\r\nMalware: AMY RAT\r\nad320839e01df160c5feb0e89131521719a65ab11c952f33e03d802ecee3f51f\r\n8a30f4c59d111658b7f9efbd5f5b794228394cd53d22a1fb389fd3a03fc4d1f7\r\nMalware: TINYMET\r\n74c5ae5e64d0a850eb0ebe3cbca4c6b92918a8365f2f78306643be9cffc32def\r\n6831fc67ca09d9027fef8b3031a11e9595fc1df1cb547c6f587947d13dad151a\r\nConclusion\r\nAs has been seen throughout the article, incorporating Qiling Framework as one of your reverse engineering\r\ntools facilitates the tasks of malware analysis. In this case, it allows us to easily and quickly unpack samples\r\npacked with TA505Packer without needing to have extensive knowledge about its implementation details.\r\nMoreover it is cross-platform.\r\nFrom Blueliv we encourage other researchers to make use of Qiling Framework and we hope this project\r\ncontinues growing.\r\nFor more details about how we reverse engineer and analyze malware, visit our targeted malware module page.\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 15 of 16\n\nReferences\r\nQiling Documentation\r\nAutomated malware unpacking with binary emulation\r\nPE Emulation With Code Coverage Using Qiling and Dragon Dance\r\nAbout the Author\r\nAlberto leads the Reverse Engineering team at Outpost24's KrakenLabs department. He has been working in\r\ncybersecurity since 2014, focusing on malware research, reverse engineering, and Sandbox development for\r\nautomated malware analysis. \r\nSource: https://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nhttps://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/\r\nPage 16 of 16",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://outpost24.com/blog/using-qiling-framework-to-unpack-ta505-packed-samples/"
	],
	"report_names": [
		"using-qiling-framework-to-unpack-ta505-packed-samples"
	],
	"threat_actors": [
		{
			"id": "42a6a29d-6b98-4fd6-a742-a45a0306c7b0",
			"created_at": "2022-10-25T15:50:23.710403Z",
			"updated_at": "2026-04-10T02:00:05.281246Z",
			"deleted_at": null,
			"main_name": "Silence",
			"aliases": [
				"Whisper Spider"
			],
			"source_name": "MITRE:Silence",
			"tools": [
				"Winexe",
				"SDelete"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "5e6b31a6-80e3-4e7d-8b0a-d94897ce9b59",
			"created_at": "2024-06-19T02:03:08.128175Z",
			"updated_at": "2026-04-10T02:00:03.636663Z",
			"deleted_at": null,
			"main_name": "GOLD TAHOE",
			"aliases": [
				"Cl0P Group Identity",
				"FIN11 ",
				"GRACEFUL SPIDER ",
				"SectorJ04 ",
				"Spandex Tempest ",
				"TA505 "
			],
			"source_name": "Secureworks:GOLD TAHOE",
			"tools": [
				"Clop",
				"Cobalt Strike",
				"FlawedAmmy",
				"Get2",
				"GraceWire",
				"Malichus",
				"SDBbot",
				"ServHelper",
				"TrueBot"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "75d4d6a9-b5d1-4087-a7a0-e4a9587c45f4",
			"created_at": "2022-10-25T15:50:23.5188Z",
			"updated_at": "2026-04-10T02:00:05.26565Z",
			"deleted_at": null,
			"main_name": "TA505",
			"aliases": [
				"TA505",
				"Hive0065",
				"Spandex Tempest",
				"CHIMBORAZO"
			],
			"source_name": "MITRE:TA505",
			"tools": [
				"AdFind",
				"Azorult",
				"FlawedAmmyy",
				"Mimikatz",
				"Dridex",
				"TrickBot",
				"Get2",
				"FlawedGrace",
				"Cobalt Strike",
				"ServHelper",
				"Amadey",
				"SDBbot",
				"PowerSploit"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "eb5915d6-49a0-464d-9e4e-e1e2d3d31bc7",
			"created_at": "2025-03-29T02:05:20.764715Z",
			"updated_at": "2026-04-10T02:00:03.851829Z",
			"deleted_at": null,
			"main_name": "GOLD WYMAN",
			"aliases": [
				"Silence "
			],
			"source_name": "Secureworks:GOLD WYMAN",
			"tools": [
				"Silence"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "88e53203-891a-46f8-9ced-81d874a271c4",
			"created_at": "2022-10-25T16:07:24.191982Z",
			"updated_at": "2026-04-10T02:00:04.895327Z",
			"deleted_at": null,
			"main_name": "Silence",
			"aliases": [
				"ATK 86",
				"Contract Crew",
				"G0091",
				"TAG-CR8",
				"TEMP.TruthTeller",
				"Whisper Spider"
			],
			"source_name": "ETDA:Silence",
			"tools": [
				"EDA",
				"EmpireDNSAgent",
				"Farse",
				"Ivoke",
				"Kikothac",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"Meterpreter",
				"ProxyBot",
				"ReconModule",
				"Silence.Downloader",
				"TiniMet",
				"TinyMet",
				"TrueBot",
				"xfs-disp.exe"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "99cb4e5b-8071-4f9e-aa1d-45bfbb6197e3",
			"created_at": "2023-01-06T13:46:38.860754Z",
			"updated_at": "2026-04-10T02:00:03.125179Z",
			"deleted_at": null,
			"main_name": "TA505",
			"aliases": [
				"SectorJ04",
				"SectorJ04 Group",
				"ATK103",
				"GRACEFUL SPIDER",
				"GOLD TAHOE",
				"Dudear",
				"G0092",
				"Hive0065",
				"CHIMBORAZO",
				"Spandex Tempest"
			],
			"source_name": "MISPGALAXY:TA505",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "e447d393-c259-46e2-9932-19be2ba67149",
			"created_at": "2022-10-25T16:07:24.28282Z",
			"updated_at": "2026-04-10T02:00:04.921616Z",
			"deleted_at": null,
			"main_name": "TA505",
			"aliases": [
				"ATK 103",
				"Chimborazo",
				"G0092",
				"Gold Evergreen",
				"Gold Tahoe",
				"Graceful Spider",
				"Hive0065",
				"Operation Tovar",
				"Operation Trident Breach",
				"SectorJ04",
				"Spandex Tempest",
				"TA505",
				"TEMP.Warlock"
			],
			"source_name": "ETDA:TA505",
			"tools": [
				"Amadey",
				"AmmyyRAT",
				"AndroMut",
				"Azer",
				"Bart",
				"Bugat v5",
				"CryptFile2",
				"CryptoLocker",
				"CryptoMix",
				"CryptoShield",
				"Dridex",
				"Dudear",
				"EmailStealer",
				"FRIENDSPEAK",
				"Fake Globe",
				"Fareit",
				"FlawedAmmyy",
				"FlawedGrace",
				"FlowerPippi",
				"GOZ",
				"GameOver Zeus",
				"GazGolder",
				"Gelup",
				"Get2",
				"GetandGo",
				"GlobeImposter",
				"Gorhax",
				"GraceWire",
				"Gussdoor",
				"Jaff",
				"Kasidet",
				"Kegotip",
				"Kneber",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"Locky",
				"MINEBRIDGE",
				"MINEBRIDGE RAT",
				"MirrorBlast",
				"Neutrino Bot",
				"Neutrino Exploit Kit",
				"P2P Zeus",
				"Peer-to-Peer Zeus",
				"Philadelphia",
				"Philadephia Ransom",
				"Pony Loader",
				"Rakhni",
				"ReflectiveGnome",
				"Remote Manipulator System",
				"RockLoader",
				"RuRAT",
				"SDBbot",
				"ServHelper",
				"Shifu",
				"Siplog",
				"TeslaGun",
				"TiniMet",
				"TinyMet",
				"Trojan.Zbot",
				"Wsnpoem",
				"Zbot",
				"Zeta",
				"ZeuS",
				"Zeus"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434578,
	"ts_updated_at": 1775826742,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/316c1c936f78837e7148812ecb761adb7345a925.pdf",
		"text": "https://archive.orkl.eu/316c1c936f78837e7148812ecb761adb7345a925.txt",
		"img": "https://archive.orkl.eu/316c1c936f78837e7148812ecb761adb7345a925.jpg"
	}
}