
Educational exploit demonstration of CVE-2014-2323 SQL injection in lighttpd's mod_mysql_vhost, with Docker-based lab for hands-on vulnerability analysis and patching.
title: Ep4 - Network-Related Vulnerability members:
Related vulnerability:
CVE-2014-2323 [1] was assigned to SQL injection bug.
CVE-2014-2324 [2] was assigned to the path traversal bug.
Confirm: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2014_01.txt
The service to be exploited is Lighttpd. It is an open-source web server (BSD license) optimized to be lightweight and fast. It emerged as a 'proof-of-concept' for the famous c10k problem (how to handle 10,000 simultaneous connections on a server), gaining considerable popularity at the time (2003), and is currently used by Whatsapp.com, Xkcd, and in the past, Youtube. Its market positioning is quite interesting, as we can see in the chart:

The server aims to handle the problem of many connections by using asynchronous event-driven mechanisms (kqueue on BSDs, epoll on Linux), reducing the need for multiple threads, thus resulting in a much smaller memory footprint and better CPU utilization (a strategy also used by Nginx servers, whose usage has increased significantly over the years):

One of lighty's features is the easy management of virtual hosts.
It is a method used to host more than one domain name that resolves to the same IP, reducing hosting costs for companies that seek to offer websites since it is not necessary to reserve a dedicated server for each website.
The technique can be IP-based (one interface per host) or name-based (one name per host, sharing the interface) - explored in this presentation.
Name-Based
: uses the 'Hostname' provided by the client to identify which service to use to respond accordingly. This method presents two difficulties: complications with handling secure sessions (TLS) - the handshake must be done before any header indicating the Host is passed to the server, thus complicating the determination of which certificate to present during the handshake. A solution to this problem is a TLS extension called Server Name Indication (SNI) that allows presenting the name at the beginning of the handshake, enabling the choice of the correct certificate. A second problem is regarding connection attempts without a well-defined Host header, leading to indetermination of which service to use.
IP-Based
: uses separate IPs for each application. The web server is then configured for multiple physical (or virtual) network interfaces under a single interface and then responds accordingly based on the (destination) IP address;
*IP aliasing* allows us to create virtual interfaces for each service.
In the case of a large company, managing such mapping can become complex depending on the number of clients. Lighty then offers support for using a database for this purpose, as we will show later.
First, let's see how to configure a server manually and then add vhosting.
Preparing a basic lighttpd server is very easy. Simply install it and create a configuration file that specifies the port to be used, how to respond to certain requests, and other settings.
server.document-root = "/usr/lighttpd/mysite.com/"
server.port = 80
mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain"
)
Now imagine we want to create a business based on selling websites and offer a custom domain to the buyer. Aiming to minimize costs, we then want to use vhosts for each client. Let's say the network course wants to acquire three websites: redes.io, mac0448.io and mac5910.io. Our company then registers the domains, all pointing to the IP of our single server with a single interface.
ps: to simulate this we can change the /etc/hosts file:
172.17.0.2 redes.io
172.17.0.2 mac0448.io
172.17.0.2 mac5910.io
In order to be able to serve the different client websites resolving from a single IP, we can then manually configure the server:
server.document-root = "/usr/lighttpd/default/"
server.port = 80
mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain"
)
$HTTP["host"] == "redes.io" {
server.document-root = "/usr/lighttpd/redes/"
} else $HTTP["host"] == "mac0448.io" {
server.document-root = "/usr/lighttpd/mac0448/"
} else $HTTP["host"] == "mac5910.io" {
server.document-root = "/usr/lighttpd/mac5910/"
}
But, as we can imagine, this can become a problem as we want to handle many clients and provide different configurations for each website as mentioned earlier.
With the mod_mysql_vhost module we can then connect our server to a mysql database responsible for such mapping. We then specify the database name, how to find it on our network, and which command to use to perform the query.
server.modules = (
"mod_accesslog",
"mod_mysql_vhost"
)
mysql-vhost.db = "NOME_DO_BANCO"
mysql-vhost.user = "USUARIO"
mysql-vhost.pass = "SENHA"
(!!!!!!!!!!!!!!!)
mysql-vhost.sql = "SELECT docroot FROM domains WHERE domain='?';"
(!!!!!!!!!!!!!!!)
mysql-vhost.hostname = "HOSTNAME"
mysql-vhost.port = "PORTA"
SQL is a declarative language for managing relational databases, being used (...) etc
TODO
TODO
Problems then occur because SQL database management systems assume that the inserted commands will be commands known to the administrator and well managed by them. Such an assumption is not always true, since flaws in systems that interact with the DB system can present vulnerabilities, especially on the web, where user interaction is high.
The problem with SQL commands arises when there is an intention to build commands using text originated by the user, be it a username, password, or any other dynamic content.
(TODO)
How to solve? Escaping.
In our configuration, for example, we have a big vulnerability:
mysql-vhost.sql = "SELECT docroot FROM domains WHERE domain='?';"
since possibly (and that's what happened until version 1.4.34) the ? can be replaced by any command and then executed by MySQL.
Let's then simulate this in a network with 3 containers: 1 mysql server and two lighttpd servers, one vulnerable and one fixed.