234 lines
12 KiB
PHP
234 lines
12 KiB
PHP
<?php
|
|
$projectName = getenv('PROJECT_NAME') ?: 'Luartex v3.2';
|
|
$projectDesc = getenv('PROJECT_DESCRIPTION') ?: 'A Luau Script Security Auditor for analyzing and deobfuscating scripts.';
|
|
$projectImage = getenv('PROJECT_IMAGE_URL') ?: ''; // Fallback to empty if not set
|
|
|
|
$analysisResult = '';
|
|
$scriptContent = '';
|
|
$dumpedData = ['strings' => [], 'constants' => []];
|
|
|
|
// Function to dump strings and constants from code
|
|
function dump_strings_and_constants($code) {
|
|
$strings = [];
|
|
$constants = [];
|
|
|
|
// Regex for single and double quoted strings, handles basic escaped quotes
|
|
// It also tries to capture content from [[...]] and [=[...]=] style long strings
|
|
preg_match_all('/"((?:[^"\\]|\\.)*)"|\'((?:[^\']|\\.)*)\'|(?:\[(=*)\[(.*?)\]\1\])/s', $code, $matches);
|
|
|
|
// Combine matches from different quote types
|
|
$rawStrings = array_merge(
|
|
array_filter($matches[1] ?? []), // Double quotes
|
|
array_filter($matches[2] ?? []), // Single quotes
|
|
array_filter($matches[4] ?? []) // Long brackets
|
|
);
|
|
|
|
foreach ($rawStrings as $str) {
|
|
// Decode all C-style backslash sequences (e.g., \n, \x41, \056)
|
|
$strings[] = stripcslashes($str);
|
|
}
|
|
|
|
// Regex for numbers (integers and floats, including negative and scientific notation)
|
|
preg_match_all('/\b-?\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i', $code, $matches);
|
|
if (!empty($matches[0])) {
|
|
$constants = $matches[0];
|
|
}
|
|
|
|
// Regex for string.char(num, num, ...)
|
|
preg_match_all('/string\.char\s*\(([\d,\s]+)\)/i', $code, $char_matches);
|
|
if (!empty($char_matches[1])) {
|
|
foreach ($char_matches[1] as $match) {
|
|
$char_codes = explode(',', $match);
|
|
$decoded_string = '';
|
|
foreach ($char_codes as $code) {
|
|
$decoded_string .= chr(intval(trim($code)));
|
|
}
|
|
if (!empty($decoded_string)) {
|
|
$strings[] = $decoded_string;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove duplicates and keep it clean
|
|
$strings = array_values(array_unique(array_filter($strings)));
|
|
$constants = array_values(array_unique(array_filter($constants)));
|
|
|
|
return ['strings' => $strings, 'constants' => $constants];
|
|
}
|
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['script'])) {
|
|
$scriptContent = $_POST['script'];
|
|
$sandboxDir = __DIR__ . '/sandbox';
|
|
if (!is_dir($sandboxDir)) {
|
|
mkdir($sandboxDir, 0755, true);
|
|
}
|
|
|
|
$fileName = $sandboxDir . '/' . uniqid('script_', true) . '.lua';
|
|
file_put_contents($fileName, $scriptContent);
|
|
|
|
// Execute the script in a sandboxed environment
|
|
$lua_interpreter = '/usr/bin/lua5.4';
|
|
$command = "timeout 10s " . escapeshellarg($lua_interpreter) . " " . escapeshellarg($fileName) . " 2>&1";
|
|
$output = shell_exec($command);
|
|
|
|
$analysisResult = "<pre class=\"text-white bg-dark p-3 rounded\">" . htmlspecialchars($output ?: 'Script executed with no output.') . "</pre>";
|
|
|
|
// Perform static analysis for dumping
|
|
$dumpedData = dump_strings_and_constants($scriptContent);
|
|
|
|
// Clean up the script file
|
|
unlink($fileName);
|
|
}
|
|
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title><?php echo htmlspecialchars($projectName); ?> - Luau Security Auditor</title>
|
|
<meta name="description" content="<?php echo htmlspecialchars($projectDesc); ?>">
|
|
|
|
<!-- Open Graph / Twitter -->
|
|
<meta property="og:title" content="<?php echo htmlspecialchars($projectName); ?>">
|
|
<meta property="og:description" content="<?php echo htmlspecialchars($projectDesc); ?>">
|
|
<?php if ($projectImage): ?>
|
|
<meta property="og:image" content="<?php echo htmlspecialchars($projectImage); ?>">
|
|
<meta name="twitter:image" content="<?php echo htmlspecialchars($projectImage); ?>">
|
|
<?php endif; ?>
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="navbar navbar-dark bg-dark">
|
|
<div class="container">
|
|
<a class="navbar-brand" href="#">
|
|
<?php echo htmlspecialchars($projectName); ?><span class="text-muted" style="font-size: 0.8rem; margin-left: 8px;">Luau Security Auditor</span>
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<main class="container my-5">
|
|
<div class="row">
|
|
<div class="col-md-10 mx-auto">
|
|
<h1 class="text-center mb-2">Luau Script Analyzer</h1>
|
|
<p class="text-center text-muted mb-4">Submit your Luau script below to dump strings/constants and execute it in a secure sandbox.</p>
|
|
|
|
<div class="card p-2">
|
|
<div class="card-body">
|
|
<form id="analysisForm" method="POST" action="">
|
|
<div class="mb-3">
|
|
<label for="scriptInput" class="form-label">Script Content</label>
|
|
<textarea class="form-control" id="scriptInput" name="script" rows="15" placeholder="-- Paste your Luau script here..."><?php echo htmlspecialchars($scriptContent); ?></textarea>
|
|
</div>
|
|
<div class="d-grid gap-2">
|
|
<button class="btn btn-primary btn-lg" type="submit" id="analyzeBtn">Analyze Script</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST'): ?>
|
|
<div id="source-code-display" class="mt-4">
|
|
<h2 class="text-center mb-3">Script Source</h2>
|
|
<div class="card">
|
|
<div class="card-body bg-dark">
|
|
<pre class="text-white mb-0"><code><?php echo htmlspecialchars($scriptContent); ?></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="dumper-results" class="mt-4">
|
|
<h2 class="text-center mb-3">String & Constant Dumper</h2>
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<div class="card h-100">
|
|
<div class="card-header">
|
|
Strings Found (<?php echo count($dumpedData['strings']); ?>)
|
|
</div>
|
|
<ul class="list-group list-group-flush" style="max-height: 300px; overflow-y: auto;">
|
|
<?php if (empty($dumpedData['strings'])): ?>
|
|
<li class="list-group-item">No strings found.</li>
|
|
<?php else: ?>
|
|
<?php foreach ($dumpedData['strings'] as $str): ?>
|
|
<li class="list-group-item">
|
|
<pre class="mb-0" style="white-space: pre-wrap; word-break: break-all;"><?php echo htmlspecialchars($str); ?></pre>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<div class="card h-100">
|
|
<div class="card-header">
|
|
Constants Found (<?php echo count($dumpedData['constants']); ?>)
|
|
</div>
|
|
<ul class="list-group list-group-flush" style="max-height: 300px; overflow-y: auto;">
|
|
<?php if (empty($dumpedData['constants'])): ?>
|
|
<li class="list-group-item">No constants found.</li>
|
|
<?php else: ?>
|
|
<?php foreach ($dumpedData['constants'] as $const): ?>
|
|
<li class="list-group-item">
|
|
<pre class="mb-0"><?php echo htmlspecialchars($const); ?></pre>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="results" class="mt-4">
|
|
<h2 class="text-center mb-3">Sandbox Execution Output</h2>
|
|
<?php echo $analysisResult; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<footer class="footer mt-auto py-3 bg-dark">
|
|
<div class="container text-center">
|
|
<span>© <?php echo date("Y"); ?> <?php echo htmlspecialchars($projectName); ?>. All Rights Reserved.</span>
|
|
<span class="mx-2">|</span>
|
|
<a href="#" data-bs-toggle="modal" data-bs-target="#termsModal">Terms of Service</a>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- Terms Modal -->
|
|
<div class="modal fade" id="termsModal" tabindex="-1" aria-labelledby="termsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="termsModalLabel">Terms of Service & Acceptable Use Policy</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>By using Luartex v3.2 ("the Service"), you agree to the following terms and conditions:</p>
|
|
<ul>
|
|
<li><strong>No Responsibility:</strong> The Service is provided "as is" without any warranties. We take no responsibility for any damage, data loss, or other issues caused by the use of this tool. You use it at your own risk.</li>
|
|
<li><strong>Lawful Use:</strong> You agree not to use the Service for any illegal activities or to analyze scripts for which you do not have proper authorization. This includes, but is not limited to, breaking platform policies, intellectual property infringement, or creating/analyzing malicious code for harmful purposes.</li>
|
|
<li><strong>Analysis & Deobfuscation:</strong> The deobfuscation and analysis tools are provided for security research and educational purposes only. They are intended to help developers and researchers understand and secure their own code or authorized codebases.</li>
|
|
<li><strong>Compliance:</strong> We reserve the right to suspend access to the Service for any user found to be violating these policies.</li>
|
|
</ul>
|
|
<p>You acknowledge and agree that you are solely responsible for your use of the Service and for any consequences thereof.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
|
</body>
|
|
</html>
|