mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 02:46:10 +00:00
330 lines
12 KiB
C#
330 lines
12 KiB
C#
|
// Decompiled with JetBrains decompiler
|
|||
|
// Type: hs
|
|||
|
// Assembly: XobniService, Version=1.8.3.7917, Culture=neutral, PublicKeyToken=6298d2d1fcfb5d85
|
|||
|
// MVID: EA9F7D71-4A8D-4739-A320-5F01FC76E972
|
|||
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Trojan.Win32.Patched.mf-01164dae267b1f13c988de64e7fce38753b97528a3dc3fe730e191fc953c65ba.exe
|
|||
|
|
|||
|
using Microsoft.Win32;
|
|||
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.IO;
|
|||
|
using System.Net;
|
|||
|
using System.Security.Cryptography;
|
|||
|
using System.Security.Cryptography.X509Certificates;
|
|||
|
using System.Text;
|
|||
|
using System.Xml;
|
|||
|
using XobniLogging;
|
|||
|
|
|||
|
public class hs
|
|||
|
{
|
|||
|
private const string a = "XobniUpdaterShared";
|
|||
|
private const string b = "E=support@xobni.com, CN=XobniUpdate, O=Xobni Corporation, S=CA, C=US";
|
|||
|
private const string c = "{0}?version={1}&source={2}&xmid={3}";
|
|||
|
public static readonly string d = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Xobni");
|
|||
|
private static readonly string e = "http://updates." + u5.a() + "/update";
|
|||
|
private static string f = (string) null;
|
|||
|
private static readonly X509Certificate2 g = new X509Certificate2(Encoding.UTF8.GetBytes("\r\n-----BEGIN CERTIFICATE-----\r\nMIIExDCCA6ygAwIBAgIJAI0ql5mKlFKYMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD\r\nVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAY\r\nBgNVBAoTEVhvYm5pIENvcnBvcmF0aW9uMRwwGgYDVQQLExNFZGd5IEdydWZmIFNl\r\nY3VyaXR5MREwDwYDVQQDEwhYb2JuaSBDQTEbMBkGCSqGSIb3DQEJARYMY2FAeG9i\r\nbmkuY29tMB4XDTA3MDcxMTAyNDUyNVoXDTE3MDcwODAyNDUyNVowgZwxCzAJBgNV\r\nBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEaMBgG\r\nA1UEChMRWG9ibmkgQ29ycG9yYXRpb24xHDAaBgNVBAsTE0VkZ3kgR3J1ZmYgU2Vj\r\ndXJpdHkxETAPBgNVBAMTCFhvYm5pIENBMRswGQYJKoZIhvcNAQkBFgxjYUB4b2Ju\r\naS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1cDGSvJVhrET8\r\niih6B77OwPeuD7AzUFvFq2zakCB6TvKzfc4KjxZuOhH3WU1wk64YAF3102bvA+7O\r\nlvOGeDJ9b5zYCQxpva2ey0HkuaxroT3fHz2ZfiWsUmcqvE/4XNri6JTdj+B4djf6\r\nPfNoE2nsxyS8LFu7oWCB5g0aRpxhbZbB0djmLQOphclw7uNETQekid0Gi/g7buFS\r\nCq8r77rnwuBsVuHKjtmWl3/+cgEHKvNxbYd1LLbkAvjiDw6IiIhpGvghbFgFQkmc\r\nMAvwzijep/Ala5xUzZFsMuLlnZhBQzmGKoWClawUALdgm/NEp+pnDb5AGOpfCWbb\r\nGhc9n/PBAgMBAAGjggEFMIIBATAdBgNVHQ4EFgQUiGwYgUQupLrtpqNAPnu+Pi7D\r\n/IAwgdEGA1UdIwSByTCBxoAUiGwYgUQupLrtpqNAPnu+Pi7D/IChgaKkgZ8wgZwx\r\nCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\r\nbzEaMBgGA1UEChMRWG9ibmkgQ29ycG9yYXRpb24xHDAaBgNVBAsTE0VkZ3kgR3J1\r\nZmYgU2VjdXJpdHkxETAPBgNVBAMTCFhvYm5pIENBMRswGQYJKoZIhvcNAQkBFgxj\r\nYUB4b2JuaS5jb22CCQCNKpeZipRSmDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB\r\nBQUAA4IBAQCBFcZV4FD0ljxSe5JCn14beYGfXxm06Opv2LsyboqywFzUE/ABZj7Z\r\nOeCV1IEQfFYb4TC+9/3Yq1FXkJhNcPajuCrm9Nq7OPxZeUD02mt45e8FS6FMadEm\r\nb6pTXETehoIcs2eYUI9dPEfKdoTOCRXDuEruOh2CjO+P0aNxSbzqTfgprcV1qSno\r\nFMDVnmH155+L8Jh9kK+ZLHms/Udcgz0YAzgze0eGKWMa2rrwCSNkqyEvkK34Ed/C\r\nXn3H0Z6AAq22Fc/bKJGomvuPWeycdB9JSIuI844a6HOfFU5+kT57nkwwxhwLntu7\r\nE/AISDiAMBLExQK2F6vOhbAGCI+55KsR\r\n-----END CERTIFICATE-----\r\n"));
|
|||
|
private static readonly char[] h = new char[16]
|
|||
|
{
|
|||
|
'0',
|
|||
|
'1',
|
|||
|
'2',
|
|||
|
'3',
|
|||
|
'4',
|
|||
|
'5',
|
|||
|
'6',
|
|||
|
'7',
|
|||
|
'8',
|
|||
|
'9',
|
|||
|
'A',
|
|||
|
'B',
|
|||
|
'C',
|
|||
|
'D',
|
|||
|
'E',
|
|||
|
'F'
|
|||
|
};
|
|||
|
|
|||
|
public static string b()
|
|||
|
{
|
|||
|
if (hs.f != null)
|
|||
|
return hs.f;
|
|||
|
try
|
|||
|
{
|
|||
|
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\Xobni", false))
|
|||
|
{
|
|||
|
if (registryKey != null)
|
|||
|
hs.f = (string) registryKey.GetValue("OverrideUpdatePath", (object) hs.e);
|
|||
|
}
|
|||
|
}
|
|||
|
catch
|
|||
|
{
|
|||
|
hs.f = hs.e;
|
|||
|
}
|
|||
|
return hs.f;
|
|||
|
}
|
|||
|
|
|||
|
internal static string a()
|
|||
|
{
|
|||
|
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\Xobni"))
|
|||
|
{
|
|||
|
if (registryKey != null)
|
|||
|
return (string) registryKey.GetValue("InstallDir");
|
|||
|
ady.a(Level.Debug, "No Xobni local machine registry key.");
|
|||
|
return (string) null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal static string b(string A_0, string A_1)
|
|||
|
{
|
|||
|
aaa aaa = hs.b(A_1);
|
|||
|
if (aaa == null)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "No new updates.");
|
|||
|
return (string) null;
|
|||
|
}
|
|||
|
hs.a(aaa);
|
|||
|
string str = Path.Combine(A_0, aaa.b());
|
|||
|
if (Directory.Exists(A_0))
|
|||
|
{
|
|||
|
if (hs.c(A_0) && hs.a(A_0, aaa))
|
|||
|
return str;
|
|||
|
ady.a(Level.Debug, "Deleting old/bad updates.");
|
|||
|
Directory.Delete(A_0, true);
|
|||
|
}
|
|||
|
if (!Directory.Exists(A_0))
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Creating update directory.");
|
|||
|
Directory.CreateDirectory(A_0);
|
|||
|
}
|
|||
|
ady.a(Level.Debug, "Downloading update...");
|
|||
|
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(aaa.c());
|
|||
|
try
|
|||
|
{
|
|||
|
httpWebRequest.Proxy = WebRequest.DefaultWebProxy;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Error setting web proxy on downloadRequest: " + ex.Message);
|
|||
|
}
|
|||
|
WebResponse response;
|
|||
|
try
|
|||
|
{
|
|||
|
response = httpWebRequest.GetResponse();
|
|||
|
}
|
|||
|
catch (WebException ex)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Could not access XobniUpdate.exe URL: " + ex.Message);
|
|||
|
return (string) null;
|
|||
|
}
|
|||
|
using (Stream responseStream = response.GetResponseStream())
|
|||
|
{
|
|||
|
using (FileStream A_1_1 = new FileStream(str, FileMode.Create))
|
|||
|
hs.a(responseStream, (Stream) A_1_1);
|
|||
|
}
|
|||
|
ady.a(Level.Debug, "Update download completed.");
|
|||
|
return hs.a(str, aaa.d()) ? str : throw new Exception("Invalid update hash.");
|
|||
|
}
|
|||
|
|
|||
|
internal static bool c(string A_0)
|
|||
|
{
|
|||
|
if (Directory.Exists(A_0) && Directory.GetFiles(A_0).Length > 0)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "An update is available (but not yet verified).");
|
|||
|
return true;
|
|||
|
}
|
|||
|
ady.a(Level.Debug, "There are no pending updates available.");
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
internal static bool a(string A_0, aaa A_1)
|
|||
|
{
|
|||
|
string str = Path.Combine(A_0, A_1.b());
|
|||
|
if (System.IO.File.Exists(str) && hs.a(str, A_1.d()))
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Correctly signed update file already exists.");
|
|||
|
return true;
|
|||
|
}
|
|||
|
ady.a(Level.Debug, "An update exists, but it is not correctly signed.");
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
internal static aaa b(string A_0)
|
|||
|
{
|
|||
|
string path1 = hs.a();
|
|||
|
if (path1 == null)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "No InstallDirectory registry value.");
|
|||
|
return (aaa) null;
|
|||
|
}
|
|||
|
string fileVersion = FileVersionInfo.GetVersionInfo(Path.Combine(path1, "XobniCommon.dll")).FileVersion;
|
|||
|
if (string.IsNullOrEmpty(fileVersion))
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Bad XobniCommon version " + fileVersion + ".");
|
|||
|
return (aaa) null;
|
|||
|
}
|
|||
|
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(string.Format("{0}?version={1}&source={2}&xmid={3}", (object) hs.b(), (object) fileVersion, (object) A_0, (object) jf.a()));
|
|||
|
httpWebRequest.KeepAlive = false;
|
|||
|
try
|
|||
|
{
|
|||
|
httpWebRequest.Proxy = WebRequest.DefaultWebProxy;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Error setting web proxy on updateRequest: " + ex.Message);
|
|||
|
}
|
|||
|
WebResponse response;
|
|||
|
try
|
|||
|
{
|
|||
|
response = httpWebRequest.GetResponse();
|
|||
|
}
|
|||
|
catch (WebException ex)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "Could not access update check URL: " + ex.Message);
|
|||
|
return (aaa) null;
|
|||
|
}
|
|||
|
if (response.ContentLength == 0L)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "No updates available");
|
|||
|
return (aaa) null;
|
|||
|
}
|
|||
|
XmlDocument xmlDocument;
|
|||
|
using (Stream responseStream = response.GetResponseStream())
|
|||
|
xmlDocument = hs.b(responseStream);
|
|||
|
XmlElement documentElement = xmlDocument.DocumentElement;
|
|||
|
string[] strArray1 = hs.a(documentElement, "version").InnerText.Split('.');
|
|||
|
string str1 = strArray1[2];
|
|||
|
int A_0_1 = int.Parse(strArray1[3]);
|
|||
|
string[] strArray2 = fileVersion.Split('.');
|
|||
|
string str2 = strArray2[2];
|
|||
|
if (int.Parse(strArray2[3]) >= A_0_1)
|
|||
|
{
|
|||
|
ady.a(Level.Debug, "No new updates");
|
|||
|
return (aaa) null;
|
|||
|
}
|
|||
|
if (string.IsNullOrEmpty(str1))
|
|||
|
throw new Exception("Invalid branch ID in update");
|
|||
|
if (str1.Equals(str2))
|
|||
|
{
|
|||
|
ady.a(Level.Debug, string.Format("Updating {0} branch", (object) str2));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (!"0".Equals(str2))
|
|||
|
throw new Exception("Invalid branch ID in update");
|
|||
|
ady.a(Level.Debug, "Updating unknown branch to release branch");
|
|||
|
}
|
|||
|
string innerText1 = hs.a(documentElement, "url").InnerText;
|
|||
|
string innerText2 = hs.a(documentElement, "hash").InnerText;
|
|||
|
string innerText3 = hs.a(documentElement, "localName").InnerText;
|
|||
|
return new aaa(A_0_1, innerText1, innerText3, innerText2);
|
|||
|
}
|
|||
|
|
|||
|
private static void a(aaa A_0) => ady.a(Level.Debug, "Update available: Hash(" + A_0.d() + "), BuildNumber(" + (object) A_0.a() + "), LocalName(" + A_0.b() + "), URL(" + A_0.c() + ")");
|
|||
|
|
|||
|
public static XmlDocument b(Stream A_0)
|
|||
|
{
|
|||
|
X509Certificate2 A_0_1 = new X509Certificate2(hs.a(A_0));
|
|||
|
if (!hs.a(A_0_1))
|
|||
|
throw new Exception("Invalid XobniUpdater certificate");
|
|||
|
byte[] signature = hs.a(A_0);
|
|||
|
byte[] buffer = hs.a(A_0);
|
|||
|
if (!((RSACryptoServiceProvider) A_0_1.PublicKey.Key).VerifyData(buffer, (object) new SHA1CryptoServiceProvider(), signature))
|
|||
|
throw new Exception("Invalid XobniUpdater signature");
|
|||
|
XmlDocument xmlDocument = new XmlDocument();
|
|||
|
xmlDocument.Load((Stream) new MemoryStream(buffer));
|
|||
|
return xmlDocument;
|
|||
|
}
|
|||
|
|
|||
|
public static void a(Stream A_0, X509Certificate2 A_1, byte[] A_2)
|
|||
|
{
|
|||
|
X509Certificate2 A_0_1 = new X509Certificate2((X509Certificate) A_1);
|
|||
|
if (!hs.a(A_0_1))
|
|||
|
throw new ArgumentException("Invalid XobniUpdate certificate");
|
|||
|
byte[] A_1_1 = ((RSACryptoServiceProvider) A_0_1.PrivateKey).SignData(A_2, (object) new SHA1CryptoServiceProvider());
|
|||
|
A_0_1.PrivateKey = (AsymmetricAlgorithm) null;
|
|||
|
hs.b(A_0, A_0_1.RawData);
|
|||
|
hs.b(A_0, A_1_1);
|
|||
|
hs.b(A_0, A_2);
|
|||
|
}
|
|||
|
|
|||
|
public static bool a(X509Certificate2 A_0)
|
|||
|
{
|
|||
|
X509Chain x509Chain = new X509Chain();
|
|||
|
x509Chain.ChainPolicy.ExtraStore.Add(hs.g);
|
|||
|
x509Chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority | X509VerificationFlags.IgnoreEndRevocationUnknown | X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown | X509VerificationFlags.IgnoreRootRevocationUnknown;
|
|||
|
return x509Chain.Build(A_0) && x509Chain.ChainElements.Count == 2 && x509Chain.ChainElements[0].Certificate.Subject.Equals("E=support@xobni.com, CN=XobniUpdate, O=Xobni Corporation, S=CA, C=US") && x509Chain.ChainElements[1].Certificate.Equals((X509Certificate) hs.g);
|
|||
|
}
|
|||
|
|
|||
|
public static XmlElement a(XmlElement A_0, string A_1)
|
|||
|
{
|
|||
|
XmlNodeList elementsByTagName = A_0.GetElementsByTagName(A_1);
|
|||
|
return elementsByTagName.Count == 1 ? elementsByTagName[0] as XmlElement : throw new Exception("Invalid XobniUpdater XML: expected single element");
|
|||
|
}
|
|||
|
|
|||
|
public static byte[] a(Stream A_0)
|
|||
|
{
|
|||
|
byte[] A_1_1 = new byte[2];
|
|||
|
hs.a(A_0, A_1_1);
|
|||
|
byte[] A_1_2 = new byte[(int) BitConverter.ToUInt16(A_1_1, 0)];
|
|||
|
hs.a(A_0, A_1_2);
|
|||
|
return A_1_2;
|
|||
|
}
|
|||
|
|
|||
|
public static void b(Stream A_0, byte[] A_1)
|
|||
|
{
|
|||
|
byte[] buffer = A_1.Length <= (int) ushort.MaxValue ? BitConverter.GetBytes((ushort) A_1.Length) : throw new ArgumentException("Data length can't be more than " + (object) ushort.MaxValue + " bytes");
|
|||
|
A_0.Write(buffer, 0, buffer.Length);
|
|||
|
A_0.Write(A_1, 0, A_1.Length);
|
|||
|
}
|
|||
|
|
|||
|
public static void a(Stream A_0, byte[] A_1)
|
|||
|
{
|
|||
|
int offset = 0;
|
|||
|
int length = A_1.Length;
|
|||
|
while (length > 0)
|
|||
|
{
|
|||
|
int num = A_0.Read(A_1, offset, length);
|
|||
|
if (num <= 0)
|
|||
|
throw new EndOfStreamException(string.Format("End of stream reached with {0} bytes left to read", (object) length));
|
|||
|
length -= num;
|
|||
|
offset += num;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void a(Stream A_0, Stream A_1)
|
|||
|
{
|
|||
|
int count1 = 4096;
|
|||
|
byte[] buffer = new byte[count1];
|
|||
|
for (int count2 = A_0.Read(buffer, 0, count1); count2 > 0; count2 = A_0.Read(buffer, 0, count1))
|
|||
|
A_1.Write(buffer, 0, count2);
|
|||
|
}
|
|||
|
|
|||
|
public static string a(byte[] A_0)
|
|||
|
{
|
|||
|
char[] chArray = new char[A_0.Length * 2];
|
|||
|
for (int index = 0; index < A_0.Length; ++index)
|
|||
|
{
|
|||
|
int num = (int) A_0[index];
|
|||
|
chArray[index * 2] = hs.h[num >> 4];
|
|||
|
chArray[index * 2 + 1] = hs.h[num & 15];
|
|||
|
}
|
|||
|
return new string(chArray);
|
|||
|
}
|
|||
|
|
|||
|
public static bool a(string A_0, string A_1)
|
|||
|
{
|
|||
|
byte[] hash;
|
|||
|
using (FileStream inputStream = new FileStream(A_0, FileMode.Open))
|
|||
|
hash = new SHA256Managed().ComputeHash((Stream) inputStream);
|
|||
|
return A_1.ToUpper().Equals(hs.a(hash));
|
|||
|
}
|
|||
|
|
|||
|
public static string a(string A_0)
|
|||
|
{
|
|||
|
byte[] hash;
|
|||
|
using (FileStream inputStream = new FileStream(A_0, FileMode.Open))
|
|||
|
hash = new SHA256Managed().ComputeHash((Stream) inputStream);
|
|||
|
return hs.a(hash);
|
|||
|
}
|
|||
|
}
|