AMSI

Antimalware Scan Interface (AMSI)

AMSI (Antimalware Scan Interface) est une interface de Windows permettant à des processus de faire analyser de la donnée aux solutions de sécurité installées sur la machine. Cette fonctionnalité est disponible sur les systèmes d’exploitation Windows à partir de Windows 10. C’est un élément important de la sécurité de Windows, car elle permet aux produits antivirus d’analyser en profondeur les données traitées par les applications et de détecter les menaces plus efficacement.

D’un point de vue processus, cette fonctionnalité permet de « s’assurer » de la non-dangerosité des données manipulées en mémoire. AMSI est agnostique du logiciel de sécurité utilisé et tout logiciel de sécurité peut s’inscrire pour recevoir des demandes d’analyse.

AMSI est utilisée nativement par plusieurs composants de Windows :

PowerShellJavaScriptVBScript
Macros VBA Office.NETGestionnaire VSS
WMIUAC

C’est notamment grâce à AMSI que les solutions de sécurité sont capables de récupérer facilement les commandes exécutées par des scripts malveillants.

Code

Plus concrètement, un processus peut faire la demande de scan AMSI via une procédure assez simple. En voici un exemple simplifié en C++ :

#include <windows.h>
#include <amsi.h>
#include <iostream>

int main()
{
    HRESULT hResult;
    HAMSICONTEXT amsi_context;
    AMSI_RESULT amsi_result;
    HAMSISESSION amsi_session = nullptr;
    LPCWSTR content = L"<DATA TO SCAN>";
    LPCWSTR content_name = L"script.sh";
    ULONG content_size = wcslen(content);


    // Initialize AMSI
    hResult = AmsiInitialize(L"MyApp", &amsi_context);
    hResult = AmsiOpenSession(amsi_context, &amsi_session);

    // Scan
    hResult = AmsiScanBuffer(amsi_context, &content, content_size, content_name, amsi_session, &amsi_result);
    //hResult = AmsiScanString(amsi_context, content, content_name, amsi_session, &amsi_result);

    // Verify Scan Result
    std::cout << "AMSI RESULT : " << amsi_result << std::endl;
    if (amsi_result == AMSI_RESULT_DETECTED) std::cout << "Détecté comme malveillant" << std::endl;


    // Cleanup
    AmsiUninitialize(amsi_context);

    return 0;
}
Compilation

Assurez-vous d’avoir installé le kit de développement logiciel (SDK) Windows et d’avoir ajouté les chemins d’accès aux fichiers d’en-tête et aux bibliothèques dans votre environnement de développement.

Sous Visual Studio, assurez-vous que la bibliothèque « amsi.lib » est incluse dans votre projet. Pour ce faire, cliquez avec le bouton droit sur votre projet dans l’Explorateur de solutions et sélectionnez Propriétés. Sous Configuration propriétés > Éditeur de liens > Entrées, ajoutez « amsi.lib » à la liste des bibliothèques supplémentaires.

Notez que vous devrez également copier la bibliothèque AMSI « amsi.dll » dans le même répertoire que votre fichier exécutable pour que le programme puisse s’exécuter correctement.

Explication

Dans le code ci-dessus, il y a d’abord une initialisation de l’interface AMSI en fournissant le nom de l’application « MyApp » pour récupérer un contexte d’exécution amsi_context.

S’en suit l’ouverture d’une session amsi_session. En effet, AMSI prend en charge la notion de session afin que les fournisseurs de logiciels de sécurité puissent mettre en corrélation différentes demandes d’analyse.

Le code lance ensuite un scan sur le contenu de content de taille content_size. Le content_name peut être un nom de fichier, une URL, un ID, etc.. Le scan est alors lancé grâce à AmsiScanBuffer. Tous les logiciels de sécurité qui se sont inscrits en tant que fournisseur AMSI vont effectuer un scan sur la donnée.

AmsiScanBuffer retourne ensuite le résultat via une structure « AMSI_RESULT » avec le verdict des scans effectués par les logiciels de sécurité :

enum AMSI_RESULT {

    AMSI_RESULT_CLEAN = 0,
    AMSI_RESULT_NOT_DETECTED  = 1,
    AMSI_RESULT_BLOCKED_BY_ADMIN_START = 0x4000,
    AMSI_RESULT_BLOCKED_BY_ADMIN_END = 0x4fff,
    AMSI_RESULT_DETECTED = 32768

}

Résultats

Pour tester le bon fonctionnement d’AMSI, nous allons choisir comme valeur à scanner la chaîne suivante :

LPCWSTR content = L"AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386";

Cette chaine de caractère est spécifiquement utilisée pour tester le bon fonctionnement d’AMSI. Elle générera donc un résultat positif lors du scan. En lançant l’exécutable après l’avoir compilé, on obtient le résultat suivant dans notre terminal :

PS C:\Users\Lun\AMSI> .\MyApp.exe
AMSI RESULT : 32768
Détecté comme malveillant

On constate ici que notre application a bel et bien effectué un scan de notre chaîne de caractère grâce à la fonctionnalité AMSI.

Si vous utilisez Microsoft Defender comme solution de sécurité, vous pourrez retrouver la trace de votre scan dans l’Observateur d’évènements dans la section Applications/Microsoft/Windows/Windows Defender/Operational:

Limites

Il existe malheureusement plusieurs techniques permettant de passer au travers de la sécurité AMSI. Bon nombre d’entre elles sont néanmoins détectées en amont par les logiciels de sécurité :

  • Offuscation de script
  • Chiffrement
  • Amsi.dll patching
  • COM Server Hijacking
  • Utiliser une ancienne version des logiciels
  • Corruption du fournisseur de scan

Sources

1 reply on “ AMSI ”

Comments are closed.