Black hat bash
Из одноименной книги "BLACK HAT BASH Creative Scripting for Hackers and Pentesters by Dolev Farhi and Nick Aleks"
Portswigger Academy CTF багбаунти
OWASP TOP 10
Тестовые контейнеры
cd ~/Black-Hat-Bash/lab/
sudo make deploy
| deploy | Собрать образы и запустить контейнеры |
| teardown | Остановить контейнеры |
| rebuild | clean up + deploy |
| cleanup | Остановить и удалить контейнеры и образы |
| status | Текущий статус |
| init | Первая инициализация окружения и инструментов |
Адреса и домены
Список адресов.
#!/bin/bash
for ip in $(seq 1 254); do
echo "172.16.10.${ip}" >> 172-16-10-hosts.txt
done
echo 10.1.0.{1..254} | sed 's/ /\n/g'
Список доменов.
Есть списки часто используемых поддоменов. Называются gists. В Kali они есть по /usr/share/wordlists/amass/bitquark_subdomains_top100K.txt Или можно в google "subdomain wordlist site:gist.github.com".
#!/bin/bash
DOMAIN=$1
FILE=$2
while read -r subdomain; do
echo "${subdomain}.${DOMAIN}"
done < "${FILE}" > ${DOMAIN}.txt
Поиск хостов.
Доступность IP хостов по ping
#!/bin/bash
FILE=$1
while read -r host; do
if ping -c 1 -W 1 -w 1 "${host}" &> /dev/null; then
echo "${host} is up."
fi
done < "${FILE}"
Через nmap, работает гораздо быстрее.
nmap -sn 172.16.10.0/24 | grep "Nmap scan" | awk -F'report for ' '{print $2}'
ARP сканирование
sudo arp-scan -f 172-16-10-hosts.txt -I br_public | grep '^[0-9]\+\.[0-9]*' | awk '{print $1}'
Поиск новых адресов в локальной сети
#!/bin/bash
KNOWN_HOSTS='172-16-10-scanning-hosts.txt'
NETWORK='172.16.10.0/24'
INTERFACE='br_public'
while true; do
echo "Сканируем сеть ${NETWORK}..."
sudo arp-scan -x -I ${INTERFACE} ${NETWORK} | while read -r line; do
host=$(echo "${line}" | awk '{print $1}')
if ! grep -q "${host}" "${KNOWN_HOSTS}"; then
echo "Found new host: ${host}!"
echo "${host}" >> "${KNOWN_HOSTS}"
source senderscripts/tgsender.sh "Найден хост ${host}!"
fi
done
sleep 10
done
Сканирование портов
Nmap
nmap ip/dns ip/dns
По умолчанию:
- отправка SYN пакета на порт
- Первые 1000 портов
- Только TCP соединения
| Параметр | Значение |
| -iL file | список хостов из файла |
| -sV | версия сервиса на порту |
| -oG - |
Информация в формате удобном для парсинга Host: 172.16.10.10 () Ports: 8081/open/tcp//blackice-icecap/// Ignored-state: closed (999) Несколько портов: Host: 172.16.10.11 () Ports: 21/open/tcp//ftp///, 80/open/tcp//http/// Ignored State: closed (998) |
| --open | выводить только открытые порты |
| --exclude | исключения из списка |
Пример вывода:
Nmap scan report for 172.16.10.13
Host is up (0.000031s latency).
Not shown: 999 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.13 (Ubuntu Linux; protocol 2.0)
MAC Address: FA:85:E8:7D:68:EE (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
RustScan
Работает гораздо быстрее nmap, однако выводит только открытые порты без определения сервиса.
| Параметр | Значение |
| -a ip/mask | Адрес или адрес сети |
| -g | Только информация по сканированию |
| -r start-end |
Диапазон портов -r 1-1024 |
$ rustscan -g -a 172.16.10.0/24 -r 1-1024 | awk -F'->' '{print $1,$2}' | tr -d '[]'
Netcat
Чаще используют для проверки одного порта.
nc -zv 172.16.10.11 1-1024
(UNKNOWN) [172.16.10.11] 80 (http) open
(UNKNOWN) [172.16.10.11] 21 (ftp) open
-z только вывод результатов,
Организация хранения результатов сканирования
Можно сохранять данные для каждого IP в отдельном файле или в зависимости от версии программ.
Пример для каждого открытого порта свой файл со списком адресов.
#!/bin/bash
HOSTS="172-16-10-scanning-hosts.txt"
nmap -iL ${HOSTS} --open -oG - | grep Ports: | while read -r line; do
curip=$(echo $line | awk {'print $2'})
echo $line | grep -oP '( \d+)(?=/)' | while read -r curport; do
echo $curip >> port-${curport}.txt
done
done
Определение сервиса на порту
Анализ баннера
У нас есть открытые порты. Но необходимо узнать, что за сервис крутится на нем. Часто сервисы публикуют т н баннер - информацию о себе. Есть сервисы, хранящие данные о сайтах, типа https://shodan.io https://zoomeye.org которые хранят базу данных. Это называется пассивным сканированием.
Естественно администраторы могут изменять баннер.
Netcat может предоставить данную информацию.
nc 172.16.10.11 -v 21
172.16.10.11: inverse host lookup failed: Unknown host
(UNKNOWN) [172.16.10.11] 21 (ftp) open
220 (vsFTPd 3.0.5)
nc 1.1.1.1 -v 22
some.address.ru [1.1.1.1] 22 (ssh) open
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.13
Ключи nc:
| Флаг | Значение | Пример |
|---|---|---|
-l |
Слушать (listen) — запускает nc в режиме сервера (ожидание входящих подключений) |
nc -l -p 4444 |
-p <порт> |
Указать порт (для прослушивания или исходного подключения) | nc -l -p 4444 |
-v |
Подробный режим (verbose), показывает процесс соединения | nc -vz 8.8.8.8 53 |
-vv |
Очень подробный (ещё больше информации) | nc -zvv 8.8.8.8 53 |
-z |
Сканирование портов (zero-I/O mode: проверка доступности портов без передачи данных) | nc -zv 192.168.0.1 20-80 |
-u |
Использовать UDP вместо TCP | nc -u 192.168.0.10 123 |
-n |
Не использовать DNS (работать только с IP, не пытаться резолвить имена) | nc -vz -n 192.168.0.1 80 |
-w <сек> |
Таймаут соединения | nc -vz -w 3 8.8.8.8 53 |
-q <сек> |
Закрыть соединение после EOF через указанное время | `echo hi |
-k |
Продолжать слушать после разрыва соединения (серверный режим) | nc -lk -p 4444 |
-e <программа> |
Запуск программы после подключения (опасный флаг!, часто отключён в безопасных сборках nc) |
nc -l -p 4444 -e /bin/bash |
Сбор информации о баннере:
#!/bin/bash
FILE="$1"
PORT="$2"
while read -r ip; do
res=$(echo -e "\n" | nc -v "${ip}" -w 1 "${PORT}" 2> /dev/null)
if [[ -n "${res}" ]]; then
echo "Service: ${ip}:${PORT}"
echo "Banner: ${res}"
fi
done < "${FILE}"
Анализ http ответа сервера
При помощи curl с помощью метода head можно получить информацию об http сервере.
curl --head 172.16.10.10:8081
HTTP/1.1 200 OK
Server: Werkzeug/3.0.1 Python/3.12.3
Date: Sat, 30 Aug 2025 08:41:02 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 7176
Connection: close
Приложение whatweb предоставляет расширенную информацию об http сервере. Синтаксис:
whatweb 172.16.10.10:8081
http://172.16.10.10:8081 [200 OK] Country[RESERVED][ZZ], HTML5,
HTTPServer[Werkzeug/3.0.1 Python/3.12.3], IP[172.16.10.10],
Python[3.12.3], Title[Menu], Werkzeug[3.0.1], X-UA-Compatible[ie=edge]
whatweb 172.16.10.10:8081 --log-json=/dev/stdout --quiet | jq
# в формате JSON
Т е скомбинировав данные, полученные после сканирования, можно определить некоторые стартовые позиции.
Получение информации об операционной системе
Способ формирования TCP ответа несколько отличаются для разных ОС. Можно определить примерный тип ОС и иногда версию ядра.
Опция -O позволяет проанализировать данную информацию.
sudo nmap -O -iL 172-16-10-scanning-hosts.txt
Nmap scan report for 172.16.10.11
Host is up (0.000038s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE
21/tcp open ftp
80/tcp open http
MAC Address: F6:F2:1D:05:71:02 (Unknown)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4)
Network Distance: 1 hop
Получение данных:
#!/bin/bash
HOSTS="$*"
if [[ "${EUID}" -ne 0 ]]; then
echo "Run script with sudo."
exit 1
fi
if [[ "$#" -eq 0 ]]; then
echo 'Need at least one IP'
exit 1
fi
nmap_scan=$(sudo nmap -O ${HOSTS} -oG -)
while read -r line; do
ip=$(echo "${line}" | awk '{print $2}')
os=$(echo "${line}" | awk -F'OS: ' '{print $2}' | sed 's/Seq.*//g')
if [[ -n "${ip}" ]] && [[ -n "${os}" ]]; then
echo "IP: ${ip} OS: ${os}"
fi
done <<< "${nmap_scan}"
Сканирование web ресурса
Есть ряд сканеров, например nikto. Использование
nikto -host 172.16.10.11 -port 80
+ Server: Apache/2.4.58 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ /: Server may leak inodes via ETags, header found with file /, inode: 29af, size: 63d6cf46a153e, mtime: gzip. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2003-1418
+ OPTIONS: Allowed HTTP Methods: GET, POST, OPTIONS, HEAD .
+ /backup/: Directory indexing found.
+ /backup/: This might be interesting.
+ 8102 requests: 0 error(s) and 6 item(s) reported on remote host
+ End Time: 2025-08-30 20:12:35 (GMT8) (40 seconds)
Скрипт сохранения файлов из открытых директории
#!/bin/bash
FILE="${1}"
OUTPUT_FOLDER="${2}"
if [[ ! -s "${FILE}" ]]; then
echo "You must provide a non-empty hosts file as an argument."
exit 1
fi
if [[ -z "${OUTPUT_FOLDER}" ]]; then
OUTPUT_FOLDER="data"
fi
while read -r line; do
url=$(echo "${line}" | xargs)
if [[ -n "${url}" ]]; then
echo "Testing ${url} for Directory indexing..."
if curl -L -s "${url}" | grep -q -e "Index of /" -e "[PARENTDIR]"; then
echo -e "\t -!- Found Directory Indexing page at ${url}"
echo -e "\t -!- Downloading to the \"${OUTPUT_FOLDER}\" folder..."
mkdir -p "${OUTPUT_FOLDER}"
wget -q -r -np -R "index.html*" "${url}" -P "${OUTPUT_FOLDER}"
fi
fi
done < <(cat "${FILE}")
Сканирование директорий, закрытых от индексирования в robots.txt
Можно просканировать закрытые директории, просмотрев коды ответов при обращении:
#!/bin/bash
TARGET_URL="http://172.16.10.12"
ROBOTS_FILE="robots.txt"
while read -r line; do
path=$(echo "${line}" | awk -F'Disallow: ' '{print $2}')
if [[ -n "${path}" ]] then
url="${TARGET_URL}/${path}"
status_code=$(curl -s -o /dev/null -w "%{http_code}" "${url}")
echo "URL: ${url} returned a status code of: ${status_code}"
fi
done < <(curl -s "${TARGET_URL}/${ROBOTS_FILE}")
Инструмент dirsearch
Поиск скрытых путей и файлов на web сервере. Отдельная база.
dirsearch -u http://172.16.10.10:8081/
--max-rate=REQUESTS Ограничение числа запросов.
Охрененный инструмент.
Получение git репозитория (GitJacking)
Можно при возможности качнуть git проекта.
gitjacker http://172.16.10.11/backup/acme-impact-alliance/ -o acme-impact-alliance-git
Потом git log и другие инструменты поиска например файлов авторизации.
Сканер уязвимостей Nuclei
Отправляет DNS, HTTP, сокеты. Общая база с возможностью расширения. Можно использовать для поиска данных авторизации в локальных файлах.
Основан на YAML шаблонах. Структура шаблона:
| ID | Уникальный идентификатор шаблона |
| Metadata | Описание шаблона (автор, ... |
| Protocol | Протокол |
| Operators | Паттерны и получаемые данные |
Простой шаблон:
id: detect-apache-welcome-page
info:
name: Apache2 Ubuntu Default Page
author: Dolev Farhi and Nick Aleks
severity: info
tags: apache
http:
- method: GET
path:
- '{{BaseURL}}'
matchers:
- type: word
words:
- "Apache2 Ubuntu Default Page: It works"
part: body