add check wxmsg

This commit is contained in:
2025-11-30 01:02:42 +08:00
parent f9169bcd8b
commit 53df135696
8 changed files with 418 additions and 9 deletions

View File

@@ -0,0 +1 @@
export * from './robot.ts';

15
src/modules/html/robot.ts Normal file
View File

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

44
src/modules/off/ban.ts Normal file
View File

@@ -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;
}

3
src/modules/off/index.ts Normal file
View File

@@ -0,0 +1,3 @@
export * from './off-link.ts'
export * from './ban.ts'

330
src/modules/off/off-link.ts Normal file
View File

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

View File

@@ -128,6 +128,7 @@ export class UserApp {
const fetchRes = await fetchDomain(domain).catch((err) => {
return {
code: 500,
data: null,
message: err,
};
});

View File

@@ -177,6 +177,7 @@ const simpleAppsPrefixs = [
"/api/s1/",
"/api/container/",
"/api/resource/",
"/api/wxmsg"
];
export const handleRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => {

View File

@@ -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();