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