CloudXli 2020-01-12
根据微软帮助文档,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处理