Memecahkan CAPTCHA 4Chan
(nullpt.rs)- Proyek ini membuat model TensorFlow.js untuk menyelesaikan CAPTCHA 4Chan secara otomatis di dalam browser, dan berhasil mencapai target minimum akurasi 80% serta target yang diinginkan di atas 90%
- Pengumpulan CAPTCHA sulit ditangani dengan scraping massal sederhana karena
ttl,cdpada API permintaan, Cloudflare Turnstile, dan waktu tunggu yang terus meningkat - Layanan pemecahan komersial berbasis manusia dan pelabelan manual terbentur kesalahan serta throttling; untuk memperoleh skala pelatihan, dibuat sekitar 50.000 data sintetis dari sekitar 2.500 latar nyata dan 50–150 gambar per karakter
- Model menggunakan arsitektur CNN+LSTM dan encoding CTC; setelah pelatihan Keras/TensorFlow, model dikonversi ke TensorFlow.js melalui Python 3.10, Keras 2, dan format
.h5 - Di browser nyata, pemuatan pertama memakan waktu sekitar 1 detik, eksekusi berikutnya terasa instan, dan pada ratusan CAPTCHA nyata menunjukkan tingkat keberhasilan di atas 90%
Tujuan dan kode publik
- Tujuannya adalah membuat model yang dapat menyelesaikan CAPTCHA 4Chan secara stabil di browser sekaligus mempelajari machine learning dan pelatihan TensorFlow
- Patokannya adalah akurasi minimal 80%, jika memungkinkan di atas 90%, dan pada akhirnya tercapai
- Kode terkait dipublikasikan di GitHub: 4chan-captcha-playground
Cara kerja CAPTCHA 4Chan
- 4Chan mewajibkan input CAPTCHA sebelum menulis posting atau balasan
- CAPTCHA biasa berupa gambar berisi 5–6 karakter alfanumerik, dan pengguna harus memasukkan semua karakter dengan tepat
- CAPTCHA slider bekerja dengan mencocokkan gambar latar yang tampak seperti potongan karakter acak dengan gambar depan yang memiliki lubang transparan, sehingga teks CAPTCHA terlihat
Batasan yang ditemui saat mengumpulkan CAPTCHA
- Saat mengamati permintaan CAPTCHA baru, browser mengirim permintaan ke
https://sys.4chan.org/captcha?framed=1&board={board} - Jika
framed=1dihapus, yang dikembalikan adalah JSON mentah alih-alihpostMessage()di dalam HTML- JSON mencakup
challenge,ttl,cd,img,img_width,img_height,bg,bg_width, dan lainnya ttltampaknya adalah waktu CAPTCHA kedaluwarsa setelah sekitar 2 menitcdditafsirkan sebagai nilai cooldown yang harus ditunggu sebelum permintaan CAPTCHA berikutnya
- JSON mencakup
- Jika mengirim permintaan berurutan,
cdmakin besar- Pada beberapa permintaan awal, permintaan bisa dikirim tiap 5 detik
- Setelah itu meningkat menjadi 8 detik, lalu terus bertambah kira-kira dua kali lipat
- Pada akhirnya mencapai batas atas di 280 detik
- Setelah mencapai timer 280 detik, CAPTCHA menjadi lebih sulit
- Muncul gambar dengan beberapa garis horizontal dan gangguan berbentuk elips
- Kualitas data menurun, tetapi masih bisa digunakan
- Sebelum meminta CAPTCHA, perlu melewati Cloudflare Turnstile
- Pendekatan memakai banyak proxy dan skrip sederhana tidak realistis
- Skrip pengumpul menyalin cookie Cloudflare dari browser dan menggunakannya, lalu menggantinya secara manual saat kedaluwarsa
- Dengan cara ini terkumpul ratusan CAPTCHA, tetapi jumlahnya belum cukup untuk pelatihan dan juga tidak ada label jawaban
Keterbatasan pelabelan berbasis manusia
- Penyelarasan CAPTCHA slider menunjukkan tingkat keberhasilan 100% dengan skrip heuristik
trainer/captcha_aligner.py - Dibuat
trainer/labeler.pyyang mengirim CAPTCHA ke layanan pemecahan CAPTCHA komersial agar manusia sungguhan memasukkan jawabannya - Puluhan CAPTCHA pertama yang dikirim sebagian besar dipecahkan dengan setidaknya satu karakter yang salah
- Fitur “100% Recognition” pada layanan digunakan agar hasil hanya diterima ketika jawaban dari beberapa pekerja cocok
- Nilai pengaturannya adalah
n = 2,x = 2,y = 3 - Pertama dikirim ke 2 orang; jika keduanya tidak cocok, dikirim ke maksimal 3 orang tambahan sampai ada dua jawaban yang cocok
- Nilai pengaturannya adalah
- Dengan pengaturan ini, sekitar 80% CAPTCHA berhasil dipecahkan; dari jumlah itu sekitar 90% benar, tetapi sekitar 10% mengandung kesalahan
- Ada kasus ketika beberapa pekerja membuat kesalahan yang sama
- Juga digunakan user script untuk menyelesaikan CAPTCHA secara langsung atau dengan bantuan kenalan, lalu menyimpan gambar dan jawabannya
- Ratusan gambar tambahan diperoleh dan dimasukkan ke set pelatihan
- Pendekatan ini dihentikan karena throttling permintaan berulang dan meningkatnya tingkat kesulitan CAPTCHA
Pembuatan data sintetis
- 4Chan dan kode CAPTCHA terkait bukan open source, sehingga kode yang sama tidak bisa dijalankan secara lokal
- Sebagai gantinya, dibuat CAPTCHA sintetis dengan mendekati struktur CAPTCHA nyata
- CAPTCHA ditangani dengan membaginya menjadi dua bagian: latar dan karakter
- Latar diperoleh dengan menemukan contour besar pada gambar nyata dan menghapus area karakter
- Setelah karakter dihapus, hanya tersisa latar noise
- Karakter individual diperoleh melalui pelabelan manual
- Karakter ditag dengan VoTT
- Karakter diekstrak dan diproses lanjutan dengan skrip sederhana
- Untuk setiap karakter diperoleh 50–150 gambar terisolasi
- CAPTCHA 4Chan hanya berisi
0, 2, 4, A, D, G, H, J, K, M, N, P, R, S, T, W, X, Y- Kemungkinan ini dipilih untuk menghindari ambiguitas
- Karakter dan latar yang diekstrak digabungkan, lalu gambar sintetis dibuat mengikuti pola penempatan karakter yang diamati
- Karena karakter input sudah diberi label, jawaban untuk CAPTCHA sintetis juga bisa dibuat otomatis
Struktur model dan prapemrosesan
- Data pelatihan menggunakan campuran CAPTCHA slider yang sudah diselaraskan, CAPTCHA biasa, dan CAPTCHA sintetis
- Skrip pelatihan menyeragamkan semua gambar menjadi 300x80 piksel dan mengubahnya menjadi hitam-putih murni
- Modelnya adalah struktur LSTM CNN yang disusun dengan merujuk berbagai tulisan terkait pemecahan CAPTCHA
- Menggunakan 3 layer convolution/max-pooling
- Menggunakan 2 layer LSTM
- Layer convolution ke-4 juga dicoba, tetapi tidak meningkatkan performa
- Karena panjang output bervariasi antara 5 atau 6 karakter, digunakan encoding CTC
- Implementasinya menggunakan Keras dan TensorFlow
Masalah urutan argumen tf.image.resize()
- Sebagian CAPTCHA slider lama yang sudah diselaraskan tidak sesuai dengan resolusi atau rasio aspek 300x80
- Skrip pelatihan menggunakan
tf.image.resize()agar dapat menangani berbagai input - Awalnya argumen ukuran diasumsikan berupa tuple
(width, height), tetapi sebenarnyatf.image.resize()mengharuskan urutan(height, width) - Kesalahan ini membuat gambar menjadi memanjang vertikal dan tidak terbaca, seperti 80x300
- Bahkan setelah dilatih lebih dari 32 epoch, performa pada gambar yang sudah dilihat hampir tidak muncul
- Pada CAPTCHA baru, prediksinya hampir acak
- Masalah terkonfirmasi saat memvisualisasikan gambar input yang telah diproses, dan setelah diperbaiki performa pelatihan meningkat signifikan
Skala pelatihan dan hasil
- Dataset akhir terdiri dari sekitar 500 gambar yang dipecahkan secara manual dan sekitar 50.000 gambar sintetis
- Gambar sintetis dibuat dengan sampling acak dari sekitar 2.500 gambar latar dan 50–150 gambar per karakter
- Dataset diacak lalu dibagi menjadi set pelatihan dan set evaluasi dengan rasio 90/10
- Pada GPU NVIDIA RTX A4000 Laptop, waktu pelatihan per epoch sekitar 45 detik
- Pada akhir epoch pertama, loss berada di kisaran 19 dan prediksi hampir tidak ada yang benar
- Pada akhir epoch ke-4, loss turun hingga 0,55, dan 5 dari 5 prediksi uji acak benar
- 8–16 epoch menjadi kompromi yang baik antara waktu dan performa akhir
- Sekitar epoch ke-8, loss mulai stabil
- Setelah melampaui 16 epoch, peningkatannya jauh berkurang
- Inferensi diuji di Python dengan
trainer/infer.py, dan hasilnya menjanjikan bahkan pada gambar yang belum pernah dilihat
Konversi TensorFlow.js dan eksekusi di browser
- User script ditulis dengan TensorFlow.js dan TypeScript
- Algoritma penyelarasan CAPTCHA dan kode prapemrosesan gambar dari Python diimplementasikan ulang
- Kode terkait ada di direktori
user-scripts/pada repositori - Format model Python TensorFlow/Keras tidak kompatibel dengan format yang diharapkan TensorFlow.js
- Harus menggunakan skrip konversi resmi, tetapi ada dua masalah
- Konverter resmi TensorFlow-to-TFJS tidak berjalan di Python 3.12 dan pesan error-nya juga tidak jelas
- Dengan menggunakan Python 3.10 melalui PyEnv, konversi berhasil
- Skrip konversi dapat mengonversi model Keras 3 ke format TensorFlow.js, tetapi TensorFlow.js ternyata tidak bisa membaca model hasil konversi itu
- Masalah terkait dikonfirmasi melalui forum post
- Solusinya adalah menggunakan Keras 2
- Menginstal paket legacy
tf_keras - Menetapkan variabel lingkungan
TF_USE_LEGACY_KERAS=1untuk pelatihan - Mengekspor ke format model legacy
.h5dan menentukan format input pada skrip konversi - Perubahan kode yang dibutuhkan hanya satu baris sederhana
- Menginstal paket legacy
Performa pada CAPTCHA 4Chan nyata
- Model juga bekerja dengan baik pada CAPTCHA 4Chan nyata
- Pemuatan model pertama memakan waktu sekitar 1 detik
- Eksekusi berikutnya terasa instan
- Berdasarkan pengalaman memecahkan ratusan CAPTCHA nyata di browser, tingkat keberhasilannya di atas 90%
- Kasus salah membaca karakter itu sendiri jarang terjadi; ketika tidak akurat, biasanya satu karakter terlewat seluruhnya
- Masih ada ruang perbaikan dengan menambah pelatihan pada data nyata atau menyesuaikan tata letak CAPTCHA pada generator data sintetis
- Akurasi model ini jauh lebih tinggi dibanding layanan pemecahan CAPTCHA komersial berbasis manusia
CAPTCHA 4 karakter dan penutup
- Setelah proyek selesai, saat tulisan ini ditulis dan diedit, 4Chan mulai sesekali menyediakan CAPTCHA 4 karakter
- Model hanya dilatih dengan CAPTCHA 5 dan 6 karakter, tetapi tetap menunjukkan performa pada level yang sama untuk CAPTCHA 4 karakter
- Selama proyek ini, banyak hal dipelajari tentang machine learning dan computer vision, dan model pemecah CAPTCHA berbasis browser yang menjadi tujuan awal berhasil diselesaikan
1 komentar
Opini Hacker News
Bagian integrasi Keras dengan TensorFlow.js yang berantakan terasa khas TensorFlow
Saat memakai TensorFlow, rasanya selalu lebih seperti sekumpulan alat yang kurang lebih terlihat terkait lalu dikumpulkan di bawah satu payung, bukan produk yang terintegrasi dan mulus
Sebenarnya bisa dibilang semua library atau alat open source Google terasa seperti ini
Jawaban untuk “mengapa pada 2019 Keras diputuskan digabungkan ke TensorFlow?” adalah “itu bukan keputusan saya. Itu keputusan para pemimpin TF pada 2018; saat itu saya adalah kontributor individu L5, sementara itu keputusan L8”
Di situs saya[0], saya butuh CAPTCHA untuk mencegah spam formulir komentar, jadi saya mencoba memakai ulang metode menarik yang pernah saya lihat dulu
Sama sekali tidak sempurna dan tidak sulit, tetapi saya sangat menyukai proses pembuatannya
[0] https://www.hybridlogic.co.uk/contact
https://vivirenremoto.github.io/doomcaptcha/
Ada alasan mengapa orang-orang mulai meninggalkan CAPTCHA berbasis teks terdistorsi
Sekarang kita hampir berada di titik komputer bisa menyelesaikannya lebih baik daripada manusia
https://www.usenix.org/system/files/conference/woot14/woot14... adalah makalah tentang topik ini, dan menurut saya cukup menarik
Meski begitu, sangat banyak CAPTCHA berbasis teks ternyata bisa dipecahkan dengan skrip shell beberapa baris yang memakai ImageMagick untuk mengubahnya ke grayscale, melakukan dilasi dan erosi, lalu meneruskannya ke Tesseract
Namun ada juga situs seperti https://2captcha.net, jadi pada akhirnya CAPTCHA lebih mirip perangkat yang menuntut sedikit upaya minimal
Solusi dalam artikel ini pun membutuhkan cukup banyak waktu, keterampilan, dan usaha, dan hasilnya juga tidak tergeneralisasi dengan baik, sehingga untuk jenis CAPTCHA lain harus mulai lagi dari awal
Sebagian besar spammer tidak akan bisa mereplikasinya, dan orang yang bisa mereplikasinya kemungkinan dapat menghasilkan uang secara legal atau menargetkan sasaran yang lebih menguntungkan
CAPTCHA semacam ini masih bekerja dengan baik untuk membuat biaya spam yang berhasil menjadi lebih tinggi daripada pendapatan yang diperkirakan
Bisakah kita membuat forum yang semua anggotanya harus menjalani wawancara video 15 menit dengan operator? Saya tahu itu “tidak skalabel”, tetapi sebagai mekanisme seperti lelucon yang lucu, rasanya mungkin saja
Itu bukan solusi, melainkan semacam benteng kecil yang perlahan-lahan menua
Menurut tautan tersebut, reCAPTCHA v3 memakan waktu 10–15 detik dan biayanya 1,3 dolar per 1000 CAPTCHA
Untuk banyak pekerjaan yang ingin melewati CAPTCHA, seperti scraping situs besar dalam skala masif, biaya ini benar-benar cukup besar dan sulit ditanggung
mCaptcha.org adalah salah satunya, dan ada implementasi lain juga
CAPTCHA tradisional, jika sedikit saja efektif, cenderung menjadi mimpi buruk dari sisi aksesibilitas
Jika tertarik pada topik seperti ini, ada juga analisis Silk Road CAPTCHA yang saya rangkum pada 2014: https://github.com/mieko/sr-captcha
Respons 4chan tampaknya masuk akal
Karena toh mudah dipecahkan dengan neural network, mereka memilih menyederhanakan pekerjaan yang diberikan kepada manusia
Sekarang, meski merancang CAPTCHA yang sangat sulit, kecil kemungkinan itu akan makin sulit bagi mesin, dan lebih besar kemungkinan hanya membuat manusia makin kesal
https://4chan.org/pass
Ini sudah ditawarkan sebagai opsi untuk menulis tanpa CAPTCHA
Jika CAPTCHA sepenuhnya tidak berguna, kesimpulannya adalah menghapus CAPTCHA dan penulisan gratis, lalu semua orang yang ingin menulis harus membeli 4chan Pass
Baru-baru ini mereka menerapkan penundaan menulis 15 menit, dan itu benar-benar menyebalkan
Saya sampai harus memasukkan 4chan ke daftar izinkan di Cookie AutoDelete
Saya pikir mungkin lebih baik berpura-pura ada CAPTCHA, padahal sebenarnya menganalisis timing dan perilaku pengguna
Sejujurnya, rasanya hal seperti itu sudah terjadi
Kalau mau sepenuhnya meta, AI juga bisa dilatih untuk menilai apakah pelaku di pihak lain itu manusia atau bukan
Dengan kata lain, kita menciptakan semacam tes Turing terbalik, dan jika AI tidak bisa membedakannya dari respons manusia normal, maka dianggap manusia
Bedanya, ini bukan soal membedakannya dari respons manusia untuk keperluan pemasaran
Memikirkan ini saja sudah membuat saya agak mual, jadi saya harus berbaring
Bahkan sebelum menampilkan CAPTCHA, mereka terlebih dahulu mengidentifikasi fingerprint TLS, IP, HTTP/2, request, lingkungan JavaScript, kemampuan rendering font dan gambar, serta browser itu sendiri
Dari informasi ini mereka menghitung skor kepercayaan, lalu memutuskan apakah CAPTCHA perlu ditampilkan sejak awal
Setelah itu barulah analisis input CAPTCHA menjadi relevan, tetapi pada titik itu 90% bot sudah tertangkap
Jumlah informasi yang bisa diberitahukan browser ke server tanpa disadari sangat tidak masuk akal, sampai-sampai fingerprint digital kita masing-masing kemungkinan lebih unik daripada sidik jari sungguhan
Saya masih menganggap contoh awal yang sekelas pelopor dalam menembus CAPTCHA 4chan adalah ketika Yannick Kilcher melakukan fine-tuning GPT-J dengan dataset “Raiders of the Lost Kek”
Mungkin ini salah satu contoh paling keren penggunaan model bahasa besar yang pernah ditampilkan dalam video: https://youtu.be/efPrtcLdcdM?si=errY0PrEhnX9ylDw
Layak dicatat dalam sejarah
Beberapa tahun lalu saya sempat mencoba machine learning secara ringan, tetapi nyaris menyerah karena hal-hal seperti “konverter model resmi TensorFlow-to-TFJS tidak berjalan di Python 3.12 dan dokumentasinya juga tidak benar-benar memadai”, atau “TensorFlow.js tidak mendukung Keras 3”
Terlalu sering tutorial terbaru ternyata sudah usang, terlalu banyak jebakan acak, dan cukup mengejutkan betapa banyak panduan “mulai cepat” yang berasumsi pembacanya sudah ahli
Lebih baik pelajari dasar-dasarnya dari buku teks statistika Bayesian lama, lalu lanjut ke framework utama seperti PyTorch
Di awal, sebaiknya tulis sendiri semua bagian arsitektur CNN, RNN, Transformer, dan pipeline pelatihan
Termasuk data loader, meski kernel matriks CUDA boleh dikecualikan
Sebaiknya jauhi wrapper yang membungkus ulang wrapper orang lain seperti LangChain
Banyak dokumentasi bukan sekadar usang, tetapi bahkan keliru soal dasar-dasarnya
Hugging Face sangat bagus jika Anda sudah memahami dasar-dasarnya dan bisa memperbaiki wrapper standar saat rusak
Ini mirip menghabiskan beberapa jam untuk mempelajari cara membuka tutup tangki septik
Kalau mengikuti tautan layanan pemecahan CAPTCHA, Anda bisa membaca profil orang-orang yang mengerjakan pekerjaan itu
Itu dipromosikan seolah-olah lebih etis daripada bekerja di pabrik berbahaya