Skip to main content

Black hat bash

Из одноименной книги "BLACK HAT BASH Creative Scripting for Hackers and Pentesters by Dolev Farhi and Nick Aleks"

Тестовые контейнеры

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)