Creating a Quick PoC for an Exploit with Docker

We will create a quick PoC for an exploit for a wordpress vulnerability. I’ll be emphasizing more on the process than the vulnerability itself. For this demo, we will be exploiting an old content injection vulnerability. You can read about its technical details here, https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html.

In short, the exploit only requires to send a rest API call to the wordpress application.

To stage the demo, we will:

  • Setup a container that runs vulnerable version of WordPress-4.7. We’ll create a wordpress/mysql stack with docker compose.
  • Make an HTTP POST request with a new content that overwrites the original post. I will use HTTPie tool. You may choose any tool you’re familiar with, eg: curl, Postman, Insomnia.

Pre-requisite:

  • You must have Docker already installed. Running the command “docker version” from CLI should return server version.
  • You have an HTTP client that can make json HTTP post. I already have HTTPie on my Mac. I installed with “brew install httpie”

Create a directory.

Save the following file as ‘docker-compose.yml’:

Within the same directory run the following command:

You should see Docker downloading images and spinning up the servers. Once finished you should be able to browse to http://localhost:8080 from your browser. Follow the instructions to finish the installation (by entering site name, username, password, fake email). Then you will see the admin dashboard. Go to Settings > Permalinks and choose the second option to enable pretty links. Open another browser window or new tab and browse to http://localhost:8080 again. You should see your blog and a Hello World post.

To start exploit, run the following command from the shell/terminal to overwrite the post content.

Now browse the site again and observe the “Hello World” blog post content has changed.

To end the PoC, press Ctrl+C on the docker-compose terminal.

Using tshark to Decrypt SSL/TLS Packets

I’m going to walk you through the process of decoding SSL/TLS traffic from a pcap file with the server’s private key using tshark (command-line version of Wireshark). You can, of course, always use ssldump for the same purpose.

I assume you know how SSL/TLS works, and basic understanding of how Wireshark works, and why we use it.

I will start with getting a sample encrypted traffic that includes the handshake part (important for decryption later). For that purpose, we are going to use openssl command to generate a pair of server certificate and key. And then run the HTTPS server with openssl’s s_server command on port 4443 (or any other port you may like) using the generated certificate and key. Then we will issue a GET request to HTTPS server via curl. In the mean time, we will collect the traffic with tshark and will save the data into ssltest.pcap file.

At this point, we should have the file called ssltest.pcap from tshark, and server.crt/server.pem from openssl commands.

Next, we are going to read the pcap file and decode the traffic.

In Wireshark GUI, we can follow “SSL stream” that will dump the ASCII output from the stream. How are we going to do it with tshark?

You will see the output similar to below:

OS X and Android SDK

Android SDK can be installed with Homebrew (http://brew.sh).

Then run the following to install the SDK packages:

If you don’t want SDK and just want to install “adb” and “fastboot” for android phones, just install:

Running Ghost on Ubuntu

Ghost blogging platform was released to public on Oct 14, 2013. It’s a nodejs app, that was started out as a kickstarter.

Since it’s out for public download, I tried to deploy it on a droplet from Digital Ocean running Ubuntu 13.04.

Firstly, Ubuntu repository does not have the latest version of nodejs. Ghost requires nodejs later than 0.8, while nodejs in Ubuntu is 0.68. I had to install nodejs from ppa and later proxy though my current nginx server.

These are the steps required to make it work:
(Initial requirement is that you already have nginx server setup and running).

  1. SSH into your machine and download the file from https://en.ghost.org/download.
  2. Unzip the file into a directory.
  3. Then run “npm install –production”
    (If you don’t have the latest version of npm, it will throw errors)
  4. In your nginx server definition, add this location:
    [bash]location / {
    proxy_pass http://127.0.0.1:2368;
    proxy_set_header Host $host;
    proxy_buffering off;
    }[/bash]
  5. Then re-start your nginx and from the Ghost installation directory run “npm start”
  6. You should see something like this, if everything is okay:
  7. Now try to access, through your nginx server. You should start seeing console is logging requests coming in.

This document is based on Ghost’s deployment guide.

HTTP and HTTPS server with Python

Python 2 has already included an HTTP server module in its later versions. And running the server is as simple as this:

It starts the server on port 8000 (by default), and if we want to run on a different port, we will just add the new port number at the end of the command.

With Python 3, the package merged into http.server. So we would call:

When we need to customize how the server behaves (e.g. to run the server on a specific IP address), we can write a very simple python codes:

If we want HTTPS server, we will need to use built-in “ssl” module. We need to wrap the httpd socket with wrap_socket method. The certificate needs to be in PEM format (RFC1422).

In general, we just need a socket and a handler to serve.

Making SQL Queries

This article is to summarize how do we make SQL queries using different languages and their methods. Making connection to the database will not be covered here.

In the examples, we will be querying “SELECT * FROM employees where eid =and dept =”

It is not recommended to use SQL statements without placeholders in order to reduce the risk of SQL injection.

Java

In Java, we can use JDBC, Hibernate, or some other database frameworks to interact with databases. Generally, I would prefer to use methods that allow me to insert “values” into an sql query. With JDBC, we can use PreparedStatement method. There is also createStatement method, where you insert user-supplied values into the query directly.

Basically the flow looks like this:

  1. Get a “Connection” object, with DriverManager
  2. From “Connection” object, we create a “Statement” object with sql statement.
  3. From the statement object, we generate “ResultSet”.

PHP

PHP has more methods to interact with database. It also depends on the module the php interpreter is built with. We can use MySQL extension, PostgreSQL extension, or ADODB or PDO as generic abstraction interfaces.

With mysqli extension

NOTE: Why mysqli instead of mysql command? If we are using MySQL v4.1.3 and above, PHP manual recommends to use mysqli which is an improved version. Reference.

With PostgreSQL extension

With ADODB

With PDO

KDE 4.8, Google Chrome and the Proxy

My KDE was just upgraded to v4.8 from v4.7.x. Privoxy was also configured on the same PC, just to strip some codes. Google Chrome is configured to use the Privoxy proxy on port 8118.

After the upgrade, Google Chrome has failed to connect to internet. At the same time, Firefox was working perfectly with or without using privoxy.

I tried to capture the packets on the local interface and on port 8118, and got nothing coming in. I wasn’t still sure what’s happening, and even tried to re-compile the privoxy, and tweak some of its settings. It was still not working.

Then, I needed to check KDE’s config file where it stores the proxy settings, as Google Chrome uses KDE’s settings. And there, the proxy is stored as “http://127.0.0.1 8118”, with a space between the host and the port. In version 4.7.x, it uses http://: format to store. Google Chrome fails to parse the setting. The config file is located under ~/.kde4/share/config/kioslaverc.

In order to make things work, I needed to manually tweak that line back to v4.7.x format, or exec Google Chrome with –proxy-server setting.

Python: Pyql module to obtain stock quotes from Y! Finance

I just made an initial attempt to fetch the stock quotes via YQL, and put the codes into a module. The method “lookup” will return a list of python dictionary item(s), based on the information decoded from Yahoo’s JSON data.

The current snapshot is posted on Google Code. The code doesn’t work with Python 3. It should work fine with Python 2.2 or higher.

To clone the source codes to a local resource, please feel free to do so via mercurial.

Example Usage:

Running WordPress with Nginx on ArchLinux

I just moved this blog over to Nginx server from Apache httpd server. I’m pretty satisfied with the overall result. I had to take some time to convert my current httpd configuration over to Nginx, since the new server does not support .htaccess or mod_redirects. This is my current requirements for move over:

  • The site is available on both HTTP and HTTPS.
  • “wp-admin” session is forced to use SSL.
  • I have “quicklook” (to check my server status) and “webalizer” directories under the blog, and they are protected by HTTP BasicAuth.
  • HTTP BasicAuth is to be carried out via SSL.
  • To enforce gzip compression on HTTP connection while disabling it on HTTPS.

Basically I followed the ArchLinux wiki for the implementation, and I will briefly describe what I did.

Nginx (pronounced “Engine X”) is a light-weight open-source http server. Its low resource consumption is the primary purpose for the moveover, and it’s suitable for my server on the cloud.

Firstly, I needed to install the package. And installed “php-cgi” package which is used to provide fastcgi interface to PHP.

Then, I configured fastcgi daemon, and add it to rc.d. So the following script was needed to be added to /etc/rc.d as “fastcgi”

And I gave it an executable permission:

What that script does is to have php-cgi process to listen on port 9000. Now, we would be able to start/stop/restart the daemon with “sudo /etc/rc.d/fastcgi start”. But the script will not be automatically started when the unit is rebooted. It needs to be added to /etc/rc.conf. So I added fastcgi to the rc.conf. Here’s the snippet.

Then I edited the /etc/nginx/conf/nginx.conf file to point to my blog physical directory. We need to add two servers, one for HTTP and one for HTTPS. This is my sample configuration for server myfineblog.local

Line 3 defines the server name (so we can configure virtual hosts based on names).
Line 4-5 defines the access logs for this web site.
Line 6 is the physical location of the web site on local system.
Line 7 is used to turn on gzip.
Line 9-11 is redirect to SSL by sending HTTP redirect if the uri contains any of wp-admin or quicklook or webalizer)
Line 13-21 is the definition of website directory and an equivalent scripts for Apache’s mod_rewrite.
Line 23-29 is the connection to the fastcgi daemon we configured above. It is *important* to change the SCRIPT_FILENAME variable to suit the real physical path of the wordpress script.

To enable SSL server, I assume we already have the certificate and key for the website. The configuration looks the same but it will have SSL options enabled and Basic HTTPAuth section for a certain directories.

This configuration turned on “SSL”, disabling SSLv2 and weak ciphers. It enabled HTTP Basic Authentication for two directories. I disabled gzip on SSL stream. And it tells the fastcgi server to turn HTTPS on.

And started the daemons with “/etc/rc.d/fastcgi start” and “/etc/rc.d/nginx start”.