< Zpět na články

Člověk vs. robot: Kdo vyřeší Google reCaptcha?

Jak si zaplnit poštovní schránku spamem? Vytvořit kontaktní formulář bez captchy!

Zastoupil vám někdy cestu formulář zaměřený proti botům zvaný Google reCaptcha? A zarazil vám někdy proces automatického získávání dat z nějaké webové stránky? Captchu od Googlu je možné strojově obejít, ale možnosti je jen pár a navíc ne všechny jsou úplně vhodné nebo funkční. Řešení ale existuje a možná pro vás bude překvapivé tím, že až tak překvapivé není. Kdo tedy vyřeší Google captchu?

Asi každý, kdo někdy potřeboval automaticky zpracovávat nějaká data z webové stránky či webové aplikace, která nemá veřejné API, pravděpodobně sáhl po skriptovacím headless browseru jako je např. PhantomJS, CasperJS nebo třeba Cypress. Vše fungovalo bezvadně, než se u přihlašovacího dialogu objevila reCaptcha (captcha od Googlu). Co s tím?

Při dotazu na řešení nám sám Google poradí následující možnosti, jak se můžeme reCaptchu pokusit strojově obejít:

  1. Zneužijeme poslechovou část pro nevidomé (ano, skutečně).
  2. Budeme střídat proxy servery a doufat, že se nám při prvním pokusu nezobrazí pop-up s titulkem “Vyberte všechny čtverce, na nichž je palma.”
  3. Použijeme human captcha solver (cože!?).

Nejdříve si u všech možností stručně rozebereme možná řešení.

1) Audio bypass

Nástřel řešení:

  1. Navštívíme přihlašovací stránku.
  2. Vyplníme údaje.
  3. Rozklikneme captchu.
  4. Z DOM struktury zjistíme cestu k poslechovému souboru.
  5. Odešleme na naši webovou službu daný odkaz k audio souboru, ta ho stáhne, prožene ho skrz ReBreakCaptchu a zašle nám zpátky textovou odpověď, kterou zadáme do captchy.
  6. Odesíláme formulář!

A kde že je problém? V době svého zvěřejnění v roce 2016 vzbudil projekt ReBreakCaptcha ve světě ohlas a Google na něj reagoval. Následně 3. března 2017 byl autorem projektu sepsán poslední update, že projekt již rozpoznávat hlasové zprávy od Googlu nedokáže.

2) Proxy, VPN

Použitím proxy nebo VPN sice můžeme snížit riziko vyskočení dialogu pro ověření, nijak tím ale neřešíme samotný problém. Navíc tento způsob vyžaduje velké množství privátních proxy serverů nebo privátních VPN sítí.

3) Human Captcha Solver!

Upřímně jsem byl – asi stejně jako vy – zaskočen slovem „human“ v souvislosti s řešením captchy. Název není vymyšlený, opravdu zní takto. Captchu za vás neřeší žádná neuronka nebo sofistikovaný algoritmus, ale reálný člověk sedící na druhé straně zeměkoule.

Co je vůbec CAPTCHA?

Podívejme se zpátky do historie: První podoba captchy byla „vynalezena“ roku 2000. Pojem CAPTCHA je akronym pro „Completely Automated Public Turing Test to tell Computers and Humans Apart“. Cíl je tedy jasně definovaný: odlišit počítač od člověka. Stojí za zmínku, že v případě captchy jsou pozice oproti původnímu turingovu testu převrácené. Tím, kdo výstup posuzuje, je totiž počítač, nikoli člověk.

Google také původní účel rozšířil a snaží se zužitkovat i vedlejší produkty testu. Výsledky z reCaptchy využívá k identifikaci objektů, rozpoznávání textu (to pak může být využito pro čtení dopravních značek), anotaci obrázků nebo k překladu knih. Skvělým příkladem je například Google překladač. Mobilním telefonem vyfotíte kus papíru s textem a on ho za vás přepíše do textového pole. Bohužel nejspíš nikdo nemá tak obsáhlý dataset jako Google a proto je potřeba zapojit do našeho automatizovaného procesu člověka.

Pomůže 2Captcha!

Představuji vám službu, která vám s tím pomůže! 2Captcha je služba určená k automatizaci rozpoznávání testů zaměřených proti botům. Jednotlivé captchy tedy řeší – tadá – lidé.

Pokud aktuálně nejste spokojeni se svojí prací, za 1000 vyřešených reCaptch budete odměněni částkou 1.02 $.

Protože my se svojí prací spokojení jsme, spíše nás zajímá, kolik my zaplatíme na 1000 vyřešených captch. Budou nás stát 3 $.

Hurá ke kódu

Nebude to ale úplně bez práce. K rozlousknutí captchy budeme muset kromě zmíněné služby využít JavaScript. Níže si můžete prohlédnout ukázku zdrojového kódu. A pro ty, kteří nemají JavaScript rádi nebo dnes neměli svou ranní kávu, celý proces rychle shrnu v bodech. Nejprve kód:

// API key  
// https://2captcha.com/enterpage  
const API_KEY = 'XXXX';  
// Find site key of a website  
const googleSiteKey = document.getElementsByClassName('g-recaptcha')[0].getAttribute('data-sitekey');  
// Helper parsing function  
const extractTextFromResponse = response => response.status === 200 ? response.text().then(text => text) : false;  
// Helper delay function  
const delay = value => new Promise(res => setTimeout(res, value));  
// Function for sending captcha we want to solve to the API  
async function sendCaptcha() {  
    const captchaDataString = [  
        'key=' + API_KEY,  
        'method=userrecaptcha',  
        'googlekey=' + googleSiteKey,  
        'pageurl=' + window.location.href,  
    ].join("&");  
    return await fetch('https://2captcha.com/in.php?' + captchaDataString)  
        .then(payload => extractTextFromResponse(payload))  
        .then(payload => {  
            if (!payload || payload.substr(0, 2) !== "OK") {  
                console.error("Payload is not okay", payload);  
                return false;  
            }  
            return payload.substr(3);  
        })  
        .catch(error => {  
            console.error("Something went wrong", error);  
            return false;  
        })  
}  
// Function that waits for a response  
async function poolResponse(requestId, counter = 0, counterLimit = 3, waitTime = 20000, decrementWaitTimeBy = 5000) {  
    if (counter === counterLimit || waitTime < 0) {  
        console.error("Captcha was not solved in time.");  
        return false;  
    }  
    await delay(waitTime - decrementWaitTimeBy); // Wait some time  
    const dataStringRes = [  
        'key=' + API_KEY,  
        'action=GET',  
        'id=' + requestId,  
        'json=0'  
    ].join("&");  
    return fetch('https://2captcha.com/res.php?' + dataStringRes)  
        .then(payload => extractTextFromResponse(payload))  
        .catch(error => {  
            console.error("Something went wrong", error);  
            reject(false);  
        });  
}  
// Start function  
(async function () {  
    // Get request id of current captcha  
    const requestId = await sendCaptcha();  
    if (!requestId) {  
        return false;  
    }  
    // Wait for somebody to solve your captcha  
    const counterLimit = 3;  
    for (let i = 0; i < counterLimit; i++) {  
        const payload = await poolResponse(requestId, i, counterLimit);  
        if (payload === "CAPCHA_NOT_READY") {  
            continue;  
        }  
        if (!payload || payload.substr(0, 2) !== "OK") {  
            console.error("Captcha was not solved.", payload);  
            return false;  
        }  
        // Save  
        document.getElementById("g-recaptcha-response").innerHTML = payload;  
        break;  
    }  
})();

A teď postup. Stačí nám jen několik jednoduchých kroků:

  1. Zjistíme site key (veřejný klíč), který web používá pro zobrazení captchy. (Secret key – privátní klíč pak používá daná stránka pro šifrovanou komunikaci s Google serverem pro ověření zda byla captcha úspěšně vyřešena.)
  2. Odešleme tuto informaci na API služby http://2captcha.com a vyčkáme na odpověd.
  3. Odpověď je ve formátu STATUS|ID_POŽADAVKU.
  4. Pokud je STATUS == 'OK', vyčkáme 20 sekund a poté se dotážeme, zda už byla nějakým pracovníkem naše captcha vyřešena.
  5. Odpověď je buď typu CAPCHA_NOT_READY, nebo STATUS|RESPONSE_HASH.
  6. Pokud je captcha je stavu CAPCHA_NOT_READY, vyčkáme poloviční čas a akci opakujeme, nejvýše třikrát.
  7. Pokud dostaneme kladnou odpověď, uložíme ji do DOMu a odešleme formulář.

Na CAPTCHu člověka

V tomto článku jsme si ukázali 2 věci. Za prvé, jak jednoduché je obejít všudypřítomnou Google reCaptchu, a za druhé, že nejlepší je využít k tomu lidský mozek. Reverzní turingův test totiž pořád nejlépe zvládá ten, komu byl určen především – člověk.

Tomáš Dvořák
Tomáš Dvořák
Frontend DeveloperTomáš prvně přičuchl k webu už jako mládě a od péhapka se prokousal až k Reactu. Studuje ČVUT FIT, rád lidem radí a poslední dobou v Ackee pomáhá i na backendu.

Máte zájem o spolupráci? Pojďme to probrat osobně!

Napište nám >