← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-0213 · CWE-284 · Disclosed 2025-01-04

A vulnerability was found in Campcodes Project Management System 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a loaded nail gun left inside the fenced job site, not on the sidewalk

CVE-2025-0213 is an unrestricted file upload flaw in Campcodes Project Management System 1.0, specifically in /forms/update_forms.php?action=change_pic2&id=4. The published proof of concept shows the handler accepting a user-supplied file and moving it into ../images/ without extension or content validation; if that directory executes PHP, an authenticated user can turn an image upload into a web shell and likely remote code execution on the web server. Publicly stated affected versioning is just 1.0, and I could not find an authoritative vendor-fixed release.

The vendor/NVD baseline of MEDIUM 6.3 is directionally right but slightly generous for enterprise prioritization. The decisive friction is not exploit complexity; it is attacker position: this is authenticated remote against a niche downloadable PHP/MySQL project, which implies the adversary already has credentials or a foothold into the app. That sharply narrows real-world reach, even though the post-auth impact can be ugly on a misconfigured PHP host.

"Real bug, real PoC, but it needs a valid app session on a niche PHP app before it becomes your problem."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Get a valid PMS session

The attack starts with a legitimate session to the Campcodes application. The CVSS vector and the published HTTP request both indicate PR:L, and the PoC includes a PHPSESSID cookie, so the attacker is not walking in unauthenticated from the internet. Weaponized tooling here is ordinary browser automation, curl, or Burp Suite replay against the login flow and then the upload endpoint.
Conditions required:
  • A reachable Campcodes Project Management System 1.0 instance
  • Valid low-privilege application credentials or a hijacked authenticated session
  • Knowledge of the app path such as /construction_pms/
Where this breaks in practice:
  • This is post-auth, so it usually depends on credential theft, password reuse, or another bug first
  • Campcodes is a niche downloadable project, not a mainstream enterprise platform with huge exposure
  • Many deployments are lab, student, or internal-only installs rather than hardened public apps
Detection/coverage: Most vulnerability scanners will identify the CVE only if they can authenticate or if they use code/package signatures on the host. WAFs rarely help at this stage because the request is a normal multipart upload from a valid session.
STEP 02

Upload a PHP payload through change_pic2

Using Burp Suite or curl, the attacker sends a multipart POST to /forms/update_forms.php?action=change_pic2&id=<project_id> with a file like test.php. The published code path uses basename() and move_uploaded_file() but does not enforce an allowlist of safe extensions or MIME types before writing into ../images/.
Conditions required:
  • The vulnerable change_pic2 code path exists in forms/update_forms.php
  • The authenticated user can reach the project picture update action
  • The server accepts multipart form uploads
Where this breaks in practice:
  • If the upload directory blocks script execution, impact falls from code execution to stored file placement
  • Local hardening like extension allowlists, web-tier rewrite rules, or PHP execution bans in images/ breaks the exploit
  • Some app roles may not be allowed to edit project records even with a valid session
Detection/coverage: HTTP logs can catch suspicious uploads of .php, double extensions, or application/x-php. EDR/web-shell detection may fire when the dropped file is later executed, but many scanners miss this if they only test unauthenticated surfaces.
STEP 03

Trigger the uploaded web shell

If the web server executes PHP in the upload directory, the attacker browses directly to the uploaded file and runs commands through a web shell parameter like the PoC's x=. Tooling is trivial: browser, curl, or web-shell clients. At that point the bug becomes server-side command execution in the security context of the PHP worker.
Conditions required:
  • The uploaded file lands in a web-accessible path
  • PHP execution is enabled for that path
  • The payload is not removed by AV, EDR, or file-integrity monitoring
Where this breaks in practice:
  • Least-privilege PHP-FPM pools and containerized deployments can limit blast radius
  • Non-executable uploads, read-only containers, or noexec-style controls stop the code-execution jump
  • Good EDR often catches the web shell only when it starts spawning system commands
Detection/coverage: This is where defenders have the best shot: web logs for direct hits on uploaded .php files, EDR alerts on php-fpm/httpd spawning shells, and file-integrity monitoring on the webroot.
STEP 04

Pivot from app compromise to host impact

Once commands run as the web service account, the attacker can enumerate credentials, local config, database secrets, and nearby network reachability. Common follow-on tools are linpeas, pspy, local shell one-liners, or simple database dumps. The eventual blast radius depends much more on host hardening than on the original upload bug.
Conditions required:
  • Command execution from the web tier
  • Interesting secrets or excessive permissions on disk
  • Weak host segmentation or privilege boundaries
Where this breaks in practice:
  • A locked-down web account can confine the attacker to one app and one database
  • Secrets vaulting, network segmentation, and EDR containment sharply reduce follow-on value
  • If the app is a throwaway internal demo, attacker ROI is low
Detection/coverage: Host telemetry matters more than vuln scanners here. Expect strong coverage from EDR on shell spawn, suspicious child processes, credential access, and outbound beaconing.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed active exploitation in the sources reviewed. CISA's ADP enrichment marks exploitation as poc, not observed-in-the-wild.
KEV statusNot listed in CISA KEV as reviewed; no KEV date applies.
Proof of conceptPublic PoC exists: shaturo1337/POCs publishes an HTTP request and PHP web-shell payload for this exact endpoint.
EPSSLow exploit probability. User-provided EPSS is 0.00112; a public aggregator snapshot shows roughly 0.08% probability and about the 24th percentile, which is consistent with low operational interest.
CVSS vector reality checkCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L means network reachable but authenticated. In practice, PR:L is the whole story: this is usually a post-compromise or stolen-credential issue, not day-one internet spray-and-pray.
Affected versionsCampcodes Project Management System 1.0 is the only affected version explicitly published in CNA/NVD records.
Fixed versionNo authoritative fixed release found in Campcodes or CNA references. Treat this as vendor patch unavailable / not disclosed unless your own source diff proves otherwise.
Exposure and scanning dataNo reliable public census (GreyNoise, Censys, or vendor advisory telemetry) was found for this specific product/CVE in the reviewed sources. My inference: exposure is likely small and manually discoverable rather than mass-fingerprinted.
Disclosure timelineDisclosed 2025-01-03 in CNA timeline; NVD published 2025-01-04 and last modified 2025-01-10.
ReporterReported by John Correche / John Alan Correche via VulDB references attached to the CNA record.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.4/10)

The single most important severity brake is that exploitation requires authenticated remote access to a niche PHP application, which makes this a post-foothold path rather than broad initial access. I kept it in MEDIUM because the public PoC is straightforward and, on weak PHP deployments, the bug can become genuine web-shell execution.

HIGH Authenticated remote access is required
MEDIUM Public PoC and exploit path through unrestricted upload
LOW Internet exposure population for this specific Campcodes product

Why this verdict

  • Downward pressure: requires valid app auth. PR:L is not a paper detail here; it implies stolen credentials, session theft, or another bug first, which makes this a post-initial-access issue.
  • Downward pressure: narrow deployment population. Campcodes is a downloadable PHP/MySQL project for small deployments and educational use, not a high-density enterprise platform with broad managed exposure.
  • Upward pressure: file upload can become code execution. The PoC is not theoretical; it shows a working multipart upload of a PHP payload into a web path, which is exactly how web shells land.
  • Upward pressure: public weaponization exists. A public GitHub PoC lowers attacker effort and raises reliability once someone already has a session.
  • Downward pressure: no exploitation evidence and very low EPSS. No KEV entry, no credible campaign reporting, and low EPSS all argue against emergency treatment across a 10,000-host estate.

Why not higher?

It is not HIGH because the attacker does not get to start from the open internet unauthenticated. Requiring a valid application session, plus the likely small and uneven deployment footprint of this software, compounds the friction hard enough that this is not a broad enterprise fire drill.

Why not lower?

It is not LOW because the technical consequence is more serious than the CVSS sub-scores imply when PHP execution is enabled in the upload path. A real public PoC exists, and once an attacker has app access, exploitation is simple enough to produce a durable web shell.

05 · Compensating Control

What to do — in priority order.

  1. Block script execution in upload paths — Disable PHP execution under the application's images/ and other writable directories using Apache/Nginx/PHP-FPM policy. For a MEDIUM noisgate verdict there is no mitigation SLA, but this is the highest-value hardening step and should go into the next routine web-tier change before the 365-day remediation deadline.
  2. Restrict access to the app — Put the Campcodes instance behind VPN, reverse-proxy allowlists, or at minimum strong SSO/MFA where possible, because the exploit chain starts with a valid session. There is no mitigation SLA for MEDIUM; apply in the next normal access-control cycle and definitely before remediation closes.
  3. Watch for web-shell patterns — Alert on multipart uploads of .php, double extensions, and direct requests to newly created files under /images/. There is no mitigation SLA for MEDIUM; deploy as standard detective coverage while you schedule remediation.
  4. Constrain the web service account — Run the app with least privilege, isolate the vhost/container, and remove unnecessary shell tools and secrets from the host so a successful upload has less room to pivot. There is no mitigation SLA for MEDIUM; fold this into normal hardening work before the remediation deadline.
  5. Retire or locally fix unsupported installs — If no vendor-fixed release exists, treat local code remediation or product retirement as the actual fix: add strict extension allowlists, server-side MIME validation, and deny executable uploads. For MEDIUM, there is no mitigation SLA — go straight to the 365-day remediation window.
What doesn't work
  • A perimeter WAF alone does not solve this well, because the exploit is a normal authenticated multipart upload and can look like expected application behavior.
  • Relying on file extension randomization does not help; the vulnerable code renames the file but preserves the attacker-controlled extension.
  • Patching only the OS or PHP runtime does not remove the application logic flaw in update_forms.php.
06 · Verification

Crowdsourced verification payload.

Run this on the target web host that serves Campcodes, not from your scanner workstation. Invoke it as sudo bash verify_cve_2025_0213.sh /var/www/html/construction_pms or point it at the application root; it only needs read access to the webroot, but sudo is often required if the files are owned by root or the web user.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify_cve_2025_0213.sh
# Checks Campcodes Project Management System for the vulnerable upload pattern in forms/update_forms.php
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

APP_ROOT="${1:-}"
TARGET_REL="forms/update_forms.php"

if [[ -z "$APP_ROOT" ]]; then
  echo "UNKNOWN - usage: $0 /path/to/construction_pms"
  exit 2
fi

TARGET="$APP_ROOT/$TARGET_REL"

if [[ ! -e "$TARGET" ]]; then
  echo "UNKNOWN - file not found: $TARGET"
  exit 2
fi

if [[ ! -r "$TARGET" ]]; then
  echo "UNKNOWN - cannot read: $TARGET"
  exit 2
fi

content="$(cat "$TARGET")"

has_change_pic2=0
has_move_upload=0
has_images_path=0
has_validation=0
has_php_block=0

printf '%s' "$content" | grep -q "change_pic2" && has_change_pic2=1
printf '%s' "$content" | grep -q "move_uploaded_file" && has_move_upload=1
printf '%s' "$content" | grep -q "\.\./images/" && has_images_path=1

# crude signs of extension/MIME validation or explicit deny rules
printf '%s' "$content" | grep -Eqi "(in_array\s*\(|preg_match\s*\(|mime_content_type\s*\(|finfo_|pathinfo\s*\(|allowed(_|)ext|whitelist|blacklist|application/x-php|php[0-9]?\$|deny)" && has_validation=1

# optional server-side defense check: look for common Apache/Nginx rules near app root
if find "$APP_ROOT" -maxdepth 2 \( -name ".htaccess" -o -name "nginx.conf" -o -name "default.conf" -o -name "*.conf" \) -type f 2>/dev/null | xargs -r grep -Eqi "<FilesMatch.*php|location.*images|deny all|return 403|php_admin_flag engine off|RemoveHandler .*php|SetHandler none"; then
  has_php_block=1
fi

if [[ $has_change_pic2 -eq 1 && $has_move_upload -eq 1 && $has_images_path -eq 1 && $has_validation -eq 0 ]]; then
  if [[ $has_php_block -eq 1 ]]; then
    echo "UNKNOWN - vulnerable code pattern present, but server config appears to block some script execution paths; validate manually"
    exit 2
  else
    echo "VULNERABLE - unrestricted upload pattern detected in $TARGET"
    exit 1
  fi
fi

if [[ $has_change_pic2 -eq 0 && $has_move_upload -eq 0 ]]; then
  echo "PATCHED - vulnerable handler signature not found in $TARGET"
  exit 0
fi

if [[ $has_validation -eq 1 ]]; then
  echo "PATCHED - upload handler contains signs of validation/hardening; review manually to confirm"
  exit 0
fi

echo "UNKNOWN - inconclusive result; review $TARGET manually"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: first, find out whether you actually run this Campcodes app anywhere internet-reachable; in most enterprises the answer will be zero, and that matters more than the CVE number. Because this is a MEDIUM reassessment, there is no noisgate mitigation SLA — go straight to the 365-day remediation window; if no vendor patch exists, your remediation is to retire the app or locally fix the upload handler and disable PHP execution in writable directories within the noisgate remediation SLA of 365 days. If you do discover an exposed instance, don't panic-patch the whole estate—contain that one app, verify auth exposure, and harden the upload path in the next normal web change window.

Sources

  1. NVD CVE-2025-0213
  2. OpenCVE record for CVE-2025-0213
  3. Public GitHub PoC
  4. Campcodes project page
  5. Campcodes download page
  6. CISA Known Exploited Vulnerabilities Catalog
  7. FIRST EPSS documentation
  8. CVE Details entry with EPSS snapshot
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.