• Страница 1 из 1
  • 1
Обход античита скоростной печати
Вт, 09 Фев 2021, 22:28 | Сообщение 1

Вт, 09 Фев 2021, 22:28 | Сообщение 1
Регистр
04 Янв 2021
Сообщений
456

Репутация
Сегодня я расскажу о одном моём интересном проекте на JS & C++, хоть он и бесполезный.

Итак, в чём суть. Думаю, все видели сервисы по скоростной печати. Мне захотелось наебать нескольких. Всё предельно просто. TamperMonkey парсит текст с страницы, а локальный веб сервер на C++ принимает этот текст, после чего начинает его сам печатать. Было бы скучно только об этом, и, к счастью, на одном сервисе я уведил античит проверку, которую необходимо пройти, чтобы тебя не считали за читера. Прикол в том, что это текст капча, и её для начала нужно разобрать. Но проблемы начались еще раньше. Сервис получал картинку запросом на сервер по ссылке server.com/randompic, и каждый раз картинка различалась. Получить запросом точно такую же картинку как и на сайте не представлялось возможным. Высунуть её я смог через Canvas, а после, одной интересной либой для JS распарсил текст с пикчи и дальше, по классике, на C++ сервер.

Конечно же, код прикладываю ниже.

Спасибо за прочтение статьи!

Код
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
#include <unistd.h>
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <iterator>

#define PORT               9000                    // Server port
#define CLIENT_BUFFER_SIZE 20480                    // Client buffer size

std::string convertToString(char* a);                    // PROTOTYPE: (Array)
void SendKey(Display *disp, KeySym keysym, KeySym modsym);                    // PROTOTYPE: (Display, KeySymbol, ModSymbol)
void log(std::string logStr, int code);                    // PROTOTYPE: (LogString, CodeProcess)
char * getTypingText(char buf[]);                    // PROTOTYPE: (Buffer)

int main(int argc, char *argv[]) {                    // ARGV: PORT, DCHAR
    int TIME_AFTER_CHAR  = atoi(argv[1]);                    // Microsecond delay after char  event                    
    int TIME_AFTER_SPACE = atoi(argv[2]);                    // Microsecond delay after space event

    struct sockaddr_in sockAddr;                    // Socket Address
    int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);                    // Socket
    sockAddr.sin_family = AF_INET;                    // Socket family    (IPv4)
    sockAddr.sin_port = htons(PORT);                    // Socket port      (#define PORT)
    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);                    // Socket address   (Any local)

    log("creating socket", s);                    // Logging creating socket
    log("bind", bind(s, (struct sockaddr*) &sockAddr, sizeof(sockAddr)));                    // Logggin bind     socket
    log("listen", listen(s, 10));                    // Logging listen   socket

    for (;;) {                    /*START: Connection handling*/
        int connectS = accept(s, 0, 0);

        char buf[CLIENT_BUFFER_SIZE];                    // Client buffer                    
        auto result = recv(connectS, buf, CLIENT_BUFFER_SIZE, 0);                    // Get a data from client && result = data size

        char *text = getTypingText(buf);

        usleep(500000);                    // Wait half second
        Display *disp = XOpenDisplay (NULL);                    // Get display
        for (int i = 0; *(text+i) != '\0'; i++) {                    /*START: Print a text*/
            if (*(text+i) <= 90 && *(text+i) != 20) {                    //START: Fake key event
                SendKey(disp, XK_Caps_Lock, 0);                    // Caps Lock for uppercase char
                usleep(TIME_AFTER_SPACE);                    // Wait
                SendKey(disp, *(text+i), 0);                    // Fake key event
                usleep(TIME_AFTER_SPACE);                    // Wait
                SendKey(disp, XK_Caps_Lock, 0);                    // Caps Lock for lowercase char
            } else SendKey(disp, *(text+i), 0);                    //END:   Fake key event
            usleep(TIME_AFTER_CHAR);                    // Wait
        }                    /*END:   Print a text*/
     
        std::stringstream response;                    // Response string
        response << "HTTP/1.1 200 OK\r\n" << "Version: HTTP/1.1\r\n" << "Content-Type: text/html; charset=utf-8\r\n" << "\r\n\r\n" << "All ok";
        send(connectS, response.str().c_str(), response.str().length(), 0);                    // Send a answer
       
        shutdown(connectS, SHUT_RDWR);                    // Close client connection  
    }  
}                    /*END:   Connection handling*/

void SendKey(Display *disp, KeySym keysym, KeySym modsym){                    /*START: Fake key event*/
    KeyCode keycode = 0, modcode = 0;                    // Declare codes
    keycode = XKeysymToKeycode(disp, keysym);                    // Get a keycode
    if (keycode == 0) return;                    // Exit if nothing
    XTestGrabControl (disp, True);                    // Grab control to Display
    XTestFakeKeyEvent(disp, keycode, True, 0);                    // Push
    XTestFakeKeyEvent(disp, keycode, False, 0);                    // Release
    XSync(disp, False);                    // Synchronise
    XTestGrabControl(disp, False);                    // Release control to Display
}                    /*END:   Fake key event*/

void log(std::string logStr, int code) {
    if (code == -1) {
        std::cout << "\033[1;31mError: \033[0m" << logStr << std::endl;                    // Error log
        exit(EXIT_FAILURE);                    // Exit with rror
    } else std::cout << "\033[1;32mSuccess: \033[0m" << logStr << std::endl;                    // Success log
}

std::string convertToString(char* a) {                    /*START: Char aray to string*/                    
    int arraySize = sizeof(a)/sizeof(a[0]);                    // Array size
    std::string resultString = "";                    // String
    for (int i = 0; i < arraySize; i++) resultString += a[i];                    // Add each char to string
    return resultString;                    // Return string
}                    /*END:   Char aray to string*/

char * getTypingText(char buf[]) {
    static char text[CLIENT_BUFFER_SIZE];
    for (int i = 0; ; i++) {
        if (buf == ' ') {
            for (int j = i+3, k = 0; ; j++, k++) {
                if (buf [j]== ' ') {
                    text [k]= '\0';
                    return text;
                }
                if (buf == '%' && buf[j+1] == '2' && buf[j+2] == '0' || buf[j-1] == '%' && buf == '2' && buf[j+1] == '0' || buf[j-2] == '%' && buf[j-1] == '2' && buf == '0') {
                    if (buf == '%')  {
                        text [k]= ' ';
                        continue;
                    }
                    k--;
                    continue;
                } else if (buf == '%' && buf[j+1] == '2' && buf[j+2] == '7' || buf[j-1] == '%' && buf == '2' && buf[j+1] == '7' || buf[j-2] == '%' && buf[j-1] == '2' && buf == '7') {
                    if (buf == '%')  {
                        text [k]= '\'';
                        continue;
                    }
                    k--;
                    continue;
                } else if (buf == '%' && buf[j+1] == '3' && buf[j+2] == 'B' || buf[j-1] == '%' && buf == '3' && buf[j+1] == 'B' || buf[j-2] == '%' && buf[j-1] == '3' && buf == 'B') {
                    if (buf == '%')  {
                        text [k]= ';';
                        continue;
                    }
                    k--;
                    continue;
                }
                text [k]= buf;
            }
        }
    }
}

// ==UserScript==
// @name FastFingersTypingText
// @description This script copying text from FastFingers.
// @author F48D1
// @grant    GM_xmlhttpRequest
// @license MIT
// @version 1.0
// @include https://10fastfingers.com/typing-test/english
// @include https://10fastfingers.com/advanced-typing-test/english
// @include https://10fastfingers.com/competition/*
// @include https://10fastfingers.com/top1000/english/*
// ==/UserScript==
(function (window, undefined) {
    var w;
    if (typeof unsafeWindow != undefined) w = unsafeWindow
    else w = window;

    if (w.self != w.top) return;

    const createText = (elem) => {
        let re = new RegExp(">[a-zA-Z\s']{1,100}<", "g");
        elem = elem.match(re);
        elem = elem.join(" ");
        elem = elem.split("<").join("");
        elem = elem.split(">").join("");
        return elem;
    };

    document.addEventListener('keydown', function(event) {
        if (event.code == 'KeyE' && (event.ctrlKey || event.metaKey)) {
            let field = document.getElementById('row1');
            let urlToServer = "http://0.0.0.0:9000/?" + createText(field.innerHTML);
            console.log(createText(field.innerHTML));
            GM_xmlhttpRequest({
                method: "GET",
                url: urlToServer,
                onload: function(response) {
                    console.log (response.responseText);
               }
            });
        }
    });
})(window);

// ==UserScript==
// @name         FastFingersAntiCheat
// @description  This script typing AntiCheat text from FastFingers.
// @author       F48D1
// @require https://unpkg.com/tesseract.js@v2.1.0/dist/tesseract.min.js
// @grant        GM_xmlhttpRequest
// @license      MIT
// @include      https://10fastfingers.com/anticheat/view/1/1
// ==/UserScript==

(function (window, undefined) {
    var w;
    let Tesseract = window.Tesseract;
    if (typeof unsafeWindow != undefined) w = unsafeWindow;
    else w = window;

    if (w.self != w.top) return;

    const createText = (elem) => {
        const canvas = document.createElement('canvas');
        canvas.width = elem.width;
        canvas.height = elem.height;
        const ctx = canvas.getContext("2d");
        ctx.drawImage(elem, 0, 0);
        const base64 = canvas.toDataURL("image/png");

        const worker = Tesseract.createWorker({
            logger: m => console.log(m)
        });

        (async () => {
            await worker.load();
            await worker.loadLanguage('eng');
            await worker.initialize('eng');
            await worker.setParameters({tessedit_char_whitelist: "ABCDEFGHIJKLMNOPQESTUVWXYZabcdefghijklmnopqrstuvwxyz' "});
            const { data: { text } } = await worker.recognize(base64);
            let textForTyping = text.split(/\r?\n/).join(' ');
            console.log(textForTyping);
            let urlToServer = "http://0.0.0.0:9000/?" + textForTyping;
            GM_xmlhttpRequest({
                method: "GET",
                url: urlToServer,
                onload: function(response) {
                    let send = document.querySelector('#submit-anticheat');
                    send.click();
               }
            });
            await worker.terminate();
        })();
    };

    let startBtn = document.querySelector('#start-btn').addEventListener("click", function() {
        let img = document.querySelector('#word-img > img');
        img.onload = function(){
            createText(img);
        }
    });
})(window);[/j][/i]

Подпишись: WiN-Prog ВКонтакте | Win Programs в Телеграм


  • Страница 1 из 1
  • 1
Поиск: