Created
February 20, 2019 20:49
-
-
Save 0xINT3/9ffa9b347372648d8ff0d7e56968678e to your computer and use it in GitHub Desktop.
Pasting the encryption function / AES I found that is used by the Jigsaw ransomware used to encrypt victim's files. This is a part of Malware Analysis.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Win32.SafeHandles; | |
using System; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
using System.Security.Permissions; | |
namespace System.Security.Cryptography | |
{ | |
[HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] | |
public sealed class AesCryptoServiceProvider : Aes | |
{ | |
private static volatile KeySizes[] s_supportedKeySizes; | |
private static volatile int s_defaultKeySize; | |
[SecurityCritical] | |
private SafeCspHandle m_cspHandle; | |
[SecurityCritical] | |
private SafeCapiKeyHandle m_key; | |
public override byte[] Key | |
{ | |
[SecuritySafeCritical] | |
get | |
{ | |
if (this.m_key == null || this.m_key.IsInvalid || this.m_key.IsClosed) | |
{ | |
this.GenerateKey(); | |
} | |
return CapiNative.ExportSymmetricKey(this.m_key); | |
} | |
[SecuritySafeCritical] | |
set | |
{ | |
if (value == null) | |
{ | |
throw new ArgumentNullException("value"); | |
} | |
byte[] array = (byte[])value.Clone(); | |
if (!base.ValidKeySize(array.Length * 8)) | |
{ | |
throw new CryptographicException(SR.GetString("Cryptography_InvalidKeySize")); | |
} | |
SafeCapiKeyHandle key = CapiNative.ImportSymmetricKey(this.m_cspHandle, AesCryptoServiceProvider.GetAlgorithmId(array.Length * 8), array); | |
if (this.m_key != null) | |
{ | |
this.m_key.Dispose(); | |
} | |
this.m_key = key; | |
this.KeySizeValue = array.Length * 8; | |
} | |
} | |
public override int KeySize | |
{ | |
get | |
{ | |
return base.KeySize; | |
} | |
[SecuritySafeCritical] | |
set | |
{ | |
base.KeySize = value; | |
if (this.m_key != null) | |
{ | |
this.m_key.Dispose(); | |
} | |
} | |
} | |
[SecurityCritical] | |
public AesCryptoServiceProvider() | |
{ | |
string providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider"; | |
if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1) | |
{ | |
providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"; | |
} | |
this.m_cspHandle = CapiNative.AcquireCsp(null, providerName, CapiNative.ProviderType.RsaAes, CapiNative.CryptAcquireContextFlags.VerifyContext, true); | |
this.FeedbackSizeValue = 8; | |
int keySizeValue = 0; | |
KeySizes[] array = AesCryptoServiceProvider.FindSupportedKeySizes(this.m_cspHandle, out keySizeValue); | |
if (array.Length != 0) | |
{ | |
this.KeySizeValue = keySizeValue; | |
return; | |
} | |
throw new PlatformNotSupportedException(SR.GetString("Cryptography_PlatformNotSupported")); | |
} | |
[SecuritySafeCritical] | |
public override ICryptoTransform CreateDecryptor() | |
{ | |
if (this.m_key == null || this.m_key.IsInvalid || this.m_key.IsClosed) | |
{ | |
throw new CryptographicException(SR.GetString("Cryptography_DecryptWithNoKey")); | |
} | |
return this.CreateDecryptor(this.m_key, this.IVValue); | |
} | |
[SecuritySafeCritical] | |
public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv) | |
{ | |
if (key == null) | |
{ | |
throw new ArgumentNullException("key"); | |
} | |
if (!base.ValidKeySize(key.Length * 8)) | |
{ | |
throw new ArgumentException(SR.GetString("Cryptography_InvalidKeySize"), "key"); | |
} | |
if (iv != null && iv.Length * 8 != this.BlockSizeValue) | |
{ | |
throw new ArgumentException(SR.GetString("Cryptography_InvalidIVSize"), "iv"); | |
} | |
byte[] array = (byte[])key.Clone(); | |
byte[] iv2 = null; | |
if (iv != null) | |
{ | |
iv2 = (byte[])iv.Clone(); | |
} | |
ICryptoTransform result; | |
using (SafeCapiKeyHandle safeCapiKeyHandle = CapiNative.ImportSymmetricKey(this.m_cspHandle, AesCryptoServiceProvider.GetAlgorithmId(array.Length * 8), array)) | |
{ | |
result = this.CreateDecryptor(safeCapiKeyHandle, iv2); | |
} | |
return result; | |
} | |
[SecurityCritical] | |
private ICryptoTransform CreateDecryptor(SafeCapiKeyHandle key, byte[] iv) | |
{ | |
return new CapiSymmetricAlgorithm(this.BlockSizeValue, this.FeedbackSizeValue, this.m_cspHandle, key, iv, this.Mode, this.PaddingValue, EncryptionMode.Decrypt); | |
} | |
[SecuritySafeCritical] | |
public override ICryptoTransform CreateEncryptor() | |
{ | |
if (this.m_key == null || this.m_key.IsInvalid || this.m_key.IsClosed) | |
{ | |
this.GenerateKey(); | |
} | |
if (this.Mode != CipherMode.ECB && this.IVValue == null) | |
{ | |
this.GenerateIV(); | |
} | |
return this.CreateEncryptor(this.m_key, this.IVValue); | |
} | |
[SecuritySafeCritical] | |
public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv) | |
{ | |
if (key == null) | |
{ | |
throw new ArgumentNullException("key"); | |
} | |
if (!base.ValidKeySize(key.Length * 8)) | |
{ | |
throw new ArgumentException(SR.GetString("Cryptography_InvalidKeySize"), "key"); | |
} | |
if (iv != null && iv.Length * 8 != this.BlockSizeValue) | |
{ | |
throw new ArgumentException(SR.GetString("Cryptography_InvalidIVSize"), "iv"); | |
} | |
byte[] array = (byte[])key.Clone(); | |
byte[] iv2 = null; | |
if (iv != null) | |
{ | |
iv2 = (byte[])iv.Clone(); | |
} | |
ICryptoTransform result; | |
using (SafeCapiKeyHandle safeCapiKeyHandle = CapiNative.ImportSymmetricKey(this.m_cspHandle, AesCryptoServiceProvider.GetAlgorithmId(array.Length * 8), array)) | |
{ | |
result = this.CreateEncryptor(safeCapiKeyHandle, iv2); | |
} | |
return result; | |
} | |
[SecurityCritical] | |
private ICryptoTransform CreateEncryptor(SafeCapiKeyHandle key, byte[] iv) | |
{ | |
return new CapiSymmetricAlgorithm(this.BlockSizeValue, this.FeedbackSizeValue, this.m_cspHandle, key, iv, this.Mode, this.PaddingValue, EncryptionMode.Encrypt); | |
} | |
[SecuritySafeCritical] | |
protected override void Dispose(bool disposing) | |
{ | |
try | |
{ | |
if (disposing) | |
{ | |
if (this.m_key != null) | |
{ | |
this.m_key.Dispose(); | |
} | |
if (this.m_cspHandle != null) | |
{ | |
this.m_cspHandle.Dispose(); | |
} | |
} | |
} | |
finally | |
{ | |
base.Dispose(disposing); | |
} | |
} | |
[SecurityCritical] | |
private static KeySizes[] FindSupportedKeySizes(SafeCspHandle csp, out int defaultKeySize) | |
{ | |
if (AesCryptoServiceProvider.s_supportedKeySizes == null) | |
{ | |
List<KeySizes> list = new List<KeySizes>(); | |
int num = 0; | |
CapiNative.PROV_ENUMALGS providerParameterStruct = CapiNative.GetProviderParameterStruct<CapiNative.PROV_ENUMALGS>(csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.RestartEnumeration); | |
while (providerParameterStruct.aiAlgId != CapiNative.AlgorithmId.None) | |
{ | |
switch (providerParameterStruct.aiAlgId) | |
{ | |
case CapiNative.AlgorithmId.Aes128: | |
list.Add(new KeySizes(128, 128, 0)); | |
if (128 > num) | |
{ | |
num = 128; | |
} | |
break; | |
case CapiNative.AlgorithmId.Aes192: | |
list.Add(new KeySizes(192, 192, 0)); | |
if (192 > num) | |
{ | |
num = 192; | |
} | |
break; | |
case CapiNative.AlgorithmId.Aes256: | |
list.Add(new KeySizes(256, 256, 0)); | |
if (256 > num) | |
{ | |
num = 256; | |
} | |
break; | |
} | |
providerParameterStruct = CapiNative.GetProviderParameterStruct<CapiNative.PROV_ENUMALGS>(csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.None); | |
} | |
AesCryptoServiceProvider.s_supportedKeySizes = list.ToArray(); | |
AesCryptoServiceProvider.s_defaultKeySize = num; | |
} | |
defaultKeySize = AesCryptoServiceProvider.s_defaultKeySize; | |
return AesCryptoServiceProvider.s_supportedKeySizes; | |
} | |
[SecuritySafeCritical] | |
public override void GenerateKey() | |
{ | |
SafeCapiKeyHandle safeCapiKeyHandle = null; | |
RuntimeHelpers.PrepareConstrainedRegions(); | |
try | |
{ | |
if (!CapiNative.UnsafeNativeMethods.CryptGenKey(this.m_cspHandle, AesCryptoServiceProvider.GetAlgorithmId(this.KeySizeValue), CapiNative.KeyFlags.Exportable, out safeCapiKeyHandle)) | |
{ | |
throw new CryptographicException(Marshal.GetLastWin32Error()); | |
} | |
} | |
finally | |
{ | |
if (safeCapiKeyHandle != null && !safeCapiKeyHandle.IsInvalid) | |
{ | |
safeCapiKeyHandle.SetParentCsp(this.m_cspHandle); | |
} | |
} | |
if (this.m_key != null) | |
{ | |
this.m_key.Dispose(); | |
} | |
this.m_key = safeCapiKeyHandle; | |
} | |
[SecuritySafeCritical] | |
public override void GenerateIV() | |
{ | |
byte[] array = new byte[this.BlockSizeValue / 8]; | |
if (!CapiNative.UnsafeNativeMethods.CryptGenRandom(this.m_cspHandle, array.Length, array)) | |
{ | |
throw new CryptographicException(Marshal.GetLastWin32Error()); | |
} | |
this.IVValue = array; | |
} | |
private static CapiNative.AlgorithmId GetAlgorithmId(int keySize) | |
{ | |
if (keySize == 128) | |
{ | |
return CapiNative.AlgorithmId.Aes128; | |
} | |
if (keySize == 192) | |
{ | |
return CapiNative.AlgorithmId.Aes192; | |
} | |
if (keySize != 256) | |
{ | |
return CapiNative.AlgorithmId.None; | |
} | |
return CapiNative.AlgorithmId.Aes256; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment