Invoke-PSImage脚本的隐写原理与PNG格式特性详解
TOPIC SOURCE
Cobalt Strike--powershell的payload免杀
在信息安全的渗透测试中,利用图像作为载体隐藏 PowerShell 脚本已不再是新奇的玩意儿,但若要把握其底层机制,仍需拆解两大要素:脚本的字节流如何映射到像素,以及 PNG 格式为何能够忠实保存这些改动。
隐写原理概述
所谓隐写,就是把任意二进制数据嵌入到另一种媒介而不被肉眼察觉。Invoke-PSImage 采用的是最直接的 LSB(Least Significant Bit)方式:每个像素的红、绿、蓝三色通道各占 8 位,其中最低的 4 位被当作“存储槽”。把脚本拆成字节后,依次填入这些槽位,形成一张看似普通的彩色图。
PNG 像素与颜色通道的天然优势
PNG 是无损压缩的位图格式,它的压缩算法只针对整块像素数据进行熵编码,而不改动每个像素的实际值。换句话说,若把 0xAB 写入某像素的蓝通道最低四位,解压后仍会得到相同的 0xAB。相较于 JPEG 那种有损 DCT 变换,PNG 能保证隐藏的字节在存储、传输以及再次读取时保持原样。
Invoke-PSImage 的实现细节
- 脚本预处理:先将 PowerShell 代码转为 UTF‑8 字节数组,并在末尾追加长度标记,以便解码时知道何时停止读取。
- 像素映射:遍历目标图片的每一行,每个像素取其 R、G、B 三通道的低四位,合并成一个字节;若字节不足则用 0 填充。
- 输出 PNG:使用 System.Drawing.Bitmap 将修改后的像素写回,随后交由 PNG 编码器保存为无损文件。
- 执行载荷:读取生成的 PNG,逆向提取低四位并恢复原始脚本,最后通过 IEX 或 Invoke-Expression 直接执行。
实战注意事项
隐写的成功率与图片分辨率息息相关。若目标图像仅有几百像素,能容纳的字节数会快速捉襟见肘;而 1920×1080 以上的高清图像轻松提供数兆字节的空间,脚本几乎可以不做压缩直接塞入。另一方面,颜色深度必须保持 24 位或以上,否则低位被裁剪会导致数据丢失。
在网络传输阶段,务必使用 HTTPS 或其他加密通道,否则中间人可能通过统计像素分布发现异常的低位模式。值得一提的是,PNG 本身支持多种过滤方式(如 Paeth、Sub),但 Invoke-PSImage 默认关闭过滤,以免在解码时产生位移。

参与讨论
这方法看着挺巧妙,PNG确实比JPEG靠谱多了,不过实际传输还得小心被检测到。
有点想试试,把小脚本塞进壁纸里当备份,1920×1080确实空间够用。
低四位做槽位是常见操作,那如果图片本身有透明通道会怎样?
我之前也试过用LSB藏点东西,确实被压缩就GG,PNG无损好用。
这写法对色彩敏感度高吗,肉眼真看不出差别吗?
执行时直接IEX好危险,感觉容易被滥用,安全性太成问题了。
挺详细的,像素映射那段看明白了,关键是长度标记不要丢。