標籤:

Invoke-PSImage利用分析

0x00 前言

最近在github看見一個有趣的項目:Invoke-PSImage,在png文件的像素內插入powershell代碼作為payload(不影響原圖片的正常瀏覽),在命令行下僅通過一行powershell代碼就能夠執行像素內隱藏的payload

這是一種隱寫(Steganography)技術的應用,我在之前的文章對png的隱寫技術做了一些介紹,可供參考:

《隱寫技巧——PNG文件中的LSB隱寫》

《隱寫技巧——利用PNG文件格式隱藏Payload》

本文將結合自己的一些心得對Invoke-PSImage進行分析,介紹原理,解決測試中遇到的問題,學習腳本中的編程技巧,提出自己的優化思路

Invoke-PSImage地址:

github.com/peewpw/Invok

0x01 簡介

本文將要介紹以下內容:

·腳本分析

·隱寫原理

·實際測試

·編程技巧

·優化思路

0x02 腳本分析

1、參考說明文件

github.com/peewpw/Invok

(1) 選取每個像素的兩個顏色中的4位用於保存payload

(2) 圖像質量將受到影響

(3) 輸出格式為png

2、參考源代碼對上述說明進行分析

(1) 像素使用的為RGB模式,分別選取顏色分量中的G和B的低4位(共8位)保存payload

(2) 由於同時替換了G和B的低4位,故圖片質量會受影響

補充:

LSB隱寫是替換RGB三個分量的最低1位,人眼不會注意到前後變化,每個像素可以存儲3位的信息

猜測Invoke-PSImage選擇每個像素存儲8位是為了方便實現(8位=1位元組),所以選擇犧牲了圖片質量

(3) 輸出格式為png,需要無損

png圖片為無損壓縮(bmp圖片也是無損壓縮),jpg圖片為有損壓縮。所以在實際測試過程,輸入jpg圖片,輸出png圖片,會發現png圖片遠遠大於jpg圖片的大小

(4) 需要注意payload長度,每個像素保存一個位元組,像素個數需要大於payload的長度

0x03 隱寫原理

參照源代碼進行舉例說明(跳過讀取原圖片的部分)

1、修改像素的RGB值,替換為payload

代碼起始位置:

github.com/peewpw/Invok

對for循環做一個簡單的修改,假定需要讀取0x73,將其寫入第一個像素RGB(0x67,0x66,0x65)

(1) 讀取payload

代碼:

$paybyte1 = [math]::Floor($payload[$counter]/16)n

說明:

$payload[$counter]/16表示$payload[$counter]/0x10

即取0x73/0x10,取商,等於0x07

所以,$paybyte1 = 0x07

代碼:

$paybyte2 = ($payload[$counter] -band 0x0f)n

說明:

即0x73 & 0x0f,結果為0x03

所以,$paybyte2 = 0x03

代碼:

$paybyte3 = ($randb[($counter+2)%109] -band 0x0f)n

說明:

作隨機數填充,$paybyte3可忽略

註:

原代碼會將payload的長度和圖片的像素長度進行比較,圖片多出來的像素會以同樣格式被填充成隨機數

(2) 向原像素賦值,添加payload

原像素為RGB(0x62,0x61,0x60)

代碼:

$rgbValues[($counter*3)] = ($rgbValues[($counter*3)] -band 0xf0) -bor $paybyte1n

說明:

即0x60 & 0xf0 | 0x07

所以,$rgbValues[0] = 0x67

代碼:

$rgbValues[($counter*3+1)] = ($rgbValues[($counter*3+1)] -band 0xf0) -bor $paybyte2n

說明:

即0x61 & 0xf0 | 0x03

所以,$rgbValues[1] = 0x63

代碼:

$rgbValues[($counter*3+2)] = ($rgbValues[($counter*3+2)] -band 0xf0) -bor $paybyte3n

說明:

隨機數填充,可忽略

綜上,新像素的修改過程為:

R: 高位不變,低4位填入隨機數

G: 高位不變,低4位填入payload的低4位

B: 高位不變,低4位填入payload的高4位

2、讀取RGB,還原出payload

對輸出做一個簡單的修改,讀取第一個像素中的payload並還原

取第0個像素的代碼如下:

sal a New-Object;nAdd-Type -AssemblyName "System.Drawing";n$g= a System.Drawing.Bitmap("C:1evil-kiwi.png");n$p=$g.GetPixel(0,0);n$p;n

還原payload,輸出payload的第一個字元,代碼如下:

$o = [math]::Floor(($p.B -band 15)*16) -bor ($p.G -band 15);n[math]::Floor(($p.B -band 15)*16) -bor ($p.G -band 15));n

0x04 實際測試

使用參數:

Invoke-PSImage -Script .test.ps1 -Image .kiwi.jpg -Out .evil-kiwi.pngn

test.ps1: 包含payload,例如」start calc.exe」

kiwi.jpg: 輸入圖片,像素數量需要大於payload長度

evil-kiwi.png: 輸出圖片路徑

腳本執行後會輸出讀取 圖片解密payload並執行的代碼

實際演示略

0x05 優化思路

結合前面的分析,選擇替換RGB中兩個分量的低4位保存payload,會在一定程序上影響圖片質量,可參照LSB隱寫的原理只替換三個分量的最低位,達到人眼無法區別的效果

當然,該方法僅是隱寫技術的一個應用,無法繞過Win10 的AMSI攔截

在Win10 系統上測試還需要考慮對AMSI的繞過

0x06 小結

本文對Invoke-PSImage的代碼進行分析,介紹加解密原理,分析優缺點,提出優化思路,幫助大家更好的進行學習研究

本文為 3gstudent 原創稿件, 授權嘶吼獨家發布,如若轉載,請聯繫嘶吼編輯: 4hou.com/technology/947 更多內容請關注「嘶吼專業版」——Pro4hou

推薦閱讀:

引入機器學習前需要先弄明白這三件事
並非勒索軟體?Petya 的真實面目令人遐想
Appleby 被黑,世界級財富大鱷財務信息泄露
參加 DEF CON、Black Hat 這樣的大會是一種怎樣的體驗?

TAG:信息安全 |