xDefcon / sinusbot-scripts

Scripts for SinusBot (sinusbot.com)
GNU General Public License v3.0
14 stars 10 forks source link

New Features #14

Closed vbrown37 closed 6 years ago

vbrown37 commented 6 years ago

/*

registerPlugin({ name: 'AntiProxy - VPN/Proxy Blocker', version: '1.2', description: 'AntiProxy Script by xdefcon', author: 'xdefcon', vars: { enableSwitch: { title: 'Activate the script?', type: 'select', options: ['no', 'yes'] }, debugSwitch: { title: 'Enable debug messages?', type: 'select', options: ['no', 'yes'] }, punishment: { title: 'Punishment when a proxy is detected', type: 'select', options: ['poke', 'kick', 'tempban', 'chatmessage', 'none (notify admins only)'] }, tempBanDuration: { title: "Temp ban duration in seconds", type: 'number', conditions: [{field: 'punishment', value: 2}] }, punishmentMessage: { title: "Punishment message (kick, poke, ban)", type: 'string', placeholder: "Proxy/VPN detected. Error? Contact: luigi@xdefcon.com or admin" }, notifyOnDetection: { title: 'Notify Admins when a proxy is detected?', type: 'select', options: ['no', 'yes'] }, permissionsMessage: { title: "Not enough permissions message", type: 'string', placeholder: "You don't have enough permissions to execute this command." }, admins: { title: "Admin Unique IDs used to send important notifications", type: "array", vars: [{ name: 'adminUID', indent: 1, title: 'Admin Client UID', type: 'string' }] }, adminGroups: { title: "Admin Group IDs used to send important notifications", type: "array", vars: [{ name: 'groupID', indent: 1, title: 'Admin Group ID', type: 'number' }] }, whitelist: { title: "Whitelist of IP addresses (Please report to lugi@xdefcon.com if false detection, this is a quick fix.)", type: "array", vars: [{ name: "address", indent: 1, title: "Client IP address to whitelist", type: "string" }] }, prefix: { title: "Prefix before messages", type: "string", placeholder: "[b][AntiProxy][b]" }, theme: { title: "Color of messages", type: "string", placeholder: "[color=black]" }
} }, function (sinusbot, config) { if (typeof config.enableSwitch == 'undefined') { config.enableSwitch = 1; } if (typeof config.debugSwitch == 'undefined') { config.debugSwitch = 0; } if (typeof config.punishment == 'undefined') { config.punishment = 1; } if (typeof config.punishmentMessage == 'undefined' || config.punishmentMessage == "") { config.punishmentMessage = "Proxy/VPN detected. Error? Contact: luigi@xdefcon.com or admin"; } if (typeof config.notifyOnDetection == 'undefined') { config.notifyOnDetection = 1; } if (typeof config.permissionsMessage == 'undefined') { config.permissionsMessage = "You don't have enough permissions to execute this command."; } if (config.punishment == 2 && typeof config.tempBanDuration == 'undefined') { config.tempBanDuration = 10; } if (typeof config.adminGroups == 'undefined') { config.adminGroups = []; } if (typeof config.admins == 'undefined') { config.admins = []; } if (typeof config.whitelist == 'undefined') { config.whitelist = []; } if (typeof config.prefix == 'undefined') { config.prefix = "[b][AntiProxy][b]"; } if (typeof config.theme == 'undefined') { config.prefix = "[color=black]"; }

var event = require("event");
var engine = require("engine");
var backend = require("backend");
var localProxies = {};
var rateLimited = false;

var startedTime = config.enableSwitch == 1 ? Date.now() : null;
var checkedIps = 0;
var detectedProxies = 0;
var apiRequests = 0;
var lastDetection = {
    client: null,
    ip: null
};

setInterval(function() {
    debug("Executing automatic purge of the local IP cache.");
    localProxies = {};
}, 86400000);

event.on("chat", function (ev) {
    var message = ev.text;
    var client = ev.client;
    if (client.isSelf()) {
        return;
    }

    switch (message) {
        case "!antiproxy enable":
            if (!checkPermissions(client)) {
                client.chat(config.permissionsMessage);
                return;
            }
            if (config.enableSwitch == 0) {
                config.enableSwitch = 1;
                startedTime = Date.now();
                rateLimited = false;
                client.chat(config.prefix + "Successfully enabled AntiProxy script.");
                debug("Enabling script by command.");
            } else {
                client.chat(config.prefix + "he script is already enabled, type '[b]" + config.theme + "!antiproxy disable[/color][/b]' to disable it.");
            }
            break;
        case "!antiproxy disable":
            if (!checkPermissions(client)) {
                client.chat(config.permissionsMessage);
                return;
            }
            if (config.enableSwitch == 1) {
                config.enableSwitch = 0;
                startedTime = null;
                client.chat(config.prefix + "Successfully disabled AntiProxy script.");
                debug("Disabling script by command.");
            } else {
                client.chat(config.prefix + "The script is already disabled, type '[b]" + config.theme + "!antiproxy enable[/color][/b]' to enable it.");
            }
            break;
        case "!antiproxy info":
            if (!checkPermissions(client)) {
                client.chat(config.permissionsMessage);
                return;
            }
            client.chat("\n" + config.prefix + " [b]AntiProxy by xDefcon[/b]\n" +
                config.prefix + " [b]Running time[/b]: " + ((Date.now() - startedTime) / 1000).toString() + "secs\n" +
                config.prefix + " [b]Proxies detected[/b]: " + detectedProxies + "\n" +
                config.prefix + " [b]Last detection[/b]: " + lastDetection.client + " " + lastDetection.ip + "\n" +
                config.prefix + " [b]Checked IPs[/b]: " + checkedIps + "\n" +
                config.prefix + " [b]IP cached locally[/b]: " + Object.keys(localProxies).length + "\n" +
                config.prefix + " [b]API requests[/b]: " + apiRequests + "\n");
            break;
        case "!antiproxy purgecache":
            if (!checkPermissions(client)) {
                client.chat(config.permissionsMessage);
                return;
            }
            localProxies = {};
            client.chat(config.prefix + " Successfully purged the local IP cache.");
            break;
        case "!antiproxy checkall":
            if (!checkPermissions(client)) {
                client.chat(config.permissionsMessage);
                return;
            }
            client.chat(config.prefix + " Checking all clients now connected to the TeamSpeak server.");
            checkAllClients();
            client.chat(config.prefix + " All clients checked.");
            break;
        case "!antiproxy commands":
            if (!checkPermissions(client)) { 
                client.chat(config.permissionsMessage) 
                return;
            }
            client.chat("\n" + config.prefix + " [b]AntiProxy Commands[/b]\n" +
                config.prefix + " [b]!antiproxy info[/b]: Give AntiProxy Infos.\n" +
                config.prefix + " [b]!antiproxy enable[/b]: Enable the script.\n" +
                config.prefix + " [b]!antiproxy disable[/b]: Disable the script.\n" +
                config.prefix + " [b]!antiproxy checkall[/b]: Checks all client connected.\n" +
                config.prefix + " [b]!antiproxy manual[/b]: Manually scan IP.\n");
            break;
        case "!antiproxy manual":
            if (!checkPermissions(client)) { 
                client.chat(config.permissionsMessage) 
                return;
            }
            client.chat("\n" + config.prefix + " [b]AntiProxy Manual[/b]\n" +
                config.prefix + " [b]Info[/b]: You can scan IPs just by adding them at the end of the link !\n" +
                config.prefix + " [b]Link[/b]: [url]https://api.xdefcon.com/proxy/check/?ip=[/url]\n" +
                config.prefix + " [b]Exemple[/b]: https://api.xdefcon.com/proxy/check/?ip=[b]12.123.123.123[/b]\n");                                       
            break;        
    }
});

event.on("clientIPAddress", function (client) {
    if (config.enableSwitch == 0) {
        return;
    }
    if (client.isSelf()) {
        return;
    }
    debug("Fired clientIPAddress - Client: " + client.name() + " [" + client.getIPAddress() + "].");
    checkForProxy(client);
});

function checkPermissions(client) {
    var check = false;
    for (var i = 0; i < config.admins.length; i++) {
        if (config.admins[i].adminUID == client.uniqueID()) {
            check = true;
            break;
        }
    }
    if (!check) {
        var clientGroups = [];
        var serverGroups = client.getServerGroups();
        for (var j = 0; j < serverGroups.length; j++) {
            clientGroups[j] = "" + serverGroups[j].id();
        }
        for (i = 0; i < config.adminGroups.length; i++) {
            if (clientGroups.indexOf("" + config.adminGroups[i].groupID) !== -1) {
                check = true;
                break;
            }
        }
    }
    return check;
}

function sendMessageToStaff(msg) {
    backend.getClients().forEach(function(client) {
        if (checkPermissions(client)) {
            client.chat(msg);
        }
    });

}

function checkAllClients() {
    debug("Running proxy check on all clients.");
    backend.getClients().forEach(function(client) {
        if (client.isSelf()) {
            return;
        }
        checkForProxy(client);
    });
}

function checkForProxy(client) {
    var ip = client.getIPAddress();
    var res = checkProxyViaAPI(ip, client);
    if (res === true) {
        debug("[PROXY DETECTED] Client: " + client.name() + " (" + client.uniqueID() + ") IP: " + ip);
        handleDetection(client);
    } else if (res === false) {
        debug("Passing proxy check for Client: " + client.name() + " - IP: " + ip);
    } else {
        debug("Waiting API response for Client: " + client.name() + " - IP: " + ip);
    }
}

function checkProxyViaAPI(ip, client) {
    ++checkedIps;

    var WhitelistException = {};
    try {
        config.whitelist.forEach(function (val) {
            if (typeof val.address != "undefined") {
                if ("" + ip == val.address) {
                    debug("[WHITELIST] Detected IP in whitelist. Skipping check for: " + ip);
                    throw WhitelistException;
                    return false;
                }
            }
        });
    } catch (e) {
        if (e == WhitelistException) {
            return false;
        }
    }

    if (localProxies[ip] != null && localProxies[ip]) {
        debug("[CACHE] The IP is present in local cache and resulted in a Proxy.");
        return true;
    } else if (localProxies[ip] != null && !localProxies[ip]) {
        debug("[CACHE] The IP is present in local cache and resulted in a clean address.");
        return false;
    }

    var httpOp = {
        method: "GET",
        headers: "Content-type: application/json",
        timeout: 4500,
        url: "https://api.xdefcon.com/proxy/check/?ip=" + ip
    };
    sinusbot.http(httpOp, function (error, response) {
        ++apiRequests;
        if (response.statusCode !== 200) {
            engine.log("Could not retrieve info for " + ip + " HTTP_ERROR: " + error);
            return false;
        }
        debug("RESPONSE: " + response.data);
        var result = JSON.parse(response.data);
        if (result.success && result.proxy != null) {
            rateLimited = false;
            if (result.proxy.valueOf()) {
                localProxies[ip] = true;
                handleDetection(client);
                return true;
            } else {
                localProxies[ip] = false;
                return false;
            }
        } else if (!result.success && result.message.toLowerCase().indexOf("rate limit") !== -1) {
            engine.log("[ERROR] API requests limit exceeded, please contact luigi@xdefcon.com to remove this limitation.");
            if (!rateLimited) {
                rateLimited = true;
                sendMessageToStaff("[b][AntiProxy][/b] It seems that you have [b]exceeded[/b] the maximum hourly rate of [b]requests to the API[/b]. " +
                    "This means that you will not be able to check [b]new IPs[/b] until the next hour (rate limit reset). If you want to " +
                    "avoid this problem, please consider contacting the developer & provider of the API via email at: " +
                    "[b][url=mailto:lugi@xdefcon.com?subject=Proxy%20API%20rate%20limit]luigi@xdefcon.com[/url][/b] - " +
                    "The script [b]will continue working with the local cache[/b], no issues about it.");
            }
            return false;
        }
        debug("Error in the API response. Is the API offline? Using cached data. URL: " + httpOp.url);
        return false;

    })
}

function handleDetection(client) {
    ++detectedProxies;
    lastDetection.client = client.name() + "(" + client.uniqueID() + ")";
    lastDetection.ip = client.getIPAddress();

    if (config.notifyOnDetection == 1) {
        sendMessageToStaff(config.prefix + " Detected Proxy on client: [URL=client://" + client.id() +"/" +
            client.uniqueID() + "~" + client.name() + "]" + client.name() + "[/URL] (" + client.uniqueID() + ") " + config.theme + "[b]IP[/b][/color]: " + client.getIPAddress() +
            "\n" + config.theme + "[b]Total client connections[/b][/color]: " + client.getTotalConnections() + " - " + config.theme + "[b]First connection at[/b][/color]: " + getDateString(client.getCreationTime()));
    }
    debug("Punishment message: " + config.punishmentMessage);
    if (config.punishment == 0) {
        client.poke(config.punishmentMessage);
        debug("Sent poke to Client: " + client.name());
    }
    if (config.punishment == 1) {
        client.kick(config.punishmentMessage);
        debug("Kicked Client: " + client.name());
    }
    if (config.punishment == 2) {
        client.ban(config.tempBanDuration, config.punishmentMessage.substring(0, 70));
        debug("Tempbanned Client: " + client.name() + " for " + config.tempBanDuration + " seconds.");
    }
    if (config.punishment == 3) {
        client.chat(config.punishmentMessage);
        debug("Sent chat message to Client: " + client.name());
    }
    if (config.punishment == 4) {
        debug("Notify admins only for Client: " + client.name());
    }
}

function debug(msg) {
    if (config.debugSwitch == 1) {
        engine.log("[DEBUG] " + msg);
    }
}

function getDateString(timestamp){
    var a = new Date(timestamp);
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var year = a.getFullYear();
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    if (hour <= 9) hour = "0" + hour;
    var min = a.getMinutes();
    if (min <= 9) min = "0" + min;
    var sec = a.getSeconds();
    if (sec <= 9) sec = "0" + sec;
    return date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
}

});

xDefcon commented 6 years ago

Can you please describe what are the new features? The code is not well formatted, thanks.

xDefcon commented 6 years ago

It seems they are:

Correct? @Axzial

vbrown37 commented 6 years ago

You can add Custom Prefix : http://prntscr.com/hkf3oq You can add Colors to detection messages : http://prntscr.com/hkf6fa New commands : !antiproxy commands : http://prntscr.com/hkf6u1 !antiproxy manual : http://prntscr.com/hkf7b6

vbrown37 commented 6 years ago

https://www.mediafire.com/file/an1m193ma96ypvv/AntiProxy.js