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 fonctionengine
et la convertit enScanSummary
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 fonctionparser
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | b19e42dbccc28e87a56413f8278d5753f348a8acd992d3bddeb4435d0c971218 |
|
MD5 | 19e0bda1ecf787e8940f2b1e53b06132 |
|
BLAKE2b-256 | b25dbc6f44f4049837f9c8777313318f03a951d5f3782200b3e1af3ad3038811 |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | c29fb5aa66313a036ce940fca0ca1e85d66dd69439b5b7705ea611312e8b3c9f |
|
MD5 | 28c7491485a83b754f99796478092482 |
|
BLAKE2b-256 | ae3358dffcdc13fc83a78703641a80b39f2d47286d28b0c79ea453a5c428977c |