Install OWASP ModSecurity with Apache on Ubuntu 24.04

Install OWASP ModSecurity dengan Apache di Ubuntu 24.04

  • Update repository ubuntu
apt update && apt upgrade -y

  • Install Apache
apt install apache2 -y

  • Install ModSecurity
apt install libapache2-mod-security2 -y
a2enmod security2
systemctl restart apache2 
  • Cek versi modsecurity
apt-cache show libapache2-mod-security2
---<output>---
Package: libapache2-mod-security2
Architecture: amd64
Version: 2.9.7-1build3
Priority: optional
Section: universe/httpd
Source: modsecurity-apache
Origin: Ubuntu
  • Aktifkan ModSecurity, edit file /etc/modsecurity/modsecurity.conf
  • Ubah bari berikut: SecRuleEngine DetectionOnly menjadi SecRuleEngine On
cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
nano /etc/modsecurity/modsecurity.conf
# -- Rule engine initialization ----------------------------------------------

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine On


# -- Request body handling ---------------------------------------------------

# Allow ModSecurity to access request bodies. If you don't, ModSecurity
# won't be able to see any POST parameters, which opens a large security
# hole for attackers to exploit.
#
SecRequestBodyAccess On
  • Restart service apache2
systemctl restart apache2

  • Aktifkan OWASP v4.3.0 rule set
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.3.0.zip
apt install unzip -y && unzip v4.3.0.zip
mv coreruleset-4.3.0/crs-setup.conf.example /etc/modsecurity/crs-setup.conf
mv coreruleset-4.3.0/rules/ /etc/modsecurity/

mv /etc/modsecurity/rules/REQUEST-922-MULTIPART-ATTACK.conf /etc/modsecurity/rules/REQUEST-922-MULTIPART-ATTACK.conf.error
mv /etc/modsecurity/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /etc/modsecurity/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
mv /etc/modsecurity/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example /etc/modsecurity/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
  • Edit file /etc/apache2/mods-enabled/security2.conf
  • Pastikan beris berikut sudah di tambahkan: IncludeOptional /etc/modsecurity/*.conf dan Include /etc/modsecurity/rules/*.conf dan pastikan #IncludeOptional /usr/share/modsecurity-crs/*.load
nano /etc/apache2/mods-enabled/security2.conf
  • Hasil edit seperti berikut:
<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier

        IncludeOptional /etc/modsecurity/*.conf
        Include /etc/modsecurity/rules/*.conf

        # Include OWASP ModSecurity CRS rules if installed
#        IncludeOptional /usr/share/modsecurity-crs/*.load
</IfModule>
  • Verifikkasi konfigurasi apache2, pastikan OK dan tidak ada error
apache2ctl -t
---<output>---
Syntax OK
  • Restart service apache2
systemctl restart apache2

  • Pengujian
  • http://ip_address_server/foo?username=1’%20or%20’1’%20=%20′
  • http://ip_address_server/?id=1 and ‘c’=’c’
  • Cek log modsec_audit.log
tail -100 /var/log/apache2/modsec_audit.log
--9159024f-A--
[08/Jun/2024:03:56:57.421409 +0000] ZmPWiaWWzopSAvjA9sSSvgAAAAg 116.206.14.15 12422 192.168.10.100 80
--9159024f-B--
GET /?id=1%20and%20%E2%80%98c%E2%80%99=%E2%80%99c%E2%80%99 HTTP/1.1
Host: lamp.sys-ops.id.sideka.my.id
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,id;q=0.8,fr;q=0.7

--9159024f-F--
HTTP/1.1 403 Forbidden
Content-Length: 199
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

--9159024f-E--
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>

--9159024f-H--
Message: Warning. detected SQLi using libinjection with fingerprint '1&sos' [file "/etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "66"] [id "942100"] [msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: 1&sos found within ARGS:id: 1 and 'c'='c'"] [severity "CRITICAL"] [ver "OWASP_CRS/4.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-sqli"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/66"] [tag "PCI/6.5.2"]
Message: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:blocking_inbound_anomaly_score. [file "/etc/modsecurity/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "233"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [ver "OWASP_CRS/4.3.0"] [tag "anomaly-evaluation"] [tag "OWASP_CRS"]
Message: Warning. Unconditional match in SecAction. [file "/etc/modsecurity/rules/RESPONSE-980-CORRELATION.conf"] [line "98"] [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=5, detection=5, per_pl=5-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=5, XSS=0, RFI=0, LFI=0, RCE=0, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=5)"] [ver "OWASP_CRS/4.3.0"] [tag "reporting"] [tag "OWASP_CRS"]
Apache-Error: [file "apache2_util.c"] [line 275] [level 3] [client 116.206.14.15] ModSecurity: Warning. detected SQLi using libinjection with fingerprint '1&sos' [file "/etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "66"] [id "942100"] [msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: 1&sos found within ARGS:id: 1 and 'c'='c'"] [severity "CRITICAL"] [ver "OWASP_CRS/4.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-sqli"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/66"] [tag "PCI/6.5.2"] [hostname "lamp.sys-ops.id.sideka.my.id"] [uri "/"] [unique_id "ZmPWiaWWzopSAvjA9sSSvgAAAAg"]
Apache-Error: [file "apache2_util.c"] [line 275] [level 3] [client 116.206.14.15] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:blocking_inbound_anomaly_score. [file "/etc/modsecurity/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "233"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [ver "OWASP_CRS/4.3.0"] [tag "anomaly-evaluation"] [tag "OWASP_CRS"] [hostname "lamp.sys-ops.id.sideka.my.id"] [uri "/"] [unique_id "ZmPWiaWWzopSAvjA9sSSvgAAAAg"]
Apache-Error: [file "apache2_util.c"] [line 275] [level 3] [client 116.206.14.15] ModSecurity: Warning. Unconditional match in SecAction. [file "/etc/modsecurity/rules/RESPONSE-980-CORRELATION.conf"] [line "98"] [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=5, detection=5, per_pl=5-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=5, XSS=0, RFI=0, LFI=0, RCE=0, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=5)"] [ver "OWASP_CRS/4.3.0"] [tag "reporting"] [tag "OWASP_CRS"] [hostname "lamp.sys-ops.id.sideka.my.id"] [uri "/"] [unique_id "ZmPWiaWWzopSAvjA9sSSvgAAAAg"]
Action: Intercepted (phase 2)
Stopwatch: 1717819017419063 2384 (- - -)
Stopwatch2: 1717819017419063 2384; combined=1760, p1=581, p2=1038, p3=0, p4=0, p5=141, sr=0, sw=0, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.9.7 (http://www.modsecurity.org/); OWASP_CRS/4.3.0.
Server: Apache
Engine-Mode: "ENABLED"

--9159024f-Z--

  • Enable mod security di virtualhost
  • Tambahkan baris berikut dibawah </Directory>
  • On = Enable , Off = Disable
     <IfModule security2_module>
        SecRuleEngine On
        IncludeOptional /etc/modsecurity/crs/*.conf
     </IfModule>
ServerTokens Prod
ServerSignature Off
<VirtualHost *:80>
     ServerAdmin [email protected]
     ServerName lamp.sys-ops.id.sideka.my.id
     ServerAlias www.lamp.sys-ops.id.sideka.my.id
     DocumentRoot /var/www/lamp.sys-ops.id.sideka.my.id

     <Directory /var/www/lamp.sys-ops.id.sideka.my.id>
        Options -Indexes +FollowSymLinks
        Require all granted
        DirectoryIndex index.php index.html
        AllowOverride All
        Order allow,deny
        Allow from all
        Header unset X-Powered-By

        Header set Access-Control-Allow-Headers "ORIGIN, X-REQUESTED-WITH, CONTENT-TYPE"
        Header set Access-Control-Allow-Origin "*"
        Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
        Header set X-XSS-Protection 1;mode=block
        Header set X-Frame-Options SAMEORIGIN
        Header set X-Content-Type-Options nosniff
        Header set Strict-Transport-Security "max-age=15552000; includeSubDomains;preload"
        Header set Referrer-Policy strict-origin-when-cross-origin
        Header set Access-Control-Max-Age 60000
        Header set Permissions-Policy "microphone=(), geolocation=(self), fullscreen=()"
        Header set Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' http: https:; img-src 'self' data: https:; font-src 'self' data: https:; frame-src 'self' data: https: blob:"
     </Directory>

     <IfModule security2_module>
        SecRuleEngine On
        IncludeOptional /etc/modsecurity/crs/*.conf
     </IfModule>

     <DirectoryMatch "^/.*/\..*/(?!\.well-known/).*$">
        Require all denied
     </DirectoryMatch>

     <FilesMatch "\.(ini|log|conf|txt|bak|old)$">
        Require all denied
     </FilesMatch>

     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

herdiana3389

A system administrator with skills in system administration, virtualization, linux, windows, networking, cloud computing, container, etc.