ASSISTANT
Certainly! Here's the full code with the requested functionality integrated. This implementation ensures that your server only accepts POST requests to `/growtopia/server_data.php` and GET requests to `/cache` or `/0098`. Any other requests will receive a forbidden response.
```javascript
const https = require('https');
const httpProxy = require('http-proxy');
const url = require('url');
const path = require('path');
const fs = require('fs');
const os = require('os');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const chalk = require('chalk');
const { EventEmitter } = require('events');
const axios = require('axios');
const geoip = require('geoip-lite'); // Importing geoip-lite for GeoIP blocking
const exec = require('child_process').exec; // For executing shell commands
const dgram = require('dgram'); // Importing dgram for UDP handling
const basicAuth = require('express-basic-auth');
const helmet = require('helmet'); // For setting various HTTP headers for security
// Rate Limiting Configurations
const rateLimit = {};
const MAX_REQUESTS_PER_MINUTE = 100;
const BLOCK_TIME_MS = 60000;
// DNS attack prevention configurations
const dnsWhitelist = ['8.8.8.8', '1.1.1.1']; // Trusted DNS resolvers
const MAX_DNS_REQUESTS_PER_MINUTE = 50;
const dnsRateLimit = {};
// UDP Rate Limiting Configurations
const udpRateLimit = {};
const MAX_UDP_REQUESTS_PER_MINUTE = 100;
const UDP_BLOCK_TIME_MS = 60000;
// Network Usage Limiting Configurations
const networkUsage = {};
const MAX_BYTES_PER_MINUTE = 1024 * 1024;
const NETWORK_BLOCK_TIME_MS = 60000;
// Cloud Server IP Ranges
const cloudServerIpRanges = ['35.', '52.', '169.', '198.', '199.', '200.', '216.', '47.'];
// Allowed Countries for GeoIP
const allowedCountries = ['ID', 'SG', 'PH'];
const configApp = express();
const CONFIG_PORT = 6969;
// Middleware
configApp.use(helmet());
configApp.set('view engine', 'ejs');
configApp.use(bodyParser.urlencoded({ extended: true }));
configApp.use(express.static('public'));
// Allowed User-Agents (Whitelist)
const allowedUserAgents = [
'UbiServices_SDK_2022.Release.9_PC64_ansi_static',
'UbiServices_SDK_2022.Release.9_ANDROID64_static',
'UbiServices_SDK_2022.Release.9_ANDROID32_static',
'UbiServices_SDK_2022.Release.9_IOS64',
];
// Blocked User-Agents (Blacklist)
const blockedUserAgents = [
'curl',
'PostmanRuntime',
'Insomnia',
'HTTPie',
'Wget',
'Python-urllib',
];
// Function to check and update DNS rate limits
const isSuspiciousDNSRequest = (ip, requestUrl) => {
if (!requestUrl.toLowerCase().includes('dns')) return false;
if (!dnsWhitelist.includes(ip)) {
const now = Date.now();
if (!dnsRateLimit[ip]) {
dnsRateLimit[ip] = { count: 1, timestamp: now };
} else {
const timePassed = now - dnsRateLimit[ip].timestamp;
if (timePassed > BLOCK_TIME_MS) {
dnsRateLimit[ip] = { count: 1, timestamp: now };
} else {
dnsRateLimit[ip].count++;
}
if (dnsRateLimit[ip].count > MAX_DNS_REQUESTS_PER_MINUTE) {
return true;
}
}
}
return false;
};
// Function to check and update UDP rate limits
const isUdpRateLimited = (ip) => {
const now = Date.now();
if (!udpRateLimit[ip]) {
udpRateLimit[ip] = { count: 1, timestamp: now };
return false;
} else {
const timePassed = now - udpRateLimit[ip].timestamp;
if (timePassed > UDP_BLOCK_TIME_MS) {
udpRateLimit[ip] = { count: 1, timestamp: now };
return false;
} else {
udpRateLimit[ip].count++;
if (udpRateLimit[ip].count > MAX_UDP_REQUESTS_PER_MINUTE) {
return true;
}
}
}
return false;
};
// Function to check and update network usage
const isNetworkUsageLimited = (ip, bytes) => {
const now = Date.now();
if (!networkUsage[ip]) {
networkUsage[ip] = { sent: bytes, received: bytes, timestamp: now };
return false;
} else {
const timePassed = now - networkUsage[ip].timestamp;
if (timePassed > NETWORK_BLOCK_TIME_MS) {
networkUsage[ip] = { sent: bytes, received: bytes, timestamp: now };
return false;
} else {
networkUsage[ip].sent += bytes;
networkUsage[ip].received += bytes;
if (networkUsage[ip].sent > MAX_BYTES_PER_MINUTE || networkUsage[ip].received > MAX_BYTES_PER_MINUTE) {
return true;
}
}
}
return false;
};
// Function to log blocked IPs
const logBlockedIP = (ip, protocol = 'TCP', reason = 'Unknown') => {
fs.appendFile('blocked_ips.log', `${new Date().toISOString()} - Blocked IP: ${ip} [${protocol}] Reason: ${reason}\n`, (err) => {
if (err) console.error(chalk.red('Error logging blocked IP:'), err);
});
};
// Function to normalize IP addresses
const normalizeIp = (ip) => {
if (ip.startsWith("::ffff:")) {
return ip.substring(7);
}
if (ip === "::1") {
return "127.0.0.1";
}
return ip;
};
// Function to check if IP is from cloud/server ranges
const isCloudOrServerIp = (ip) => {
return cloudServerIpRanges.some((range) => ip.startsWith(range));
};
// Helper function to check GeoIP blocking
const isBlockedGeoIp = (ip) => {
const geo = geoip.lookup(ip);
if (geo && !allowedCountries.includes(geo.country)) {
return true;
}
return false;
};
// Function to animate loading
const animateLoading = async () => {
const frames = [
'\x1b[32m[■□□□□□□□□□]\x1b[0m',
'\x1b[32m[■■□□□□□□□□]\x1b[0m',
'\x1b[32m[■■■□□□□□□□]\x1b[0m',
'\x1b[32m[■■■■□□□□□□]\x1b[0m',
'\x1b[32m[■■■■■□□□□□]\x1b[0m',
'\x1b[32m[■■■■■■□□□□]\x1b[0m',
'\x1b[32m[■■■■■■■□□□]\x1b[0m',
'\x1b[32m[■■■■■■■■□□]\x1b[0m',
'\x1b[32m[■■■■■■■■■□]\x1b[0m',
'\x1b[32m[■■■■■■■■■■]\x1b[0m',
];
let i = 0;
const interval = setInterval(() => {
console.clear();
process.stdout.write(`${frames[i]}\r`);
i = (i + 1) % frames.length;
}, 300);
setTimeout(() => {
clearInterval(interval);
console.clear();
process.stdout.write('Loading complete!\n');
startServer();
}, 5000);
};
animateLoading();
const configPath = path.resolve(__dirname, './config/main.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
// Function to read configuration
const readConfig = () => {
try {
const data = fs.readFileSync(configPath, 'utf8');
return JSON.parse(data);
} catch (err) {
console.error(chalk.red('Error reading main.json:'), err);
return {};
}
};
// Function to write configuration
const writeConfig = (config) => {
try {
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
console.log(chalk.green('Configuration successfully updated.'));
} catch (err) {
console.error(chalk.red('Error writing to main.json:'), err);
}
};
// Middleware Authentication
configApp.use('/config', basicAuth({
users: { [config.username]: config.password }, // Use credentials from config
challenge: true,
realm: 'Config Area'
}));
// Route to display configuration form
configApp.get('/config', (req, res) => {
const config = readConfig();
res.render('config', { config });
});
// Route to process configuration changes
configApp.post('/config', (req, res) => {
const { ip, port, loginurl, cdn } = req.body;
const newConfig = { ip, port: parseInt(port), loginurl, cdn };
writeConfig(newConfig);
res.redirect('/config');
});
const synFloodTracker = {};
const MAX_SYN_REQUESTS = 10;
const SYN_BLOCK_TIME_MS = 60000;
const isSynFlood = (ip) => {
const now = Date.now();
if (!synFloodTracker[ip]) {
synFloodTracker[ip] = { count: 1, timestamp: now };
return false;
}
const timePassed = now - synFloodTracker[ip].timestamp;
if (timePassed > SYN_BLOCK_TIME_MS) {
synFloodTracker[ip] = { count: 1, timestamp: now };
return false;
} else {
synFloodTracker[ip].count++;
if (synFloodTracker[ip].count > MAX_SYN_REQUESTS) {
console.log(chalk.red(`SYN flood detected from IP: ${ip}`));
logBlockedIP(ip, 'SYN Flood', 'SYN Flood Attack Detected');
return true;
}
}
return false;
};
// Start UI Server
configApp.listen(CONFIG_PORT, () => {
console.log(chalk.blue(`Admin dashboard is running on http://localhost:${CONFIG_PORT}/config`));
});
// Fetch password from Pastebin
const fetchPassword = async () => {
try {
const response = await axios.get('https://pastebin.com/raw/xuWjQnYu');
return response.data.trim();
} catch (error) {
console.error(chalk.red('SERVER DOWN'));
process.exit(1);
}
};
// Prompt for password
const promptForPassword = async () => {
const password = await new Promise((resolve) => {
process.stdout.write('Enter password: ');
process.stdin.on('data', (data) => {
resolve(data.toString().trim());
});
});
const correctPassword = await fetchPassword();
if (password === correctPassword) {
console.log(chalk.green('Password correct. Starting server...'));
return true;
} else {
console.log(chalk.red('Incorrect password.'));
process.exit(1);
}
};
// Middleware to restrict access to specific paths and methods
const allowSpecificRequests = (req, res, next) => {
const allowedPaths = {
'/growtopia/server_data.php': 'POST', // Allow only POST
'/cache': 'GET', // Allow only GET
'/0098': 'GET', // If you want to include access to /0098 as well
};
const method = allowedPaths[req.url];
// Check if the URL is one we want to allow and if the method matches
if (method && req.method === method) {
return next(); // Allow the request through to actual handler
}
console.log(chalk.red(`Access denied for ${req.method} ${req.url} from IP: ${normalizeIp(req.connection.remoteAddress)}`));
logBlockedIP(normalizeIp(req.connection.remoteAddress), 'TCP-Method', `Invalid HTTP Method or URL: ${req.url}`);
res.statusCode = 403;
res.end('Forbidden: Access is denied.');
};
// Start Server Function
const startServer = async () => {
await promptForPassword();
const proxy = httpProxy.createProxyServer({});
const pk = fs.readFileSync(path.join(__dirname, 'server.key'));
const pc = fs.readFileSync(path.join(__dirname, 'server.crt'));
const optss = { key: pk, cert: pc };
const trustedIPs = ['127.0.0.1'];
const port = process.argv[2] || 443;
import('open').then(module => {
module.default(`http://localhost:${CONFIG_PORT}/config`);
}).catch(err => {
console.error(chalk.red('Failed to open admin dashboard automatically', err));
});
EventEmitter.defaultMaxListeners = 100;
const packet = `server|${config.ip}\nport|${config.port}\ntype|1\n#maint|Server is currently initializing or re-syncing with sub servers. Please try again in a minute.\n\n\nloginurl|${config.loginurl}\nbeta_server|127.0.0.1\nbeta_port|17091\nbeta_type|1\nbeta2_server|127.0.0.1\nbeta2_port|17099\nbeta2_type|1\nmeta|${Math.floor(Date.now() / 1000)}\nRTENDMARKERBS1001`;
const server = https.createServer(optss, function (req, res) {
allowSpecificRequests(req, res, () => {
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const normalizedIp = normalizeIp(ip);
console.log(chalk.green(`[DEVELOPER MODE]`, req.headers['user-agent']));
console.log(chalk.green(`Request received from IP: ${normalizedIp}`));
// **Start of Global User-Agent Check**
const userAgent = req.headers['user-agent'] || '';
const userAgentLower = userAgent.toLowerCase();
// Check if User-Agent is in allowed list
const isAllowedUA = allowedUserAgents.some(allowedUA => userAgentLower === allowedUA.toLowerCase());
if (!isAllowedUA) {
console.log(chalk.red(`Blocked connection from IP: ${normalizedIp} due to disallowed User-Agent: ${userAgent}`));
logBlockedIP(normalizedIp, 'TCP-UserAgent', 'Disallowed User-Agent');
req.socket.destroy(); // Immediately close the connection
return;
}
// **End of Global User-Agent Check**
if (isSynFlood(ip)) {
req.socket.destroy();
return;
}
// Rate Limiting Logic
if (!rateLimit[normalizedIp]) {
rateLimit[normalizedIp] = { count: 1, timestamp: Date.now() };
} else {
const currentTime = Date.now();
const timePassed = currentTime - rateLimit[normalizedIp].timestamp;
// Reset count if more than 1 minute has passed
if (timePassed > BLOCK_TIME_MS) {
rateLimit[normalizedIp] = { count: 1, timestamp: currentTime };
} else {
rateLimit[normalizedIp].count++;
}
// Check if the limit is reached
if (rateLimit[normalizedIp].count > MAX_REQUESTS_PER_MINUTE) {
console.log(chalk.red(`Rate limit exceeded for IP: ${normalizedIp}`));
logBlockedIP(normalizedIp, 'TCP', 'Rate Limit Exceeded');
res.statusCode = 429; // Too Many Requests
res.end('Too many requests. Your connection is being throttled.');
return;
}
}
// DNS attack protection
if (isSuspiciousDNSRequest(normalizedIp, req.url)) {
console.log(chalk.red(`DNS DDoS detected from IP: ${normalizedIp}`));
logBlockedIP(normalizedIp, 'TCP-DNS', 'DNS DDoS Attack');
res.statusCode = 403; // Forbidden
res.end('Forbidden: DNS DDoS attack detected.');
return;
}
// Network Usage Limiting for TCP
const requestBytes = Buffer.byteLength(req.url); // Approximate
if (isNetworkUsageLimited(normalizedIp, requestBytes)) {
console.log(chalk.red(`Network usage limit exceeded for IP: ${normalizedIp} (TCP)`));
logBlockedIP(normalizedIp, 'TCP-NETWORK', 'Network Usage Limit Exceeded');
res.statusCode = 429; // Too Many Requests
res.end('Too many requests. Your connection is being throttled.');
return;
}
// Check for cloud or server IP range
if (!trustedIPs.includes(normalizedIp) && isCloudOrServerIp(normalizedIp)) {
console.log(chalk.red(`Blocking cloud/server IP: ${normalizedIp}`));
logBlockedIP(normalizedIp, 'TCP-Cloud', 'Cloud/Server IP Blocked');
res.statusCode = 403;
res.end('Forbidden: Access from cloud/server IP is blocked.');
return;
}
// Check for GeoIP block
if (isBlockedGeoIp(normalizedIp)) {
console.log(chalk.red(`Blocking access from IP: ${normalizedIp} (GeoIP Block)`));
logBlockedIP(normalizedIp, 'TCP-GeoIP', 'GeoIP Block');
res.statusCode = 403;
res.end('Forbidden: Access from your location is blocked.');
return;
}
const parsedUrl = url.parse(req.url);
const pathname = `.${parsedUrl.pathname}`;
const ext = path.parse(pathname).ext;
console.log(chalk.blue(`Connection Request from: ${normalizedIp} URL: ${req.url} Method: ${req.method}`));
const map = {
'.ico': 'image/x-icon',
'.html': 'text/html',
'.js': 'text/javascript',
'.json': 'application/json',
'.css': 'text/css',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.wav': 'audio/wav',
'.mp3': 'audio/mpeg',
'.svg': 'image/svg+xml',
'.pdf': 'application/pdf',
'.doc': 'application/msword'
};
// Handle /growtopia/server_data.php - Only POST and allowed User-Agents
if (req.url === "/growtopia/server_data.php") {
// **Start of Endpoint-Specific User-Agent Check**
const specificUserAgent = req.headers['user-agent'] || '';
const specificUserAgentLower = specificUserAgent.toLowerCase();
// Check against blocked User-Agents using partial matching
const isBlockedUA = blockedUserAgents.some(blockedUA => specificUserAgentLower.includes(blockedUA.toLowerCase()));
if (isBlockedUA) {
console.log(chalk.red(`Blocked /growtopia/server_data.php access from IP: ${normalizedIp} using blocked User-Agent: ${specificUserAgent}`));
logBlockedIP(normalizedIp, 'TCP-UserAgent', 'Blocked Tool User-Agent for server_data.php');
req.socket.destroy(); // Immediately close the connection
return;
}
// **End of Endpoint-Specific User-Agent Check**
// Check if method is POST
if (req.method !== 'POST') {
console.log(chalk.red(`Blocked: Invalid method for ${req.url}`));
logBlockedIP(normalizedIp, 'TCP-Method', 'Invalid HTTP Method for server_data.php');
res.statusCode = 403;
res.end('Forbidden: Only POST requests allowed.');
return;
}
res.write(packet, function (err) {
if (err) console.log(chalk.red(err));
});
res.end();
}
// Handle /cache and /0098 - Only GET and allowed User-Agents
else if (req.url.indexOf("/cache") !== -1 || req.url.indexOf("/0098") !== -1) {
if (req.method !== 'GET') {
console.log(chalk.red(`Blocked: Invalid method for ${req.url}`));
logBlockedIP(normalizedIp, 'TCP-Method', 'Invalid HTTP Method for cache/0098');
res.statusCode = 403;
res.end('Forbidden: Only GET requests allowed.');
return;
}
console.log(chalk.blue(`[CACHE-SPEED] Connection from: ${normalizedIp}\n Downloading assets: ${req.url}`));
fs.exists(pathname, function (exist) {
if (!exist) {
res.statusCode = 301;
res.writeHead(301, {
Location: `https://ubistatic-a.akamaihd.net/${config.cdn}${req.url}`
}).end();
return;
}
fs.readFile(pathname, function (err, data) {
if (err) {
res.statusCode = 404;
res.end(`error`);
} else {
res.setHeader('Content-type', map[ext] || 'text/plain');
res.end(data);
}
});
});
}
// Block all other requests
else {
console.log(chalk.red(`🛡 [PROTECTION] Blocked request: ${req.method} ${req.url} from IP: ${normalizedIp}`));
logBlockedIP(normalizedIp, 'TCP-Other', 'Unhandled Endpoint');
res.statusCode = 403;
res.end('Forbidden: Access is denied.');
}
});
});
server.listen(port, () => {
console.log(chalk.green(`HTTPS Server is running on port ${port}`));
});
// -------------------- UDP Server Setup --------------------
const udpServer = dgram.createSocket('udp4');
const UDP_PORT = 53; // DNS typically uses port 53
udpServer.on('error', (err) => {
console.error(`UDP server error:\n${err.stack}`);
udpServer.close();
});
udpServer.on('message', (msg, rinfo) => {
const ip = rinfo.address;
const normalizedIp = normalizeIp(ip);
console.log(chalk.yellow(`UDP request from IP: ${normalizedIp}, Port: ${rinfo.port}`));
// Rate Limiting
if (isUdpRateLimited(normalizedIp)) {
console.log(chalk.red(`UDP Rate limit exceeded for IP: ${normalizedIp}`));
logBlockedIP(normalizedIp, 'UDP', 'UDP Rate Limit Exceeded');
return; // Drop the packet silently or send a response indicating rate limiting
}
// GeoIP Blocking
if (isBlockedGeoIp(normalizedIp)) {
console.log(chalk.red(`Blocking UDP access from IP: ${normalizedIp} (GeoIP Block)`));
logBlockedIP(normalizedIp, 'UDP-GeoIP', 'GeoIP Block');
return; // Drop the packet silently or send a forbidden response
}
// Network Usage Limiting for UDP
const messageBytes = msg.length;
if (isNetworkUsageLimited(normalizedIp, messageBytes)) {
console.log(chalk.red(`Network usage limit exceeded for IP: ${normalizedIp} (UDP)`));
logBlockedIP(normalizedIp, 'UDP-NETWORK', 'UDP Network Usage Limit Exceeded');
return; // Drop the packet
}
// Implement your DNS handling logic here
// For example, respond with a simple DNS response or forward the request to a legitimate DNS server
// Example: Forward the DNS request to an external DNS server (e.g., Google DNS)
const externalDns = '8.8.8.8';
const externalDnsPort = 53;
const externalClient = dgram.createSocket('udp4');
externalClient.send(msg, 0, msg.length, externalDnsPort, externalDns, (error) => {
if (error) {
console.error(`Error forwarding UDP request: ${error}`);
externalClient.close();
}
});
externalClient.on('message', (response) => {
udpServer.send(response, 0, response.length, rinfo.port, rinfo.address, (err) => {
if (err) {
console.error(`Error sending UDP response: ${err}`);
}
externalClient.close();
});
});
// Optional: Implement timeouts to prevent hanging
externalClient.on('error', (err) => {
console.error(`External DNS client error: ${err}`);
externalClient.close();
});
// Set a timeout for the external DNS response
externalClient.setTimeout(5000, () => { // 5 seconds timeout
console.error(`External DNS request timed out for IP: ${normalizedIp}`);
externalClient.close();
});
});
udpServer.on('listening', () => {
const address = udpServer.address();
console.log(chalk.green(`UDP Server listening on ${address.address}:${address.port}`));
});
udpServer.bind(UDP_PORT);
// ---------------------------------------------------------
console.log('')
console.log(chalk.magenta('========================================================'));
console.log(chalk.magenta(`- CONFIGURATION LOADS : `));
console.log(chalk.magenta(`[@] Login URL : ${config.loginurl}`));
console.log(chalk.magenta(`[@] HTTP Port ${port}`));
console.log(chalk.magenta(`[@] ANTI-HOSTCHECK ${port}`));
console.log(chalk.magenta(`[@] ANTI-SCAN SERVER DATA PHP STATUS : ENABLED [PENTEST-SECURITY]`));
console.log(chalk.magenta(`[@] OPERATION SYSTEM : WINDOWS`));
console.log(chalk.magenta(`[@] HTTP KING VERSION : 3.3.8`));
console.log(chalk.greenBright(`[@] SUBSCRIPTION : VIP-SUPER`));
console.log(chalk.greenBright(`[@] LAST HTTP UPDATE : 6/10/2024`));
console.log(chalk.magenta('========================================================'));
console.log('')
console.log(chalk.green(`
::: ::: ::::::::::: :::: ::: :::::::: ::: ::: :::::::: ::::::::
:+: :+: :+: :+:+: :+: :+: :+: :+: :+: :+: :+: :+: :+:
+:+ +:+ +:+ :+:+:+ +:+ +:+ +:+ +:+ +:+ +:+
+#++:++ +#+ +#+ +:+ +#+ :#: +#+ +:+ +#++: +#++:
+#+ +#+ +#+ +#+ +#+#+# +#+ +#+# +#+ +#+ +#+ +#+
#+# #+# #+# #+# #+#+# #+# #+# #+#+# #+# #+# #+# #+#
### ### ########### ### #### ######## ### ######## ########
`));
};
// Execute the startServer function after loading is complete
```
### Key Components
- **`allowSpecificRequests` Middleware**: This function ensures that only specified endpoints (`/growtopia/server_data.php` with POST and `/cache` or `/0098` with GET) are accessible. All other requests will receive a `403 Forbidden` response.
- **Response Logic**: The server logic is structured to respond with specific handling for allowed paths, ensuring minimal exposure and maximum security.
- **Security Controls**: Other middleware functions, such as for rate limiting, network usage limits, and IP checks, are in place to add additional layers of protection.
This configuration should enforce strict route accessibility on the server, respecting your specific requirements for handling requests at port 443 securely.