The Solfa Cipher (NSEC17 Write-Up)



Between May 19th and 21st, 2017, I’ve participated to the NSEC 17 Capture-the-Flag (CtF) event held annually in Montreal, QC. As usual, the team and I had a blast spending days and nights solving challenges and drinking free beer. Among the challenges was a two-part cryptographic puzzle printed on the first and last pages of the passport of Rao’s Intricate Kingdom – the country part of the story line of the event. The challenge was divided in two parts: a Braille encoded message and the second part was encrypted using the Solfa cipher, which I had never heard of before. As such I decided to learn more about it and complete a write-up for the challenge at the same time. I’ll first quickly cover the Braille part of the challenge, then move on to the Solfa part of it and the decryption process.

The Second Half of the Flag

Upon entrance at the NSEC competition this year, participants received a passport designed to be stamped based on events happening during the CtF. The back of the front cover contains a sequence of dotted symbols which can be recognized quickly as Braille as shown in the figure below:

Braille-encoded message in Rao's Passport
Figure 1: Braille-encoded message in Rao’s Passport at NSEC’17

As most of you probably know, the Braille writing system was developed for the blind and visually impaired individuals to be able to read using touch. Examples of braille can often be found on elevators. The system is based on a matrix of 3×2 dots which can be blank or filled. Each dot is numbered from 1 to 6 as shown below:

Braille Matrix Numbers
Figure 2: A matrix of the 6 dots representing an individual character Braille

Each character of a natural alphabet can then be associated with a specific matrix configuration. For example, a simple Braille-English translation is shown below:

The Braille Alphabet
Figure 3: The Braille Alphabet (linked from

Additional “shortcut” symbols are used for specific sounds, punctuation, symbols and words. The figure below shows some examples of common words in Braille:

Braille for words and abbreviations
Figure 4: Braille for words and abbreviations (from the Tennessee Council of the Blind)

Additional abbreviations can be found in [1]. Going back to the passport, we can obtain the transcription using Unicode:


We then translate into English and obtain the following translation from Braille to English.:

G I S THE  (Cap) P L A T Y P U S
T O O B T A  IN  A  C O M P L E T
E F L A G . (Cap) G L O R Y T O
 (Cap) R A O

Table 1: Resulting message from translating from Braille to English.

Putting everything together, we obtain the first part of the flag included in the passport:

The second half of the flag is the word Platypus. Add x after the first half to obtain a complete flag. Glory to Rao

First Half of the Flag

The second part of the flag is much more obscure and less documented than the first one. The inside of cover page contains a small partition holding a total of 4 staves: the first one appears to be a chord while the last 3 are simply a sequence of notes. We noticed that the first staff contains a treble clef, the label “KEY-997” and is shorter than the other staves. Furthermore it contains the type of notes

Music Sheet in the Rao's Passport
Figure 5: Scanned copy of the lullaby on the last page of Rao’s passport.

Clearly, there is something in there, but how do we extract a flag out of this? My knowledge of music theory is extremely low and was basically non-existent prior to this challenge. As such feel free correct me in the comments if I misrepresent a musical concept or term.

The Cipher

Googling for words relating to music and cryptography will return a limited set of relevant sites, the first relating to musical cryptograms, which is not quite was we are looking for at the moment. The second page is about the Solfa Cipher. Once you’ve found the latter website, you’re almost at the solution, but let’s take a better look at it.

The Solfa cipher is a substitution cipher, but rather than using an alphabet to encode keys and cipher text, it uses musical notation. The encryption/decryption key is defined using a clef, a tonic, a mode and a rhythmic unit. The links will provide a much better definition of each different item than I could ever do in this article. However, be aware that the 4 elements mentioned above can have the following values:

Clefs Tonic Mode Rhythmic Unit
Treble C, C# Minor 1/4 (Quarter)
Alto D♭, D Major 1/8 (Eighth)
Bass E♭, E Phrygian 1/16 (Sixteenth)
F, F# Dorian
G♭, G Lydian
A♭, A Mixolydian
B♭, B Locrian

Table 2: Valid values for the properties of the Solfa key.

Like any symmetric cipher, a key is needed to encrypt the message, which will have to be shared with the intended recipients of the message. In this case, the key is in musical notation rather than a sequence of characters or bytes. The first staff of the page represents the key of the cipher, as the label clearly shows. The encryption key is composed of the four elements mentioned above: a treble clef, in C minor, using 1/8 as the rhythmic unit:

Solfa Cipher Key used in NSEC17
Figure 6: Solfa Cipher Key used in the passport at NSEC ’17: treble key in C minor with a 1/8 rhythm is used.

Each note is linked to a the seven pitches of the solfege, i.e. Do (D), Re (R), Mi (M), Fa (F), Sol (S), La (L) and Si (T). The “KEY-554” is only a randomly generated label and has no significance in the algorithm. With the key known, this puzzle becomes a chain of translations from musical notes to a list of tuple of tones and rhythms using the standard matrix below:

Do (D) Re (R) Mi (M) Fa (F) So (S) La (L) Ti (T)
1:  T I A S E N O  :1
2:  K Z X J Å Æ  :2
3: R C H M D L U  :3
4: F Y G P W B V  :4

Table 3: English language translation matrix usually used for the Solfa cipher.

The columns represents the pitch, while the rows represent the duration of the note (1, 2, 3 or 4).

Let’s go through a complete example to better understand the process. Consider the staff below:

Example of a Solfa-encrypted message
Figure 7: The word “SOLFA” encrypted using the Solfa Cipher

In this case, we assume that we are using a 4/4 meter i.e. the length of a single measure.  That means that each measure has a duration of 4 units. The key used to generate this melody was in C major, with a clef of Treble and a rhythmic unit of 1/4 (Quarter). The first note is Fa and starts at the first time unit, i.e. 1. Therefore the first note can be translated to (F, 1). The Fa is 4 units long, meaning that the second note, Si, also starts at time 1, translating to (T, 1). However this time, the note is only 2 time units long and thus the third note – Sol – starts at 3 and lasts only 1 time unit. Thus the third node is translated to (S, 3) while the fourth one will be translated to (D, 4). Finally, the last note is a Mi and starts at 1 and thus is translated to (M, 1). Putting everything together we have (F, 1), (T, 1), (S, 3), (D, 4) and (M, 1). Using the matrix above, we obtain (F, 1) = “S”, (T, 1) = “O”, (S, 3) = “L”, (D, 4) = “F” and (M, 1) = “A” and thus the plain text is the word “SOLFA”. This process is better represented in the figure below:

Decryption of the Solfa-encrypted word "SOLFA"
Figure 8: Decryption of the word “SOLFA” by reading the notes and their duration.

Going back to the NSEC challenge, we have a much larger melody to decrypt. Luckily, we have the key and the same process as the one we used to decrypt the cipher text in figure 8 applies.

Solfa-encrypted Message from the Passport
Figure 9: Solfa-encrypted Message from the Passport in NSEC ’17

Let’s take the first 9 notes listed in the figure above. For each of the note, we first determine its pitch (do, re, mi, …) and then its duration. The key given specify a 1/8 rhythm, as such a Eighth note will be worth 1 time unit, a Quarter note will be worth 2 time units and the half note will be worth 4 time units. Unless specified otherwise, the meter is 4/4, i.e. a measure is 4 time units long.

First 9 notes of Solfa encrypted for NSEC
Figure 10: The first 9 notes of the Solfa-encrypted message and the initial tempo of the melody.

Using the figure above, we can then extract the notes and their time from the partition:

The note is used as the column and the time as the row to read the corresponding value defined in the translation matrix. We can put a quick script what will read these notes and find the corresponding characters. Using table 3, the notes above will be translated to

d, 1 m, 3 s, 1 d, 4 r, 1 d, 3 m, 4 d, 1 m, 3

Table 4: First 9 characters decrypted from the partition at the back of the passport.

Applying this process to every note in the figure 9, we obtain the following message:


Or with spaces and punctuation added: “The first half of the flag is the word subdermal. Concatenate with the second half to obtain a complete flag. Glory to Rao“. Mixing the 2 halfs of the flag, we get the string “SUBDERMALxPlatypus” and get 5 points out of it.

In case you are wondering what the melody in figure 9 sounds like, you can download the resulting MIDI file here: A Revolutionary Lullaby.


Braille and Solfa are quick and fun ways to encode/encrypt data in unusual ways. While they obviously should not be used for serious application, they could potentially be used as novel ways to exfiltrate data and bypass some filters. For example, a text file could be Base32 encoded and the padding character (“=”) could be replace with the number 1 for example. Then the resulting string could be encrypted using the Solfa cipher, transformed into a MIDI file and then uploaded to a remote location. I highly suspect that most network security appliances would not pick up on MIDI file being uploaded, although it would probably strike a careful analyst as suspicious. Feel free to experiment with it. A partial Python implementation can be found here.


[1] Simpson, C,  The Rules of Unified English Braille, Second Edition, 2013, International Council on English Braille,, Visited on 2017-06-05

[2] Chambers, John, An ABC primer,, Visited on 2017-06-04

[3] Solfa Cipher, 2013,, visited on 2017-06-06

Additional Readings

Schneier, Bruce. Applied cryptography: protocols, algorithms, and source code in C. john wiley & sons, 2007.

Carter, Nicholas. Music Theory: From Absolute Beginner to Expert: The Ultimate Step-by-step Guide to Learning Music Theory Effortlessly. United States: CreateSpace Independent Platform, 2016. Print.

Software Exploit Development – Fuzzing with AFL


It’s quite impressive to look back in the past to the early days of software vulnerabilities and observe the ongoing dance between new  mitigation and new exploitation techniques. Powerful fuzzing tools are now common place and operated on a daily basis by IT corporations and security labs; either to find crashes in their software or others’ program, seeking workable exploit out of it. New research is continuously presented to mitigate new procedures while multiple organizations develop new counter-mitigation tricks. In this post, we’ll overview the entire software exploitation process: from fuzzing with American Fuzzy Lop (AFL) to exploit development with gdb-peda and pwntools. For this purpose, we will develop a quick 64-bit program exhibiting a glaring buffer overflow vulnerability. We will then fuzz it to find that vulnerability, analyze the results and development an exploit for it. A video is also available.

The Vuln1 Vulnerable Program

While we could use a known vulnerable program online, we decide to craft our own quick C program so we can understand all its facets. The program below uses two characters buffers of 32 characters; one to hold the username and the other one to hold a password. To manage user input, we used the well-known insecure gets() function, which fails to check buffer boundaries and leads to buffer overflows.

Once executed, the program first asks for a username and a password. The inputs are stored in the login and passwd variables. Their value are then compared with the expected value using strcmp(). If the credentials entered are “root” and “1qazxsw2”, then a “Access Granted.” message is printed out to the console, otherwise “Access Denied.” is shown to the user and the program exits.

To simplify the exploitation process of this exercise, we will compile this program with absolutely no memory protection, i.e. NX will be disabled and no stack canary. NX is usually enabled to prevent code to be executed directly from the stack, which there is no need for other than exploitation purposes. As for stack canaries, they can detect stack overflows by adding an extra value to the software stack. If this value is not found when the function returns, an exception is thrown to prevent further execution. Nowadays, these protection schemes are enabled in a vast majority of cases, but we adopt simplicity rather than realism for this post. Disabling these protection mechanism can be achieved using the following GCC command:

The  -fno-stack-protector will disable the stack canaries while the  -z execstack makes both the heap and stack executable. To verify that these options have not been included, we can use a nifty tool call checksec which is included with pwntools, which will will present later in this post. By executing  checksec vuln1 we confirm that both the stack canaries and NX bit are disabled:

Checksec reports on 2 additional security mechanisms other than the stack canaries and No-eXecute bit. While these concepts are out of scope for this post, we will simply present them

With our target created, we are now ready to start fuzzing it to uncover the buffer overflow it contains.

Fuzzing with AFL

AFL is a popular open-source and free fuzzer that has been leveraged to discover vulnerabilities in a large set of applications and libraries. Before starting AFL, we need to instrumentalize our target using the afl-gcc compiler. The AFL compiler will add code around the source in order to maximize coverage. To compile the source code with AFL, use the same command used above to compile Vuln1 using afl-gcc rather than gcc or use the associated Makefile

The resulting binary is the one that will be used with AFL, but when analyzing the crash later one, we will do it with the gcc compiled binary. Until then, let’s learn how to use AFL to assess the Vuln1 program.

A critical aspect of fuzzing is to craft meaningful test cases, e.g. inputs that will maximize code coverage by exploring all potential paths of the targeted program. The vuln1 program is simple and only has 3 paths:

  1. Username is invalid;
  2. Username is valid, but password in invalid;
  3. Username and password are valid.

In order to reach these 3 paths, we will design our test cases appropriately by creating 3 files. The first file will have 2 lines, none of them containing the appropriate credentials, the second file will have the right username, but an invalid password and the third file will have both correct credentials. AFL will read the contents of each file and feed each line to the stdin of Vuln1. Create a directory called testcases and in it, create 3 files representing these cases. The name of the files does not matter.

test1.txt test2.txt test3.txt

After creating these 3 files, create another directory called results, which will contains the results of the fuzzing run. At this point you’re ready to start AFL using afl-fuzz, the actual fuzzing program. You can do so with the following command:

Where -t ./testcases specifies the directory containing the testcases, -o ./results specifies the output directory and ./vuln1 is that target program. If you run AFL for the first time, you’ll likely be greeted with the following warning:

Core_pattern file warning when running AFL
AFL Warns that the core_pattern file must be changed.

Just follow the instruction given and you’ll get rid of this message. Simply a shell as root using  sudo bash and type the suggested command, i.e.

Retry to start AFL using the same command and you should have no issue this time. A screen will appear and present you with quite a few statistics. This AFL Readme file explains all of these fields very well, and should definitively be read and well understood. For now, let’s focus on the “Overall Results” section.

Fuzzing Vuln1 with AFL - Results
Results of Fuzzing the Vuln1 Program

Two rows of this section are particularly interesting in this example:

  • Total paths; and
  • Unique crashes.

Notice that after a few seconds, the total paths field is 3, which is what we expected based on the code of vuln1. As such, once we reached 3 paths, we can stop AFL by pressing Ctrl-C, as it will not find anything new. In the real world, we have no idea how many paths may be possible. As such AFL provides color codes to help you assess if it’s time to stop. Another field that can help is the last path found. When no new paths have been found after a while, AFL may have cover most of the code it can find and is unlikely to find anything new. Finally, the most interesting field is the unique crashes, which indicates that some of the inputs, stored in the results directory, have successfully crashed the program and should be investigated. We have 2 files in the results/crashes directory:

Each file contains the input that crashed the program so you can reproduce the event and investigate to see if the crash is exploitable.

We can confirm the crash and observe an segmentation fault by piping the contents of the crash to our vuln1 program:

The next step is to analyze the crash data and determine if it can be converted into an exploitable vulnerability. Spoiler alert: it can.


This short post is a simple introduction to AFL, a powerful fuzzer that can be leveraged on source code and binaries to find potential vulnerabilities. This step is usually the first step in exploit development. In the next post, we’ll use PEDA to analyze the results found here and determine it exploitability.


See Also

  • Related YouTube Video: Software Exploitation Research: Fuzzing with AFL

Further Reading

Reversing the Trendnet TS-402


The Trendnet TS-S402 is a discontinued network storage enclosure that was sold to individuals for personal data storage. Like every Internet-of-Things (IoT) device, it runs on software programmed and/or configured by the manufacturer before shipping it to the end-user, i.e. the firmware. Firmware versions 2.00.10 and below of this particular device have a serious vulnerability allowing remote root access . This target thus provides an excellent exercise for reverse engineering while providing an example of a vulnerability that is unfortunately way too common in IoT: backdoors by design. In this post, we will introduce Binwalk and provide the background necessary to do the same on a large variety of firmware for consumer-level devices, using the TS-S402 as a practical example. A video of this post is also available.

Trendnet TS-S402
The Trendnet TS-S402 Network Storage Enclosure (from

The Trendnet TS-S402

Before reversing any device, it’s important to actually understand its functionalities, components and any other piece of information that may help along the analysis of its firmware. The webpage of the product highlights the following features:

  • Access your data from the Internet (FTP) and on your local network
  • Microprocessor: Marvell 88F5182
  • IDE Controller: ITE IT8211F
  • Real Time OS: Embedded Linux (Kernel Version 2.4.25)
  • File Protocols: Microsoft Networks (CIFS / SMB) Internet (HTTP 1.1) FTP, FTPS (SSL FTP)

Why are these facts important? Not all of the will be useful, but some may provide you with an overall idea of what to expects once you start analyzing the firmware file. In many cases, especially with consumer-level devices, reversing firmware is fairly straightforward and common open-source tools will do the heavy lifting for you. But if you move on to industrial firmware, awareness of the device is important as you will be faced with unheard operating systems, libraries and unknown file formats. In this case, we can expect to see a Linux-based Operating System (OS) hosting a HTTP and FTP server, along with Samba compatibility. The manufacturer is even generous enough to provide the underlying microprocessor, which can be helpful when conducting even deeper analysis for vulnerabilities in the binaries.

Reversing the Firmware

The vulnerability we are looking for is present only in versions 2.00.10 and below of the firmware, which you can download from the repository of the company. Unzip the archive and you’ll to obtain the following files:

  • TS-S402_FW_2_00_10.bin
  • readme.txt
  • release_TS-S402.txt
  • REMOTE_PACKAGE_2_20.bin

It’s always a good idea to read the release notes and README files. Doing so may save you time and headaches trying to figure things out. If you’re into bug hunting, the release notes can be useful to list the changes and patches included in this version, providing potential hints to patched vulnerabilities of previous versions.

The two “.bin” files contain the programs and OS of the device. In this case, based on the filename, the TS-S402_FW_2_00_10.bin is the main firmware file and thus, the focus of this post. The first step is always to check if we can determine the file type by using the file command. If we are lucky, it is a known file type and some application exists to extract the relevant files/information out of it.

However we are not so lucky. The file command returns “data”, which means it found the file to be binary data without any specific structure or format. So we will need to use a more powerful tool: binwalk. Binwalk is very useful reverse engineering toolkit which can analyze and extract files from unknown binary files. However note that it can also return quite a few false positives. The only way to recognize them is with experience and trial-and-error. If not already done, install binwalk with apt using  sudo apt-get install binwalk and run the following command:

The command above asks binwalk to check out the TS-S402_FW_2_00_10.bin file and try to find interesting files or structures inside it. We use the “-x lzma” argument to eXclude any findings about LZMA-compressed data: these are false positives in this case. You will obtain the following result:

In other words, there seems to be a 32-bytes header followed by a GZip-compressed file. At this point, we want to carve this gzip file out of the binary file for further investigation. You can use the dd command to do so, but binwalk provides the -e option to Extract files for you.

The carved files will be outputted to a directory labelled _TS-S402_FW_2_00_10.bin.extracted, in which you will find a single file called 20, which is the offset of the file in the larger firmware. Using the file command again, we now get a more interesting result:

This time, the file command clearly recognized a TAR archive, meaning we can simply untar the file with the command below:

This archive contained even more files: a uImage and a filesystem:

  • uImage
  • rootfs.armeb.squashfs

The uImage is the boot loader of the firmware and you will often find this file or something similar in most Linux-based firmware. Analysis of the uImage will be left for another post. For now, we are interested in the filesystem contained in rootfs.armeb.squashfs, which as its name implies, is a SquashFS. To access the files it contains, we can normally use the unsquashfs tool, however in this case doing so won’t work:

Depending on how the file system was created and the development software used, it may have incompatibilities with the way unsquashfs expects the file system to be structured. As a workaround, we will use Sasquatch, which is more flexible when it comes to extracting file from non-standard Squash file systems. Clone the project and build the code by following the instructions n the file, or you can download a pre-compiled binary for Ubuntu and variants. Now let’s try again carving out the files, but with Sasquatch this time by typing  ./sasquatch rootfs.armeb.squashfs . After a while, Sasquatch will extract all files in the squashfs-root directory, at which point you can finally access the files hosted on the targeted device.

Find the Backdoor

There is a fairly obvious backdoor hidden in the file system. Go ahead and explore the files and configuration and see if you can find it. When you are ready read on.

Most commercial devices are accessible remotely via a web interface. The web server and its contents are therefore a good starting point to hunt down potential vulnerabilities. On the TS-S402, the web application is located in the /home/httpd directory. The partial listing of the contents of this directory is included below:

As you can see, one of the web page is named “backdoor.html”; quite an obvious indicator that something is wrong. If you look at the webpage, you’ll notice that it seems to enable the telnetd daemon, thus allowing Telnet connections to the device. Unless specially configured to be blocked in the network firewall, this web page should be accessible to anyone on the network, potentially anyone if facing the Web. All that is missing right now is credentials to access the device. Let’s look at /etc/shadow to see if we can potentially figure out the default password for the root account:

Well, there isn’t any password setup for the root account. So in other words, anyone who can access the backdoor.html page on the device can enabled remote Telnet connections, and then login as root. While I haven’t tested it as I do not own this device. this vulnerability was previously confirmed and reported.


This post provided an example of reversing the firmware of a consumer-level IT appliance to locate vulnerabilities allowing remote access to the device. Such vulnerabilities may seem trivial an unimportant until a botnet such as the Mirai botnet comes along and use tens of thousands of these vulnerable devices – which are rarely updated – to DDoS websites across the web. Hence the need to understand the techniques and skills require to pwn these devices in order to defend them.

See Also

Learn More



Installing WordPress on OpenBSD 6.0 with Httpd



In the previous posts, we setup a minimal but secure web server using OpenBSD 6.0. In this post, we start from a fresh install with httpd, MariaDB and PHP 5.6.23 setup on the host. In most cases, you may now want to install a web application on it. One of the most popular is WordPress. If you have followed all the steps in the previous tutorial, installing WordPress will be fairly easy. However, because the web server is sand boxed in OpenBSD, many issues can arise. Additionally, introduction of new application may also introduce new security concerns. In this tutorial, we go through the basics of setting the database and configuring the application. We’ll also assume that you have the networking aspect configured and working. You can also consult the accompanying video.

Setting Up WordPress 4.7 on OpenBSD 6.0

To install WordPress on OpenBSD 6.0 using the native httpd web server requires quite a few steps, but most are straightforward and requires only some Linux command shell knowledge. It’s a good idea to be well-versed in the Bash scripting language and basic Linux/OpenBSD knowledge. In any case, following the steps below will get you going with your new WordPress blog in no time.

Downloading WordPress

Once validated, unzip and untar the archive into your web root directory, likely /var/www/htdocs using:

This will untar all files into /var/www/htdocs/wordpress. Feel free to rename the wordpress directory to anything you’d like.

Configuring the Database

In previous post, we installed MariaDB and thus this section will assume you have installed this database application. Otherwise, refer to the documentation of your database to use the proper SQL statements to create databases, users and manage permissions.

Log into the MariaDB database using  mysql -u root -p your_password . If you are logging from a remote location, use the  -h host argument. Once logged in, we will conduct 3 steps:

    1. Create a database for the WordPress application:

    1. Create a user for WordPress to use in order to connect to the database by using the following SQL statement:

    1. Grant permissions to the new user in order to edit the database and tables as required:

Now, the WordPress application has a place to store data on our database. Before we proceed thought, I encourage you to look at the ~/.mysql_history for a glimpse of what happened while you were doing the steps above. As you will see, the password for the user has been logged into this file. Remove this file with rm ~/.mysql_history  and let’s disable logging to prevent such leaks by adding this line in your rc.conf.local file:

Installing WordPress

From a remote host, use your favorite browser and go to https://<your_address>/wordpress/ and the installer should popup automatically. The first step is create the configuration file by filling information about the database. So gather the following information, which we have from the previous section and click “Let’s Go“:

  1. Database name: Database name use with the “CREATE DATABASE” SQL statement, i.e. “db_wordpress
  2. Database username: Username enter in the “CREATE USER” SQL statement, i.e. “wp_user
  3. Database password: type in your password;
  4. Database host; Enter or ::1. Do not leave it as “localhost” as we want to use the sockets;
  5. Table prefix; Prefix for each table created. Unless you plan to have multiple WordPress sites, leave the default value.
Wordpress Installer Welcome Page
The WordPress Installer will guide you step-by-step on setting it up.

On the next page, enter the required data and click “Submit“. If every thing is setup right, you will be prompted to continue with the setup of the site. However, you may also get a blank “step2” page, i.e. the URL will be “setup-config.php?step=2” but nothing will show up. This problem can be caused by many different things. First, make sure you have setup PHP to use your MySQL database by enabling the proper extensions in the php-5.6.ini configuration file. See previous post for an explanation on how to do this.

Next issue you may encounter is a warning that WordPress cannot create the wp-config.php file. This is mostly due to permissions issues with /var/www/htdocs/wordpress/. The best option is to manually create the file by copy-pasting its contents. Another alternative is to temporarily change the permissions of the directory to allow write permissions with  chmod 777 /var/www/htdocs/wordpress for the installer to create the file. Doing so allows anyone to write and execute code to your directory and as such, it must be change immediately after you are finished installing and configuring WordPress.

Wordpress Fail to Create Wp-config.php
WordPress warns that it could not create the wp-config.file.

Quick Hardening

Before calling “Mission Accomplished”, take some time to test your new site and set the proper file permissions. Create a test post and try to upload an image to it. You may find that it fails, again because of permission issues. According to [1], you should have the following permissions for your WordPress install:

  • Folder set to 755;and
  • Files set to 644, except wp-config.php should be 440 or 400

This can be done with the following commands;

Furthermore, note the following quote from [1]:

No directories should ever be given 777, even upload directories. Since the php process is running as the owner of the files, it gets the owners permissions and can write to even a 755 directory.

Meaning that you should avoid the temptation to solve your uploads issues, or any other issues by setting full permissions, even the upload folder. Based on [2], all files outside the wp-content directory should be owned by your OpenBSD user account so they cannot be modified. The owner of the wp-content will be set to www and will be writable, allowing uploads of files themes and plugins. Note that once you chose your theme and plugins, you could further harden your blog by restricting the wp-content/themes and wp-content/plugins directories as some attackers hide web shells in those.

Retest to make sure it works.

Upload Failures due to Directory Permissions
Setting the minimal and proper permissions on the Uploads directory is critical.

One last quick thing you may want to do is delete unneeded installation files.  WordPress should have remove them for you, but just double check. You can also remove the readme.html and any release notes that may be present, this way, it will be harder for an attacker to find the version of your WordPress installation.


WordPress becomes insecure when adding plugins, which introduces the majority of new vulnerabilities. As such, attempt to avoid unnecessary plugins and themes and uninstall them once they are unneeded. Also enable auto-updates. There are quite further actions you can take to harden your WordPress install, and I’d recommend reading the reference at [1]. You can also review the database permissions you have granted to the “wp_user” in MariaDB, and possibly restrict them to simply INSERT/UPDATE/SELECT/DELETE instructions. Then test your installation with wp-scan, a great, free and open-source WordPress vulnerability assessment.


[1] Hardening WordPress, Core Directories/Files,, (accessed on 2017-01-09)

[2] Correct File Permissions for WordPress, StackOverflow,, (accessed on 2017-01-16)

See Also

Secure WebServers with OpenBSD 6.0 – Setting Up Httpd, MariaDB and PHP



In this tutorial, we setting up a web server on OpenBSD 6.0 using the native httpd web server, MariabDB and PHP. There can be quite a few issues popping up unlike other systems, mostly due to the fact that the web server is “chroot jailed” during execution. In other words, the web server is sandboxed and cannot access other parts of the operating system, which requires more work than other similar setups on other distributions. However, this greatly decreases the damages if your server gets whacked. In this post, we setup a minimal web server that will allow you to host simple web content. I’ll assume you have an OpenBSD 6.0 VM created with root access to it. From there, we will stand up our web server with HTTPS, install MariaDB and PHP. Please note that this tutorial is not meant for professional/commercial settings, but for personal and educational uses. A video version of this tutorial is also available.

Standing up a Minimal Web Server with Httpd

The strategy we will employ is to create a very minimal web server, test if it works as intended, and then enable additional features as we go along. So first, we’ll start by enabling the httpd daemon. To do so, first copy the httpd.conf file from /etc/examples/httpd.conf to /etc/ by typing  cp /etc/examples/httpd.conf /etc . Open the copied file as root using vi or another text editing tool if you have any install. In the file, you will delete all the examples provided and only keep the “minimal web server” and “types” sections:

Make sure you save your changes and now start your web server with the following command:  /etc/rc.d/httpd -f start . Make sure you include the  -f , other you may get an error message. We will fix this later. If everything goes well, you should get an “httpd(ok)” message. Otherwise, there is likely an error in your configuration file. You can confirm by using  httpd -n .

Let’s confirm everything works so far. Retrieve your IP address using  ifconfig em0 and using another host on your network, browse to http://<your_ip>. If everything works as expected, you will see something similar to the figure below:

OpenBSD WebServer - 403 Forbidden
Receiving a 403 Forbidden error from the OpenBSD web server.

We received a 403 error because we do not have any web pages created yet and by default, httpd prevents directory listing – which is a good thing. So let’s create a quick index.html web page. Use the following command  vi /var/www/htdocs/index.html and type the following:

Save the file and point your browser to http://<your_ip>/index.html. You should see your web page. If not, make sure you created the file in /var/www/htdocs and you haven’t made a typo in your URL. Also note that if you go to http://<your_ip>/, you will also end up on your web page. By default httpd looks for “index.html” and serves this web page when none is specified.

Fantastic. We got ourselves a web server. But not a very secure or useful one unless you want to host Geocities-like webpages. Next, we will enable HTTPS on our web server and redirect all traffic to it. We’ll need to do this in 2 steps:

  1. Create a certificate for your web server; and
  2. Setup httpd to use your certificate and HTTPS

First, we’ll need to generate a SSL private key. This is straightforward by using openssl:

The server.key file is your private key and must be secured! It’s very important that nobody else other than you have access to it. Next, we will use this key to generate a self-signed certificate. This is also done by using openssl:

The command above basically requests OpenSSL to generate a certificate (server.crt) using our private key (server.key) that will be valid for 365 days. Afterwards, you will be asked a couple of questions to craft the certificate. Since this is self-signed, feel free to enter anything. Once done, the first step is completed. Next, we will modify our configuration file again and update out minimal web server to tell it to use HTTPS:

Every time your modify the httpd.conf file, you will need to restart your web server for the changes to take effect. Use  /etc/rc.d/httpd -f restart do so and test your website again, this time using https://<your_ip>. You should be greeted with a warning message fro your browser, warning you that it cannot validate the certificate. That’s because it is self-signed. Click on “Advanced” and add it to the exceptions. Afterwards, you will be serve our web page via an encrypted link.

Web Server Certificate Exception
Receiving a warning from the browser on self-signed certificate.

So at this point, we have a functioning web server over HTTPS. However, unencrypted communications are still enabled. We would like to have ALL users over HTTPS. This can be done by replacing this line in httpd.conf:


Anyone using http://<your_site> will be automatically redirected to https://<your_site>.

Setting Up MariaDB

Installing the database is quite simple in contrast with many other activities we need to do. First, we’ll need to download some packages, so make sure you have the PKG_PATH environment defined with a mirror containing the packages you need. If not, select a mirror on and define your variable:

And as root, install the mariadb-server package:

Once completed, install the database using the included script by typing  mysql_install_db and when completed, start the mysqld daemon:  /etc/rc.d/mysqld -f start . The last step is to configure it by running the  mysql_secure_installation . The script will ask you a couple of questions:

  1. First, it will ask you to set a password for root. Choose a good password. Long simple passwords can be more efficient than short complex one that you won’t remember;
  2. It will then ask if it should remove anonymous users. Select “Y” to remove them;
  3. When asked if it should disallow remote root access, answer by the positive to prevent root access from remote hosts;
  4. Choose to remove all test databases; and
  5. Press “Y” to reload all privileges in the database application.

You are now done with installing the database. Before moving on to the next section, confirm that everything is working by login into MariaDB:

If everything went fine, you will be given access to the database engine. Type  quit; to exit the application.

Setting Up PHP

The last step of this tutorial involve downloading and install PHP. Very few webpages nowadays rely solely on static HTML, and I suspect most will want to install web applications later on, so let’s setup PHP. First, download some of the required packages. Note that additional packages may be needed depending on the web applications you wish to install later on, but for now, let’s setup the core PHP packages:

There are several versions of PHP available on the OpenBSD repository. What is important is that you select the same version for all packages you install. For example, at the time of writing version 5.6.23 and 7.0.8 were available, but php-mysql 7.0.8 was not, thus we select 5.6.23 for all PHP packages to prevent issues later one. Dismiss any packages ending with “-ap2” as these are for the Apache web server. For the purpose of this tutorial, we will select version 5.6.23 every time we are asked.

Before starting up PHP, we have a couple of things to do. First, we need to tell httpd to send PHP pages to the PHP processor. We also need to specify the PHP processor that we have a database it needs to be aware of. So let’s start by modifying our httpd.conf file again by adding a section about .php files. Also, we’ll add a “directory” section to tell the web server to look for “index.php” files first instead of “index.html“:

Next, let’s modify the PHP configuration file to enable MySQL. We do so by adding extensions to the /etc/php5.6.ini file. Open this file as root and add the following lines under the “Dynamic Extensions” section:

Since we modified configuration files, we’ll need to restart the httpd and php-fpm daemons. Do so with  /etc/rc.d/httpd -f restart and  /etc/rc.d/php56-fpm start . Hopefully, you will get “httpd(ok)” and “php56_fpm(ok)”. Otherwise, you may have introduce a typo in your configuration files or some packages may have not downloaded/installed properly.

Wrapping Up

One last thing we will do before calling it quit for today, is to make sure the httpd, php56-fpm and mysqld services are started on bootup of OpenBSD. To do so create a new rc.conf.local file in /etc/ using  vi /etc/rc.conf.local and type the following in it:

At startup, OpenBSD will use this file to initiate the services and the PKG_PATH environment variable. You will not have to use the  -f anymore when restarting the httpd daemon.


So in this post, we have enabled a HTTPS web server, along with a MariaDB and PHP, allowing use to serve dynamic content on a OpenBSD 6.0 machine. At this point, you should be able to host basic dynamic content. However, if you try to install more complex web applications, you will need an extra few steps in many cases. Sometimes, you will need additional packages and extra work to connect to the database via your web application. In the next tutorial, we will install WordPress to show some of the difficulties you may encounter with the chroot jail and file permissions of the web root.

See Also

The Past, Present and Future of Chinese Cyber Operations

China, as one of many alleged actors on the frontier of cyber espionage, is best understood by briefly examining the past century, how it influences contemporary cyber operations attributed to Chinese-based actors, and how they could be used against the Canadian Armed Forces in a potential Southeast Asian conflict.


Out of nowhere, here’s an article I wrote for the Canadian Military Journal. China,  as one of many alleged actors on the frontier of cyber espionage, is best understood by briefly examining the past century, how it influences contemporary cyber operations attributed to Chinese-based actors, and how they could be used against the Canadian Armed Forces in a potential Southeast Asian conflict.

See the full article here:; or



RAAF website defaced


Atul Dwivedi, an Indian hacker paid a visit to the Royal Australian Air Force (RAAF) last Monday by defacing their website.

This accident comes amid a raise in violence targeted towards Indian native in Australia and apparently Dwivedi protested this situation by leaving a message on the website:

“This site has been hacked by Atul Dwivedi. This is a warning message to the Australian government. Immediately take all measures to stop racist attacks against Indian students in Australia or else I will pawn all your cyber properties like this one.”

Racist incident in Australia against Indian students has increased in the last months
Racist incident in Australia against Indian students has increased in the last months

This site is now up and running as per normal. Of course the webserver wasn’t connected to any internal network and didn’t contain any classified information according to a spokewoman:

“No sensitive information was compromised as the air force internet website is hosted on an external server and, as such, does not hold any sensitive information,1

Microsoft products are used in pretty much every Western armed forces. So it’s save to assume the webserver used by the RAAF is probably running IIS. Of course, IIS implies as Windows machine and a Windows Server machine means that everything is almost certainly all Microsoft based. Of course we can now verify those claims and according to David M Williams from ITWire2 the website is hosted through Net Logistics, an Australian hosting company. The aforementioned article tries to explain the hack with the use of exploits. Which might have been the way Dwivedi did it, but the analysis is quite simple and lacks depth. The site still has an excellent link to a blog detailing the WebDAV exploit, see below for the link.

It’s not impossible to think that Dwivedi might have tricked someone into giving out too much information also. Social engineering can do lots and is usually easier than technical exploits. The Art of Deception by Kevin Mitnick should convince most people of that. Someone could look up on Facebook or another social networking site for some people in the RAAF and then try to pose as them and pose as them.

Then also, why not look for the FTP server? And God knows what else the server is running; maybe a SMTP server also (and probably it does). Now I wouldn’t suggest doing this, but running a port scan would probably reveal a lot of information. Moreover, using web vulnerability tools like Nikto could help find misconfigured settings in ASP or forgotten test/setup pages/files. Up to there, only two things are important: information gathering and imagination.

See also:

Hacker breaks into RAAF website”, AAP, Brisbane Times, July 16, 2009, accessed on 2009-07-17

WebDAV Detection, Vulnerability Checking and Exploitation”, Andrew, SkullSecurity, May 20, 2009, accessed on 2009-07-17

1Indian hacks RAAF website over student attacks”, Asher Moses, The Sydney Morning Herald, July 16, 2009, accessed on 2009-07-16

2 “How did Atul Dwivedi hack the RAAF web site this week?”, David M Williams, ITWire, July 17, 2009, accessed on 2009-07-16

Firefox Javascript Vulnerability


Once again, Javascript is the source of a new exploit that has been recently discovered on Firefox1. The vulnerability can be exploited by crafting malicious Javascript code on a Firefox 3.5 browser and leads to the execution of arbitrary code on the user’s machine. This is due to a vulnerability in the JIT engine of Firefox and affects machine running a x86, SPARC or arm architectures.

The vulnerability resolves around the return value of the escape function in the JIT engine. It’s exploited using the <font> tag. The code for the exploit is public and can be found at milw0rm. The exploit use a heap spraying technique to execute the shellcode.

A fix should be available soon, but the best solution is always to disable Javascript, although a lot of sites rely on it to operate. Another way is to use the NoScript plug-in, which let you enable and disable scripts easily according to a whitelist/blacklist system.

See also:

Mozilla Firefox Memory Corruption Vulnerability”, Secunia, July 14, 2009, accessed on 2009-07-15

Exploit 9137”, SBerry, July 13, 2009, accessed on 2009-07-15

Stopgap Fix for Critical Firefox 3.5 Security Hole”, Brian Krebs, The Washington Post, July 14, 2009, accessed on 2009-07-15

Critical JavaScript vulnerability in Firefox 3.5”, Mozilla Security Blog, July 14, 2009, accessed on 2009-07-15

1 “Mozilla Foundation tackles Firefox bug”, Nick Farell, The Inquirer, Wednesday, 15, July, 2009, accessed on 2009-07-15