From 53df135696c777034d172530c4446d8fc1374db2 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Sun, 30 Nov 2025 01:02:42 +0800 Subject: [PATCH] add check wxmsg --- src/modules/html/index.ts | 1 + src/modules/html/robot.ts | 15 ++ src/modules/off/ban.ts | 44 ++++ src/modules/off/index.ts | 3 + src/modules/off/off-link.ts | 330 ++++++++++++++++++++++++++++ src/modules/user-app/index.ts | 1 + src/routes-simple/handle-request.ts | 1 + src/routes-simple/page-proxy.ts | 32 ++- 8 files changed, 418 insertions(+), 9 deletions(-) create mode 100644 src/modules/html/index.ts create mode 100644 src/modules/html/robot.ts create mode 100644 src/modules/off/ban.ts create mode 100644 src/modules/off/index.ts create mode 100644 src/modules/off/off-link.ts diff --git a/src/modules/html/index.ts b/src/modules/html/index.ts new file mode 100644 index 0000000..5ecc7d7 --- /dev/null +++ b/src/modules/html/index.ts @@ -0,0 +1 @@ +export * from './robot.ts'; \ No newline at end of file diff --git a/src/modules/html/robot.ts b/src/modules/html/robot.ts new file mode 100644 index 0000000..5fe6953 --- /dev/null +++ b/src/modules/html/robot.ts @@ -0,0 +1,15 @@ +export const robotsTxt = `User-agent: * +Disallow: /admin/ +Disallow: /config/ +Disallow: /settings/ +Disallow: /private/ +Disallow: /secret/ +Disallow: /.git/ +Disallow: /.env +Disallow: /backup/ +Disallow: /backups/ +Disallow: /logs/ +Disallow: /log/ +Disallow: /tmp/ +Disallow: /plus/ +`; diff --git a/src/modules/off/ban.ts b/src/modules/off/ban.ts new file mode 100644 index 0000000..6315c90 --- /dev/null +++ b/src/modules/off/ban.ts @@ -0,0 +1,44 @@ +// 常备黑的 http://web/ban/ +// 禁止使用这些用户名注册 +// 容易被黑客扫描, 也容易被滥用 +// +export const bannedUserNames = [ + "admin", // 常见管理员名 + "user", // 常见用户名 + "guest", // 常见访客名 + "core", // 常见系统名 + "config", // 配置相关 + "system", // 系统相关 + "setting", // 设置相关 + "storage", // 存储相关 + "logs", // 日志相关 + "log", // 日志相关 + "backup", // 备份相关 + "backups", // 备份相关 + "tmp", // 临时相关 +] + +/** + * 检查用户名是否在禁止列表中 + * @param username + * @returns + */ +export const userIsBanned = (username: string): boolean => { + if (username.startsWith('.')) { + return true; + } + if (username.endsWith('.')) { + return true; + } + return bannedUserNames.includes(username.toLowerCase()); +} + +export const appIsBanned = (appname: string): boolean => { + if (appname.startsWith('.')) { + return true; + } + if (appname.endsWith('.')) { + return true; + } + return false; +} \ No newline at end of file diff --git a/src/modules/off/index.ts b/src/modules/off/index.ts new file mode 100644 index 0000000..afe9c67 --- /dev/null +++ b/src/modules/off/index.ts @@ -0,0 +1,3 @@ +export * from './off-link.ts' + +export * from './ban.ts' \ No newline at end of file diff --git a/src/modules/off/off-link.ts b/src/modules/off/off-link.ts new file mode 100644 index 0000000..8fb1ad6 --- /dev/null +++ b/src/modules/off/off-link.ts @@ -0,0 +1,330 @@ +/** + * 黑客敏感文件爬取清单(TS 配置版) + * + * 黑客在渗透测试或自动化扫描中,会优先爬取以下敏感文件和目录, + * 以获取系统配置、凭证、密钥、数据库连接、源码泄露等高价值信息。 + * 本列表按类别组织,便于安全审计、WAF规则、防御系统匹配。 + * + * 注意:实际攻击中,黑客常使用工具如 dirsearch、gobuster、nuclei、Burp Suite 等进行批量扫描。 + */ + +// ======================== +// 🌐 环境变量配置文件(最常见目标) +// ======================== +// 黑客优先扫描 .env 文件,因其中常包含数据库密码、API密钥、JWT密钥、云服务凭证等 +const envFiles = [ + ".env", + ".env.local", + ".env.development", + ".env.production", + ".env.example", + ".env.dist", + ".env.sample", + ".env.backup", + ".env.bak", + ".env.old", + ".env.txt" +]; + +// ======================== +// ⚙️ 应用配置文件(框架/语言相关) +// ======================== +// 不同语言/框架的配置文件,常暴露数据库连接、密钥、调试开关 +const configFiles = [ + // Node.js / JavaScript + "config.js", + "config.json", + "config.ts", + "config.yaml", + "config.yml", + "settings.js", + "settings.json", + "appsettings.json", + "server.js", + "server.ts", + + // PHP + "config.php", + "wp-config.php", // WordPress 核心配置,含数据库凭证 + "database.php", + "settings.php", + "app.php", + "bootstrap.php", + "config.ini", + + // Python + "settings.py", + "config.py", + "local_settings.py", + "secrets.py", + "django_settings.py", + "flask_config.py", + + // Java / Spring + "application.properties", + "application.yml", + "application-dev.properties", + "application-prod.properties", + + // .NET + "appsettings.json", + "web.config", + "app.config", + + // Go + "config.yaml", + "config.json", + "config.toml", + + // Node + ".npmrc", + ".yarnrc", + ".yarnrc.yml" +]; + +// ======================== +// 🐳 容器与部署配置 +// ======================== +// Dockerfile、docker-compose 等文件可能暴露端口、挂载路径、密钥注入方式 +const dockerFiles = [ + "Dockerfile", + "Dockerfile.prod", + "Dockerfile.dev", + "docker-compose.yml", + "docker-compose.yaml", + "docker-compose.prod.yml", + "docker-compose.dev.yml", + "docker-compose.override.yml", + ".dockerignore" +]; + +// ======================== +// 💾 备份与临时文件(高危!常被忽略) +// ======================== +// 黑客专门扫描备份文件,因开发者常忘记删除,其中包含原始敏感数据 +const backupFiles = [ + // 通用备份 + "*.bak", + "*.backup", + "*.old", + "*.tmp", + "*.swp", + "*.swo", + "~", + + // 具体文件类型备份 + ".env.bak", + ".env.backup", + ".env.old", + "config.php.bak", + "wp-config.php.bak", + "database.sql", + "database.sql.bak", + "database.dump", + "db.sql", + "db_backup.sql", + "backup.zip", + "backup.tar.gz", + "backup.tar", + "backup.rar" +]; + +// ======================== +// 🛠️ 管理面板与控制台文件(视具体项目而定) +// ======================== +// 某些项目可能包含自定义管理面板,黑客会尝试爬取这些路径 +const adminFiles = [ + "admin/", + "administrator/", + "admin.php", + "admin.html", + "controlpanel/", + "cpanel/", + "manage/", + "dashboard/", + "console/" +] +// ======================== +// 📜 日志文件(泄露调试信息、路径、错误堆栈) +// ======================== +// 日志文件常包含敏感错误信息、堆栈追踪、数据库查询、用户输入等 +const logFiles = [ + "logs/", + "log/", + "storage/logs/", + "app/logs/", + "var/log/", + "logs/error.log", + "logs/access.log", + "logs/debug.log", + "logs/app.log", + "runtime/logs/*.log", + "nginx/error.log", + "nginx/access.log", + "apache/error.log", + "apache/access.log", + "php_error.log", + "debug.log", + "system.log" +]; + +// ======================== +// 🌐 WordPress 特有敏感文件 +// ======================== +// WordPress 是最常被攻击的 CMS,黑客会扫描其专属配置与插件 +const wordpressFiles = [ + "wp-config.php", + "wp-admin/", + "wp-login.php", + "wp-content/uploads/", + "wp-content/plugins/", + "wp-content/themes/", + "readme.html", + "license.txt", + "xmlrpc.php", + "wp-includes/", + "wp-json/wp/v2/users" // API 接口,可枚举用户 +]; + +// ======================== +// 🔐 密钥与凭证文件(最高优先级) +// ======================== +// 包含私钥、公钥、令牌、证书等,泄露即等于系统沦陷 +const secretFiles = [ + "id_rsa", + "id_rsa.pub", + "authorized_keys", + "known_hosts", + "ssh_config", + "config", + "credentials", + "secrets.json", + "secrets.yaml", + "secrets.yml", + "key.pem", + "cert.pem", + "certificate.crt", + "private.key", + "public.key", + "token", + "access_token", + "refresh_token", + "oauth_token", + "jwt.key", + "jwt.secret", + "api_key", + "apikey", + "API_KEY", + "SECRET_KEY", + "ACCESS_KEY", + "SECRET", + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY", + "GOOGLE_API_KEY", + "TWILIO_ACCOUNT_SID", + "TWILIO_AUTH_TOKEN", + "STRIPE_SECRET_KEY", + "SENDGRID_API_KEY", + "DATABASE_URL", + "MONGODB_URI", + "REDIS_URL" +]; + +// ======================== +// 🧩 .git 仓库泄露(致命!可还原完整源码) +// ======================== +// 黑客利用 .git 目录泄露,通过 git-dumper、GitTools 等工具还原整个项目源码 +const gitFiles = [ + ".git/", + ".git/config", + ".git/HEAD", + ".git/index", + ".git/objects/", + ".git/refs/", + ".git/refs/heads/", + ".git/refs/remotes/", + ".git/FETCH_HEAD", + ".git/COMMIT_EDITMSG", + ".git/logs/HEAD", + ".gitignore", // 虽非敏感,但可辅助判断项目结构 + ".gitattributes" +]; + +// ======================== +// 🧱 通用敏感文件(跨平台高危) +// ======================== +// 常见于各类项目中,黑客通用扫描项 +const commonSensitiveFiles = [ + "README.md", + "LICENSE", + "package.json", + "package-lock.json", + "yarn.lock", + "composer.json", + "composer.lock", + "requirements.txt", + "Pipfile", + "Pipfile.lock", + "Gemfile", + "Gemfile.lock", + "manifest.json", + "robots.txt", // 可能暴露隐藏路径 + "sitemap.xml", + "crossdomain.xml", + "client-secrets.json", // Google OAuth + "firebase.json", + "netlify.toml", + "vercel.json", + + // 邮件配置文件 + "mailsettings.json", + "smtp.config", + "email.config", + "brevo", +]; + +// ======================== +// 🚨 汇总:所有敏感文件路径(供安全系统统一调用) +// ======================== +// 将所有类别合并为一个全量列表,便于 WAF、IDS、扫描器使用 +export const ALL_SENSITIVE_FILES = [ + ...envFiles, + ...configFiles, + ...dockerFiles, + ...backupFiles, + ...adminFiles, + ...logFiles, + ...wordpressFiles, + ...secretFiles, + ...gitFiles, + ...commonSensitiveFiles +]; + +// ======================== +// 📌 使用建议 +// ======================== +// 1. 在 Nginx/Apache 中禁止访问上述文件/目录 +// 2. 在 CI/CD 中禁止提交 .env、*.bak、.git 等文件 +// 3. 使用 .gitignore 正确排除敏感文件 +// 4. 使用安全扫描工具(如 Trivy、Semgrep、Snyk)定期检测 +// 5. 生产环境禁止暴露 .env、wp-config.php、.git 等文件 +// +// ✅ 安全实践:所有敏感文件应存储在服务器外部,通过环境变量注入 + +/** + * 快速查看是否被攻击者爬取了敏感文件 + * @param filePath + */ +export const hasBadUser = (filePath: string): boolean => { + return ALL_SENSITIVE_FILES.some(sensitivePath => { + // 精确匹配或通配符匹配 + if (sensitivePath.includes('*')) { + // 转换通配符为正则表达式 + const regexStr = sensitivePath.replace(/\./g, '\\.').replace(/\*/g, '.*'); + const regex = new RegExp(`^${regexStr}$`); + return regex.test(filePath); + } else { + return filePath === sensitivePath; + } + }); +} \ No newline at end of file diff --git a/src/modules/user-app/index.ts b/src/modules/user-app/index.ts index 82c29cb..cbdc749 100644 --- a/src/modules/user-app/index.ts +++ b/src/modules/user-app/index.ts @@ -128,6 +128,7 @@ export class UserApp { const fetchRes = await fetchDomain(domain).catch((err) => { return { code: 500, + data: null, message: err, }; }); diff --git a/src/routes-simple/handle-request.ts b/src/routes-simple/handle-request.ts index 3defce4..4f86487 100644 --- a/src/routes-simple/handle-request.ts +++ b/src/routes-simple/handle-request.ts @@ -177,6 +177,7 @@ const simpleAppsPrefixs = [ "/api/s1/", "/api/container/", "/api/resource/", + "/api/wxmsg" ]; export const handleRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => { diff --git a/src/routes-simple/page-proxy.ts b/src/routes-simple/page-proxy.ts index 2ef5bef..ed6fa7c 100644 --- a/src/routes-simple/page-proxy.ts +++ b/src/routes-simple/page-proxy.ts @@ -13,6 +13,8 @@ import { getLoginUser } from '../modules/auth.ts'; import { rediretHome } from '../modules/user-app/index.ts'; import { logger } from '../modules/logger.ts'; import { UserV1Proxy } from '../modules/ws-proxy/proxy.ts'; +import { hasBadUser, userIsBanned, appIsBanned } from '@/modules/off/index.ts'; +import { robotsTxt } from '@/modules/html/index.ts'; const domain = config?.proxy?.domain; const allowedOrigins = config?.proxy?.allowedOrigin || []; @@ -22,14 +24,6 @@ const notAuthPathList = [ user: 'root', paths: ['center'], }, - { - user: 'admin', - paths: ['center'], - }, - { - user: 'user', - paths: ['login'], - }, { user: 'public', paths: ['center'], @@ -53,6 +47,12 @@ const checkNotAuthPath = (user, app) => { }); return notAuthPath; }; +const forBadUser = (req: http.IncomingMessage, res: http.ServerResponse) => { + // TODO: 记录日志,封禁IP等操作 + const dns = getDNS(req); + logger.warn(`Bad user access from IP: ${dns.ip}, Host: ${dns.hostName}, URL: ${req.url}`); + // 这里可以添加更多的处理逻辑,比如封禁IP等 +} export const handleRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => { const querySearch = new URL(req.url, `http://${req.headers.host}`).searchParams; const password = querySearch.get('p'); @@ -153,6 +153,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR console.error('Invalid domain: ', req.url, dns.hostName); res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Invalid domain\n'); + forBadUser(req, res); return res.end(); } // 验证域名 @@ -198,9 +199,18 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR // 原始url地址 const urls = url.split('/'); if (urls.length < 3) { - console.log('urls errpr', urls); + const [_, _user] = urls; + if (_user === 'robots.txt') { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(robotsTxt); + return; + } + console.log('urls error', urls, 'originUrl:', url); res.writeHead(404, { 'Content-Type': 'text/html' }); res.write('Invalid Proxy URL\n'); + if (hasBadUser(_user)) { + forBadUser(req, res); + } return res.end(); } const [_, _user, _app] = urls; @@ -244,6 +254,10 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR const userApp = new UserApp({ user, app }); let isExist = await userApp.getExist(); logger.debug('userApp', userApp, isExist); + if (userIsBanned(user) || appIsBanned(app)) { + forBadUser(req, res); + return createErrorPage(); + } if (!isExist) { try { const { code, loading, message } = await userApp.setCacheData();