SlideShare a Scribd company logo
puerto:22
WORDPRESS
FOR SYSADMINS
Javier Arturo Rodríguez
@codehead
javier.rodriguez@puerto22.com
puerto:22
MYTHS AND
MISCONCEPTIONS
puerto:22
MYTHS AND
MISCONCEPTIONS
• WordPress is:
• Troublesome to install
• Hard to maintain
• Impossible to secure
puerto:22
NOPE
puerto:22
IN FACT,
• WordPress is:
• Troublesome Trivial to install
• Hard Easy to maintain
• Hard to secure Securable
puerto:22
WP-CLI
Image: Petr Kratochvil (PD)
puerto:22
HTTP://WP-CLI.ORG/
puerto:22
DOWNLOAD WP-CLI
$ curl -O https://raw.githubusercontent.com/
wp-cli/builds/gh-pages/phar/wp-cli.phar
puerto:22
VERIFY YOUR
CHECKSUMS!
puerto:22
VERIFY WP-CLI
$ md5sum wp-cli.phar
8c9113f5de2a892837771fdacf6f8c16 wp-cli.phar
puerto:22
---
- name: wordpress - install wp-cli
get_url: url=https://raw.githubusercontent.com/wp-cli/builds/e94cf3fd57116b84c86a2578a0c66757fa77a592/phar/wp-cli.phar
sha256sum=b4dd0b82df6ffd3ccbedcd9d2789dbc9f26fd21c86fc62b6f9f524d1775c9fd3
dest=/usr/local/bin/wp-0180
owner=root
group=root
mode=0755
Known commit
Known version Known hash
puerto:22
INSTALL WP-CLI
$ chmod +x wp-cli.phar
$ sudo mv wp-cli.phar /usr/local/bin/wp
$ wp --info
WP-CLI 0.18.0
puerto:22
$ wp help
puerto:22
INSTALL WITH WP-CLI
puerto:22
INSTALL WITH WP-CLI
$ wp core download [{arguments}]
$ wp core config {arguments}
$ wp core install {arguments}
puerto:22
DOWNLOAD
wp core download
[--path=<path>]
[--locale=<locale>]
[--version=<version>]
[--force]
puerto:22
CREATE WP-CONFIG.PHP
wp core config
--dbname=<dbname>
--dbuser=<dbuser>
[--dbpass=<dbpass>]
[--dbhost=<dbhost>]
[--dbprefix=<dbprefix>]
[--dbcharset=<dbcharset>]
[--dbcollate=<dbcollate>]
[--locale=<locale>]
[--extra-php]
[--skip-salts]
[--skip-check]
puerto:22
CREATE TABLES
wp core install
--url=<url>
--title=<site-title>
--admin_user=<username>
--admin_password=<password>
--admin_email=<email>
puerto:22
https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install
puerto:22
https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install
puerto:22
WPMU DEV
https://www.youtube.com/watch?v=ell0SiTZyX8
https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install
puerto:22
30-SECOND INSTALL
puerto:22
$ time ~/wordpress-install
/home/admin/wordpress.config
Downloading WordPress 4.2 (en_US)...
Using cached file '/home/admin/.wp-cli/cache/core/en_US-4.2.tar.gz'...
Success: WordPress downloaded.
Success: Generated wp-config.php file.
Success: WordPress installed successfully.
!
real 0m2.715s
user 0m0.460s
sys0m0.232s
puerto:22
303-SECOND INSTALL
puerto:22
OTHER WP-CLI
COMMANDS
$ wp plugin install
$ wp theme install
puerto:22
BACKUP
$ wp export
$ wp db export
puerto:22
RESTORE
$ wp db import
$ wp import
puerto:22
MULTISITE
$ wp core multisite-convert
$ wp core multisite-install
puerto:22
LANGUAGE	
$ wp core multisite-convert
$ wp core multisite-install
puerto:22
INTEGRITY CHECK
$ wp core verify-checksums
puerto:22
SECURITY
puerto:22
(FROM A SYSADMIN
PERSPECTIVE)
puerto:22
91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:57 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:59 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:08 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:15 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
POST /wp-login.php HTTP/1.1
puerto:22
A BRUTE-FORCE ATTACK
IS A BRUTE-FORCE ATTACK
IS A BRUTE-FORCE ATTACK
puerto:22
Apr 21 05:40:03 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
Apr 21 05:40:05 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
Apr 21 05:40:07 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
Apr 21 05:40:10 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
Apr 21 05:40:12 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
Apr 21 05:40:13 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
Apr 21 05:40:39 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
Apr 21 05:40:41 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
Apr 21 05:40:44 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
Apr 21 05:40:47 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
Apr 21 05:40:49 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
Apr 21 05:40:51 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
Apr 21 05:40:54 myserver sshd[859]: Failed password for root from 43.255.190.126 port 54151 ssh2
Apr 21 05:47:36 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
Apr 21 05:47:36 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
Apr 21 05:47:39 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
Apr 21 05:47:39 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
Apr 21 05:47:41 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
Apr 21 05:47:41 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
Apr 21 05:47:44 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
Apr 21 05:47:46 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
Apr 21 05:47:48 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
Apr 21 05:47:51 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
Apr 21 05:47:52 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
Apr 21 05:47:53 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
Apr 21 05:47:54 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
Apr 21 05:47:56 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
Apr 21 05:47:57 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
Apr 21 05:48:19 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
Apr 21 05:48:21 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
Apr 21 05:48:22 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
Apr 21 05:48:25 myserver sshd[2026]: Failed password for root from 43.255.190.186 port 52811 ssh2
puerto:22
FAIL2BAN
puerto:22
FAIL2BAN
$ wp plugin install --activate wp-fail2ban
puerto:22
/VAR/LOG/AUTH.LOG
Apr 21 19:09:07 blog wordpress(my.wordpress.install)[9298]: Authentication failure for vubpuhttcp from 110.80.74.204
Apr 21 20:39:45 blog wordpress(my.wordpress.install)[9562]: Authentication failure for vubpglyghg from 110.80.74.204
Apr 21 21:11:31 blog wordpress(my.wordpress.install)[12395]: Authentication failure for mougcersdlcrh from 176.97.116.134
Apr 21 21:11:35 blog wordpress(my.wordpress.install)[8190]: Authentication failure for mougcersdvooi from 176.97.116.134
Apr 21 21:51:34 blog wordpress(my.wordpress.install)[12395]: Authentication failure for zeeidrwz54 from 199.168.141.171
Apr 21 22:05:35 blog wordpress(my.wordpress.install)[9562]: Authentication failure for carteykilolye from 176.97.116.134
Apr 21 22:06:36 blog wordpress(my.wordpress.install)[11573]: Authentication failure for dkbzhydsxlmnvj from 176.97.116.134
Apr 22 02:28:46 blog wordpress(my.wordpress.install)[12028]: Authentication failure for gerberktzksy from 176.97.116.134
Apr 22 02:28:47 blog wordpress(my.wordpress.install)[10641]: Authentication failure for carteykilojht from 176.97.116.134
puerto:22
/ETC/FAIL2BAN/JAIL.LOCAL
# Fail2Ban configuration file
#
# Author: Charles Lecklider
#
!
[INCLUDES]
!
before = common.conf
!
!
[Definition]
_daemon = wordpress
failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$
!
ignoreregex =
puerto:22
/ETC/FAIL2BAN/JAIL.LOCAL
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/auth.log
port = http,https
bantime = 3600
puerto:22
# fail2ban-client status wordpress
Status for the jail: wordpress
|- filter
| |- File list:/var/log/auth.log
| |- Currently failed:0
| `- Total failed: 1016
`- action
|- Currently banned:0
| `- IP list:
`- Total banned: 53
puerto:22
TELNET?
$ telnet wordpress
Trying 173.194.65.104...
Connected to wordpress.
Escape character is '^]'.
Debian GNU/Linux 7
wordpress login:
puerto:22
SSH!
$ ssh wordpress
Host key fingerprint is
e0:84:30:20:97:36:53:f1:69:12:7a:fe:5d:32:8d:30
+--[ RSA 2048]----+
|o.+o+. |
|..=+ + . |
| ..o+ E |
| o = + o |
| . . S o |
| . . + |
| . . |
| |
| |
+-----------------+
!
javier@wordpress password:
puerto:22
http://my.wordpress.com/wp-login.php
puerto:22
ENABLE HTTPS
puerto:22
$ a2enmod ssl
puerto:22
$ wp plugin install --activate wordpress-https
puerto:22
https://my.wordpress.com/wp-login.php
puerto:22
TWO-FACTOR
AUTHENTICATION
puerto:22
$ wp plugin install --activate google-authenticator
puerto:22
$ wp plugin install --activate google-authenticator
puerto:22
EASY. RIGHT?
puerto:22
puerto:22
SECURITY
IS NOT
AN ADD-ON
puerto:22
CODE INJECTION
puerto:22
puerto:22
puerto:22
FILESYSTEM
PERMISSIONS
puerto:22
USER ACCOUNTS
Account type Administrative Web daemon
uid configmgr www-data
Permissions Read/Write Read-only
puerto:22
FILE OWNERSHIP
Directory Owner
htdocs/ configmgr
htdocs/wp-content/uploads/ www-data
puerto:22
$ chown -R configmgr.wheel htdocs/
$ chown -R www-data.www-data 
htdocs/wp-content/uploads
puerto:22
NOEXEC
# Prevent malicious scripts in upload dirs
<Directory …/htdocs/wp-content/uploads>
Options -Indexes -ExecCGI
SetHandler None
RemoveHandler .php .php3 .php4 .phps
php_flag engine off
</Directory>
puerto:22
BUT THIS BREAKS
AUTO-UPDATE!
puerto:22
$ wp core update
$ wp core update-db
$ wp plugin update --all
$ wp theme update --all
puerto:22
/USR/LOCAL/BIN

/WP-UPDATE
#!/bin/sh -
cd /var/www
wp core update
wp core update-db
wp plugin update --all
wp theme update --all
puerto:22
/ETC/CRON.D/WP
0 3 * * * configmgr /usr/local/bin/wp-update
puerto:22
SQL INJECTION
puerto:22
SQL INJECTION
Comic: Rockin’ Randall Munroe, XKCD 327 (CC)
puerto:22
MOD_SECURITY
puerto:22
MOD_SECURITY
# apt-get install libapache2-modsecurity
# a2enmod mod-security
puerto:22
Image: GirlieMac, http://httpcats.herokuapp.com/403
puerto:22
BUT I GET FALSE
POSITIVES!
puerto:22
APACHE2.CONF
# Mod_security tweaks
<IfModule mod_security2.c>
# wp-login.php should allow redirects
<LocationMatch "^/(wp-login.php)">
SecRuleRemoveById 950901
</LocationMatch>
</IfModule>
puerto:22
APACHE2.CONF
# Mod_security tweaks
<IfModule mod_security2.c>
# wp-login.php should allow redirects
<LocationMatch "^/(wp-login.php)">
SecRuleRemoveById 950901
</LocationMatch>
# Images are (mostly) harmless
<FilesMatch ".(gif|jpe?g|png)$">
SecRuleEngine Off
</FilesMatch>
</IfModule>
puerto:22
APACHE2.CONF
# Mod_security tweaks
<IfModule mod_security2.c>
# wp-login.php should allow redirects
<LocationMatch "^/(wp-login.php)">
SecRuleRemoveById 950901
</LocationMatch>
# Images are (mostly) harmless
<FilesMatch ".(gif|jpe?g|png)$">
SecRuleEngine Off
</FilesMatch>
# wp-admin/ is a protected area
<LocationMatch "^/(wp-admin/)">
SecRuleEngine Off
</LocationMatch>
</IfModule>
!
# Enable Basic Auth on /wp-admin/ to discourage attacks
<Location /wp-admin/>
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/wpadmin.passwd
Require valid-user
</Location>
puerto:22
SPAM
Image: Der Hupe (CC)
puerto:22
Image: Der Hupe (CC)
puerto:22
COMMENT SPAM
puerto:22
$ wp plugin install --activate akismet
$ wp plugin install --activate google-captcha
puerto:22
REFERRER SPAM
puerto:22
SETENVIF*
puerto:22
.HTACCESS
SetEnvIfNoCase Via evil-spam-proxy spammer=yes
SetEnvIfNoCase Referer evil-spam-domain.com spammer=yes
SetEnvIfNoCase Referer evil-spam-keyword spammer=yes
SetEnvIfNoCase Via pinappleproxy spammer=yes
SetEnvIfNoCase Referer semalt.com spammer=yes
SetEnvIfNoCase Referer poker spammer=yes
...
Order allow,deny
Allow from all
Deny from env=spammer
https://wordpress.org/support/topic/how-to-block-semaltcom-from-visiting-your-wordpress-website
puerto:22
CREEPY CRAWLERS
Image: David Featherston (CC)
puerto:22
ROBOTS.TXT
puerto:22
ROBOTS.TXT
User-agent: *
Crawl-delay: 30
puerto:22
MOD_QOS
puerto:22
MOD_QOS
# apt-get install libapache2-mod-qos
# a2enmod qos
puerto:22
<IfModule qos_module>
# minimum request rate (bytes/sec at request reading):
QS_SrvRequestRate 120
!
# limits the connections for this virtual host:
QS_SrvMaxConn 100
!
# allows keep-alive support till the server reaches 600 connections:
QS_SrvMaxConnClose 80
!
# allows max 50 connections from a single ip address:
QS_SrvMaxConnPerIP 10
</IfModule>
puerto:22
SEE ALSO
• wplib
• mod_evasive
• Bedrock
puerto:22
SUMMARY
• wp-cli for the win
• WordPress can be managed like any other system
• WordPress security can be managed at the system level
• Automate!
puerto:22
Q&A
puerto:22
THANK YOU!
Javier Arturo Rodríguez
@codehead
http://scribd.com/javierrgz/

More Related Content

PDF
Access Patterns for Robots and Humans in Web Archives
PDF
Logs: O que comem, onde vivem e como se reproduzem.
PDF
SmartData Webinar Slides JSON-LD
PDF
Porque VIM?
KEY
WebSocket - May 2011
PPTX
WebRTC for Managers!
PDF
OSDC 2015: Pere Urbon | Scaling Logstash: A Collection of War Stories
PDF
Bradley Horowitz of Yahoo at FOWA 2007
Access Patterns for Robots and Humans in Web Archives
Logs: O que comem, onde vivem e como se reproduzem.
SmartData Webinar Slides JSON-LD
Porque VIM?
WebSocket - May 2011
WebRTC for Managers!
OSDC 2015: Pere Urbon | Scaling Logstash: A Collection of War Stories
Bradley Horowitz of Yahoo at FOWA 2007

Similar to WordPress for SysAdmins (20)

PDF
Real-time data analysis using ELK
DOCX
1 Web Page Foundations Overview This lab walk.docx
PDF
From Zero to Hero - Centralized Logging with Logstash & Elasticsearch
PDF
From zero to hero - Easy log centralization with Logstash and Elasticsearch
PPTX
HTTP 2.0 - Web Unleashed 2015
PDF
Puppet Camp Berlin 2014 Closing Keynote: Next steps for doing more awesome th...
PPTX
Developers’ mDay 2019. - Nikola Krgović, Twin Star Systems – Big Data for Dev...
PDF
LogStash - Yes, logging can be awesome
PPTX
Pivotal Open Source: Using Fluentd to gain insights into your logs
KEY
The Devil and HTML5
PPTX
Who and What Links to the Internet Archive
PDF
העתיד כבר כאן - שימוש בטכנולוגיות החדשות כבר היום
PPTX
Configurare https mule
PDF
20190516 web security-basic
PPTX
Windows Azure Visual Studio "Monaco"", Because it’s mundane
PDF
Smashing the stats for fun (and profit)
PDF
Introducing OWASP OWTF Workshop BruCon 2012
PDF
Application Performance Troubleshooting 1x1 - Von Schweinen, Schlangen und Pa...
PDF
The Web Becomes Graceful
PPTX
Cloud Device Insecurity
Real-time data analysis using ELK
1 Web Page Foundations Overview This lab walk.docx
From Zero to Hero - Centralized Logging with Logstash & Elasticsearch
From zero to hero - Easy log centralization with Logstash and Elasticsearch
HTTP 2.0 - Web Unleashed 2015
Puppet Camp Berlin 2014 Closing Keynote: Next steps for doing more awesome th...
Developers’ mDay 2019. - Nikola Krgović, Twin Star Systems – Big Data for Dev...
LogStash - Yes, logging can be awesome
Pivotal Open Source: Using Fluentd to gain insights into your logs
The Devil and HTML5
Who and What Links to the Internet Archive
העתיד כבר כאן - שימוש בטכנולוגיות החדשות כבר היום
Configurare https mule
20190516 web security-basic
Windows Azure Visual Studio "Monaco"", Because it’s mundane
Smashing the stats for fun (and profit)
Introducing OWASP OWTF Workshop BruCon 2012
Application Performance Troubleshooting 1x1 - Von Schweinen, Schlangen und Pa...
The Web Becomes Graceful
Cloud Device Insecurity
Ad

More from Javier Arturo Rodríguez (9)

PDF
Introduction to ansible
PDF
Minimizing cognitive load
 in Perl source code parsing (a.k.a. Pretty program...
PDF
WordPress Performance Tuning
PDF
Easy native wrappers with SWIG
PDF
Open Data: a view from the trenches
PDF
Barcelona.pm Curs1211 sess01
PDF
Build an autoversioning filesystem with Apache2
PDF
Periodismo de Datos II: Construyendo y explorando conjuntos de datos con las ...
PDF
DatosEnCrudo.org
Introduction to ansible
Minimizing cognitive load
 in Perl source code parsing (a.k.a. Pretty program...
WordPress Performance Tuning
Easy native wrappers with SWIG
Open Data: a view from the trenches
Barcelona.pm Curs1211 sess01
Build an autoversioning filesystem with Apache2
Periodismo de Datos II: Construyendo y explorando conjuntos de datos con las ...
DatosEnCrudo.org
Ad

Recently uploaded (20)

PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Cloud computing and distributed systems.
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Approach and Philosophy of On baking technology
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Electronic commerce courselecture one. Pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Big Data Technologies - Introduction.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Encapsulation theory and applications.pdf
Network Security Unit 5.pdf for BCA BBA.
Cloud computing and distributed systems.
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Approach and Philosophy of On baking technology
Encapsulation_ Review paper, used for researhc scholars
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Electronic commerce courselecture one. Pdf
Machine learning based COVID-19 study performance prediction
Spectral efficient network and resource selection model in 5G networks
NewMind AI Monthly Chronicles - July 2025
Empathic Computing: Creating Shared Understanding
Big Data Technologies - Introduction.pptx
The AUB Centre for AI in Media Proposal.docx
“AI and Expert System Decision Support & Business Intelligence Systems”
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Unlocking AI with Model Context Protocol (MCP)
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Encapsulation theory and applications.pdf

WordPress for SysAdmins

  • 1. puerto:22 WORDPRESS FOR SYSADMINS Javier Arturo Rodríguez @codehead javier.rodriguez@puerto22.com
  • 3. puerto:22 MYTHS AND MISCONCEPTIONS • WordPress is: • Troublesome to install • Hard to maintain • Impossible to secure
  • 5. puerto:22 IN FACT, • WordPress is: • Troublesome Trivial to install • Hard Easy to maintain • Hard to secure Securable
  • 8. puerto:22 DOWNLOAD WP-CLI $ curl -O https://raw.githubusercontent.com/ wp-cli/builds/gh-pages/phar/wp-cli.phar
  • 10. puerto:22 VERIFY WP-CLI $ md5sum wp-cli.phar 8c9113f5de2a892837771fdacf6f8c16 wp-cli.phar
  • 11. puerto:22 --- - name: wordpress - install wp-cli get_url: url=https://raw.githubusercontent.com/wp-cli/builds/e94cf3fd57116b84c86a2578a0c66757fa77a592/phar/wp-cli.phar sha256sum=b4dd0b82df6ffd3ccbedcd9d2789dbc9f26fd21c86fc62b6f9f524d1775c9fd3 dest=/usr/local/bin/wp-0180 owner=root group=root mode=0755 Known commit Known version Known hash
  • 12. puerto:22 INSTALL WP-CLI $ chmod +x wp-cli.phar $ sudo mv wp-cli.phar /usr/local/bin/wp $ wp --info WP-CLI 0.18.0
  • 15. puerto:22 INSTALL WITH WP-CLI $ wp core download [{arguments}] $ wp core config {arguments} $ wp core install {arguments}
  • 17. puerto:22 CREATE WP-CONFIG.PHP wp core config --dbname=<dbname> --dbuser=<dbuser> [--dbpass=<dbpass>] [--dbhost=<dbhost>] [--dbprefix=<dbprefix>] [--dbcharset=<dbcharset>] [--dbcollate=<dbcollate>] [--locale=<locale>] [--extra-php] [--skip-salts] [--skip-check]
  • 18. puerto:22 CREATE TABLES wp core install --url=<url> --title=<site-title> --admin_user=<username> --admin_password=<password> --admin_email=<email>
  • 23. puerto:22 $ time ~/wordpress-install /home/admin/wordpress.config Downloading WordPress 4.2 (en_US)... Using cached file '/home/admin/.wp-cli/cache/core/en_US-4.2.tar.gz'... Success: WordPress downloaded. Success: Generated wp-config.php file. Success: WordPress installed successfully. ! real 0m2.715s user 0m0.460s sys0m0.232s
  • 25. puerto:22 OTHER WP-CLI COMMANDS $ wp plugin install $ wp theme install
  • 27. puerto:22 RESTORE $ wp db import $ wp import
  • 28. puerto:22 MULTISITE $ wp core multisite-convert $ wp core multisite-install
  • 29. puerto:22 LANGUAGE $ wp core multisite-convert $ wp core multisite-install
  • 30. puerto:22 INTEGRITY CHECK $ wp core verify-checksums
  • 33. puerto:22 91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:57 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:59 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:08 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:15 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" POST /wp-login.php HTTP/1.1
  • 34. puerto:22 A BRUTE-FORCE ATTACK IS A BRUTE-FORCE ATTACK IS A BRUTE-FORCE ATTACK
  • 35. puerto:22 Apr 21 05:40:03 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2 Apr 21 05:40:05 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2 Apr 21 05:40:07 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2 Apr 21 05:40:10 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2 Apr 21 05:40:12 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2 Apr 21 05:40:13 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2 Apr 21 05:40:39 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2 Apr 21 05:40:41 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2 Apr 21 05:40:44 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2 Apr 21 05:40:47 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2 Apr 21 05:40:49 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2 Apr 21 05:40:51 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2 Apr 21 05:40:54 myserver sshd[859]: Failed password for root from 43.255.190.126 port 54151 ssh2 Apr 21 05:47:36 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2 Apr 21 05:47:36 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2 Apr 21 05:47:39 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2 Apr 21 05:47:39 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2 Apr 21 05:47:41 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2 Apr 21 05:47:41 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2 Apr 21 05:47:44 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2 Apr 21 05:47:46 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2 Apr 21 05:47:48 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2 Apr 21 05:47:51 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2 Apr 21 05:47:52 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2 Apr 21 05:47:53 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2 Apr 21 05:47:54 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2 Apr 21 05:47:56 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2 Apr 21 05:47:57 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2 Apr 21 05:48:19 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2 Apr 21 05:48:21 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2 Apr 21 05:48:22 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2 Apr 21 05:48:25 myserver sshd[2026]: Failed password for root from 43.255.190.186 port 52811 ssh2
  • 37. puerto:22 FAIL2BAN $ wp plugin install --activate wp-fail2ban
  • 38. puerto:22 /VAR/LOG/AUTH.LOG Apr 21 19:09:07 blog wordpress(my.wordpress.install)[9298]: Authentication failure for vubpuhttcp from 110.80.74.204 Apr 21 20:39:45 blog wordpress(my.wordpress.install)[9562]: Authentication failure for vubpglyghg from 110.80.74.204 Apr 21 21:11:31 blog wordpress(my.wordpress.install)[12395]: Authentication failure for mougcersdlcrh from 176.97.116.134 Apr 21 21:11:35 blog wordpress(my.wordpress.install)[8190]: Authentication failure for mougcersdvooi from 176.97.116.134 Apr 21 21:51:34 blog wordpress(my.wordpress.install)[12395]: Authentication failure for zeeidrwz54 from 199.168.141.171 Apr 21 22:05:35 blog wordpress(my.wordpress.install)[9562]: Authentication failure for carteykilolye from 176.97.116.134 Apr 21 22:06:36 blog wordpress(my.wordpress.install)[11573]: Authentication failure for dkbzhydsxlmnvj from 176.97.116.134 Apr 22 02:28:46 blog wordpress(my.wordpress.install)[12028]: Authentication failure for gerberktzksy from 176.97.116.134 Apr 22 02:28:47 blog wordpress(my.wordpress.install)[10641]: Authentication failure for carteykilojht from 176.97.116.134
  • 39. puerto:22 /ETC/FAIL2BAN/JAIL.LOCAL # Fail2Ban configuration file # # Author: Charles Lecklider # ! [INCLUDES] ! before = common.conf ! ! [Definition] _daemon = wordpress failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$ ^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$ ^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$ ! ignoreregex =
  • 40. puerto:22 /ETC/FAIL2BAN/JAIL.LOCAL [wordpress] enabled = true filter = wordpress logpath = /var/log/auth.log port = http,https bantime = 3600
  • 41. puerto:22 # fail2ban-client status wordpress Status for the jail: wordpress |- filter | |- File list:/var/log/auth.log | |- Currently failed:0 | `- Total failed: 1016 `- action |- Currently banned:0 | `- IP list: `- Total banned: 53
  • 42. puerto:22 TELNET? $ telnet wordpress Trying 173.194.65.104... Connected to wordpress. Escape character is '^]'. Debian GNU/Linux 7 wordpress login:
  • 43. puerto:22 SSH! $ ssh wordpress Host key fingerprint is e0:84:30:20:97:36:53:f1:69:12:7a:fe:5d:32:8d:30 +--[ RSA 2048]----+ |o.+o+. | |..=+ + . | | ..o+ E | | o = + o | | . . S o | | . . + | | . . | | | | | +-----------------+ ! javier@wordpress password:
  • 47. puerto:22 $ wp plugin install --activate wordpress-https
  • 50. puerto:22 $ wp plugin install --activate google-authenticator
  • 51. puerto:22 $ wp plugin install --activate google-authenticator
  • 59. puerto:22 USER ACCOUNTS Account type Administrative Web daemon uid configmgr www-data Permissions Read/Write Read-only
  • 60. puerto:22 FILE OWNERSHIP Directory Owner htdocs/ configmgr htdocs/wp-content/uploads/ www-data
  • 61. puerto:22 $ chown -R configmgr.wheel htdocs/ $ chown -R www-data.www-data htdocs/wp-content/uploads
  • 62. puerto:22 NOEXEC # Prevent malicious scripts in upload dirs <Directory …/htdocs/wp-content/uploads> Options -Indexes -ExecCGI SetHandler None RemoveHandler .php .php3 .php4 .phps php_flag engine off </Directory>
  • 64. puerto:22 $ wp core update $ wp core update-db $ wp plugin update --all $ wp theme update --all
  • 65. puerto:22 /USR/LOCAL/BIN
 /WP-UPDATE #!/bin/sh - cd /var/www wp core update wp core update-db wp plugin update --all wp theme update --all
  • 66. puerto:22 /ETC/CRON.D/WP 0 3 * * * configmgr /usr/local/bin/wp-update
  • 68. puerto:22 SQL INJECTION Comic: Rockin’ Randall Munroe, XKCD 327 (CC)
  • 70. puerto:22 MOD_SECURITY # apt-get install libapache2-modsecurity # a2enmod mod-security
  • 72. puerto:22 BUT I GET FALSE POSITIVES!
  • 73. puerto:22 APACHE2.CONF # Mod_security tweaks <IfModule mod_security2.c> # wp-login.php should allow redirects <LocationMatch "^/(wp-login.php)"> SecRuleRemoveById 950901 </LocationMatch> </IfModule>
  • 74. puerto:22 APACHE2.CONF # Mod_security tweaks <IfModule mod_security2.c> # wp-login.php should allow redirects <LocationMatch "^/(wp-login.php)"> SecRuleRemoveById 950901 </LocationMatch> # Images are (mostly) harmless <FilesMatch ".(gif|jpe?g|png)$"> SecRuleEngine Off </FilesMatch> </IfModule>
  • 75. puerto:22 APACHE2.CONF # Mod_security tweaks <IfModule mod_security2.c> # wp-login.php should allow redirects <LocationMatch "^/(wp-login.php)"> SecRuleRemoveById 950901 </LocationMatch> # Images are (mostly) harmless <FilesMatch ".(gif|jpe?g|png)$"> SecRuleEngine Off </FilesMatch> # wp-admin/ is a protected area <LocationMatch "^/(wp-admin/)"> SecRuleEngine Off </LocationMatch> </IfModule> ! # Enable Basic Auth on /wp-admin/ to discourage attacks <Location /wp-admin/> AuthType Basic AuthName "Restricted Area" AuthUserFile /etc/wpadmin.passwd Require valid-user </Location>
  • 79. puerto:22 $ wp plugin install --activate akismet $ wp plugin install --activate google-captcha
  • 82. puerto:22 .HTACCESS SetEnvIfNoCase Via evil-spam-proxy spammer=yes SetEnvIfNoCase Referer evil-spam-domain.com spammer=yes SetEnvIfNoCase Referer evil-spam-keyword spammer=yes SetEnvIfNoCase Via pinappleproxy spammer=yes SetEnvIfNoCase Referer semalt.com spammer=yes SetEnvIfNoCase Referer poker spammer=yes ... Order allow,deny Allow from all Deny from env=spammer https://wordpress.org/support/topic/how-to-block-semaltcom-from-visiting-your-wordpress-website
  • 87. puerto:22 MOD_QOS # apt-get install libapache2-mod-qos # a2enmod qos
  • 88. puerto:22 <IfModule qos_module> # minimum request rate (bytes/sec at request reading): QS_SrvRequestRate 120 ! # limits the connections for this virtual host: QS_SrvMaxConn 100 ! # allows keep-alive support till the server reaches 600 connections: QS_SrvMaxConnClose 80 ! # allows max 50 connections from a single ip address: QS_SrvMaxConnPerIP 10 </IfModule>
  • 89. puerto:22 SEE ALSO • wplib • mod_evasive • Bedrock
  • 90. puerto:22 SUMMARY • wp-cli for the win • WordPress can be managed like any other system • WordPress security can be managed at the system level • Automate!
  • 92. puerto:22 THANK YOU! Javier Arturo Rodríguez @codehead http://scribd.com/javierrgz/