mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-23 03:46:10 +00:00
290 lines
12 KiB
C#
290 lines
12 KiB
C#
|
// Decompiled with JetBrains decompiler
|
|||
|
// Type: Microsoft.InfoCards.RoamingStoreFileUtility
|
|||
|
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|
|||
|
// MVID: 1D4D5564-A025-490C-AF1D-DF4FBB709D1F
|
|||
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00001-msil\Virus.Win32.Expiro.w-f8f9f26e940480624825f6bddbea86e70fc4aa746c4dd8efa7d98dcb477000ed.exe
|
|||
|
|
|||
|
using Microsoft.InfoCards.Diagnostics;
|
|||
|
using System;
|
|||
|
using System.IO;
|
|||
|
using System.Security.Cryptography;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace Microsoft.InfoCards
|
|||
|
{
|
|||
|
internal sealed class RoamingStoreFileUtility
|
|||
|
{
|
|||
|
private const int ENCRYPTIONKEYBUFFERSIZE = 32;
|
|||
|
private const int ENCRYPTIONKEYBITLENGTH = 256;
|
|||
|
private const int ENCRYPTIONIVBUFFERSIZE = 16;
|
|||
|
private const int ENCRYPTIONIVBITLENGTH = 128;
|
|||
|
private const int ITERATIONCOUNT = 1000;
|
|||
|
private const int SHA256_BUFFERSIZE = 32;
|
|||
|
private static readonly byte[] DerivedKeySignatureEntropy = new byte[16]
|
|||
|
{
|
|||
|
(byte) 196,
|
|||
|
(byte) 1,
|
|||
|
(byte) 123,
|
|||
|
(byte) 241,
|
|||
|
(byte) 107,
|
|||
|
(byte) 173,
|
|||
|
(byte) 47,
|
|||
|
(byte) 66,
|
|||
|
(byte) 175,
|
|||
|
(byte) 244,
|
|||
|
(byte) 151,
|
|||
|
(byte) 125,
|
|||
|
(byte) 4,
|
|||
|
(byte) 104,
|
|||
|
(byte) 3,
|
|||
|
(byte) 219
|
|||
|
};
|
|||
|
private static readonly byte[] DerivedKeyEncryptionEntropy = new byte[16]
|
|||
|
{
|
|||
|
(byte) 217,
|
|||
|
(byte) 89,
|
|||
|
(byte) 123,
|
|||
|
(byte) 38,
|
|||
|
(byte) 30,
|
|||
|
(byte) 216,
|
|||
|
(byte) 179,
|
|||
|
(byte) 68,
|
|||
|
(byte) 147,
|
|||
|
(byte) 35,
|
|||
|
(byte) 179,
|
|||
|
(byte) 150,
|
|||
|
(byte) 133,
|
|||
|
(byte) 222,
|
|||
|
(byte) 149,
|
|||
|
(byte) 252
|
|||
|
};
|
|||
|
|
|||
|
public static int SaltLength => 16;
|
|||
|
|
|||
|
private RoamingStoreFileUtility()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public static int CalculateEncryptedSize(int decryptedLength)
|
|||
|
{
|
|||
|
int num = decryptedLength;
|
|||
|
return num + (16 - num % 16) + 48;
|
|||
|
}
|
|||
|
|
|||
|
public static int CalculateDecryptedSize(int encryptedLength) => encryptedLength - 48;
|
|||
|
|
|||
|
public static void Decrypt(
|
|||
|
Stream source,
|
|||
|
Stream destination,
|
|||
|
string passwordString,
|
|||
|
byte[] salt)
|
|||
|
{
|
|||
|
byte[] bytes = Encoding.Unicode.GetBytes(passwordString);
|
|||
|
byte[] encryptionKey;
|
|||
|
byte[] signatureKey;
|
|||
|
try
|
|||
|
{
|
|||
|
RoamingStoreFileUtility.CreateKeyPair(bytes, salt, out encryptionKey, out signatureKey);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) bytes, 0, bytes.Length);
|
|||
|
}
|
|||
|
try
|
|||
|
{
|
|||
|
byte[] numArray1 = new byte[16];
|
|||
|
if (numArray1.Length != source.Read(numArray1, 0, numArray1.Length))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ImportException(SR.GetString("InvalidImportFile")));
|
|||
|
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
|
|||
|
{
|
|||
|
rijndaelManaged.Padding = PaddingMode.PKCS7;
|
|||
|
rijndaelManaged.Mode = CipherMode.CBC;
|
|||
|
rijndaelManaged.BlockSize = numArray1.Length * 8;
|
|||
|
rijndaelManaged.KeySize = encryptionKey.Length * 8;
|
|||
|
using (RijndaelManagedTransform decryptor = (RijndaelManagedTransform) rijndaelManaged.CreateDecryptor(encryptionKey, numArray1))
|
|||
|
{
|
|||
|
using (SHA256Managed shA256Managed = new SHA256Managed())
|
|||
|
{
|
|||
|
byte[] numArray2 = new byte[decryptor.InputBlockSize];
|
|||
|
byte[] numArray3 = new byte[decryptor.OutputBlockSize];
|
|||
|
byte[] numArray4 = new byte[shA256Managed.HashSize / 8];
|
|||
|
using (MemoryStream inputStream = new MemoryStream(new byte[numArray1.Length + encryptionKey.Length + decryptor.OutputBlockSize]))
|
|||
|
{
|
|||
|
if (numArray4.Length != source.Read(numArray4, 0, numArray4.Length))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ImportException(SR.GetString("InvalidImportFile")));
|
|||
|
inputStream.Write(numArray1, 0, numArray1.Length);
|
|||
|
inputStream.Write(signatureKey, 0, signatureKey.Length);
|
|||
|
while (source.Position < source.Length - (long) numArray2.Length)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
int inputCount = source.Read(numArray2, 0, numArray2.Length);
|
|||
|
int count = decryptor.TransformBlock(numArray2, 0, inputCount, numArray3, 0);
|
|||
|
if (count > 0)
|
|||
|
destination.Write(numArray3, 0, count);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) numArray3, 0, numArray3.Length);
|
|||
|
Array.Clear((Array) numArray2, 0, numArray2.Length);
|
|||
|
}
|
|||
|
}
|
|||
|
int inputCount1 = source.Read(numArray2, 0, numArray2.Length);
|
|||
|
byte[] buffer = decryptor.TransformFinalBlock(numArray2, 0, inputCount1);
|
|||
|
destination.Write(buffer, 0, buffer.Length);
|
|||
|
inputStream.Write(buffer, buffer.Length - decryptor.OutputBlockSize, decryptor.OutputBlockSize);
|
|||
|
inputStream.Flush();
|
|||
|
inputStream.Seek(0L, SeekOrigin.Begin);
|
|||
|
if (!RoamingStoreFileUtility.CompareSignature(shA256Managed.ComputeHash((Stream) inputStream), numArray4))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ImportException(SR.GetString("InvalidImportFile")));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) encryptionKey, 0, encryptionKey.Length);
|
|||
|
Array.Clear((Array) signatureKey, 0, signatureKey.Length);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void Encrypt(
|
|||
|
Stream source,
|
|||
|
Stream destination,
|
|||
|
string passwordString,
|
|||
|
out byte[] salt)
|
|||
|
{
|
|||
|
RandomNumberGenerator randomNumberGenerator = (RandomNumberGenerator) new RNGCryptoServiceProvider();
|
|||
|
salt = new byte[16];
|
|||
|
randomNumberGenerator.GetBytes(salt);
|
|||
|
byte[] bytes = Encoding.Unicode.GetBytes(passwordString);
|
|||
|
byte[] encryptionKey;
|
|||
|
byte[] signatureKey;
|
|||
|
try
|
|||
|
{
|
|||
|
RoamingStoreFileUtility.CreateKeyPair(bytes, salt, out encryptionKey, out signatureKey);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) bytes, 0, bytes.Length);
|
|||
|
}
|
|||
|
try
|
|||
|
{
|
|||
|
byte[] numArray1 = new byte[16];
|
|||
|
randomNumberGenerator.GetBytes(numArray1);
|
|||
|
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
|
|||
|
{
|
|||
|
rijndaelManaged.Padding = PaddingMode.PKCS7;
|
|||
|
rijndaelManaged.Mode = CipherMode.CBC;
|
|||
|
rijndaelManaged.BlockSize = numArray1.Length * 8;
|
|||
|
rijndaelManaged.KeySize = encryptionKey.Length * 8;
|
|||
|
using (RijndaelManagedTransform encryptor = (RijndaelManagedTransform) rijndaelManaged.CreateEncryptor(encryptionKey, numArray1))
|
|||
|
{
|
|||
|
using (SHA256Managed shA256Managed = new SHA256Managed())
|
|||
|
{
|
|||
|
byte[] numArray2 = new byte[encryptor.InputBlockSize];
|
|||
|
byte[] buffer1 = (byte[]) null;
|
|||
|
byte[] numArray3 = new byte[encryptor.OutputBlockSize];
|
|||
|
byte[] numArray4 = new byte[numArray1.Length + shA256Managed.HashSize / 8];
|
|||
|
using (MemoryStream inputStream = new MemoryStream(new byte[numArray1.Length + signatureKey.Length + encryptor.InputBlockSize]))
|
|||
|
{
|
|||
|
inputStream.Write(numArray1, 0, numArray1.Length);
|
|||
|
inputStream.Write(signatureKey, 0, signatureKey.Length);
|
|||
|
try
|
|||
|
{
|
|||
|
destination.Write(numArray4, 0, numArray4.Length);
|
|||
|
int num = 0;
|
|||
|
while (source.Position < source.Length - (long) numArray2.Length)
|
|||
|
{
|
|||
|
num = source.Read(numArray2, 0, numArray2.Length);
|
|||
|
try
|
|||
|
{
|
|||
|
int count = encryptor.TransformBlock(numArray2, 0, numArray2.Length, numArray3, 0);
|
|||
|
destination.Write(numArray3, 0, count);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) numArray2, 0, numArray2.Length);
|
|||
|
Array.Clear((Array) numArray3, 0, numArray3.Length);
|
|||
|
}
|
|||
|
}
|
|||
|
int inputCount = source.Read(numArray2, 0, numArray2.Length);
|
|||
|
if (inputCount != numArray2.Length)
|
|||
|
{
|
|||
|
byte[] buffer2 = new byte[numArray2.Length];
|
|||
|
source.Seek(source.Length - (long) numArray2.Length, SeekOrigin.Begin);
|
|||
|
InfoCardTrace.Assert(source.Read(buffer2, 0, buffer2.Length) == buffer2.Length && buffer2.Length == numArray2.Length, "Should have read exactly 0x20 bytes");
|
|||
|
inputStream.Write(buffer2, 0, buffer2.Length);
|
|||
|
}
|
|||
|
else
|
|||
|
inputStream.Write(numArray2, 0, numArray2.Length);
|
|||
|
buffer1 = encryptor.TransformFinalBlock(numArray2, 0, inputCount);
|
|||
|
destination.Write(buffer1, 0, buffer1.Length);
|
|||
|
destination.Flush();
|
|||
|
inputStream.Flush();
|
|||
|
inputStream.Seek(0L, SeekOrigin.Begin);
|
|||
|
byte[] hash = shA256Managed.ComputeHash((Stream) inputStream);
|
|||
|
Array.Copy((Array) numArray1, 0, (Array) numArray4, 0, numArray1.Length);
|
|||
|
Array.Copy((Array) hash, 0, (Array) numArray4, numArray1.Length, hash.Length);
|
|||
|
destination.Seek(0L, SeekOrigin.Begin);
|
|||
|
destination.Write(numArray4, 0, numArray4.Length);
|
|||
|
destination.Flush();
|
|||
|
destination.Seek(0L, SeekOrigin.End);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) numArray2, 0, numArray2.Length);
|
|||
|
Array.Clear((Array) numArray3, 0, numArray3.Length);
|
|||
|
Array.Clear((Array) numArray4, 0, numArray4.Length);
|
|||
|
if (buffer1 != null)
|
|||
|
Array.Clear((Array) buffer1, 0, buffer1.Length);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Array.Clear((Array) encryptionKey, 0, encryptionKey.Length);
|
|||
|
Array.Clear((Array) signatureKey, 0, signatureKey.Length);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void CreateKeyPair(
|
|||
|
byte[] password,
|
|||
|
byte[] salt,
|
|||
|
out byte[] encryptionKey,
|
|||
|
out byte[] signatureKey)
|
|||
|
{
|
|||
|
byte[] sourceArray = RoamingStoreFileUtility.DoPkcs5(password, salt);
|
|||
|
using (SHA256Managed shA256Managed = new SHA256Managed())
|
|||
|
{
|
|||
|
byte[] numArray1 = new byte[32 + RoamingStoreFileUtility.DerivedKeyEncryptionEntropy.Length];
|
|||
|
byte[] numArray2 = new byte[32 + RoamingStoreFileUtility.DerivedKeySignatureEntropy.Length];
|
|||
|
Array.Copy((Array) RoamingStoreFileUtility.DerivedKeyEncryptionEntropy, 0, (Array) numArray1, 0, RoamingStoreFileUtility.DerivedKeyEncryptionEntropy.Length);
|
|||
|
Array.Copy((Array) RoamingStoreFileUtility.DerivedKeySignatureEntropy, 0, (Array) numArray2, 0, RoamingStoreFileUtility.DerivedKeySignatureEntropy.Length);
|
|||
|
Array.Copy((Array) sourceArray, 0, (Array) numArray1, RoamingStoreFileUtility.DerivedKeyEncryptionEntropy.Length, 32);
|
|||
|
Array.Copy((Array) sourceArray, 0, (Array) numArray2, RoamingStoreFileUtility.DerivedKeySignatureEntropy.Length, 32);
|
|||
|
encryptionKey = shA256Managed.ComputeHash(numArray1);
|
|||
|
signatureKey = shA256Managed.ComputeHash(numArray2);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static byte[] DoPkcs5(byte[] password, byte[] salt) => new PasswordDeriveBytes(password, salt, "SHA256", 1000).GetBytes(32);
|
|||
|
|
|||
|
internal static bool CompareSignature(byte[] input, byte[] expected)
|
|||
|
{
|
|||
|
if (input.Length == 0 || input.Length != expected.Length)
|
|||
|
return false;
|
|||
|
for (int index = 0; index < input.Length; ++index)
|
|||
|
{
|
|||
|
if ((int) expected[index] != (int) input[index])
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|