www.huntress.com
Open in
urlscan Pro
2606:2c40::c73c:671c
Public Scan
URL:
https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-shellcode-detection
Submission: On October 04 via api from DE — Scanned from DE
Submission: On October 04 via api from DE — Scanned from DE
Form analysis
4 forms found in the DOM/hs-search-results
<form action="/hs-search-results" data-hs-cf-bound="true">
<div class="pwr--relative">
<input type="text" id="pwr-js-burger-search__input" class="pwr-burger-search__input hs-search-field__input" name="term" autocomplete="off" aria-label="Search" placeholder="Type search here">
<button class="pwr-search-field__icon" type="submit"><span id="hs_cos_wrapper_module_167327601750737_" class="hs_cos_wrapper hs_cos_wrapper_widget hs_cos_wrapper_type_icon" style="" data-hs-cos-general-type="widget" data-hs-cos-type="icon"><svg
version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-hidden="true">
<g id="search2_layer">
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z">
</path>
</g>
</svg></span></button>
</div>
</form>
/hs-search-results
<form action="/hs-search-results" data-hs-cf-bound="true">
<input type="text" id="pwr-js-burger-search__input" class="" name="term" autocomplete="off" aria-label="Search" placeholder="Search">
</form>
/hs-search-results
<form action="/hs-search-results" data-hs-cf-bound="true">
<div class="pwr--relative">
<input type="text" id="pwr-header-search__input" class="pwr-header-search__input hs-search-field__input" name="term" autocomplete="off" aria-label="Search" placeholder="Type search here. Hit enter to submit or escape to close.">
<button class="pwr-search-field__icon" type="submit"><span id="hs_cos_wrapper_module_167327601750737_" class="hs_cos_wrapper hs_cos_wrapper_widget hs_cos_wrapper_type_icon" style="" data-hs-cos-general-type="widget" data-hs-cos-type="icon"><svg
version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-hidden="true">
<g id="search3_layer">
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z">
</path>
</g>
</svg></span></button>
<a href="#" id="pwr-js-header-search__close" class="pwr-header-search__close">
<span class="pwr-header-search__close-icon"></span>
</a>
</div>
</form>
POST https://forms.hsforms.com/submissions/v3/public/submit/formsnext/multipart/3911692/196be66c-f1bb-4156-af05-2952954526cd
<form id="hsForm_196be66c-f1bb-4156-af05-2952954526cd_6056" method="POST" accept-charset="UTF-8" enctype="multipart/form-data" novalidate=""
action="https://forms.hsforms.com/submissions/v3/public/submit/formsnext/multipart/3911692/196be66c-f1bb-4156-af05-2952954526cd"
class="hs-form-private hsForm_196be66c-f1bb-4156-af05-2952954526cd hs-form-196be66c-f1bb-4156-af05-2952954526cd hs-form-196be66c-f1bb-4156-af05-2952954526cd_06045364-21c8-4ab8-abef-7ca2b7ba2fe9 hs-form stacked hs-custom-form"
target="target_iframe_196be66c-f1bb-4156-af05-2952954526cd_6056" data-instance-id="06045364-21c8-4ab8-abef-7ca2b7ba2fe9" data-form-id="196be66c-f1bb-4156-af05-2952954526cd" data-portal-id="3911692" data-hs-cf-bound="true">
<div class="hs_email hs-email hs-fieldtype-text field hs-form-field"><label id="label-email-196be66c-f1bb-4156-af05-2952954526cd_6056" class="" placeholder="Enter your Work Email (required)"
for="email-196be66c-f1bb-4156-af05-2952954526cd_6056"><span>Work Email (required)</span><span class="hs-form-required">*</span></label>
<legend class="hs-field-desc" style="display: none;"></legend>
<div class="input"><input id="email-196be66c-f1bb-4156-af05-2952954526cd_6056" name="email" required="" placeholder="" type="email" class="hs-input" inputmode="email" autocomplete="email" value=""></div>
</div>
<div class="hs_submit hs-submit">
<div class="hs-field-desc" style="display: none;"></div>
<div class="actions"><input type="submit" class="hs-button primary large" value="Subscribe"></div>
</div><input name="hs_context" type="hidden"
value="{"embedAtTimestamp":"1696427275716","formDefinitionUpdatedAt":"1674667130846","lang":"en","embedType":"REGULAR","clonedFromForm":"6da6c019-9d2a-47d7-8966-09563d0875cf","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36","pageTitle":"Hackers No Hashing: Randomizing API Hashes to Evade Cobalt Strike Shellcode Detection","pageUrl":"https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-shellcode-detection","pageId":"66424554568","isHubSpotCmsGeneratedPage":true,"canonicalUrl":"https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-shellcode-detection","contentType":"blog-post","hutk":"56b18107339c374c18ddbf164521d6fc","__hsfp":1666088104,"__hssc":"1139630.1.1696427276870","__hstc":"1139630.56b18107339c374c18ddbf164521d6fc.1696427276869.1696427276869.1696427276869.1","formTarget":"#hs_form_target_module_155266670085300_subscribe","formInstanceId":"6056","pageName":"Hackers No Hashing: Randomizing API Hashes to Evade Cobalt Strike Shellcode Detection","locale":"en","timestamp":1696427276885,"originalEmbedContext":{"portalId":"3911692","formId":"196be66c-f1bb-4156-af05-2952954526cd","region":"na1","target":"#hs_form_target_module_155266670085300_subscribe","isBuilder":false,"isTestPage":false,"isPreview":false,"formInstanceId":"6056","formsBaseUrl":"/_hcms/forms","css":"","isMobileResponsive":true,"pageName":"Hackers No Hashing: Randomizing API Hashes to Evade Cobalt Strike Shellcode Detection","pageId":"66424554568","contentType":"blog-post","formData":{"cssClass":"hs-form stacked hs-custom-form"},"isCMSModuleEmbed":true},"correlationId":"06045364-21c8-4ab8-abef-7ca2b7ba2fe9","renderedFieldsIds":["email"],"captchaStatus":"NOT_APPLICABLE","emailResubscribeStatus":"NOT_APPLICABLE","isInsideCrossOriginFrame":false,"source":"forms-embed-1.3812","sourceName":"forms-embed","sourceVersion":"1.3812","sourceVersionMajor":"1","sourceVersionMinor":"3812","_debug_allPageIds":{"embedContextPageId":"66424554568","analyticsPageId":"66424554568","pageContextPageId":"66424554568"},"_debug_embedLogLines":[{"clientTimestamp":1696427275828,"level":"INFO","message":"Retrieved customer callbacks used on embed context: [\"getExtraMetaDataBeforeSubmit\"]"},{"clientTimestamp":1696427275831,"level":"INFO","message":"Retrieved pageContext values which may be overriden by the embed context: {\"pageTitle\":\"Hackers No Hashing: Randomizing API Hashes to Evade Cobalt Strike Shellcode Detection\",\"pageUrl\":\"https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-shellcode-detection\",\"userAgent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36\",\"pageId\":\"66424554568\",\"isHubSpotCmsGeneratedPage\":true}"},{"clientTimestamp":1696427275833,"level":"INFO","message":"Retrieved countryCode property from normalized embed definition response: \"DE\""},{"clientTimestamp":1696427276878,"level":"INFO","message":"Retrieved analytics values from API response which may be overriden by the embed context: {\"hutk\":\"56b18107339c374c18ddbf164521d6fc\",\"canonicalUrl\":\"https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-shellcode-detection\",\"contentType\":\"blog-post\",\"pageId\":\"66424554568\"}"}]}"><iframe
name="target_iframe_196be66c-f1bb-4156-af05-2952954526cd_6056" style="display: none;"></iframe>
</form>
Text Content
This website stores cookies on your computer. These cookies are used to improve your website and provide more personalized services to you, both on this website and through other media. To find out more about the cookies we use, see our Privacy Policy. Accept Decline Skip to content Close * Platform * Platform Overview Cybersecurity for the 99% * Managed EDR Stop Attacks with Process Insights * SOC 24/7 Human Threat Hunting * Persistent Footholds Find Attackers Hiding in Plain Sight * Managed Antivirus Strengthen Frontline Protection * MDR for Microsoft 365 Microsoft 365 Threat Detection * Ransomware Canaries Detect Ransomware Faster * External Recon Scan Ports & Potential Exposures * Security Awareness Training Sharpen Your Employees' Defenses * Partner Enablement Grow Your Cybersecurity Practice See The Huntress Managed Security Platform in Action Ask questions, explore the dashboard and more Book a demo > * Who We Serve * Managed Service Providers Empowering MSPs to Secure End Customers * Value Added Resellers A Complete ready-to-sell platform for VARs * Businesses & IT Teams Empowering IT to Bridge the Cyber Gap * Resources * Cybersecurity Education Webinars, eBooks and More * Upcoming Events Tradeshows and Live Industry Events * Tradecraft Tuesday No Product. No Pitches. Just Tradecraft. * Success Stories Case Studies & Testimonials * Community Fireside Chat Check out the latest Fireside Chats * Blog * Company * Leadership Team Meet the Team Taking the Fight to Hackers * Press Media Coverage, Interviews & More * Careers Join the Hunt - We're Hiring! * Contact Us Talk to Sales, Get Help or Say Hello :) * Partners * Partner Login Access Your Huntress Dashboard * Support Documentation Technical Product Support, FAQs & More SEARCH Free Trial * Platform * Platform Overview Cybersecurity for the 99% * Managed EDR Stop Attacks with Process Insights * SOC 24/7 Human Threat Hunting * Persistent Footholds Find Attackers Hiding in Plain Sight * Managed Antivirus Strengthen Frontline Protection * MDR for Microsoft 365 Microsoft 365 Threat Detection * Ransomware Canaries Detect Ransomware Faster * External Recon Scan Ports & Potential Exposures * Security Awareness Training Sharpen Your Employees' Defenses * Partner Enablement Grow Your Cybersecurity Practice See The Huntress Managed Security Platform in Action Ask questions, explore the dashboard and more Book a demo > * Who We Serve * Managed Service Providers Empowering MSPs to Secure End Customers * Value Added Resellers A Complete ready-to-sell platform for VARs * Businesses & IT Teams Empowering IT to Bridge the Cyber Gap * Resources * Cybersecurity Education Webinars, eBooks and More * Upcoming Events Tradeshows and Live Industry Events * Tradecraft Tuesday No Product. No Pitches. Just Tradecraft. * Success Stories Case Studies & Testimonials * Community Fireside Chat Check out the latest Fireside Chats * Blog * Company * Leadership Team Meet the Team Taking the Fight to Hackers * Press Media Coverage, Interviews & More * Careers Join the Hunt - We're Hiring! * Contact Us Talk to Sales, Get Help or Say Hello :) * Partners * Partner Login Access Your Huntress Dashboard * Support Documentation Technical Product Support, FAQs & More Free Trial Matthew Brennan 02.16.2022 17 min read HACKERS NO HASHING: RANDOMIZING API HASHES TO EVADE COBALT STRIKE SHELLCODE DETECTION Previous Post Next Post Share on Twitter Share on LinkedIn Share on Facebook Share on Reddit While researching Application Programming Interface (API) hashing techniques commonly used in popular malware (particularly Metasploit and Cobalt Strike), the Huntress ThreatOps Team found that hackers are sticking to the default settings that come with hacker tooling. Our research has suggested that many detection/antivirus (AV) vendors have realized this and have built their detection logic around the presence of artifacts left by these defaults. With a bit of tinkering and curiosity, we found that if trivial changes are made to those defaults, a large number of vendors will fail to detect otherwise simple and commodity malware. As a result, simple and commodity malware suddenly starts approaching FUD status. đ In this post, weâll dive into how we discovered those minor changes and how you can implement them yourself to test your detection tooling. We have included a script that automates a large portion of this process, as well as a YARA rule which will detect most modifications made using this technique. Whether youâre on Team Red, Team Blue, or anywhere in between, we hope this blog provides some useful insight into an interesting bypass and detection technique. If screenshots like this excite you, read on. Technical TL;DR Our research suggests that a large number of vendors have based their Cobalt Strike and Metasploit shellcode detection capability on the presence of ROR13 API hashes. By making trivial changes to the ROR13 logic and updating the hashes accordingly, a large number of vendor detections can be seemingly bypassed without breaking code functionality. In order to detect this behavior, YARA rules that previously detected ROR13 hashes can be modified to detect blocks of code associated with typical ROR-based hashing. This move to detection of ROR blocks can provide a more robust means of detection than detecting on hashes alone. Graphical TL;DR BUT FIRST, A QUICK REFRESHER ON API HASHING API hashing is a technique often used by malware to disguise the usage of suspicious APIs (essentially functions) from the prying eyes of a detection analyst or security engineer. Traditionally, if a piece of software needed to call a function of the Windows API (for example, if it wanted to use CreateFileW to create a file), the software would need to reference the API name âdirectlyâ in the code. This typically looks like the screenshot below. By âdirectlyâ using an API, the name of the API is left present in the code. This enables an analyst to easily identify what the piece of suspicious code might be doing. In this case, that suspicious action is creating or opening a file. When a âdirectâ API call is used, it also leaves the API present in the import table of the file. This import table can be easily viewed within PeStudio or any other analysis tool and looks like the screenshot below. Note we can also see the other APIs that the malware is using. If youâre an attacker trying to hide the creation of a malicious file, then neither of these situations is ideal. It would be far better if you could hide your API usage away from an analyst who may see `CreateFileW` and then go searching for suspicious files. If an attacker doesnât want their API to show up in an import table, then the alternative is to load the APIs dynamically (when the malware actually runs). The easiest way to do this is to use a Windows function called GetProcAddress. This method avoids leaving suspicious APIs in the import table as we saw above in PeStudio. A quick caveat using dynamic loading is that although the original suspicious API `CreateFileW` would be absent from the import table, the usage of âGetProcAddressâ will now be in the import table instead. A keen-eyed analyst who sees the presence of GetProcAddress can run the malware in a debugger and find out what is being loaded. With a well-placed breakpoint, an analyst can view the arguments being passed to the GetProcAddress function and find out what is being loaded. Upon running the suspicious code, a debugger would then present something like this, revealing the usage of CreateFileW and indicating to an analyst that they should go looking for suspicious files that may have been created. A common means of avoiding both of these situations is to use a technique known as API hashing. This is a technique where attackers will implement their own version of GetProcAddress that will load a function by a hash rather than a name. This avoids leaving suspicious APIs in import tables and avoids using suspicious APIs that can be easily viewed in a debugger. If an analyst wants to find out whatâs going on, they would need to get familiar with x86 assembly. THE TL;DR TAKEAWAYS * There are multiple ways to load suspicious APIs; however, most will leave easy-to-find indicators for malware analysts * API hashing uses unique hashes rather than function names. This hinders the analysis of function names that target strings or arguments at breakpoints HASHING INDICATORS Now that we know why someone might want to use API hashing, we can take a look at how to deal with it when analyzing suspicious code. It is relatively easy to identify, as you will often see random hex values pushed to the stack, followed by an immediate call to a register value. Typically, this call will resemble call rbp, but the register could technically be any value. Below is a screenshot taken from some Cobalt Strike shellcode where API hashing was used. In the screenshot, we can see two hex values pushed to a register prior to a `call rbp`. These are the hashes that will be resolved and used to load suspicious functions used by malware. The hashes above correspond to 0x726774c (LoadLibraryA) and 0xa779563a (InternetOpenA). If you were to find the value of rbp in this situation, you would find that it points to the âmanualâ implementation of GetProcAddress, which then resolves the hash and calls the associated API. At a high level, the hash resolution logic is similar to the below pseudo code. Additionally, you would find that the Calculatehash Logic, which is largely based on the ror13 hashing algorithm, is similar to this. The value of 0xd (13) is important here as later we will change this value to generate new hashes that can bypass detection. This is a simplification, and the actual logic is slightly more complex. If youâre interested in understanding the logic in more detail, there are some great write-ups on the topic from Nviso and Avast. After analyzing numerous malware samples using API hashing in shellcode, we noticed that similar malware families will often use extremely similar hashing logic to calculate and resolve API hashes. In particular, we found that most Cobalt Strike, Msfvenom and Metasploit use exactly the same hashing logic for resolving API hashes. Since they utilize the same logic, they produce the same hashes for any given function. For example, both Cobalt Strike and Metasploit will use the hash 0x726774c when resolving âLoadLibraryAâ. THE TL;DR TAKEAWAYS * API hashing is relatively simple to identify through static analysis, although it is difficult to find what the hashes resolve to * Similar hashing logic is often used across similar malware families * The exact same hashing logic is often across samples from MsfVenom, Metasploit and Cobalt Strike POKING A BIT FURTHER We eventually found that it was easy to identify shellcode that was generated by Cobalt Strike or Metasploit simply by googling the hash values present in the code. If we were to google the value of 0x726774c (LoadLibraryA), we would immediately get hits for the Metasploit framework (which shares code with Cobalt Strike). We see the same if we google the hash for 0xa779563a (InternetOpenA). Generating our own shellcode samples from these frameworks, we observed that the hashes present in our payloads were consistently identifiable as those used by Metasploit and Cobalt Strike. THE TL;DR TAKEAWAYS * Metasploit and Cobalt Strike (at least by default) use the same API hashing routine and will produce the same hash values when using the same function * These hashes introduce unique hex values that can be used to easily identify the malware families by using Google YARA RULES From the perspective of a security analyst or detection engineer, this was great information. Without performing a deep dive into shellcode and assembly, we could easily identify that a payload likely belonged to either Metasploit or Cobalt Strike. This got us thinkingâif these hash values are unique to tools like Cobalt Strike and Metasploit⊠what if those hashes are unique enough to be used for YARA rules? We found a fantastic article from Avast that captured the same idea. Their article details the use of these same API hashes to detect Cobalt Strike and Metasploit shellcode. Below we can see a YARA rule from Avast which relies largely on the hashes we previously identified (as well as the other hashes required for an HTTP stager). Testing these YARA rules against our raw Cobalt Strike and Metasploit shellcode (without any encoders enabled), we confirmed the Avast YARA ruleset reliably detected and identified all of our generated payloads. Great news for Team Blueâand great work from the Threat Intel Team at Avast. THE TL;DR TAKEAWAYS * API hashes present in shellcode are reliable indicators that can be used for detection * Vendors are actively using these indicators to detect malicious shellcode BUT WHAT IF THE HASHES IN THE SHELLCODE ARE CHANGED? At face value, the usage of API hashes for detection is a great idea. But that got us thinking, what happens if those hash values were to change? As an initial proof-of-concept, we took our payloads and rather crudely changed the hashes to 0x11111111. We knew this would break the shellcode as the hashes would no longer resolveâbut it would allow us to check how well the shellcode is detected without the presence of known API hashes. Our new shellcode would contain hashes like this in place of the actual hashes seen before. We then did a before and after check on a Cobalt Strike HTTP payload using Virustotal, and found that 15 vendors failed to detect the shellcode after these changes were made. As a proof-of-concept, this was pretty interesting. But as an attacker, this is largely useless. In its current modified state, the shellcode would no longer resolve hashes and would not be able to find the APIs it requires in order to executeâturning our shellcode into a nice digital paperweight. THE TL;DR TAKEAWAYS * At least some vendors are using API hashes to detect Cobalt Strike and similar malware * If these defaults are changed, at least some vendors will fail to detect previously detected payloads * Crudely modifying API hashes will break your code BUT WHAT IF MODIFIED HASHES COULD RESOLVE PROPERLY? After confirming our suspicion that vendors were using API hashes to detect shellcode, we decided to explore what would happen if the hashes were modified less crudely, in a way that would still enable the modified hashes to resolve and execute. First, we needed to understand exactly how the hashes were generated. Our ThreatOps team was able to discover this through a combination of the Metasploit source code and by analyzing the assembly instructions present in samples of shellcode. By nature of how hashing works, we theorized that it should only take minor changes to the hashing logic to produce vastly different hashes. In the end, rather than getting fancy with any entirely new hashing routines, we decided to just change the rotation value in the existing logic from 0xd/13 to 0xf/15. In theory, this would result in entirely new hashes, while maintaining largely the same logic and hashing structure. We then created a script to generate new hashes according to our new rotation value of 0xf. This logic can be found in the final script included in this post. After generating new hash values, we then updated our shellcode to correspond to our new hashes, and our new ror value of 0xf. Note that our shellcode structure is still largely intact, the only thing that changed is the hash and rotation (ror) values. We then confirmed that our code was still able to function as expected. This process was vastly sped up using the Speakeasy tool from FireEye. Below we can see a screenshot of the APIs still successfully resolving in our newly modified shellcode. Using a combination of netcat and the BlobRunner tool from OAlabs, we did an extra check to confirm that our shellcode still worked and would âcall outâ as expected. After confirming that our code definitely still worked, we uploaded it to VirusTotal. And found that we still had two vendors remaining, the same two vendors from our previous dummy value testing. This was pretty interesting, since this was now functioning Cobalt Strike shellcodeâwith 15 fewer detections than before it was modified. For a sanity check, we re-ran the same process using a TCP bind shell from Metasploit (no encoders enabled). After confirming that the code still worked, we submitted it to VirusTotal and found that 26 vendors had failed to detect the modified payload. During our analysis, it was interesting to note that the two remaining vendors differed between the modified payloads. At this point, we also checked that the original YARA rules were no longer detecting our payloads. And confirmed that they were no longer being detected. THE TL;DR TAKEAWAYS * A large number of vendors are using default ror13 hashes to detect Cobalt Strike and Metasploit/Msfvenom payloads. * Modifying these hashes has a considerable impact on detection rates. * When done properly, modifying these hashes will not break shellcode functionality. * This technique works well on both Msfvenom and Cobalt Strike. Hence likely works on other malware families too. SO WHAT ABOUT THOSE REMAINING VENDORS? Rather than leave it at 2/55, we decided to tackle the two remaining vendors detecting our shellcode. First, we noted that the remaining vendors were detecting generic shellcode and not Cobalt Strike or Metasploit specifically. This led us to believe that they were detecting generic shellcode indicators, rather than anything specific to our family of malware. We theorized the following might be targeted by the remaining vendors, since they are behaviors typically associated with shellcode. * CLD/0xfc being the first instructions executed - (CLD is used to reset direction flags used in byte/string copy operations) * Suspicious calls to registers (eg call rbp) * Presence of library names in stack strings To test, we slightly modified these indicators in our remaining payload. We achieved this by * Moving the initial CLD instruction to another location in our shellcode, so that it still executed but was no longer the first instruction. (Assuming CLD executes before any string operations, this should have no impact on shellcode functionality) * Inserting a NOP/0x90 in place of the original CLD * Inserting an uppercase character in the arguments to the initial call to LoadLibraryA. (Since LoadLibraryA is not case sensitive, this shouldnât break any functionality) Below, we have a before and after of the modified shellcode. Note the minor changes from âwininetâ (all lower case) to âwIninetâ (one upper case I). As well as the CLD instruction now located after our pop rbp. We then confirmed that our shellcode still functioned, and then resubmitted it to VirusTotal. Finally, we had hit 0/55 detections without breaking our code. We then checked the same with Antiscan and found that we had also hit zero detections for our Cobalt Strike shellcodeâwhereas a non-modified copy had 13 detections. The TL;DR Takeaways * Vendors are definitely using API hashes to identify Cobalt Strike shellcode * Removing API hashes will remove mostâbut not allâVirusTotal detections * Lacking hashes, some vendors will detect on other generic shellcode indicators * We can modify these remaining indicators to achieve zero detections AUTOMATING THE PROCESS Since the hashing replacement process could be achieved with a byte-level search and replace, the Huntress ThreatOps team developed a script to automate the process. This script⊠* Takes a raw shellcode file as input (no encoders present) * Automates the hash replacement process, using a randomized ror value between one and 255 * Since a different ror value is used each time, a unique file and hash is generated upon each run, allowing multiple files to be created for a single piece of shellcode We decided not to automate the process of upper-casing the library name and moving the CLD/0xfc, so you will need to do those manually if you wish to have zero detections. Both activities can be done manually and with minimal effort using a hex editor. In order to use the script, generate a raw payload with Msfvenom or Cobalt Strike (make sure your output is rawâdo NOT use any encoders), save it to a raw binary file and then pass it as an argument to the Python script. The script will handle the hash replacement process with a random ror value and unique hashes. An example of how to generate a simple reverse shell payload using msfvenom. Note the use of â--format rawâ to avoid using encoders. Below is an example of how to use the script to modify the shellcode file. NOTES AND LIMITATIONS OF THIS SCRIPT * This script only replaces hashes and the hashing logic. If there are other suspicious indicators in your shellcode, you may need to find your own method to hide them * This script is NOT an encoder, so you will still need to deal with bad characters and null bytes within your shellcode * Using a public and well-known encoder (like Shikata ga nai) will introduce its own indicators which will work against you DETECTION OF MODIFIED SHELLCODE After confirming that our script for generating new shellcode works for bypassing generic detections, we then developed a YARA rule for detecting shellcode generated by our script. Below weâve included a copy of a YARA that detected all Msfvenom and Cobalt Strike payloads that we tested with, regardless of whether they had been modified by our script. In our testing, we did not hit any false positives within our test set of binaries, but you may wish to modify the rule to fit your needs if false positives arise. HOW IT WORKS Since existing detection rules are detecting hashes generated by the hashing routine (which can be easily changed), this rule detects the hashing routine itself. This allows for slightly more robust detection of Cobalt Strike and Metasploit shellcode. As with any detection, this rule is not bulletproof. A determined attacker can introduce more complex changes to the hashing routine which will break this YARA rule. We have allowed for minor variations in our rule, but more complex changes will still defeat it. FINAL COMMENTS Clearly, detections arenât always perfect, and a well-determined attacker will always be able to sneak through. If youâre a defender, make sure youâre always testing and updating your detection rules (you never know what might sneak past). If youâre an attacker (a Red Teamer, of course), donât rely on defaults to get you byâsimple changes can have a significant impact on your chances of being detected. And finally, a few key takeaways for Blue and Red Teamers, respectively: Team Blue * Continuously test and update your detection logic * Actively threat hunt! No alerts â no malware * Search through a variety of log sourcesâan AV may not have caught this, but the network traffic might stand out like a sore thumb Team Red * Donât use defaults! Tinker with everything * Donât be afraid to get familiar with assembly! SCRIPTS/YARA RULES YARA Main Script (view the full script here) References * https://decoded.avast.io/threatintel/decoding-cobalt-strike-understanding-payloads/ * https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/hash.py * https://blog.nviso.eu/2021/09/02/anatomy-and-disruption-of-metasploit-shellcode/ * https://www.boozallen.com/insights/cyber/shellcode/shikata-ga-nai-encoder.html * https://www.youtube.com/watch?v=Tk3RWuqzvII Share on Twitter Share on LinkedIn Share on Facebook Share on Reddit MATTHEW BRENNAN Malware Enthusiast. Appreciator of Burritos. Detection Engineer at Huntress. YOU MAY ALSO LIKE Team Huntress 09.26.2023 13 min read NETSCALER EXPLOITATION TO SOCIAL ENGINEERING: MAPPING CONVERGENCE OF ADVERSARY TRADECRAFT ACROSS VICTIMS The following is an analysis by the Huntress team of several recent intrusions connected ... Start Reading Joe Slowik 09.14.2023 7 min read SPIDERING THROUGH IDENTITY FOR PROFIT AND DISRUPTION Dive into the recent Las Vegas casino cyberattacks linked to Scattered Spider, and learn ... Start Reading Harlan Carvey 09.7.2023 6 min read EVOLUTION OF USB-BORNE MALWARE, RASPBERRY ROBIN A deep dive into the USB-borne Raspberry Robin malware and how Huntress Managed EDR and ... Start Reading Hackers are constantly evolving to better attack small and mid-size businessesâHuntress is how SMBs and managed service providers stay ahead with managed cybersecurity solutions for endpoints, email, and identity. LinkedIn Twitter Facebook YouTube BizRatings * Platform * Platform Overview * For MSPs * For VARs * Free Trial * Resources * Cybersecurity Education * Blog * Events * Careers Sign Up for Blog Updates Work Email (required)* © 2023 Huntress - All rights reserved * Terms of Use * Privacy Policy * Legal * Cookie Policy