Giải mã CAPTCHA của 4Chan
(nullpt.rs)- Đây là dự án tạo mô hình TensorFlow.js để tự động giải CAPTCHA của 4Chan ngay trong trình duyệt, đạt mục tiêu tối thiểu 80% và mục tiêu mong muốn trên 90% độ chính xác
- Việc thu thập CAPTCHA khó xử lý bằng cách scrape hàng loạt đơn giản do
ttl,cdcủa API yêu cầu, Cloudflare Turnstile và thời gian chờ tăng dần - Dịch vụ giải bằng người thật thương mại và gán nhãn thủ công gặp lỗi và bị throttling; dự án tạo khoảng 50.000 ảnh dữ liệu tổng hợp từ khoảng 2.500 nền thực tế và 50–150 ảnh cho từng ký tự để có đủ quy mô huấn luyện
- Mô hình dùng kiến trúc CNN+LSTM và mã hóa CTC; sau khi huấn luyện bằng Keras/TensorFlow, được chuyển đổi sang TensorFlow.js qua Python 3.10, Keras 2 và định dạng
.h5 - Trong trình duyệt thực tế, lần tải đầu mất khoảng 1 giây, các lần chạy sau gần như tức thì theo cảm nhận, và đạt tỷ lệ thành công trên 90% trên hàng trăm CAPTCHA thực tế
Mục tiêu và mã nguồn công khai
- Mục tiêu là vừa học machine learning và huấn luyện TensorFlow, vừa tạo một mô hình giải CAPTCHA 4Chan ổn định trong trình duyệt
- Tiêu chí là độ chính xác tối thiểu 80%, nếu có thể thì trên 90%, và cuối cùng đã đạt được
- Mã liên quan được công khai trên GitHub tại 4chan-captcha-playground
Cách CAPTCHA của 4Chan hoạt động
- 4Chan yêu cầu nhập CAPTCHA trước khi viết bài đăng hoặc trả lời
- CAPTCHA thông thường là ảnh chứa 5–6 ký tự chữ-số, và người dùng phải nhập chính xác tất cả ký tự
- CAPTCHA dạng thanh trượt hoạt động bằng cách căn khớp ảnh nền trông như các mảnh ký tự ngẫu nhiên với ảnh tiền cảnh có lỗ trong suốt để làm lộ văn bản CAPTCHA
Các giới hạn gặp phải khi thu thập CAPTCHA
- Khi quan sát yêu cầu CAPTCHA mới, trình duyệt gửi request tới
https://sys.4chan.org/captcha?framed=1&board={board} - Nếu bỏ
framed=1, thay vìpostMessage()trong HTML, máy chủ trả về JSON thô- JSON bao gồm
challenge,ttl,cd,img,img_width,img_height,bg,bg_width, v.v. ttlcó vẻ là thời điểm CAPTCHA hết hạn sau khoảng 2 phútcdđược hiểu là giá trị cooldown phải chờ đến lần yêu cầu CAPTCHA tiếp theo
- JSON bao gồm
- Nếu gửi yêu cầu liên tiếp,
cdngày càng lớn- Những lần đầu có thể yêu cầu mỗi 5 giây
- Sau đó tăng lên 8 giây, rồi tiếp tục tăng gần như gấp đôi
- Cuối cùng chạm trần ở 280 giây
- Sau khi chạm bộ đếm 280 giây, CAPTCHA trở nên khó hơn
- Xuất hiện ảnh có thêm nhiều đường ngang và nhiễu hình elip
- Chất lượng dữ liệu thấp hơn nhưng vẫn có thể dùng được
- Trước khi yêu cầu CAPTCHA cần vượt qua Cloudflare Turnstile
- Cách dùng nhiều proxy và script đơn giản là không thực tế
- Script thu thập sao chép cookie Cloudflare từ trình duyệt để dùng, và thay thủ công khi hết hạn
- Bằng cách này đã thu thập được vài trăm CAPTCHA, nhưng chưa đủ cho huấn luyện và cũng không có nhãn đáp án
Giới hạn của gán nhãn bằng người
- Việc căn chỉnh CAPTCHA dạng thanh trượt đạt tỷ lệ thành công 100% bằng script heuristic
trainer/captcha_aligner.py - Tác giả viết
trainer/labeler.pyđể gửi CAPTCHA tới dịch vụ giải CAPTCHA thương mại, cho người thật nhập đáp án - Vài chục CAPTCHA đầu tiên gửi đi đa số bị giải sai ít nhất một ký tự
- Dùng tính năng “100% Recognition” của dịch vụ để chỉ nhận kết quả khi câu trả lời của nhiều worker khớp nhau
- Giá trị thiết lập là
n = 2,x = 2,y = 3 - Trước tiên gửi cho 2 người; nếu hai người không khớp, gửi thêm tối đa 3 người cho đến khi có hai đáp án trùng nhau
- Giá trị thiết lập là
- Với thiết lập này, khoảng 80% CAPTCHA được giải, trong đó khoảng 90% là chính xác nhưng khoảng 10% có lỗi
- Có trường hợp nhiều worker mắc cùng một lỗi
- Cũng dùng userscript để tự mình hoặc nhờ người quen giải CAPTCHA rồi lưu ảnh và đáp án
- Thu thêm vài trăm ảnh để đưa vào tập huấn luyện
- Cách tiếp cận này dừng lại do throttling khi yêu cầu lặp lại và CAPTCHA tăng độ khó
Tạo dữ liệu tổng hợp
- 4Chan và mã CAPTCHA tương ứng không phải mã nguồn mở nên không thể chạy cùng mã đó cục bộ
- Thay vào đó, dự án tạo CAPTCHA tổng hợp bằng cách xấp xỉ cấu trúc CAPTCHA thực tế
- CAPTCHA được xử lý thành hai phần: nền và ký tự
- Nền được lấy bằng cách tìm contour lớn trong ảnh thực tế rồi loại bỏ vùng ký tự
- Sau khi xóa ký tự, chỉ còn nền nhiễu
- Từng ký tự riêng lẻ được thu thập bằng gán nhãn thủ công
- Dùng VoTT để tag ký tự
- Dùng script đơn giản để trích xuất ký tự và hậu xử lý
- Thu được 50–150 ảnh tách biệt cho mỗi ký tự
- CAPTCHA của 4Chan chỉ bao gồm
0, 2, 4, A, D, G, H, J, K, M, N, P, R, S, T, W, X, Y- Có khả năng đây là lựa chọn nhằm tránh nhầm lẫn
- Kết hợp các ký tự và nền đã trích xuất, rồi tạo ảnh tổng hợp theo các mẫu bố trí ký tự đã quan sát
- Vì ký tự đầu vào đã được gán nhãn, đáp án của CAPTCHA tổng hợp cũng có thể tạo tự động
Kiến trúc mô hình và tiền xử lý
- Dữ liệu huấn luyện trộn CAPTCHA thanh trượt đã căn chỉnh trước, CAPTCHA thông thường và CAPTCHA tổng hợp
- Script huấn luyện đưa mọi ảnh về 300x80 pixel và chuyển thành đen trắng thuần
- Mô hình là kiến trúc LSTM CNN được xây dựng tham khảo từ nhiều bài viết về giải CAPTCHA
- Dùng 3 lớp convolution/max-pooling
- Dùng 2 lớp LSTM
- Cũng thử lớp convolution thứ 4 nhưng hiệu năng không cải thiện
- Do độ dài đầu ra thay đổi giữa 5 hoặc 6 ký tự, mô hình dùng mã hóa CTC
- Phần triển khai dùng Keras và TensorFlow
Vấn đề thứ tự tham số của tf.image.resize()
- Một số CAPTCHA thanh trượt đã căn chỉnh cũ không khớp với độ phân giải hoặc tỷ lệ 300x80
- Script huấn luyện dùng
tf.image.resize()để xử lý nhiều loại đầu vào - Ban đầu tác giả giả định tham số kích thước là tuple
(width, height), nhưng thực tếtf.image.resize()yêu cầu thứ tự(height, width) - Lỗi này khiến ảnh bị kéo dọc thành dạng như 80x300, không thể đọc được
- Dù huấn luyện hơn 32 epoch, hiệu năng trên ảnh đã thấy gần như không có
- Với CAPTCHA mới, dự đoán gần như ngẫu nhiên
- Khi trực quan hóa ảnh đầu vào đã xử lý, vấn đề được xác nhận; sau khi sửa, hiệu năng huấn luyện cải thiện mạnh
Quy mô huấn luyện và kết quả
- Tập dữ liệu cuối cùng gồm khoảng 500 ảnh giải thủ công và khoảng 50.000 ảnh tổng hợp
- Ảnh tổng hợp được tạo bằng cách lấy mẫu ngẫu nhiên từ khoảng 2.500 ảnh nền và 50–150 ảnh cho từng ký tự
- Tập dữ liệu được xáo trộn ngẫu nhiên rồi chia theo tỷ lệ 90/10 thành tập huấn luyện và tập đánh giá
- Trên NVIDIA RTX A4000 Laptop GPU, thời gian huấn luyện mỗi epoch khoảng 45 giây
- Khi kết thúc epoch đầu, loss ở mức 19 và dự đoán hầu như không đúng
- Khi kết thúc epoch thứ 4, loss giảm xuống 0,55, và đúng cả 5/5 dự đoán thử nghiệm ngẫu nhiên
- 8–16 epoch là điểm cân bằng tốt giữa thời gian và hiệu năng cuối cùng
- Khoảng epoch thứ 8, loss ổn định
- Sau 16 epoch, mức cải thiện giảm đáng kể
- Dùng
trainer/infer.pyđể kiểm thử suy luận trong Python, kết quả trên ảnh chưa từng thấy cũng khá hứa hẹn
Chuyển đổi sang TensorFlow.js và chạy trong trình duyệt
- Userscript được viết bằng TensorFlow.js và TypeScript
- Thuật toán căn chỉnh CAPTCHA và mã tiền xử lý ảnh từ Python được triển khai lại
- Mã liên quan nằm trong thư mục
user-scripts/của repository - Định dạng mô hình TensorFlow/Keras của Python không tương thích với định dạng mà TensorFlow.js kỳ vọng
- Cần dùng script chuyển đổi chính thức, nhưng có hai vấn đề
- Trình chuyển đổi TensorFlow-to-TFJS chính thức không hoạt động trên Python 3.12 và thông báo lỗi cũng không rõ ràng
- Khi dùng Python 3.10 bằng PyEnv, quá trình chuyển đổi thành công
- Script chuyển đổi có thể chuyển mô hình Keras 3 sang định dạng TensorFlow.js, nhưng TensorFlow.js thực tế lại không đọc được mô hình đã chuyển đổi đó
- Vấn đề liên quan được xác nhận qua bài đăng diễn đàn
- Cách giải quyết là dùng Keras 2
- Cài đặt gói legacy
tf_keras - Đặt biến môi trường
TF_USE_LEGACY_KERAS=1để huấn luyện - Xuất ra định dạng mô hình legacy
.h5và chỉ định định dạng đầu vào cho script chuyển đổi - Chỉ cần một thay đổi đơn giản một dòng trong mã
- Cài đặt gói legacy
Hiệu năng trên CAPTCHA 4Chan thực tế
- Mô hình cũng hoạt động tốt trên CAPTCHA 4Chan thực tế
- Lần tải mô hình đầu tiên mất khoảng 1 giây
- Các lần chạy sau gần như tức thì theo cảm nhận
- Theo kinh nghiệm giải hàng trăm CAPTCHA thực tế trong trình duyệt, tỷ lệ thành công trên 90%
- Trường hợp sai ký tự bản thân khá hiếm; khi không chính xác, thường là bỏ sót nguyên một ký tự
- Có thể cải thiện thêm bằng cách tăng huấn luyện trên dữ liệu thực tế hoặc điều chỉnh layout CAPTCHA của bộ tạo dữ liệu tổng hợp
- Độ chính xác của mô hình này cao hơn nhiều so với dịch vụ giải CAPTCHA bằng người thật thương mại
CAPTCHA 4 ký tự và kết thúc
- Trong lúc viết và chỉnh sửa bài sau khi hoàn thành dự án, 4Chan đôi khi bắt đầu cung cấp CAPTCHA 4 ký tự
- Mô hình chỉ được huấn luyện trên CAPTCHA 5 và 6 ký tự, nhưng vẫn đạt mức hiệu năng tương tự trên CAPTCHA 4 ký tự
- Trong quá trình dự án, tác giả đã học được nhiều về machine learning và computer vision, đồng thời hoàn thành mô hình giải CAPTCHA trên trình duyệt đúng như mục tiêu ban đầu
1 bình luận
Ý kiến trên Hacker News
Phần tích hợp Keras với TensorFlow.js lộn xộn đúng kiểu TensorFlow
Mỗi lần dùng TensorFlow, tôi luôn có cảm giác nó giống một loạt công cụ trông có vẻ liên quan được gom đại dưới cùng một mái nhà, hơn là một sản phẩm tích hợp và trơn tru
Thật ra có thể nói hầu như mọi thư viện hay công cụ mã nguồn mở của Google đều mang cảm giác như vậy
Câu trả lời cho “vì sao năm 2019 lại quyết định sáp nhập Keras vào TensorFlow?” là “đó không phải quyết định của tôi. Đó là quyết định của các lãnh đạo TF vào năm 2018; lúc đó tôi là một cá nhân đóng góp cấp L5, còn đó là quyết định cấp L8”
Tôi cần CAPTCHA để chặn spam ở form bình luận trên trang của mình[0], nên đã tái sử dụng một cách khá thú vị mà tôi từng thấy trước đây
Nó chắc chắn không hoàn hảo và cũng không khó, nhưng tôi rất thích quá trình làm ra nó
[0] https://www.hybridlogic.co.uk/contact
https://vivirenremoto.github.io/doomcaptcha/
Có lý do khiến mọi người rời xa CAPTCHA dựa trên văn bản bị bóp méo
Giờ gần như đã đến điểm máy tính giải chúng giỏi hơn con người
https://www.usenix.org/system/files/conference/woot14/woot14... là một bài báo về chủ đề này, theo tôi khá thú vị
Dù vậy, đáng ngạc nhiên là rất nhiều CAPTCHA dạng văn bản vẫn có thể bị giải bằng vài dòng shell script: dùng ImageMagick chuyển sang ảnh xám, xử lý giãn nở và co ảnh, rồi đưa cho Tesseract
Nhưng cũng có các trang như https://2captcha.net, nên rốt cuộc CAPTCHA gần giống một cơ chế đòi hỏi một chút công sức tối thiểu
Cách giải trong bài này cũng tốn khá nhiều thời gian, kỹ năng và công sức; kết quả lại không khái quát hóa tốt, nên với loại CAPTCHA khác thì phải làm lại từ đầu
Phần lớn spammer sẽ không tái hiện được điều này, còn những người có thể làm được thì có khả năng kiếm tiền hợp pháp hoặc nhắm vào mục tiêu sinh lợi hơn
Những CAPTCHA như vậy vẫn hoạt động tốt trong việc đẩy chi phí spam thành công lên cao hơn lợi nhuận kỳ vọng
Liệu có thể làm một diễn đàn mà mọi thành viên đều phải phỏng vấn video 15 phút với quản trị viên không? Tôi biết là “không mở rộng được”, nhưng như một cơ chế đùa vui thì có vẻ khả thi
Nó không phải giải pháp, mà giống một pháo đài nhỏ đang dần lỗi thời
Theo liên kết, reCAPTCHA v3 mất 10–15 giây và tốn 1,3 USD cho mỗi 1000 CAPTCHA
Với nhiều tác vụ muốn vượt CAPTCHA, chẳng hạn cào dữ liệu các website lớn ở quy mô lớn, chi phí này thực sự khá lớn và trở nên khó gánh
mCaptcha.org là một trong số đó, và cũng có các triển khai khác
CAPTCHA truyền thống hễ hiệu quả dù chỉ một chút thì rất dễ trở thành cơn ác mộng về khả năng tiếp cận
Nếu bạn quan tâm đến chủ đề kiểu này, tôi cũng có một phân tích về Silk Road CAPTCHA mà tôi đã tổng hợp năm 2014: https://github.com/mieko/sr-captcha
Cách 4chan phản ứng trông có vẻ hợp lý
Dù sao thì mạng nơ-ron cũng giải được dễ dàng, nên họ chọn đơn giản hóa phần việc giao cho con người
Giờ dù thiết kế CAPTCHA cực khó thì khả năng làm máy khó giải cũng thấp, còn xác suất chỉ khiến con người bực hơn lại cao
https://4chan.org/pass
Nó vốn đã được cung cấp như một tùy chọn để đăng bài không cần CAPTCHA
Nếu CAPTCHA hoàn toàn vô hiệu, kết luận kéo theo là nên bỏ CAPTCHA và đăng bài miễn phí, còn ai muốn đăng thì đều phải mua 4chan Pass
Gần đây họ đưa vào độ trễ đăng bài 15 phút, thật sự rất bực
Tôi đã phải đưa 4chan vào danh sách cho phép trong Cookie AutoDelete
Có lẽ giả vờ như có CAPTCHA, nhưng thực ra phân tích thời điểm và hành vi của người dùng thì tốt hơn chăng
Nói thật là tôi cũng có cảm giác chuyện đó đã đang xảy ra rồi
Nếu đi theo hướng hoàn toàn meta, cũng có thể huấn luyện AI để phán đoán xem tác nhân ở phía bên kia có phải là người hay không
Tức là coi như phát minh ra một bài kiểm tra Turing ngược, theo kiểu nếu AI không phân biệt được với phản hồi của một người bình thường thì xem là người
Điểm khác là không phải phân biệt với phản hồi của con người dùng cho mục đích marketing
Chỉ nghĩ đến chuyện này thôi đã thấy hơi buồn nôn, chắc phải đi nằm
Trước cả khi hiển thị CAPTCHA, họ đã nhận diện trước dấu vân tay TLS, IP, HTTP/2, request, môi trường JavaScript, khả năng render phông chữ và hình ảnh, cũng như chính trình duyệt
Họ dùng các thông tin này để tính điểm tin cậy, rồi quyết định ngay từ đầu có hiển thị CAPTCHA hay không
Sau đó việc phân tích phần nhập CAPTCHA mới có ý nghĩa, nhưng đến thời điểm đó thì có thể coi là đã bắt được 90% bot rồi
Lượng thông tin mà trình duyệt có thể báo cho máy chủ mà không hề nhận thức gì là phi lý đến mức dấu vân tay số của mỗi chúng ta có khi còn độc nhất hơn cả dấu vân tay thật
Tôi vẫn cho rằng trường hợp gốc thuộc hàng kinh điển của việc vượt CAPTCHA 4chan là Yannick Kilcher fine-tune GPT-J bằng dataset “Raiders of the Lost Kek”
Có thể đây là một trong những ví dụ hay nhất về việc dùng mô hình ngôn ngữ lớn từng được đưa lên video: https://youtu.be/efPrtcLdcdM?si=errY0PrEhnX9ylDw
Đáng được ghi vào kỷ lục
Vì những chuyện như “bộ chuyển đổi mô hình TensorFlow-to-TFJS chính thức không hoạt động trên Python 3.12 và tài liệu cũng không được viết đàng hoàng”, “TensorFlow.js không hỗ trợ Keras 3”, vài năm trước tôi định thử làm machine learning nhẹ nhàng mà gần như bỏ cuộc
Có quá nhiều tutorial mới nhất thực ra đã lỗi thời, quá nhiều bẫy ngẫu nhiên, và thật sốc khi nhiều hướng dẫn “bắt đầu” lại mặc định rằng bạn đã là chuyên gia
Tốt hơn là học nền tảng từ một giáo trình thống kê Bayes cũ, rồi sau đó chuyển sang các framework chính như PyTorch
Ban đầu nên tự viết mọi phần của các kiến trúc CNN, RNN, Transformer và pipeline huấn luyện
Bao gồm cả data loader, nhưng có thể bỏ qua CUDA matrix kernel
Nên tránh xa những wrapper bọc lại wrapper của người khác như LangChain
Tài liệu không chỉ lỗi thời, mà nhiều khi còn sai hẳn về những kiến thức nền tảng
Hugging Face rất tuyệt nếu bạn nắm được cơ bản và có thể sửa khi wrapper chuẩn bị hỏng
Chuyện này giống như bỏ ra vài giờ để học cách mở nắp bể phốt
Nếu lần theo liên kết tới các dịch vụ giải CAPTCHA, bạn có thể đọc hồ sơ của những người làm công việc đó
Nó được quảng bá theo kiểu việc này có đạo đức hơn so với làm trong các nhà máy nguy hiểm