Hướng dẫn "vượt tường" Captcha bằng Javale
Java
164
White

Alex viết ngày 13/01/2020

Đúng như tên gọi của mình, Captcha (Completely Automated Public Turing test to tell Computers and Humans Apart) được sử dụng để phân biệt Con người và ro-bot, từ đó ngăn chặn ro-bot truy cập và thực hiện các hành động khác nhau trên Website hoặc ứng dụng.

Hiện tại, Google ReCaptcha v2 là Captcha phổ biến trên nhiều website và ứng dụng. Và vấn đề được đề cập đến trong bài viết này chính là việc làm thế nào để "bẻ khóa" được loại Captcha này.

Thử thách mà Google ReCaptcha v2 đưa ra khá đơn giản, đó là yêu cầu người dùng nhấp vào hộp kiểm. Sau đó, dịch vụ này sẽ phân tích rất nhiều yếu tố để xác định xem đó là con người hay ro-bot. Việc phân tích này được thực hiện như thế nào? Không ai biết chính xác và Google chắc chắn là không trả lời sự tò mò này của hàng trăm nghìn con người, nhưng những suy đoán thì vẫn không ngừng được đưa ra:

• Phân tích hành vi dựa vào việc nhấp hộp kiểm: Phần nào của hộp kiểm được nhấp? (vị trí ngẫu nhiên hoặc ở giữa), tốc độ nhấp chuột,...;
• Sử dụng công cụ định danh (kỹ thuật kết hợp những thông tin thu thập từ trước để xác định người dùng đã ghé thăm và làm gì trước đó) để lấy được Browser Fingerprinting phục vụ mục đích tracking online;
• Phân tích lịch sử nhấp chuột: chỉ click vào 1 vị trí duy nhấp hay ngẫu nhiên, và cách hành động giống như Con người;
• Cookies và lịch sử trình duyệt.

Với những Captcha đời đầu, việc sử dụng kỹ thật Nhận dạng ký tự quang học (OCR) và gần đây là các framework của Machine Learning đã và đang cung cấp các kết quả giải mã có độ chính xác cao (đôi khi hơn cả Con người), nhưng với ReCaptcha v2, cách dễ dàng và chính xác hơn là sử dụng dịch vụ của bên thứ ba.

Nhiều công ty đang cung cấp dịch vụ thông qua API và có một đội ngũ nhân sự để giải mã captcha. Chúng ta có thể lựa chọn sử dụng của một bên cung cấp dịch vụ nào đó và 2captcha.com chính là một trong số những công cụ đáng tin cậy, dễ sử dụng nhưng có giá không hề rẻ (2,99 USD cho 1000 recaptchas).

Để giải mã Captcha, API sẽ cần các thông tin liên quan đến site-key và URL của website đích.

Về mặt kỹ thuật, thử thách Recaptcha là một iFrame với một ma trận mã Javascript ma thuật và một số input dạng hidden (dạng này sẽ không hiển thị và được sử dụng khi không muốn dữ liệu bị thay đổi). Khi bạn bắt đầu "cuộc chơi", bằng cách nhấp hộp kiểm hoặc giải mã hình ảnh, thẻ hidden input sẽ được điền bởi mã token.

Mã token này sẽ được gửi thông qua API của 2captcha. Sau đó, bạn sẽ điền mã này vào thẻ hidden input và submit form.

Để sử dụng dịch vụ 2captcha, điều đầu tiên bạn cần làm là tạo một tài khoản và nạp tiền. API key sẽ được hiển thị trên màn hình dashboard.

Chúng tôi đã thiết lập một webpage mẫu với một hình thức đơn giản gồm 1 thẻ input và mã Recaptcha:

ReCaptcha

Chúng tôi sẽ sử dụng chức năng headless mode của Chrome để tạo formvà HtmlUnit để thực hiện các lệnh gọi API tới 2captcha (chúng tôi có thể sử dụng bất kỳ phương thức HTTP). Bắt đầu code nào!

final String API_KEY = "YOUR_API_KEY";
final String API_BASE_URL = "http://2captcha.com/";
final String BASE_URL = "https://www.javawebscrapingsandbox.com/captcha";
WebClient client = new WebClient();
client.getOptions().setJavaScriptEnabled(false);
client.getOptions().setCssEnabled(false);
client.getOptions().setUseInsecureSSL(true);
java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF); // replace with your own chromdriver path 
final String chromeDriverPath = "/usr/local/bin/chromedriver";
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--disable-gpu", "--windowsize=1920,1200", "--ignore-certificate-errors", "--silent");
options.addArguments("--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/60.0.3112.113 Chrome/60.0.3112.113 Safari/537.36");
WebDriver driver = new ChromeDriver(options);

Dưới đây là một số mã có sẵn để khởi tạo cả WebDriver và WebClient, cùng với URL và API key.

Sau đó, chúng tôi phải gọi API 2captcha bằng site-kry, API key và URL trang đích. API được cho là đáp ứng với định dạng sau: OK | 123456.

String siteId = "";
WebElement elem = driver.findElement(By.xpath("//div[@class='g-recaptcha']"));
try {
    siteId = elem.getAttribute("data-sitekey");
} catch (Exception e) {
    System.err.println("Catpcha's div cannot be found or missing attribute data-sitekey");
    e.printStackTrace();
}
String QUERY = String.format("%sin.php?key=%s&method=userrecaptcha&googlekey=%s&pageurl=%s&here=now", API_BASE_URL, API_KEY, siteId, BASE_URL);
Page response = client.getPage(QUERY);
String stringResponse = response.getWebResponse().getContentAsString();
String jobId = "";
if (!stringResponse.contains("OK")) {
    throw new Exception("Error with 2captcha.com API, received : " + stringResponse);
} else {
    jobId = stringResponse.split("\\|")[1];
}

Bây giờ các step có thể được xâu chuỗi cùng nhau để chạy như một job và chúng tôi có Job ID. Tuy nhiên, chúng ta sẽ phải sử dụng một API khác để biết khi nào ReCaptcha được giải mã và nhận mã token Nếu trả về CAPCHA_NOT_READY nghĩa là quá trình giải mã chưa sẵn sàng, cho đến khi nhận được phản hồi OK | TOKEN:

boolean captchaSolved = false;
while (!captchaSolved) {
    response = client.getPage(String.format("%sres.php?key=%s&action=get&id=%s", API_BASE_URL, API_KEY, jobId));
    if (response.getWebResponse().getContentAsString().contains("CAPCHA_NOT_READY")) {
        Thread.sleep(3000);
        System.out.println("Waiting for 2Captcha.com ...");
    } else {
        captchaSolved = true;
        System.out.println("Captcha solved !");
    }
}
String captchaToken = response.getWebResponse().getContentAsString().split("\\|")[1];

Lưu ý rằng có thể mất tới 1 phút để giải mã captcha. Đây có thể là một ý tưởng tốt để thực hiện một biện pháp bảo vệ / tạm ngưng trong vòng lặp, bởi vì có những trường hợp mà captcha không bao giờ được giải quyết.

Bây giờ, khi đã có mã token, chúng ta chỉ cần tìm thẻ hidden input, điền mã token và submit form.

API Selenium không thể điền vào thẻ hidden input, vì vậy chúng tôi phải thao tác DOM để hiển thị các thẻ input bị ẩn, điền mã, ẩn thẻ input và submit form:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('g-recaptcha-response').style.display = 'block';");
WebElement textarea = driver.findElement(By.xpath("//textarea[@id='g-recaptcha-response']"));
textarea.sendKeys(captchaToken);
js.executeScript("document.getElementById('g-recaptcha-response').style.display = 'none';");
driver.findElement(By.id("name")).sendKeys("Kevin");
driver.getPageSource();
driver.findElement(By.id("submit")).click();
if (driver.getPageSource().contains("your captcha was successfully submitted")) {
    System.out.println("Captcha successfuly submitted !");
} else {
    System.out.println("Error while submitting captcha");
}

Nói chung, các trang web không cần thiết phải sử dụng ReCaptcha cho tất cả các phương thức HTTP, nó chỉ sử dụng các hành động cụ thể như tạo tài khoản,... Bạn nên tìm hiểu xem trang web có hiển thị[Re]captcha không vì bạn đã thực hiện quá nhiều yêu cầu có cùng địa chỉ IP hoặc cùng một tác nhân người dùng (user-agent) hoặc có thể bạn đã thực hiện quá nhiều yêu cầu mỗi giây.

Giảm thiểu cơ hội nhận Captcha là cách tốt nhất vì nó giúp bạn tiết kiệm thời gian cũng như chi phí. Tuy nhiên điều đó rất hiếm khi xảy ra, vì nhiều trang web luôn hiển thị Captcha 100% mỗi khi bạn truy cập.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Alex

6 bài viết.
2 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
4 0
Sử dụng 2Captcha và Puppeteer giúp tự động hóa "vượt tường" CAPTCHA Trong khoảng hơn một thập kỷ trở lại đây, Captcha đã trở nên quen thuộc ở khắp...
Alex viết 10 tháng trước
4 0
White
3 0
Một câu chuyện rất đỗi quen thuộc và thường diễn ra như sau: Sam cần phải điền vào các biểu mẫu tự động. Nó có thể dành cho các mục đích khác nhau...
Alex viết 10 tháng trước
3 0
White
1 0
Machine Learning (Học máy) đã tiến xa như thế nào trong lĩnh vực giải mã Captcha? Trong thời gian gần đây, Machine Learning là một trong những cụm...
Alex viết 9 tháng trước
1 0
Bài viết liên quan
White
0 0
Trong bài viết này, một số hình ảnh hoặc nọi dung có thể bị thiếu do quá trình chế bản. Vui lòng xem nội dung ở blog gốc sau: (Link) (Link), chúng...
programmerit viết 5 năm trước
0 0
White
0 0
Giới thiệu Trong bài hôm nay chúng ta sẽ tìm hiểu cách handle request POST của Spring Boot. Trước đó, bạn nên biết 1. 「Spring Boot 8」Tạo Web He...
https://loda.me viết hơn 1 năm trước
0 0
White
2 0
1. Prepare Tools IDE: Netbean 8.2 JDK: 1.8 Maven: 3.5.0 2. Target Build project thỏa mãn các yêu cầu sau: Sử dụng spring boot + spring ...
xoandaica viết hơn 1 năm trước
2 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
6 bài viết.
2 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!