HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > БЕЗОПАСНОСТЬ И УЯЗВИМОСТИ > Уязвимости > Веб-уязвимости
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 29.03.2025, 00:00
apache2
Познающий
Регистрация: 23.04.2021
Сообщений: 64
С нами: 2663594

Репутация: 0
По умолчанию

Введение
В процессе работы в Red Team часто приходится проводить разведку облачных сервисов. Для этого я решил написать инструмент AWScanner, который автоматически собирает и анализирует диапазоны IP Amazon Web Services с помощью Masscan и TLS-сканирования. В этой статье я разберу ход своих мыслей при создании сканера, объясню каждую функцию, чтобы даже новичок понял, как это работает, чтобы он смог создавать в будущем свои инструменты по ИБ.
Советую ознакомиться ещё с мой статьёй в которой разбирается сканирование облачных сервисов Статья - Жёстко сканируем и хакаем облачные сервисы Amazon

Определение целей
Когда я задумался о написании сканера, у меня были следующие требования:
  1. Скорость - облака масштабируемы, IP-диапазоны огромны, поэтому необходимо использовать быстрые инструменты.
  2. Автоматизация - минимальное количество ручных действий.
  3. Информативность - важно не только найти открытые порты, но и извлечь полезную информацию, например, домены сертификатов.
Структура скрипта
Я сделал AWScanner в виде командной строки с интерактивным интерфейсом. Пользователь может вводить команды, такие как
Код:
list_regions
для просмотра доступных регионов,
Код:
scan
для запуска сканирования.
Это сделало инструмент простым в использовании, особенно для тех, кто только начинает заниматься пентестингом.

Реализация функций
Теперь давайте разберём каждую функцию, чтобы понять, как она работает и почему я её добавил.

Цветной вывод и удобство использования
Сначала добавил поддержку цветного вывода, чтобы пользователю было проще ориентироваться:

Python:


Код:
class
Colors
:
RED
=
'\033[91m'
GREEN
=
'\033[92m'
RESET
=
'\033[0m'
UNDERLINE
=
'\033[4m'
Это простой класс для цветного вывода в терминале. Например, зелёный цвет (GREEN) используется для успешных сообщений, а красный (RED) - для ошибок. Это делает интерфейс более читаемым.

Список регионов
Отфильтровал в огромнос json файле при помощи команд для обработки строк, таких как jq, awkи прочее.

Python:


Код:
AVAILABLE_REGIONS
=
[
"af-south-1"
,
"ap-east-1"
,
"ap-east-2"
,
.
.
.
,
"us-west-2"
]
Функция print_available_regions

Python:


Код:
def
print_available_regions
(
)
:
print
(
"Available regions:"
)
for
region
in
AVAILABLE_REGIONS
:
print
(
f"{Colors.GREEN}-{Colors.RESET}{region}"
)
Эта функция просто выводит список регионов с зелёным тире перед каждым, чтобы было красиво.
Это помогает пользователю увидеть, какие регионы доступны.

Функция run_command

Python:


Код:
def
run_command
(
command
)
:
try
:
subprocess
.
run
(
command
,
shell
=
True
,
check
=
True
,
stderr
=
subprocess
.
DEVNULL
)
except
subprocess
.
CalledProcessError
as
e
:
print
(
f"{Colors.RED}[ERROR]{Colors.RESET}Command failed:{command}"
)
sys
.
exit
(
1
)
Эта функция выполняет команды в оболочке и обрабатывает ошибки. Если команда не сработает, она выведет красное сообщение и завершит скрипт.

Код:
check=True
-если команда завершится с кодом возврата != 0 (ошибка), Python вызовет исключение CalledProcessError.

Код:
stderr=subprocess.DEVNUL
- перенаправляет стандартный поток ошибок (stderr) в /dev/null (ошибки не выводятся).

Функция is_file_empty

Python:


Код:
def
is_file_empty
(
file_path
)
:
return
not
os
.
path
.
exists
(
file_path
)
or
os
.
path
.
getsize
(
file_path
)
==
0
Эта функция проверяет, существует ли файл и пустой ли он. Например, если после сканирования файл с открытыми IP пуст, мы не будем пытаться его обрабатывать.

Код:
os.path.exists(file_path)
- Возвращает False, если файл не существует

Код:
os.path.getsize(file_path) == 0
- Если файл существует, проверяет его размер.

Функция scan_region

Python:


Код:
def
scan_region
(
region
,
rate
)
:
ip_ranges_command
=
(
f"wget -qO- https://ip-ranges.amazonaws.com/ip-ranges.json | "
f"jq '.prefixes[] | select(.region == \"{region}\") | .ip_prefix' -r | "
f"sort -u >{region}-range.txt"
)
run_command
(
ip_ranges_command
)
Загружаем IP-диапазоны для региона с помощью wget и jq, сохраняем в файл.

wget загружает JSON-файл с публичными IP-диапазонами AWS.
  • jq фильтрует данные;
  • prefixes[] - перебирает массив CIDR-блоков;
  • select(.region == "region") - выбирает блоки, привязанные к указанному региону (например, eu-central-1);
  • ip_prefix - извлекает значение поля (например, 52.93.244.0/24);
  • -r - выводит результат в raw-формате (без кавычек).
  • sort -u удаляет дубликаты и сохраняет уникальные значения в файл {region}-range.txt;

Python:


Код:
print
(
f"{Colors.GREEN}[+]{Colors.RESET}IP ranges for{region}saved to{region}-range.txt"
)
masscan_command
=
f"masscan -iL{region}-range.txt -oL{region}-range.masscan -p 443 --rate{rate}"
run_command
(
masscan_command
)
print
(
f"{Colors.GREEN}[+]{Colors.RESET}Masscan results saved to{region}-range.masscan"
)
Запускаем masscan для сканирования этих IP на порт 443 с заданной скоростью и выводим, что результат сохранён в файл
  • -iL - указывает файл со списком целей (CIDR-блоков из {region}-range.txt);
  • -oL - сохраняет результаты в файл {region}-range.masscan;
  • -p 443 - сканирует только порт 443;
  • --rate - задает скорость сканирования (пакетов/секунду).

Python:


Код:
tls_open_command
=
f"awk '/open/ {{print $4}}'{region}-range.masscan >{region}-range.tlsopen"
run_command
(
tls_open_command
)
print
(
f"{Colors.GREEN}[+]{Colors.RESET}Open TLS IPs saved to{region}-range.tlsopen"
)
Извлекаем IP с открытым портом 443 с помощью awk.
  • awk парсит файл {region} - range.masscan;
  • /open/ - ищет строки с состоянием open;
  • print $4 - извлекает 4-е поле (IP-адрес);
  • Результат сохраняется в {region}-range.tlsopen.

Python:


Код:
if
not
is_file_empty
(
f"{region}-range.tlsopen"
)
:
tls_scan_command
=
f"cat{region}-range.tlsopen | tls-scan --port=443 -o{region}-range-tlsinfo.json"
run_command
(
tls_scan_command
)
convert_to_csv
(
region
)
else
:
print
(
f"{Colors.RED}[WARNING]{Colors.RESET}TLS open IPs file is empty, skipping CSV conversion."
)
Тут собираем данные о сертификатах (например, Common Name) для найденных IP.
  • tls-scan подключается к каждому IP из {region}-range.tlsopen на порту 443;
  • Извлекает информацию о TLS-сертификате (версия, алгоритмы, Common Name и др.);
  • Сохраняет результат в JSON-файл {region}-range-tlsinfo.json.
и дальше происходит конвертация в csv табличку

Функция convert_to_csv

Python:


Код:
def
convert_to_csv
(
region
)
:
"""Convert TLS info JSON to CSV format for different JSON structures."""
json_file
=
f"{region}-range-tlsinfo.json"
csv_file
=
f"{region}-range-tlsinfo.csv"
if
is_file_empty
(
json_file
)
:
print
(
f"{Colors.RED}[WARNING]{Colors.RESET}TLS info file{json_file}is empty or missing, skipping CSV conversion."
)
return
# Attempt to convert JSON to CSV using various jq commands
csv_commands
=
[
f"jq -r '.[] | {{ip, commonName: .cert.subject.commonName}} | [.ip, .commonName] | @csv'{json_file}>{csv_file}"
,
f"jq -r '.[] | {{ip, commonName: .cert.subject.commonName}} | [.ip, .commonName] | @csv'{json_file}>{csv_file}"
,
f"jq -r '[.ip, .cert.subject.commonName] | @csv'{json_file}>{csv_file}"
,
f"jq -r '[.ip, .commonName] | @csv'{json_file}>{csv_file}"
]
for
command
in
csv_commands
:
try
:
run_command
(
command
)
print
(
f"{Colors.GREEN}[+]{Colors.RESET}TLS info converted to CSV and saved to{csv_file}"
)
return
except
:
continue
# Try the next command if the current one fails
print
(
f"{Colors.RED}[ERROR]{Colors.RESET}Failed to convert{json_file}to CSV."
)
Эта функция преобразует JSON в CSV, но я добавил несколько вариантов команд jq, потому что структура JSON может отличаться на разных регионах. Например, иногда поле называется
Код:
.cert.subject.commonName
, а иногда просто
Код:
.commonName
. Поэтому я сделал массив csv_commands, я его сделал, потому что одной командой не получилось спарсить и перевести все запросы в табличку (да, я тестировал на большинстве регионах, чтобы отследить ошибки в моей программе).

Основная функция main

Python:


Код:
def
main
(
)
:
if
os
.
geteuid
(
)
!=
0
:
print
(
f"{Colors.RED}[ERROR]{Colors.RESET}You must run this script as the root user."
)
sys
.
exit
(
1
)
while
True
:
print
(
f"{Colors.UNDERLINE}awscan{Colors.RESET}> "
,
end
=
''
)
user_input
=
input
(
)
if
user_input
==
"help"
:
print_help
(
)
elif
user_input
==
"list_regions"
:
print_available_regions
(
)
elif
user_input
.
startswith
(
"scan"
)
:
_
,
region
,
rate
=
user_input
.
split
(
)
if
region
not
in
AVAILABLE_REGIONS
:
print
(
f"{Colors.RED}[ERROR]{Colors.RESET}You must specify a correct region."
)
continue
scan_region
(
region
,
int
(
rate
)
)
elif
user_input
==
"exit"
:
print
(
"See you later!"
)
exit
(
0
)
Это главная функция, которая запускает интерактивный цикл. Сначала проверяет, запущен ли скрипт от root, затем ждёт ввода команд. Если пользователь введёт scan eu-central-1 10000, скрипт вызовет scan_region с этими параметрами.

Python:


Код:
_
,
region
,
rate
=
user_input
.
split
(
)
Разбивает строку по пробелам и присваивает значения переменным:
_ - игнорирует первый элемент ("scan"), так как он не нужен.
region - сохраняет название региона (например, us-west-1).
rate - сохраняет скорость сканирования (например, 10000).

Функция print_help

Python:


Код:
def
print_help
(
)
:
"""Display help information for commands."""
print
(
f"""Description: AWS IP range scanner with Masscan and TLS analysis made by q1ncite
Core commands
=============

       Command                     Description
    -------------                 -------------
    list_regions                    Show available regions for scanning.
    scan              Start scan of region (e.g.,{Colors.RED}scan eu-central-1 10000{Colors.RESET}).
"""
)
Эта функция выводит помощь, показывая доступные команды.
Таблица: Основные функции и их назначение

ФункцияНазначениеprint_available_ regionsВыводит список доступных регионов AWS.run_commandВыполняет команды в оболочке и обрабатывает ошибки.is_file_emptyПроверяет, пустой ли файл или не существует.scan_regionВыполняет сканирование региона: загрузка IP, masscan, анализ TLS.convert_to_csvПреобразует JSON с информацией TLS в CSV, учитывая разные структуры.mainЗапускает интерактивный цикл и обрабатывает команды пользователя.print_helpПоказыв ет помощь с описанием команд.

Заключение
Я надеюсь, что этот подробный разбор поможет вам, особенно если вы только начинаете, понять, как создавать подобные инструменты.
Разработка AWScannerбыла интересным процессом, который помог мне глубже понять Python, т.к я не программист.
Этот скрипт можно улушать! Как? Предлагайте идеи или форкайте проект

Исходники и дополнения:
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.