Skip to main content

Отладка

  • Берем напильник и приступаем. В одной руке - терминал
tail -f /var/log/apache2/modsec_audit.log | grep -iE ".*notice.*|*.warning.*|.*error.*|.*critical.*"
  • Другой - начинаем проверять функционал приложения. 
Проблема 1
Message: Rule 7faba9cd8db8 [id "951250"][file "/etc/crs4/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf"][line "365"] - Execution error - PCRE limits exceeded (-47): (null).
  • Здесь каких-то рекомендаций кроме как trial and error нет. Предлагаю сделать следующее (не забываем рестартить Apache после внесения изменений)
nano -w /etc/modsecurity/modsecurity.conf
# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 500000
SecPcreMatchLimitRecursion 250000
Проблема 2
Message: Warning. Match of "within %{tx.allowed_request_content_type}" against "TX:content_type" required. [file "/etc/crs4/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1012"] [id "920420"] [msg "Request content type is not allowed by policy"] [data "|multipart/form-data|"] [severity "CRITICAL"] [ver "OWASP_CRS/4.10.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153"] [tag "PCI/12.1"]
  • Объективно у нас отсутствует Content Type = multipart/form-data. Фиксим
nano -w /etc/crs4/crs-setup.conf
SecAction \
    "id:900220,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    tag:'OWASP_CRS',\
    ver:'OWASP_CRS/4.10.0',\
    setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |text/html|'"
Проблема 3 - фундаментальная
Message: Warning. Found 24 byte(s) in ARGS:name outside range: 32-36,38-126. [file "/etc/crs4/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1611"] [id "920272"] [msg "Invalid character in request (outside of printable chars below ascii 127)"]

e.g.
ARGS:name: \xd0\x9e\xd1\x82\xd0\xbb\xd0\xb0\xd0\xb4\xd0\xba\xd0\xb0
  • Все дело в том, что OWASP CRS отказывается в кириллические кодировки, а у нас именно тот случай. (Я пробовал подсунуть ему и windows-1251 charset, и koi8-r - безрезультатно. Разработчик отделывается общими фразами аля "дефолтный конфиг работает". Не знаю, не проверял, да и зачем нам дефолт ? Что либо с этим сделать не понижая PL практически невозможно, посему пишем байпас.
cd /etc/crs4/rules/

mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

nano -w REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
SecRule ARGS:name "@rx (.*)" \
        "id:001001001,\
        phase:1,\
        pass,\
        nolog,\
        msg:'Charset Check Bypass - Cyrilic encoding is not supported',\
        ctl:ruleRemoveById=920272"
Проблема 4
Message: Warning. Matched phrase "var/log" at ARGS:html. [file "/etc/crs4/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "116"] [id "930120"] [msg "OS File Access Attempt"] [data "Matched Data: var/log found within ARGS:html: ***** tail -f /var/log/apache2/modsec_audit.log
  • Здесь он уже умничает при анализе содержимого страницы :) Выхода три: править сигнатуру, писать байпас либо не использовать ругательных слов в контенте. Первое отработает ровно до первого апдейта, третье, в нашем случае, не вариант. Пишем байпас.
SecRule ARGS:html "@rx (.*)" \
        "id:001001002,\
        phase:1,\
        pass,\
        nolog,\
        msg:'Matched pattern bypass',\
        ctl:ruleRemoveById=930120"
Проблема 5 - отсюда вытекающая
  • По факту мы с вами столкнулись с тем, что у нас огромное количество ложных срабатываний по причине используемой кодировки и по причине весьма специфичного контента. Что же делать ? Глобально - либо понижать PL либо писать байпасы (выбор ваш). Плохо и то, и другое. По этому учитывайте специфику при подборе WAF.
  • Я уже был готов понижать PL и вовсю парсил логи, как пришло озарение :) 99% процентов срабатываний происходит в момент публикации контента из админки. Что это значит ? Ничего более чем то, что мы можем привязаться к HTTP REQUEST_METHOD и сделать глобальный байпас всего.
  • Плюсы-минусы ? Плюсы - избавимся от срабатываний по кодировке и истерии по поводу скриптового контента. Минусы - на сайте есть формы поиска и авторизации, так что в них можно будет долбиться в обход политик.
  • Выбор в целом сводится к тому чтобы либо принять риски, либо писать 100500 правил без гарантии отсутствия ложных срабатываний в будущем. Я эти риски принял. В целом можно прикрутить IPS с сигнатурами на POST метод и спать несколько спокойнее.
  • Мои кривые потуги в парсер если кому будет нужно
echo > /var/log/apache2/modsec_audit.log

cat /var/log/apache2/modsec_audit.log | grep -iE ".*notice.*|*.warning.*|.*error.*|.*critical.*" | perl -ne 'm/.*(ARGS:\w+)/ && print "$1\n"' | sort | uniq >> /var/tmp/args.txt

cat /var/log/apache2/modsec_audit.log | grep -iE ".*notice.*|*.warning.*|.*error.*|.*critical.*" | perl -ne 'm/ARGS:html.*(id "\d+")/ && print "$1\n"' | sort | uniq >> /var/tmp/args_html.txt

cat /var/tmp/args_html.txt | sed 's/id \"/ctl:ruleRemoveById=/g' | sed 's/\"/\,\\/g' >> /var/tmp/html_rules.txt
  • Правило для админки (даем два, ибо автосохранение реализовано через PUT)
SecRule REQUEST_METHOD "@rx (POST|PUT)" \
        "id:001001001,\
        phase:1,\
        pass,\
        nolog,\
        msg:'Admin Panel WAF bypass',\
        ctl:ruleEngine=Off"
  • В принципе в энтерпрайзе можно привязаться к блоку доверенных адресов и выше описанные проблемы уйдут. Например так.
SecRule REMOTE_ADDR "@ipMatchFromFile admin_panel_whitelist.txt" \
        "id:001001001,\
        phase:1,\
        pass,\
        log,\
        msg:'Admin Panel WAF bypass - POST|PUT only',\
        ctl:ruleEngine=Off,\
        chain"

SecRule REQUEST_METHOD "@rx (POST|PUT)"
  • Еще раз проверяем логи на предмет срабатываний и закручиваем порог блокировки
nano -w /etc/crs4/crs-setup.conf
SecAction \
    "id:900110,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    tag:'OWASP_CRS',\
    ver:'OWASP_CRS/4.10.0',\
    setvar:tx.inbound_anomaly_score_threshold=5,\
    setvar:tx.outbound_anomaly_score_threshold=4"
  • Проверяем логи
Action: Intercepted (phase 2)
Apache-Handler: application/x-httpd-php
Stopwatch: 1737805433007092 8481 (- - -)
Stopwatch2: 1737805433007092 8481; combined=5102, p1=911, p2=2835, p3=0, p4=0, p5=1355, sr=75, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.9.7 (http://www.modsecurity.org/); OWASP_CRS/4.10.0.
Server: Apache
Engine-Mode: "ENABLED"
  • Если у вас стоит Fail2Ban, можно глянуть и туда
fail2ban-client status apache-modsecurity
Status for the jail: apache-modsecurity
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     14
|  `- File list:        /var/log/apache2/error.log
`- Actions
   |- Currently banned: 1
   |- Total banned:     6
   `- Banned IP list:   193.41.206.98