Последнее время появилась острая необходимость проверять, что прилетело с очередными обновлениями кода в папку /vendor /venv или любую другую, где лежат исходники внешних зависимостей проекта. (poetry, composer, go install и тд., кто на чем пишет).
Сканеры безопасности решают данный класс задач, но их может не оказаться под рукой или тяжелое решение не подходит. Гугл не дал быстрого готового решения, когда под рукой только консоль.
Часть задач сводится к тому, чтобы найти определенный текст, ключевые слова, хардкод (например ip адрес) или опасный системный вызов. В голову сразу приходит grep. Но мы же хотим не только искать по одному слову и только в одном или группе файлов. Мы хотим проверить весь код по всем возможным словарям, которые определим сами.
Создаем словари
touch words
Обычный текстовый файл, где в каждой строчке будет ключевое слово. Файлов можно создать несколько, для разных логических групп. Мы для простоты оставим один.
Допустим каталог, который мы хотим рекурсивно проверить ./content
Мало кто знает но, grep умеет искать не только по параметру из командной строки, но и умеет использовать набор строк из файла (искать их все).
find ./content -type f | grep -v 'words' | xargs -I % grep -i --with-filename -f words %
Готово! Но как же быть с данными, например IP-адресов, по которым злоумышленник выполняет нужную вредоносную логику. Их в словарь не прописать.
IP-адреса
Все еще проще
find ./content -type f | xargs -I % grep -i --with-filename -E -o "([0-9]{1,3}[.]){3}[0-9]{1,3}" %
Можно ограничить только валидными IPv4
grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" ips.txt
Дальше можно развивать в зависимости от задачи.
Объединим вместе в scan.sh
#!/bin/bash
echo
echo "Words:"
echo
find ./content -type f | grep -v 'words' | xargs -I % grep -i --with-filename -f words %
echo
echo "IPv4:"
echo
find ./content -type f | grep -v 'words' | xargs -I % grep -i --with-filename -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" %
echo
chmod +x scan.sh
./scan.sh
Обновление словарей
Можно добавлять руками, сортировать, удалять дубли тд. Но можно автоматизировать.
update_dict.sh
#!/bin/bash
awk '{print tolower($0)}' words > tmp && mv tmp words
cat words | sort | uniq > tmp && mv tmp words
Можно запускать отдельно. Или добавить в начало скрипта сканирования. Все слова будут уникализироваться, приводиться к нижнему регистру и сортироваться для удобства.
Итого
В несколько строк мы получили простейший скрипт, который будет почти на любой Linux машине искать прямые вхождения по словарю и IP адерса.
Легко развивается по функционалу. Белые списки, черные, дополнительные группы, настройка алертов, или интеграция в процесс обновления пакетов.