29 Aug 2016, 00:00

Detect the CMS with CMSmap

There are plenty of tools available that you can use to find vulnerability flaws on a website. One tool I use is CMSmap (https://github.com/Dionach/CMSmap) that is written in Python.

Let’s install CMSmap

Installing CMSmap is an easy job. On my clean Debian 8.5 machine it was done in a second. There is one tool that you will need, and that is git.

apt install git

After installing git you can create a local clone of the repo.

# git clone https://github.com/Dionach/CMSmap.git
Cloning into 'CMSmap'...
remote: Counting objects: 34, done.
remote: Total 34 (delta 0), reused 0 (delta 0), pack-reused 34
Unpacking objects: 100% (34/34), done.
Checking connectivity... done.

Be sure you update CMSmap before you use it.

# python cmsmap.py --update A
[-] Date & Time: 29/08/2016 23:52:36
[-] Updating CMSmap to the latest version from GitHub repository... 
Already up-to-date.
[-] CMSmap is now updated to the latest version!
[-] Downloading wordpress plugins from svn website
[-] 62039 plugins found
[-] Wordpress Plugin File: /opt/tools/CMSmap/data/wp_plugins.txt
[-] Downloading WordPress plugins from ExploitDB website
[-] File: /opt/tools/CMSmap/data/wp_plugins_small.txt
[-] Downloading WordPress themes from ExploitDB website
[-] File: /opt/tools/CMSmap/data/wp_themes_small.txt
[-] Downloading Joomla components from ExploitDB website
[-] File: /opt/tools/CMSmap/data/joo_plugins_small.txt
[-] Downloading drupal modules from drupal.org
[-] Drupal Plugin File: /opt/tools/CMSmap/data/dru_plugins_small.txt

Your first CMSmap scan

CMSmap takes it time to run and find some useful information. Sometimes it runs for 5 minutes or longer. You can speed this up (or low it down!) when needed and specify the maximum of threads (--theads) the program can use.

Run the scan with this command:

python cmsmap.py -t https://xpired.nl

See the results:

[-] Date & Time: 30/08/2016 00:02:21
[-] Target: https://xpired.nl
[I] Server: Caddy
[L] X-Frame-Options: Not Enforced
[I] X-Content-Security-Policy: Not Enforced
[L] Robots.txt Found: https://xpired.nl/robots.txt
[I] CMS Detection: Wordpress
[I] Wordpress Theme: twentysixteen
[-] Enumerating Wordpress Usernames via "Feed" ...
[-] Enumerating Wordpress Usernames via "Author" ...
[M] Sebastian Broekhoven
[I] Forgotten Password Allows Username Enumeration: https://xpired.nl/wp-login.php?action=lostpassword
[M] Website vulnerable to XML-RPC Brute Force Vulnerability
[I] Autocomplete Off Not Found: https://xpired.nl/wp-login.php
[-] Default WordPress Files:
[I] https://xpired.nl/license.txt
[I] https://xpired.nl/wp-includes/images/crystal/license.txt
[I] https://xpired.nl/wp-includes/images/crystal/license.txt
[I] https://xpired.nl/wp-includes/js/plupload/license.txt
[I] https://xpired.nl/wp-includes/js/tinymce/license.txt
[I] https://xpired.nl/wp-includes/js/swfupload/license.txt
[I] https://xpired.nl/wp-includes/ID3/license.txt
[I] https://xpired.nl/wp-includes/ID3/readme.txt
[I] https://xpired.nl/wp-includes/ID3/license.commercial.txt
[-] Searching Wordpress Plugins ...
[-] Searching Wordpress TimThumbs ...
[I] Checking for Directory Listing Enabled ...
[-] Date & Time: 30/08/2016 00:05:25
[-] Completed in: 0:03:03

When you are sure that the website is running Wordpress for example, and you want to do a full scan, the command to use is:

python cmsmap.py -f W -F -t https://xpired.nl

Some thoughts

Tools like CMSmap are great for automatic testing. But when you are testing websites that are secured with plugins like Wordfence, there is big chance that you will not find where you are looking for. You cannot always trust on automated scans. If you do an automated scan on your website, and it thinks the state of your website is OK, think again and do some manual auditing. You always have to double-check your results.

Note: https://xpired.nl is my test website

24 Aug 2016, 00:00

Play with Nmap

Nmap is most used as a portscanner. If you want to know if your firewall correctly setup, Nmap is THE tool to use. Unfortunately, Nmap is also used by hackers and script kiddies. I think, most of the time, it are the script kiddies who use it to do some harm. IDS’s and firewalls are getting better at detecting portscans with for example Nmap. Hackers want to stay more under the radar to avoid detection.

More than a portscanner

There is a scripting engine in Nmap, called the Nmap Scripting Engine (NSE), that you can use with Nmap to do some more than a portscan. NSE scripts are programmed in Lua and there are a bunch delivered with the installation of Nmap. You can find NSE documentation over here: https://nmap.org/nsedoc/.

Installing Nmap

Nmap has installable packages in much Linux distributions. So, installing it with a package can be easy as:

# Debian / Ubuntu
apt install nmap
# Redhat / CentOS
yum install nmap
# Fedora
dnf install nmap

Script catecories

The NSE scripts delivered with Nmap are divided in a few categories so you can find and run them seperatly. These are the main categories:

  • auth
  • broadcast
  • brute
  • default
  • discovery
  • dos
  • exploit
  • external
  • fuzzer
  • intrusive
  • malware
  • safe
  • version
  • vuln

You can find them all here: https://nmap.org/book/nse-usage.html#nse-categories

Running the scripts

Running the script is easy. The default scripts are from itself very powerful. But if you want to go further and look for vulnerabilitys, you can use the vuln category like this.

nmap --script vuln yourdomain.nl

Running all the NSE scripts in de vuln category can take a while.

Another nice category is the discover category.

nmap --script discover yourdomain.nl

To run the default scripts:

nmap -sC yourdomain.nl

When you get the message “check disables” you can add an argument to run unsage scripts.

nmap --script-args=unsafe=1 --script vuln yourdomain.nl

Updates for the scripts

Nmap can be installed and updated with your package manager, but the development of some scripts are going a bit faster than your package manager knows.

nmap --script-updatedb

Starting Nmap 6.47 ( http://nmap.org ) at 2016-08-25 00:18 CEST
NSE: Updating rule database.
NSE: Script Database updated successfully.
Nmap done: 0 IP addresses (0 hosts up) scanned in 0.34 seconds

Take a look at the scripts and go play with them. There are some awesome scripts packed with Nmap. Most of the time, you can find them here: /usr/share/nmap/scripts.

It’s a multitool!

As you can see, Nmap can be a real multitool. With some effort you can cat much information of your server with it.

17 Aug 2016, 00:00

PTR Records

When using the internet, we all use DNS records to resolve the name of websites so our computer and/or browser knows that when we go to https://binaryfigments.com the browser has to go to the webserver with the IP address of the IPv6 address 2a01:448:1003::130.

The other way around

There is also a way to get a name behind an IP address. This is also a DNS record named a PTR record. PTR stand for Pointer Record, also known as reverse DNS record. If you do reversed lookup for a IP address, you will get the name behind it. There records are commonly used by mail systems to check if the sending mail server is who he is that he say he is.

For example, if we do a look up to the name of SMTP server of my domain provider we get the following results:

$ dig A filter01.networking4all.net +short

Or for IPv6:

$ dig AAAA filter01.networking4all.net +short

With the host command:

$ host filter01.networking4all.net
filter01.networking4all.net has address
filter01.networking4all.net has IPv6 address 2a01:448:1:1002::8

These are normal lookup’s checking what IP address is behind what full qualified domain name. If we want to do a reversed lookup to these addresses, we can also use the dig or host command.

With dig:

$ dig -x +short
$ dig -x 2a01:448:1:1002::8 +short

With host:

$ host domain name pointer filter01.networking4all.net.
host 2a01:448:1:1002::8 domain name pointer filter01.networking4all.net.

Notation of a PTR record

As you can see in the results of the last host commands, PTR records have a bit of a strange notation. These PTR records are the IP address, but in a reversed notation in the zone in-addr.arpa, for IPv4 and for IPv6 the zone ip6.arpa. (.in-addr.arpa)

Who is maintaining these records?

The PTR records are in the DNS servers of the network maintainer. If I want to get a PTR record on the IP address that I have from my provider and add the name binaryfigments.com to it, I will have to ask them to set it for me. Even better it is if you can set it up on your own in a portal. The provider will set this PTR record in their name server. If you have a IP subnet, you can possible use your own nameservers.

To get the zone you are in you can run the command:

$ dig

; <<>> DiG 9.8.3-P1 <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21458
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;	IN	A

93.249.213.in-addr.arpa. 1799	IN	SOA	ns1.networking4all.com. hostmaster.yourdomainprovider.net. 2016081703 14400 3600 1209600 7200

;; Query time: 48 msec
;; WHEN: Wed Aug 17 14:47:08 2016
;; MSG SIZE  rcvd: 136

And for IPv6:

$ dig

; <<>> DiG 9.8.3-P1 <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 806
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

; IN A

;; AUTHORITY SECTION: 1799	IN	SOA	ns1.networking4all.com. hostmaster.networking4all.com. 2016081706 3600 3600 1209600 7200

;; Query time: 131 msec
;; WHEN: Wed Aug 17 14:42:22 2016
;; MSG SIZE  rcvd: 159

At the authority section you see the SOA of the zone of the IP address. The name server in the SOA is the authoritive name server for the zone of your IP address.

Zone for my IPv4: 93.249.213.in-addr.arpa.

Zone for my IPv6:

The primary name server for this zone is ns1.networking4all.com, and there you have to add the right PTR record.

How and where is this set?

The RIPE is the organization that manages the IP subnets in the region I am in. My provider, Networking4all, need to add an DOMAIN object in de database off the RIPE with the right name servers in it.

You can search it here: https://apps.db.ripe.net/search/query.html?searchtext=93.249.213.in-addr.arpa#resultsAnchor

This is the DOMAIN object that you will find: https://apps.db.ripe.net/search/lookup.html?source=ripe&key=93.249.213.in-addr.arpa&type=domain

You can see, PTR records have a slightly different approach for looking up. It is important to set a right PTR record for your IP address on your server if you user services like e-mail and DNS.

21 Apr 2016, 00:00

Generate Random Passwords

Who needs random password generators when you can do it on the command-line on you Mac or Linux computer? Even Windows!

You simply start a terminal, type the command, choose how many characters and go!

The easy way is with OpenSSL:

openssl rand -base64 12

If you don’t have OpenSSL, you can also use this command:

date | md5

This creates a md5 hash of the date. Because md5 does not use special characters, the password is less advanced.

16 Apr 2016, 00:00

Cleaning Up PowerDNS Records

PowerDNS is a nice and advanced domain name server. PowerDNS is written in C++. One of the upsides of PowerDNS is that is can work with multiple back-ends like Bind, MySQL and PostgreSQL. A PowerDNS server can in MASTER / SLAVE mode and in NATIVE mode. I personal like the NATIVE mode because your can use database replication for your other nameservers. So if you have PowerDNS running and a working back-end, it just serve your zones.


While working with PowerDNS and a MySQL back-end, I thing the flexibility can also be a huge downside for people who do not fill in the records and zones with great care. Your nameserver is the back-bone of your domain! If make a mistake, your domain can get unresolvable and that is not what you want. A better way is NOT writing directly in the MySQL back-end and do some input control.

Search the records

While running MySQL as a back-end for PowerDNS, your can easily run queries to find the faulty records. Most of the time people cut and paste the values from an other system, copying to many characters of spaces and even TABS! There is also a difference between systems. For one system you have to use the @ as a placeholder for the domain and end CNAMES and MX records with a dot (.). A few queries I run to cleanup my records are down here.

SELECT id, name, type, content FROM records WHERE name LIKE '.%';
SELECT id, name, type, content FROM records WHERE name LIKE '%..%';
SELECT id, name, type, content FROM records WHERE name LIKE '% %';
SELECT id, name, type, content FROM records WHERE name LIKE '%@.%';
// This one is nice to, find tabs!
SELECT id, name, type, content FROM records WHERE name LIKE '\t%';

When you get some results, you know that to cleanup. If you dare to, you can create a query for that to do dat for you. Like replace the @. in some records. Please make backups before doing this! And test your results.

update records set name = replace(name,'@.','');

After this query , your records like @.domainname.com will be domainname.com. You can also do that wit a double dot.

update records set name = replace(name,'..','.');

To check the concistancy of all your zones, you can run a command like this:

# vanaf PowerDNS 3.x:
pdnssec check-all-zones
# vanaf PowerDNS 4.x:
pdnsutil check-all-zones

This commang gave me much work… But, we are creating a new better and improved system to manage your zones!

06 Feb 2016, 00:00

Limit requests on Caddy with fail2ban

I’m using Caddy for a few weeks at the moment. I like the sense and simplicity of this web server. The only thing is that my website scanner complains about infinite HTTP requests. It is able to send many requests. The Caddy web server doesn’t crash, that is a good thing, but a downside can be that it is eating up de CPU and RAM resources.

The simple solution

It would be nice if Caddy has a solution for that. Looking at the project in Github, they are thinking about it. For now, I choose for the easy way with Fail2Ban. Fail2Ban is a tool that can scan log files, find patterns and take actions on the findings in the patterns.


The first thing we do is create a filter file for this. The file name in my example is /etc/fail2ban/filter.d/caddy-req-limit.conf but you can name it what you want.

So, Start the text editor:

vim /etc/fail2ban/filter.d/caddy-req-limit.conf

And add this content to the file:

failregex = ^<HOST> -.*"(GET|POST).*
ignoreregex =

Then we edit the /etc/fail2ban/jail.local file.

vim /etc/fail2ban/jail.local

Add the following lines to the bottom:

# Caddy request limit

enabled = true
filter = caddy-req-limit
action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]
logpath = /opt/CaddyServer/logs/binaryfigments.log
findtime = 300
bantime = 7200
maxretry = 300

Be aware that you change the logpath value the the correct file on your system. You can also adjust the values of findtime, bantime and maxretry to whatever fits your needs.

After this is done, you have to restart fail2ban.

systemctl restart fail2ban

You can see is the fail2ban jail / filter is running:

fail2ban-client status caddy-req-limit

Status for the jail: caddy-req-limit
|- filter
|  |- File list:	/opt/CaddyServer/logs/binaryfigments.log
|  |- Currently failed:	0
|  `- Total failed:	669
`- action
   |- Currently banned:	2
   |  `- IP list:
   `- Total banned:	2

In the output above, fail2ban has already found some heavy requesters.

Note on logging with Caddy

Logging in Caddy can be enabled with editing the Caddyfile. Add the following options to the website that you want.

log logs/binaryfigments.log {
    rotate {
        size 100 # Rotate after 100 MB
        age  14  # Keep log files for 14 days
        keep 10  # Keep at most 10 log files

This is from the example on the website of Caddy.