根據微軟幫助文檔,convertto-securestring有兩種加密模式。如果在指定密碼的情況下,則使用aes加密,否則使用windows dpapi加密。而且aes加密也沒有指明iv值與加密模式。
該命令在Microsoft.PowerShell.Security包中,去github中查找相關代碼
可以看出,在 SecureStringHelper.Encrypt(SecureString, Key);中對待加密的字符串執行加密操作。跟進
https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/security/SecureStringHelper.cs
如果iv不存在的話,則使用aes對象默認的iv,文檔在這里
https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=netframework-4.8
iv默認為隨機數生成
加密完成后,iv通過base64存儲,而加密后的數據,通過 ByteArrayToString函數編碼。
internal static string ByteArrayToString(byte[] data)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sb.Append(data[i].ToString("x2", System.Globalization.CultureInfo.InvariantCulture));
}
return sb.ToString();
}
其實就是轉換hex,直接存儲,類似於webshell上傳文件的編碼
securityHelpers.encrypt 函數返回上圖中的EncryptionResult對象,回到最開始的processrecord函數中
將結果拼接為,c#本地化處理,2, iv,加密后的值,中間用| 分割。再經過一次base64編碼。最終輸出給用戶
python解密注意事項,
1.
c# 中字符串等等,都是雙字節,例如ascii的話,會通過假如0x00來格式化為雙字節,所以再windows中如果編碼函數用錯了,極易導致null截斷問題。(windows核心編程第一章)
python 解密程序如下
import base64
import binascii
from Crypto.Cipher import AES
sc = base64.b64decode(
"76492d1116743f0423413b16050a5345MgB8ADcAdwBsAHgAUwBRAFAAUwBNADEAUABIAHkAKwBUAHUAWABkAEQAYgBHAEEAPQA9AHwAMAA2ADgAZQAxADkANwBiADQAZAAxADgAOAA1ADkAZgA0ADEAZQAyADcAYQA5AGQANgBiADYANABhAGEAYgBjAGYAMwA3AGEANgA5ADUANQBkADIAMQA4AGUANwBhAGMANgAwADMAZAA2ADgANAA3ADIAMQBkADAAYgA5ADEAYQAzADAANQBkAGUANAA2ADcANwBhADAAMQA0ADQAMwA2ADIAYwBlAGEAMgBjADIANwAyAGMAMQA2AGIAMABkADgA")
iv = sc.split(b'|')[1]
iv = base64.b64decode(iv)
enc = sc.split(b'|')[2]
enc = enc.replace(b'\x00', b"")
dataLen = len(enc) // 2
byte_enc = bytearray(dataLen)
i = 0
while i < dataLen:
byte_enc[i] = int(enc[2 * i:2 * i + 2], 16)
i += 1
key = base64.b64decode("dGhpc19pc190aGVfa2V5MXRoaXNfaXNfdGhlX2tleTE=")
cipher = AES.new(key, AES.MODE_CBC, iv)
plan_text = cipher.decrypt(byte_enc)
print(plan_text.replace(b'\x00', b""))
注意:該dem沒有做padding處理