Skip to main content

No project description provided

Project description

Malin

Description

Paquet Python permettant de créer facilement de nouveaux moteurs antiviraux à intégrer dans l'environnement Malin.

Introduction

Pourquoi ce paquet ?

Malin a initialement été développé en Golang. Cependant, ce langage peut être assez niche et présenter une courbe d'apprentissage élevée. Il m'a semblé naturel de créer un paquet Python pour faciliter le développement pour les consultants, les analystes SOC, et les équipes CERT. Ce paquet a été conçu pour être le plus simple possible à utiliser.

A qui est dédié ce paquet ?

Si vous ne connaissez pas Malin, ce paquet n'est probablement pas pour vous :) En effet, il n'est pas destiné à un usage grand public. En effet, sans l'environnement Malin comprenant l'ordonnanceur, les workers, etc., ce paquet ne sera pas très utile, car il a été développé pour un usage très spécifique.

Usage

Comme j'aime bien les exemples et que je pense que c'est plus sympa d'apprendre avec des exemples, je vais vous décrire l'utilisation du paquet pas à pas.

Quick Start

Installation

Avant de plonger dans le code, il faut d'abord installer le paquet. Rien de plus simple :

pip install malin

Une fois cela fait, vous avez accompli la partie la plus difficile ;)

Boilerplate Code

Concernant le code, voici le code de base à utiliser :

from malin import Malin, ScanSummary

def parser(engineResult) -> ScanSummary:
    # Parser le résultat de l'engine et le convertir en ScanSummary

def engine(filename: str) -> str:
    # Lancer l'engine avec le nom de fichier reçu depuis le worker
    # Renvoyer le résultat pour qu'il soit passé au parser

malinEngine = Malin(engine, parser)
malinEngine.run(hots="0.0.0.0", port=5000) # On peut specifier les champs host et port

La classe Malin expose une API avec les bons endpoints et méthodes pour que le worker puisse envoyer et recevoir les rapports d'analyse. La seule partie non générique est :

  • Comment lancer et récupérer le résultat d'un moteur
  • Comment parser la reponse de l'engine

En effet, les éditeurs d'antivirus n'ont pas uniformisé l'usage de leurs moteurs ni leurs sorties :| Cela dépend donc de chaque moteur. C'est pourquoi il est demandé de coder deux fonctions :

  • engine: Cette fonction lance l'analyse avec le moteur, récupère la sortie et la retourne pour qu'elle soit envoyée au parser.
  • parser: Cette fonction parse la sortie de la fonction engine et la convertit en ScanSummary

La class ScanSummary est definie comme suit:

@dataclass
class ScanSummary:
    engine: str
    message: str
    detected: bool
    malware: List[str]

Error handling

Parfois, les choses ne se passent pas comme prévu (mdr, tout le temps). Il est possible de renvoyer des erreurs prédéfinies telles que :

  • InvalidOutput : Peut être levée dans la fonction parser quand les règles de parsing ne sont pas respectées. Par exemple, si le binaire lancé n'est pas le bon ou qu'il y a une erreur dans le rapport fourni.

Exemple concret:

Maintenant que vous êtes devenus des pros (eh oui, on n'a pas de temps à perdre ici), nous allons voir comment implémenter un moteur antiviral peu connu, "Windows Defender" :)

Pour interagir avec "Windows Defender", on peut appeler le binaire MpCmdRun.exe avec les bonnes options. Comme ce tutoriel vise à vous familiariser avec le paquet malin et non à expliquer comment utiliser "MpCmdRun.exe", nous allons utiliser un wrapper pour "Windows Defender" appelé pyrattle (petite promo). Vous pourriez aussi l'implémenter différemment (avec os.system par exemple), c'est vous qui voyez ;)

Engine

Commençons par la partie engine. Il suffit de lancer l'analyse du fichier donné en paramètre (filename) et de retourner le résultat obtenu. À noter : Le type de la valeur de retour n'est pas très important. Tant que la fonction parser gère le type retourné, ça fonctionne. Dans notre cas, nous retournons une instance de ScanResult, mais nous aurions très bien pu retourner un str :

from pyrattle import PyDefender
from pyrattle.pyrattle import ScanType, ScanResult

from malin import Malin
#...
def defenderEngine(filename: str) :
    scanner = PyDefender()
    result : ScanResult = scanner.scan(scan_type=ScanType.CUSTOM ,file=filename, disable_remediation=True)
    return result

Parser

Maintenant, la partie la plus difficile (c'est faux XD). Puisque l'engine retourne un ScanResult, la fonction parser doit prendre en argument un ScanResult. Tout ce qu'on fait ici, c'est convertir le résultat en ScanSummary et adapter le message.

from malin import Malin, ScanSummary

# ...

def defenderParser(output: ScanResult) -> ScanSummary:
    message: str = "Malware Detected"
    if (not output.is_threat):
       message = "Malware not Detected" 

    result = ScanSummary(engine="Windows Defender", message=message, detected=output.is_threat, malware=[output.threat])
    
    return result 

Code final

En réunissant les fonctions précédentes, on obtient le code final :

from pyrattle import PyDefender
from pyrattle.pyrattle import ScanType, ScanResult

from malin import Malin, ScanSummary

def defenderParser(output: ScanResult) -> ScanSummary:
    message: str = "Malware Detected"
    if (not output.is_threat):
       message = "Malware not Detected" 

    result = ScanSummary(engine="Windows Defender", message=message, detected=output.is_threat, malware=[output.threat])
    
    return result 

def defenderEngine(filename: str) :
    scanner = PyDefender()
    result : ScanResult = scanner.scan(scan_type=ScanType.CUSTOM ,file=filename, disable_remediation=True)
    return result

malinDefender = Malin(defenderEngine, defenderParser)
malinDefender.run(host="0.0.0.0")

Licence

Ce projet est sous licence MIT. Consultez le fichier LICENSE pour plus d'informations.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

malin-0.2.2.tar.gz (8.6 kB view details)

Uploaded Source

Built Distribution

malin-0.2.2-py3-none-any.whl (10.5 kB view details)

Uploaded Python 3

File details

Details for the file malin-0.2.2.tar.gz.

File metadata

  • Download URL: malin-0.2.2.tar.gz
  • Upload date:
  • Size: 8.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.3 Windows/10

File hashes

Hashes for malin-0.2.2.tar.gz
Algorithm Hash digest
SHA256 b19e42dbccc28e87a56413f8278d5753f348a8acd992d3bddeb4435d0c971218
MD5 19e0bda1ecf787e8940f2b1e53b06132
BLAKE2b-256 b25dbc6f44f4049837f9c8777313318f03a951d5f3782200b3e1af3ad3038811

See more details on using hashes here.

File details

Details for the file malin-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: malin-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 10.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.3 Windows/10

File hashes

Hashes for malin-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c29fb5aa66313a036ce940fca0ca1e85d66dd69439b5b7705ea611312e8b3c9f
MD5 28c7491485a83b754f99796478092482
BLAKE2b-256 ae3358dffcdc13fc83a78703641a80b39f2d47286d28b0c79ea453a5c428977c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page