NashTech Blog

Table of Contents

 

1. Introduction

Automation testing, a crucial aspect of continuous integration, often encounters challenges when dealing with security measures such as captchas. The need for continuous and repetitive test runs may trigger security mechanisms, like Cloudflare captchas, leading to test failures. While it’s possible to disable captchas during test execution, there are scenarios where this might not be feasible. In this blog post, we delve into the world of Cloudflare captchas, focusing on the Standalone Cloudflare Turnstile Captcha and the Cloudflare Turnstile Challenge Page. We will explore the intricacies of these captchas and discuss two effective ways to bypass them in an automated fashion.

2. Understand Cloudflare Captchas

 

  • There are 2 types of Cloudflare turnstile captcha:
    • Standalone Cloudflare Turnstile Captcha: The captcha widget is placed on a website page, protecting a form from automated submission. See this example.
    • Cloudflare Turnstile Challenge Page: The captcha on websites proxied proxied through Cloudflare. See this example.

3. Bypass Techniques

 

3.1. Complimentary (Python only):

 

import undetected_chromedriver as uc

driver = uc.Chrome(headless=True,use_subprocess=False)
driver.get('https://rucaptcha.com/42')
driver.save_screenshot('captcha.png')

 

from DrissionPage import ChromiumPage

page = ChromiumPage()
page.get('https://rucaptcha.com/42')

 

3.2. Paid Bypass Using 2Captcha:

 

How does it work?
Send an API to 2Captcha to receive the cf-turnstile-response token. Their workers will bypass this captcha manually and send us the cf-turnstile-response token back. Finally, use this token to bypass Cloudflare by setting the value for the cf-turnstile-response input.

 

3.2.1. Standalone Turnstile captcha

 

Step 1: Send turnstile bypass request to 2Captcha with:

{
"key": "YOUR_API_KEY", // Go to https://2captcha.com/enterpage and copy your API key and paste it here
"method": "turnstile",
"sitekey": "0x4AAAAAAAC3DHQFLr1GavRN", // Each website using an unique sitekey
"pageurl": "https://2captcha.com/demo/cloudflare-turnstile", // Your website url using CF turnstile
"json": 1
}
  • How can you take the site key value? In the CF iframe tag, you can take the value from the src attribute. See more details below:
  • A sample response:
{

"status": 1,
"request": "2122988149" // request Id to get bypass token
}

Step 2: Wait for 10 seconds

  • The request at step 1 triggers a job to bypass Cloudflare manually. Therefore, it takes 7-10 seconds to handle the job. You need to wait.

Step 3: Send a GET request to receive the cf-turnstile-response token

{

"status": 1,
"request": "0.WoGeDojxQzHCCk023JRjfxv23olYh37jFdvPrcqmNeQ7PbSYIEuiBTK2SR_GdjfMitYEC23Gm7Vt93U1CPcI6aIFEhG-ffe1i9e6tIfIlYCFtb7OMxTB4tKCyTdpiaA.SP5YT77nuMNdOhZlvoBWAQ.da6448d22df7dd92f56a9fcf6d7138e5ee712bcf7d00c281f419b3bc091cbe64"
}

Step 4: Set the value for cf-turnstile-response input on the console tab of the development tool.

document.querySelector('[name="cf-turnstile-response"]').value = 'TOKEN';

Step 5: Captcha is bypassed. Continue with your work.

You can view the latest guidelines for standalone turnstile captcha here. If you’re looking for 2Captcha code samples in C#, PHP, Ruby, Java, Python, or Javascript please go to their git repositories.

 

3.2.2. Cloudflare Challenge page

 

Bypass with puppeteer JS

 

  • Firstly, send the same POST request as the standalone turnstile captcha to trigger the 2Captcha bypass job. However, there are 3 more mandatory fields that need to be set, including data, pagedata, and action.
Endpoint: https://2captcha.com/in.php

Method: POST



{

"key": "YOUR_API_KEY",

"method": "turnstile",

"sitekey": "0x0AAAAAAADnPIDROzbs0Aaj",

"data": "7fab0000b0e0ff00",

"pagedata": "3gAFo2...0ME1UVT0=",

"pageurl": "https://2captcha.com/",

"action": "managed",


"json": 1

}
  • How can we grab the value for these fields? You should intercept the window.turnstile.render call by injecting the following JavaScript before the Turnstile widget is loaded.
// This file is named inject.js

console.clear = () => console.log('Console was cleared')

const i = setInterval(() => {

if (window.turnstile) {

clearInterval(i)

window.turnstile.render = (a, b) => {

let params = {

sitekey: b.sitekey,

pageurl: window.location.href,

data: b.cData,

pagedata: b.chlPageData,

action: b.action,


userAgent: navigator.userAgent,

json: 1

}

// we will intercept the message in puppeeter

console.log('intercepted-params:' + JSON.stringify(params))

window.cfCallback = b.callback

return

}

}

}, 50)
  • In Puppeteer, use the method Page.evaluateOnNewDocument(inject_script) to inject the script whenever there is a new document loaded. Store the JS script above in a file named inject.js, the script to bypass will be:
import { launch } from 'puppeteer'

import { Solver } from '2captcha-ts'

import { readFileSync } from 'fs'



const solver = new Solver(`API_KEY`) // Set your API key here



const example = async () => {

const browser = await launch({

headless: false,

devtools: true

})

const [page] = await browser.pages()

// Load inject.js content

const preloadFile = readFileSync('./inject.js', 'utf8');

await page.evaluateOnNewDocument(preloadFile);



// Here we intercept the console messages to catch the message logged by inject.js script

page.on('console', async (msg) => {

const txt = msg.text()

if (txt.includes('intercepted-params:')) {

const params = JSON.parse(txt.replace('intercepted-params:', ''))

console.log(params)



try {

console.log(`Solving the captcha...`)

const res = await solver.cloudflareTurnstile(params)

console.log(`Solved the captcha ${res.id}`)

console.log(res)

await page.evaluate((token) => {

cfCallback(token)

}, res.data)

} catch (e) {

console.log(e.err)

return process.exit()

}

} else {

return;

}

})

// When the page is redirected, there is a log "intercepted-params: ..." in the browser console

page.goto('https://rucaptcha.com/42')

}

example() // Run the example function above
Bypass with Selenium C#

 

  • C# is just an implementation example. 2Captcha can be implemented in any other language.
  • In Selenium, go the same way with Puppeteer. Call the command Page.addScriptToEvaluateOnNewDocument of Chrome Dev Tools instead of page.evaluateOnNewDocument(); to inject the script.
string injectedScripts = File.ReadAllText("inject.js", Encoding.UTF8);

((ChromeDriver)AtataContext.Current.Driver)
.ExecuteCdpCommand("Page.addScriptToEvaluateOnNewDocument",
new System.Collections.Generic.Dictionary<string, object> { { "source", injectedScripts } }
);
  • Load the message containing the text “intercepted-params”. And don’t forget to set logging Preference at all levels to receive log by: chromeOptions.SetLoggingPreference(LogType.Browser, OpenQA.Selenium.LogLevel.All);
// Get the message logged by the inject.js for 2captcha params
LogEntry message = AtataContext.Current.Driver.Manage().Logs.GetLog(LogType.Browser).FirstOrDefault(m => m.Message.Contains("intercepted-params:"));
  • Handle the params into the Turnstile Captcha request for data, pageData, and action. Finally, call back Cloudflare verification with the token to bypass with the js script $”cfCallback(‘{token}’);”
if (message != null)

{

string paramString = Regex.Replace(message.Message, @".*intercepted-params:", "")

.Replace("}\"", "}")

.Replace("\\", "");

TwoCaptchaParams param = JsonConvert.DeserializeObject<TwoCaptchaParams>(@$"{paramString}");



// Solve the CAPTCHA using 2captcha-csharp

CustomTwoCaptcha solver = new CustomTwoCaptcha(_apiKey);



TurnstileChallengePage captcha = new TurnstileChallengePage();

captcha.SetSiteKey(param.SiteKey);

captcha.SetUrl(param.PageUrl);

captcha.SetData(param.Data);

captcha.SetPageData(param.PageData);

captcha.SetAction(param.Action);

captcha.SetUserAgent(param.UserAgent);



var captchaId = solver.SendRequest(captcha).GetAwaiter().GetResult();

Thread.Sleep(10);

string token = solver.GetResult(captchaId).GetAwaiter().GetResult();

// Inject the solved CAPTCHA token

AtataContext.Current.Driver.AsScriptExecutor().ExecuteScript($"cfCallback('{token}');");

}

else

{

Console.WriteLine("Console message not found.");

}
  • Finally, run it and you will bypass CloudFlare successfully. Congratulation!

4. Conclusion

Bypassing Cloudflare captchas in an automated manner requires a nuanced understanding of the different types of challenges presented by the security measures. In this scenario, 2captcha emerges as a dependable and sustainable solution.

It’s important to note that automated bypass techniques should be used responsibly and ethically. I hope this topic proves beneficial for you!

 

5. References

 

2Captcha Guideline: https://2captcha.com/blog/bypass-cloudflare-turnstile-captcha

Picture of Đại Phạm Ngọc

Đại Phạm Ngọc

I am an automation test engineer with 9 years of experience in the software testing field across various platforms. I have extensive experience in applying testing development techniques such as BDD and TDD. I have previously spent more than 3 years managing teams in different areas of testing. Currently, I am responsible for teaching automation test-related content.

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top