Sichere Dein Apache mit mod_security

Bis jetzt ist noch nicht viel passiert. Ich werde Dir nun ein paar Filter Rules präsentieren, die Aufschluss darüber geben sollen, was Du alles mod_security anstellen kannst. Gehen wir davon aus, Du hast eine Anwendung, die von SQL Injection Attacken bedroht wird. Ein Attacker könnte versuchen, alle Einträge einer MySQL Tabelle wie folgt zu löschen:http://www.example.com/login.php?user=tom‘;DELETE%20FROM%20users–Dies kannst Du mit diser Regel verhindern:

SecFilter „delete[[:space:]]+from“

Wenn eine Anfrage von Deinem Filter aufgegriffen wird, wird etwas in der Art auf Deinem audit_log geloggt:

========================================
Request: 192.168.0.207 - - [04/Jul/2006:23:43:00 +1200] "GET /login.php?user=tom';DELETE%20FROM%20users-- HTTP/1.1" 500 1215
Handler: (null)
----------------------------------------
GET /login.php?user=tom';DELETE%20FROM%20users-- HTTP/1.1
Host: 192.168.0.100
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
mod_security-message: Access denied with code 500. Pattern match "delete[[:space:]]+from" at THE_REQUEST
mod_security-action: 500

HTTP/1.1 500 Internal Server Error
Last-Modified: Fri, 21 Oct 2005 14:30:18 GMT
ETag: "8238-4bf-833a5280"
Accept-Ranges: bytes
Content-Length: 1215
Connection: close
Content-Type: text/html

und die SecFilterDefaultAction wird angewandt (d.h. die Anfrage wird verweigert, geloggt und der Benutzer erhält einen 500 Error). Wenn eine andere Aktion ausgeführt werden soll, kannst Du das wie folgt für jede Regel definieren:

SecFilter „delete[[:space:]]+from“ log,redirect:http://example.com/invalid_request.html

Dies würde die Anfrage zu einer HTML Seite umleiten, die anzeigen könnte, dass die Anfrage ungültig war.

Um weitere SQL Injection Attacks zu verhindern, können wir noch ein paar andere Regeln hinzufügen:

SecFilter „insert[[:space:]]+into“
SecFilter „select.+from“
SecFilter „drop[[:space:]]table“

Folgende Direktiven tragen dazu bei, Cross-Site Scripting Attacks zu verhindern:

SecFilter „<script“
SecFilter „<.+>“

Diese verhindert Path Traversal Attacks:

SecFilter „../“


Bitte Merke: manchmal stößt Du aufSecFilter „../“anstelle vonSecFilter „../“

Ab mod_security Version 1.8, ist es nicht mehr nötig, Punkte zu escapen. Dies wird von mod_security automatisch vorgenommen, was bedeutet, dass es nicht darauf ankommt, ob Du Punkte escapst oder nicht!


Dies blockt alle Anfragen, die nicht das Zeichen php enthalten:SecFilter !phpDiese Direktive blockt Anfragen, die versuchen, /bin/sh auf Deinem Server auszuführen:SecFilter /bin/sh

Diese blockt alle Anfragen, die die Zeichenfolge viagra enthalten:

SecFilter „viagra“

Du kannst auch reguläre Ausdrücke wie diese verwenden:

SecFilter „(viagra|mortgage|herbal)“

Das Problem mit der SecFilter Direktive besteht darin, dass es die gesamte Anfrage scannt anstelle von bestimmten Bereichen. Wenn der Referrer ihateviagra.mydomain.com ist, würde es von den letzten beiden Direktiven geblockt werden. Wenn Du allerdings den üblichen Spam vermeiden möchtest und Dein HTML Formular per POST abgesendet wird, dann wäre es einfacher nur nach dem Wort viagra zu prüfen. Wir können dies mit der SecFilterSelective Direktive ausführen:

SecFilterSelective „POST_PAYLOAD“ „viagra“

Du kannst auch andere Bereiche der Anfrage überprüfen:

SecFilterSelective „HTTP_REFERER“ „(viagra|mortgage|texasholdem)“

würde alle Anfrage blocken, die entweder viagra, mortgage oder texasholdem im HTTP_REFERER Bereich enthalten.

Diese Regel benötigt HTTP_USER_AGENT und HTTP_HOST Headers in jeder Anfrage:

SecFilterSelective „HTTP_USER_AGENT|HTTP_HOST“ „^$“

Du kannst auch IP Adressen blocken:

SecFilterSelective „REMOTE_ADDR“ „^1.2.3.4$“

Wenn Du ein Eingabefeld in Deinem HTML Formular hast und Du den Wert der URL für das Wort viagra überprüfen möchtest, kannst Du das wie folgt tun:

SecFilterSelective „ARG_url“ „viagra“

Folgende Regel würde den Googlebot zur Google Start Seite umleiten:

SecFilterSelective „HTTP_USER_AGENT“ „Google“ nolog,redirect:http://www.google.com

Eine Liste von allen Bereichen, die Du überprüfen kannst, findest Du in der ModSecurity Dokumentation: http://www.modsecurity.org/documentation/modsecurity-apache/1.9.3/html-multipage/04-rules.html#N103D0

Weiterhin solltest Du Dir dies Seite: http://www.onlamp.com/pub/a/apache/2003/11/26/mod_security.html und diese http://atomicplayboy.net/blog/2005/01/30/an-introduction-to-mod-security/ ansehen, sie beinhalten eine Menge nützlicher Beispiele und genauere Erklärungen.

mod_security ermöglicht Deinem Apache vorzugeben, er sei ein anderer Web Server, z.B. wie folgt:

SecServerSignature „Microsoft-IIS/5.0″

Falls Apache gar keine Signatur anzeigt, verwende dies:

SecServerSignature “ “

mod_security ermöglicht Dir außerdem ausgehenden Inhalt zu filtern. Wenn Du zum Beispiel PHP Skripte verwendest, und es sein kann, dass Deine PHP Skripte in einem fatalen Fehler enden und Du Deinen Benutzern nicht die wirkliche Fehlermelden zeigen möchtest, (da sie einige wichtige Angaben enthalten könnte, die nur Du sehen solltest), kannst Du Folgendes ausführen:

SecFilterScanOutput On
SecFilterSelective OUTPUT „Fatal error:“ deny,status:500
ErrorDocument 500 /php-fatal-error.html

Falls ein fataler Fehler auftauchen sollte, wird der Benutzer zur Datei php-fatal-error.html (die Du vorher natürlich erstellen musst) umgeleitet.

Dies sollte Dir einen Überblick geben, was Du mit mod_security tun kannst. Wenn Du mehr Beispiele und Informationen benötigst, solltest Du Dir auf jeden Fall fogende URLs ansehen:

Es gibt außerdem einen Online Rule Creator für mod_security: http://leavesrustle.com/tools/modsecurity der Dir hilft, Deine eigenen Regeln zu erstellen.

Nun solltest Du in der Lage sein, Deine eigenen Regeln der Basiskonfiguration hinzuzufügen. Wenn Du Dir nicht sicher bist, kannst Du mit diesre Konfiguration starten:

<IfModule mod_security.c>
    # Turn the filtering engine On or Off
    SecFilterEngine On

    # Change Server: string
    SecServerSignature " "

    # Make sure that URL encoding is valid
    SecFilterCheckURLEncoding On

    # This setting should be set to On only if the Web site is
    # using the Unicode encoding. Otherwise it may interfere with
    # the normal Web site operation.
    SecFilterCheckUnicodeEncoding Off

    # Only allow bytes from this range
    SecFilterForceByteRange 1 255

    # The audit engine works independently and
    # can be turned On of Off on the per-server or
    # on the per-directory basis. "On" will log everything,
    # "DynamicOrRelevant" will log dynamic requests or violations,
    # and "RelevantOnly" will only log policy violations
    SecAuditEngine RelevantOnly

    # The name of the audit log file
    SecAuditLog /var/log/apache2/audit_log

    # Should mod_security inspect POST payloads
    SecFilterScanPOST On

    # Action to take by default
    SecFilterDefaultAction "deny,log,status:500"

    # Require HTTP_USER_AGENT and HTTP_HOST in all requests
    SecFilterSelective "HTTP_USER_AGENT|HTTP_HOST" "^$"

    # Prevent path traversal (..) attacks
    SecFilter "../"

    # Weaker XSS protection but allows common HTML tags
    SecFilter "<[[:space:]]*script"

    # Prevent XSS atacks (HTML/Javascript injection)
    SecFilter "<(.|n)+>"

    # Very crude filters to prevent SQL injection attacks
    SecFilter "delete[[:space:]]+from"
    SecFilter "insert[[:space:]]+into"
    SecFilter "select.+from"
    SecFilter "drop[[:space:]]table"

    # Protecting from XSS attacks through the PHP session cookie
    SecFilterSelective ARG_PHPSESSID "!^[0-9a-z]*$"
    SecFilterSelective COOKIE_PHPSESSID "!^[0-9a-z]*$"
</IfModule>

Ein weiterer guter Startpunkt wäre die Konfiguration, die von der mod_security Dokumentation vorgeschlagen wird (http://www.modsecurity.org/documentation/modsecurity-apache/1.9.3/html-multipage/aa-recommended_configuration.html):

<IfModule mod_security.c>
    # Turn ModSecurity On
    SecFilterEngine On

    # Reject requests with status 403
    SecFilterDefaultAction "deny,log,status:403"

    # Some sane defaults
    SecFilterScanPOST On
    SecFilterCheckURLEncoding On
    SecFilterCheckUnicodeEncoding Off

    # Accept almost all byte values
    SecFilterForceByteRange 1 255

    # Server masking is optional
    # SecServerSignature "Microsoft-IIS/5.0"

    SecUploadDir /tmp
    SecUploadKeepFiles Off

    # Only record the interesting stuff
    SecAuditEngine RelevantOnly
    SecAuditLog /var/log/apache2/audit_log

    # You normally won't need debug logging
    SecFilterDebugLevel 0
    SecFilterDebugLog /var/log/apache2/modsec_debug_log

    # Only accept request encodings we know how to handle
    # we exclude GET requests from this because some (automated)
    # clients supply "text/html" as Content-Type
    SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chain
    SecFilterSelective HTTP_Content-Type
    "!(^application/x-www-form-urlencoded$|^multipart/form-data;)"

    # Do not accept GET or HEAD requests with bodies
    SecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" chain
    SecFilterSelective HTTP_Content-Length "!^$"

    # Require Content-Length to be provided with
    # every POST request
    SecFilterSelective REQUEST_METHOD "^POST$" chain
    SecFilterSelective HTTP_Content-Length "^$"

    # Don't accept transfer encodings we know we don't handle
    SecFilterSelective HTTP_Transfer-Encoding "!^$"
</IfModule>

Oder Du verwendest die Konfiguration, die in Fedoras mod_security Paket integriert ist. Pass aber immer auf, dass Du die Pfade an die Log-Dateien anpasst!

3 Links

Das könnte Dich auch interessieren …