Security

From wiki.mikejung.biz
Jump to: navigation, search

Liquidweb 728x90.jpg

Finding symlinks

symlinks

touch /root/public_symlinks
find /home/*/public_html/ -type l > /root/public_symlinks
for each in `cat /root/public_symlinks` ; do rm -vf $each ; done

Finding recently updated files with the same name

updatedb
locate akismet.php > /root/akismet.php
for each in `cat /root/akismet.php` ; do find $each -mtime -1 ; done

The process

This is a pretty good outline for what should be done if a site was recently defaced, or hacked. It assumes that you have a few days worth of domlogs.

1) If domlogs are being rotated out daily, and a site keeps getting hacked, turn off domlog deletion!

2) Figure out what files were recently modified in public_html

find ./ -mtime -1

The output may look something like this: ./wp-content/themes/gothamnews2/footer.php ./wp-content/themes/gothamnews2/index.php

3) Stat the files

4) Get the formatting of the dom logs, something like head access.log

5) Grep for the timestamps of the files in the access log:

grep '23/May/2012:15:54:1' domain.com

6) From there you should be able to figure out what happened.

It's a good idea to change the wp-admin password if you suspect that was compromised, to do this:

UPDATE wp_users SET user_pass="password that is in md5 format" WHERE ID = 1;

Suggested server php settings (work in progress)

disable_functions = show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open, allow_url_fopen, allow_url_include, ini_set 
display_errors = Off

log_errors = On

Also, these may work as well:

disable_functions = show_source,system,shell_exec,passthru,exec,proc_open,allow_url_fopen,symlink,exec,proc_close,dl,escap,eshellarg,escapeshellcmd,popen

Find bad things

Find base64 injected code

grep -R 'eval(base64_decode($_POST' /home/username/public_html/* 

Find php files owned by nobody

cd /home/user/public_html
find . -type f -name '*.php' -user nobody 

Find all index.* files then remove bad things

find /home/*/public_html/ -name index.* > /root/list
for each in `cat /root/list` ; do sed -i.lwbak 's/Badthing\/script>//g' $each ; done


Find exploited scripts

grep "=http" /home/$user/access-logs/domain.com | grep "HTTP\/1\.1\" 200"

Robots.txt

Wordpress

User-agent: *
Disallow: /wp-*
Disallow: /*.js$
Disallow: /*.inc$
Disallow: /*.css$
Disallow: /*.php$
Disallow: /cgi-bin
Disallow: images/
Disallow: _private/
Disallow: _vti_bin/
Disallow: _vti_cnf/
Disallow: _vti_log/
Disallow: _vti-pvt/
Disallow: _vti-txt/

User-agent: Googlebot-Image
Disallow: /

User-agent: ia_archiver
Disallow: /

User-agent: duggmirror
Disallow: /

.htaccess directives

stop symlink from getting access to config files lol

Current best fix to stop symlink from getting access to config files

cd /home/

vim .htaccess

<FilesMatch "(wp-config|config|configuration|conf|settings).php">
    order allow,deny
    deny from all
</FilesMatch>

Protect a File .htaccess

Protect a file from zero cool

# protect phpinfo
<Files php-info.php>
	Order Deny,Allow
	Deny from all
	Allow from 123.456.789
</Files>

Disable Shells and Text links

Disable Shells, txt links, etc

# Block access to .php and .pl files in an images or other dir
<FilesMatch "\.(p(hp|hp3|hp4|hp5|l|html|hp.jpg))$">
  Deny from all
</FilesMatch>

<FilesMatch "\.(ht(m|ml))$">
  Deny from all
</FilesMatch>

<FilesMatch "\.txt$">
  Deny from all
</FilesMatch>

<Files *.zip>
Order Deny,Allow
Deny from all
</Files>

Options -indexes

Disable Script Execution an Hide Indexes with .htaccess

Disable Script Execution an Hide Indexes with .htaccess

Options -Indexes
Options -ExecCGI
AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi 

Mod Sec

Modsec rule for blocking symlinks

SecRule REQUEST_URI (/sym/|/root/) "log,deny,msg:'SymLink attempt!',id:555445"


modsec removal / reset

rpm -qa |grep lp- 
rpm -e whatever mod sec version
lpyum -y install lp-modsec2-rules && /etc/init.d/httpd restart 

Generic whitelist format

<LocationMatch "/whatever/uri">
  SecRuleRemoveById someid#
</LocationMatch>

Port Scanners

Nmap

Nmap commands:
Flags:
-s what type of scan
-T TCP connect
-S SYN
-U UDP
-p scan all the things
-PN scan all and pretend they are alive

TCP scan:
nmap -sT -p -PN xxx.xxx.xxx.xxx

SYN scan:
nmap -sS -p -PN xxx.xxx.xxx.xxx

UDP scan:
nmap -sU xxx.xxx.xxx.xxx

Versioning UDP scan:
nmap -sUV xxx.xxx.xxx.xxx

XMAS scan:
nmap -sX -p -PN xxx.xxx.xxx.xxx

NULL scan:
nmap -sN -p -PN xxx.xxx.xxx.xxx

Version Finders

Wordpress

for i in $(cat /usr/local/apache/conf/httpd.conf | grep DocumentRoot | awk '{print $2}'| sort | uniq | sort); 
do if [ `ls -A $i | grep wp-settings.php` ]; then echo $i `grep Vers $i/readme.html | awk '{print $4}'`; fi; done

Joomla

for i in $(cat /usr/local/apache/conf/httpd.conf | grep DocumentRoot | awk '{print $2}'| sort | uniq | sort); 
do if [ `ls -A $i | grep CHANGELOG.php` ]; then echo $i `grep "Stable Release" $i/CHANGELOG.php | head -1 | awk '{print $2}'`; fi; done

SuPHP

Restrict all accounts to the global php.ini file

Edit: /opt/suphp/etc/suphp.conf

From

[phprc_paths]
;Uncommenting these will force all requests to that handler to use the php.ini
;in the specified directory regardless of suPHP_ConfigPath settings.
;application/x-httpd-php=/usr/local/lib/
;application/x-httpd-php4=/usr/local/php4/lib/
;application/x-httpd-php5=/usr/local/lib/

To

[phprc_paths]
;Uncommenting these will force all requests to that handler to use the php.ini
;in the specified directory regardless of suPHP_ConfigPath settings.
application/x-httpd-php=/usr/local/lib/
application/x-httpd-php4=/usr/local/php4/lib/
application/x-httpd-php5=/usr/local/lib/

Putting individual user settings into the global php.ini file

At the bottom of /usr/local/lib/php.ini file, you can actually define individual user php.ini directives with the path to that user's application:

[PATH=/home/username/public_html]
register_globals=On
post_max_size=5000M

Save the file, then restart Apache for good measure. Now, if any account tries to put suPHP_ConfigPath into their .htaccess file, that account will return an Internal Server Error until they remove the .htaccess line. No account will be able to use another php.ini file with this as the default unless you allow the account in the php.ini file itself.

Symlinks

A good method we have found is setting the following in Apache pre_virtualhost_global includes:

<Directory "/home">
Options +All +ExecCGI -FollowSymLinks +Includes +IncludesNOEXEC -Indexes -MultiViews +SymLinksIfOwnerMatch
AllowOverride All Options=ExecCGI,Includes,IncludesNOEXEC,Indexes,MultiViews,SymLinksIfOwnerMatch
</Directory>

This requires all .htaccess files containing "FollowSymLinks" to be changed to "SymLinksIfOwnerMatch" and any future change by clients or installing new applications will result in 500 errors when using "FollowSymLinks" so inform your users that they must use "SymLinksIfOwnerMatch" instead.

wpscan

WPSCAN EXAMPLES

Do 'non-intrusive' checks...

ruby wpscan.rb --url www.example.com

Do wordlist password brute force on enumerated users using 50 threads...

ruby wpscan.rb --url www.example.com --wordlist darkc0de.lst --threads 50

Do wordlist password brute force on the 'admin' username only...

ruby wpscan.rb --url www.example.com --wordlist darkc0de.lst --username admin

Enumerate installed plugins...

ruby wpscan.rb --url www.example.com --enumerate p

Run all enumeration tools...

ruby wpscan.rb --url www.example.com --enumerate

Update WPScan...

ruby wpscan.rb --update

Hashes

If you look at a password hash in /etc/shadow, you'll notice strange characters along with a few $ thrown in. These $ characters delimit different sections of the hash as follows:

$id $salt $encrypted

The id section tells you what hash is being used:

1 = MD5

5 = SHA-256

6 = SHA-512

Apps

http://hashcat.net/oclhashcat-plus/