ModSecurity: Instalasi Ubuntu 22.04

From OnnoWiki
Jump to navigation Jump to search

Sumber: https://www.howtoforge.com/how-to-install-apache-with-modsecurity-on-ubuntu-22-04/

Mod security adalah Web Application Firewall (WAF) gratis yang bekerja dengan Apache, Nginx dan IIS. Mendukung aturan yang fleksibel untuk melakukan operasi sederhana dan kompleks dan dilengkapi dengan Core Rule Set (CRS) yang memiliki aturan untuk injeksi SQL, cross site scripting scripting, Trojans, user agen yang jahat, session hijacking dan banyak eksploit lainnya. Untuk Apache, ini adalah modul tambahan yang membuatnya mudah untuk menginstal dan mengkonfigurasi.

Core Rules Set (CRS) dari OWASP bisa di ambil dari

Dalam rangka untuk menyelesaikan tutorial ini, Anda akan perlu LAMP diinstal pada server anda.

Kebutuhan

  • Instalasi Ubuntu LTS server, atau yang terbaru di mesin anda.
  • Instalasi Apache2 webserver, di setup dan di konfigurasi:
sudo add-apt-repository ppa:ondrej/php -y
sudo add-apt-repository ppa:ondrej/apache2 -y
sudo apt update
sudo apt -y install gnupg2 software-properties-common curl wget git unzip
sudo apt -y install apache2 php php-xmlrpc php-mysql php-gd php-cli \
php-curl php-mysql php-mbstring php-xdebug libapache2-mod-php

Install mariadb kadang masalah di dependency jadi agak2 susah,

sudo apt -y install mariadb-server mariadb-client

Instalasi mod_security

Instalasi ModSecurity

sudo su
sudo apt -y install libapache2-mod-security2 modsecurity-crs

Periksa apakah modul mod_security dimuat.

apachectl -M | grep --color security

Akan keluar

security2_module (shared)

Anda akan melihat modul bernama security2_module (shared) yang menunjukkan bahwa modul dimuat.

Instalasi ModSecurity meliputi file konfigurasi yang disarankan yang harus diganti:

mv /etc/modsecurity/modsecurity.conf{-recommended,}

Reload Apache

a2enmod security2
systemctl restart apache2
systemctl status apache2

Konfigurasi mod_security

Secara default, ModSecurity tidak melakukan apa-apa karena kebutuhan aturan untuk bekerja. File konfigurasi default diset ke DetectionOnly yang mencatat permintaan sesuai dengan aturan yang cocok dan tidak memblokir apa-apa.

Agar modsecurity bereaksi saat terjadi serangan, kita dapat ubah dengan mengedit file modsecurity.conf:

vi /etc/modsecurity/modsecurity.conf

Temukan kalimat ini

SecRuleEngine DetectionOnly

Ubah menjadi

SecRuleEngine On
SecAuditLogParts ABCEFHJKZ

Jika Anda mencoba ini pada server produksi, ubah direktif ini hanya setelah menguji semua aturan Anda.

Direktif lain yang perlu dimodifikasi adalah SecResponseBodyAccess. Ini mengkonfigurasi apakah tubuh respon dibuffered (yaitu dibaca oleh ModSecurity). Ini hanya diperlukan jika deteksi kebocoran data dan perlindungan diperlukan. Oleh karena itu, membiarkannya On akan menggunakan sumber daya droplet dan juga meningkatkan ukuran logfile.

Temukan

SecResponseBodyAccess On

Ubah menjadi

SecResponseBodyAccess Off

Sekarang kita akan membatasi data maksimum yang dapat diposting ke aplikasi web Anda. Dua parameter yang mengkonfigurasi ini:

SecRequestBodyLimit
SecRequestBodyNoFilesLimit

Parameter SecRequestBodyLimit menentukan ukuran data POST maksimal. Jika ada yang lebih besar dikirim oleh client maka server akan merespon dengan error 413 Request Entity Too Large. Jika aplikasi web Anda tidak memiliki file upload nilai ini dapat sangat dikurangi.

Nilai yang disebutkan dalam file konfigurasi

SecRequestBodyLimit 13107200

yaitu 12.5MB.

Sama dengan cara di atas adalah parameter SecRequestBodyNoFilesLimit . Perbedaan terutama pada besarnya data yang di POST dikurangi file uploads -- nilai ini sebaiknya "sekecil-kecilnya yang memungkinkan".

Nilai yang disebutkan dalam file konfigurasi

SecRequestBodyNoFilesLimit 131072

yaitu 128KB.

Diantara parameter-parameter diatas, parameter yang mungkin akan sangat mempengaruhi performance adalah SecRequestBodyInMemoryLimit. Parameter ini menentukan berapa banyak "request body" data (POST data) yang akan di simpan di RAM, selebihnya akan di simpan di harddisk (seperti swap). Jika kita menggunakan SSD, maka hal ini bukan sebuah masalah besar. Kita dapat menset lebih besar jika kita mempunyai RAM lebih,

SecRequestBodyInMemoryLimit 131072

Nilai ini 128KB seperti yang di set di file konfigurasi.

Install OWASP Core Rule Set

Download dan Install

cd /usr/local/src
wget https://github.com/coreruleset/coreruleset/archive/v3.3.5.tar.gz
tar xvf v3.3.5.tar.gz
mkdir /etc/apache2/modsecurity-crs/
mv coreruleset-3.3.5/ /etc/apache2/modsecurity-crs
cd /etc/apache2/modsecurity-crs/coreruleset-3.3.5/
mv crs-setup.conf.example crs-setup.conf

Edit,

vi /etc/apache2/mods-enabled/security2.conf

Tambahkan / Uncomment,

IncludeOptional /etc/modsecurity/*.conf
IncludeOptional /etc/apache2/modsecurity-crs/coreruleset-3.3.5/crs-setup.conf
IncludeOptional /etc/apache2/modsecurity-crs/coreruleset-3.3.5/rules/*.conf

Cek,

apache2ctl -t
systemctl restart apache2
systemctl status apache2

Verifikasi modsecurity

Lakukan ini di server yang kita install modsecurity.

Ketik,

curl http://localhost/index.html?exec=/bin/bash

Harusnya keluar,

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>

Forbidden

You don't have permission to access this resource.


<address>Apache/2.4.52 (Ubuntu) Server at localhost Port 80</address>
</body></html>


Ketik,

curl localhost?doc=/bin/ls

Harusnya keluar,

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>

Forbidden

You don't have permission to access this resource.


<address>Apache/2.4.52 (Ubuntu) Server at localhost Port 80</address>
</body></html>

Cek log

tail /var/log/apache2/modsec_audit.log

Keluar kira-kira,

SecRule "TX:INBOUND_ANOMALY_SCORE" "@ge %{tx.inbound_anomaly_score_threshold}" 
"phase:5,id:980130,pass,t:none,log,noauditlog,msg:'Inbound Anomaly Score Exceeded (Total 
Inbound Score: %{TX.INBOUND_ANOMALY_SCORE} - SQLI=%{tx.sql_injection_score},XSS=% 
{tx.xss_score},RFI=%{tx.rfi_score},LFI=%{tx.lfi_score},RCE=%{tx.rce_score},PHPI= % {tx.php_injection_score},HTTP=%{tx.http_violation_score},SESS=%{tx.session_fixation_score}):  individual paranoia level scores: %{TX.ANOMALY_SCORE_PL1}, %{TX.ANOMALY_SCORE_PL2}, % {TX.ANOMALY_SCORE_PL3}, %{TX.ANOMALY_SCORE_PL4}',tag:event-correlation,ver:OWASP_CRS/3.3.0"

SecAction 
"phase:5,id:980145,pass,t:none,nolog,noauditlog,ver:OWASP_CRS/3.3.0,setvar:tx.executing_ano maly_score=%{tx.outbound_anomaly_score_pl1},setvar:tx.executing_anomaly_score=+ %{tx.outbound_anomaly_score_pl2},setvar:tx.executing_anomaly_score=+ % {tx.outbound_anomaly_score_pl3},setvar:tx.executing_anomaly_score=+ %{tx.outbound_anomaly_score_pl4}"

SecRule "TX:OUTBOUND_ANOMALY_SCORE" "@lt %{tx.outbound_anomaly_score_threshold}" 
"phase:5,id:980150,pass,t:none,log,noauditlog,msg:'Outbound Anomaly Score (Total Outbound 
Score: %{TX.OUTBOUND_ANOMALY_SCORE}): individual paranoia level scores: % {TX.OUTBOUND_ANOMALY_SCORE_PL1}, %{TX.OUTBOUND_ANOMALY_SCORE_PL2}, % {TX.OUTBOUND_ANOMALY_SCORE_PL3}, %{TX.OUTBOUND_ANOMALY_SCORE_PL4}',tag:event- correlation,ver:OWASP_CRS/3.3.0,chain" 
  1. SecRule "TX:MONITOR_ANOMALY_SCORE" "@gt 1"


--c2d93508-Z--

Logrotate jika dibutuhkan

Ini dibutuhkan di web yang sibuk. Lakukan,

nano /etc/logrotate.d/modsec

Isi dengan,

/var/log/apache2/modsec_audit.log
{
        rotate 31
        daily
        missingok
        compress
        delaycompress
        notifempty
}



Testing SQL Injection

Sebelum melanjutkan dengan konfigurasi aturan, kita akan membuat script PHP yang rentan terhadap injeksi SQL dan mencobanya. Harap dicatat bahwa ini hanyalah sebuah script PHP untuk login tanpa penanganan sesi. Pastikan untuk mengganti password MySQL di script di bawah ini sehingga akan terhubung ke database:

/var/www/html/login.php

Jika password root MySQL adalah 123456, maka isinya

<!DOCTYPE html>
<html>
<body>

<?php
if (isset($_POST['login'])) {
    $username = $_POST['username'];
    $password = $_POST['password'];
    $con = mysqli_connect('localhost', 'root', '123456', 'sample');

    if (!$con) {
        die('Error connecting to the database');
    }

    $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");

    if (mysqli_num_rows($result) == 0) {
        echo 'Invalid username or password';
    } else {
        echo 'Logged in - A Secret for you....';
    }

    mysqli_close($con);
} else {
?>

    <form action="" method="post">
        Username: <input type="text" name="username"/>
        Password: <input type="password" name="password"/>
        <input type="submit" name="login" value="Login"/>
    </form>

<?php
}
?>

</body>
</html>


Script ini akan menampilkan form login. Dengan memasukan password yang tepat akan menampilkan pesan "A Secret for you."

Kita perlu password dalam database. Buat database MySQL dan table, kemudian masukkan username dan password.

mysql -u root -p123456
create database sample;
connect sample;
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('jesin','pwd');
insert into users values('alice','secret');
quit;

Buka browser, masuk ke

http://ip-address-web-anda/login.php

misalnya

http://192.168.0.100/login.php

dan masukan pasangan kredensial

Username: jesin
Password: pwd

Kita akan melihat message yang mengindikasikan login sukses. Coba lagi, tapi masukan pasangan kredential yang salah -- kita akan melihat message

Invalid username or password 


Langkah selanjutnya, kita dapat mencoba SQL injection untuk mem-bypass login page. Masukan perintah berikut di username:

' or true -- 

Perhatikan ada "spasi" sesudah -- , jika "spasi" tidak di tambahkan sesudah -- maka SQL injection ini tidak akan jalan. Biarkan password kosong. Tekan tombol login.

Simsalabim! script akan memperlihatkan semua message yang harusnya untuk user yang terauthentikasi!

Set Up Rules / Aturan

Untuk membuat hidup kita lebih mudah, akan banyak aturan yang di install bersama dengan mod_security. Hal ini di sebut CRS (Core Rule Set) dan lokasinya di

ls -l /usr/share/modsecurity-crs/
total 44
drwxr-xr-x 2 root root  4096 Mar 31 06:15 activated_rules
drwxr-xr-x 2 root root  4096 Mar 31 06:15 base_rules
drwxr-xr-x 2 root root  4096 Mar 31 06:15 experimental_rules
drwxr-xr-x 2 root root  4096 Mar 31 06:15 lua
-rw-r--r-- 1 root root 13774 Jul 13  2013 modsecurity_crs_10_setup.conf
drwxr-xr-x 2 root root  4096 Mar 31 06:15 optional_rules
drwxr-xr-x 2 root root  4096 Mar 31 06:15 slr_rules
drwxr-xr-x 8 root root  4096 Mar 31 06:15 util

Dokumen tersedia di

ls -l /usr/share/doc/modsecurity-crs/
total 16
-rw-r--r-- 1 root root  623 Jul 12  2013 changelog.Debian.gz
-rw-r--r-- 1 root root 1297 Jul  2  2012 copyright
-rw-r--r-- 1 root root 1138 Mar 16  2012 README.Debian
-rw-r--r-- 1 root root 1485 Jul  2  2013 README.md


Untuk me-load aturan / rules ini, kita perlu memberitahukan Apache untuk melihat directory tersebut. Edit file mod-security.conf

vi /etc/apache2/mods-enabled/security2.conf

Tambahkan aturan berikut di dalam <IfModule security2_module> </IfModule>:

Include "/usr/share/modsecurity-crs/*.conf"
Include "/usr/share/modsecurity-crs/activated_rules/*.conf"

Directory activated_rules sama dengan directory mods-enabled pada Apache. Rules / Aturan yang ada tersedia di directory:

/usr/share/modsecurity-crs/base_rules
/usr/share/modsecurity-crs/optional_rules
/usr/share/modsecurity-crs/experimental_rules

Kita perlu membuat symlinks di dalam directory activated_rules untuk mengaktifkan aturan tersebut.

Contoh, untuk mengaktifkan rules / aturan SQL injection.

cd /usr/share/modsecurity-crs/activated_rules/
ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

Apache harus di reload agar rules beroperasi / berefek.

service apache2 reload

Sekarang buka halaman login yang kita buat sebelumnya dan coba menggunakan SQL injection query pada kolom username. Jika kita sudah mengubah SecRuleEngine menjadi On, kita akan melihat 403 Forbidden error.

Jadi semua tergantung pada opsi DetectionOnly, injection akan berhasil tapi akan tercatat pada file modsec_audit.log .


Menulis Rules mod_security sendiri

Pada bagian ini, kita akan mencoba membuat aturan yang akan memblok request juga ada kata-kata "yang tidak di inginkan" di masukan ke dalam form HTML.

Pertama-tama, kita akan membuat script PHP yang akan mengambil input dari textbox dan akan menampilkannya kembali ke user.

/var/www/html/form.php

isinya

<html>
    <body>
        <?php
            if(isset($_POST['data']))
                echo $_POST['data'];
            else
            {
        ?>
                <form method="post" action="">
                        Enter something here:<textarea name="data"></textarea>
                        <input type="submit"/>
                </form>
        <?php
            }
        ?>
    </body>
</html>

Custom rules dapat di tambahkan ke semua file konfigurasi atau di letakan di directory modsecurity. Kita akan mencoba untuk menempatkan aturan / rules kita di sebuah file baru:

vi /etc/modsecurity/modsecurity_custom_rules.conf

Tambahkan perintah kalimat berikut:

SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"

Save file kemudian reload Apache. Buka lagi

http://websiteanda.com/form.php

atau (contoh)

http://192.168.0.100/form.php


Masuk ke browser dan masukan text yang ada kata-kata: pills, insurance, rolex.

Anda akan akan melihat halman 403 dan catatan di log, atau hanya catatan di log berdasarkan konfigurasi SecRuleEngine. Sintaks untuk SecRule adalah

SecRule VARIABLES OPERATOR [ACTIONS]

Disini kita menggunakan chain action untuk mencocokan variable REQUEST_FILENAME dengan form.php, REQUEST_METHOD dengan POST dan REQUEST_BODY dengan regular expression (@rx) string (pills|insurance|rolex). Variable ?i: melakukan pencocokan yang tidak case sensitive. Jika ke tiga aturan tersebut berhasil cocok dengan baik, ACTION yang dilakukan adalah menolak dan mencatat di log dengan message "Spam detected." Chain action mensimulasi operasi logical AND untuk mencocokan ke tiga rules / aturan.

Excluding Host dan Directory

Kadang kala ada baiknya kita meng-exclude directory tertentu atau domain name jika dia menjalankan aplikasi seperti phpMyAdmin karena modsecurity akan memblok SQL queries. Juga sebaiknya meng-exclude admin backend dari aplikasi CMS seperti WordPress.

Untuk men-disable modsecurity untuk sebuah VirtualHost lakukan / tambahkan sebagai berikut

<IfModule security2_module>
    SecRuleEngine Off
</IfModule>

dalam bagian <VirtualHost>

Untuk directory tertentu:

<Directory "/var/www/wp-admin">
    <IfModule security2_module>
        SecRuleEngine Off
    </IfModule>
</Directory>

Jika kita tidak ingin mem-disable secara penuh modsecurity, gunakan SecRuleRemoveById untuk membuang aturan / rule / rule chain tertentu dengan menentukan ID-nya sebagai berikut

<LocationMatch "/wp-admin/update.php">
    <IfModule security2_module>
        SecRuleRemoveById 981173
    </IfModule>
</LocationMatch>

Referensi