├── proxies.txt ├── README.md └── main.py /proxies.txt: -------------------------------------------------------------------------------- 1 | proxies here 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Funcaptcha Solver 2 | A funcaptcha audio-based solver that uses google's speech_recognition to solve images, which is being tested on a **now patched** roblox vulnerability in this project to complete captchas with ease. 3 | 4 | # Requirements 5 | ```bash 6 | requests 7 | termcolor 8 | radnom 9 | string 10 | threading 11 | itertools 12 | speech_recognition 13 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import speech_recognition as sr 2 | import requests 3 | import termcolor 4 | import random 5 | import string 6 | import time 7 | import os 8 | import threading 9 | from itertools import cycle 10 | 11 | os.system('color') 12 | 13 | with open('proxies.txt','r+', encoding='utf-8') as f: 14 | ProxyPool = cycle(f.read().splitlines()) 15 | 16 | 17 | def get_token(): 18 | r = requests.post('https://client-api.arkoselabs.com/fc/gt2/public_key/476068BF-9607-4799-B53D-966BE98E2B81', proxies=proxy, data = { 19 | 'bda': '', 20 | 'public_key': '476068BF-9607-4799-B53D-966BE98E2B81', 21 | 'site': 'https://www.roblox.com', 22 | 'userbrowser': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36', 23 | 'rnd': f'0.{random.choice("12334565789")}' 24 | }) 25 | return r.json()['token'] 26 | 27 | def recognize(audiofilename): 28 | r = sr.Recognizer() 29 | with sr.AudioFile(audiofilename + '.wav') as s: 30 | data = r.record(s) 31 | raw = r.recognize_google(data) 32 | answer = '' 33 | for char in raw: 34 | if char.isdigit(): 35 | answer += char 36 | return answer 37 | 38 | def getDirectory(name): 39 | mypath = os.getcwd() 40 | path = rf"{mypath}\Audios\{name}" 41 | return path 42 | 43 | def solveCaptcha(token, proxy, threadnum): 44 | session_token = token.split('|')[0] 45 | print(f'[{threadnum}]: Attempting to solve {session_token}') 46 | r = requests.get(f'https://client-api.arkoselabs.com/fc/get_audio/?session_token={session_token}&analytics_tier=40&r=us-east-1&game=1&language=en', proxies=proxy) 47 | res = ''.join(random.choices(string.ascii_uppercase + string.digits, k = 7)) 48 | dirpath = getDirectory(res) 49 | open(dirpath + '.wav', 'wb+').write(r.content) 50 | 51 | 52 | r = requests.post('https://client-api.arkoselabs.com/fc/audio/', 53 | 54 | headers = { 55 | 'authority': 'client-api.arkoselabs.com', 56 | 'accept': '*/*', 57 | 'cache-control': 'no-cache', 58 | 'x-newrelic-timestamp': str(round(time.time())), 59 | 'x-requested-with': 'XMLHttpRequest', 60 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36', 61 | 'content-type': 'application/x-www-form-urlencoded', 62 | 'origin': 'https://client-api.arkoselabs.com', 63 | 'sec-fetch-site': 'same-origin', 64 | 'sec-fetch-mode': 'cors', 65 | 'sec-fetch-dest': 'empty', 66 | 'accept-language': 'en-US,en;q=0.9' 67 | }, 68 | data={ 69 | 'session_token': session_token, 70 | 'language': 'en', 71 | 'r': 'us-east-1', 72 | 'audio_type': '2', 73 | 'response': recognize(dirpath), 74 | 'analytics_tier': '40' 75 | }, 76 | proxies=proxy 77 | ) 78 | try: 79 | if r.json()['response'] == 'correct': 80 | print(termcolor.colored(f'[{threadnum}]: Successfully solved captcha!', color='green')) 81 | print(r.text) 82 | elif r.json()['response'] != 'correct': 83 | print(f'[{threadnum}]: ratelimited on funcaptcha API or response was incorrect. Retrying.') 84 | proxy = {"https": "https://" + next(ProxyPool)} 85 | else: 86 | print(f'[{threadnum}]: Captcha solver response incorrect.') 87 | except KeyError: 88 | pass 89 | except: 90 | pass 91 | 92 | def worker(proxy, threadnum): 93 | while True: 94 | token = get_token() 95 | solveCaptcha(token, proxy, threadnum) 96 | 97 | for threadnum in range(50): 98 | proxy = {"https": "https://" + next(ProxyPool)} 99 | threading.Thread(target=worker, args=[proxy, threadnum]).start() 100 | --------------------------------------------------------------------------------