Difference between revisions of "ModSecurity: Instalasi Ubuntu 22.04"
Onnowpurbo (talk | contribs) |
Onnowpurbo (talk | contribs) |
||
Line 138: | Line 138: | ||
apache2ctl -t | apache2ctl -t | ||
systemctl restart apache2 | systemctl restart apache2 | ||
+ | systemctl status apache2 | ||
==Verifikasi modsecurity== | ==Verifikasi modsecurity== |
Revision as of 05:18, 23 January 2024
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
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"
- 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
<html> <body> <?php if(isset($_POST['login'])) { $username = $_POST['username']; $password = $_POST['password']; $con = mysqli_connect('localhost','root','123456','sample'); $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....'; } 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>