mirror of
https://github.com/aydinnyunus/gpt4-captcha-bypass.git
synced 2025-07-13 12:52:25 +08:00
add captcha bypass and requirements
This commit is contained in:
parent
43be02bbba
commit
229b60eb67
295
main.py
Normal file
295
main.py
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver import ActionChains
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.firefox.service import Service as FirefoxService
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
from webdriver_manager.firefox import GeckoDriverManager
|
||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
def average_of_array(arr):
|
||||||
|
if not arr:
|
||||||
|
return 0 # Handle edge case of empty array
|
||||||
|
sum_elements = sum(arr)
|
||||||
|
average = sum_elements / len(arr)
|
||||||
|
return average - 5
|
||||||
|
|
||||||
|
def upload_image_to_imgur(image_path):
|
||||||
|
url = "https://api.imgur.com/3/image"
|
||||||
|
client_id = os.getenv("IMGUR_CLIENT_ID")
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Client-ID {client_id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(image_path, "rb") as image_file:
|
||||||
|
payload = {
|
||||||
|
"image": image_file.read(),
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
response = requests.post(url, headers=headers, files=payload)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
return data['data']['link']
|
||||||
|
else:
|
||||||
|
print("Failed to upload image", response.text)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ask_recaptcha_to_chatgpt(image_url):
|
||||||
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
||||||
|
short_prompt = ("You are an object detection assistant. Understand what is asked on the top instruction of the "
|
||||||
|
"image. For Example if instruction says select all squares with motorcycle. There are 16 squares "
|
||||||
|
"give number for each square 0 to 15. The numbers starts from top left to right. Then answer only "
|
||||||
|
"with the square numbers like 1-3-5-6."
|
||||||
|
"Understand the instruction and give me the highest probability squares as answer. Give only the correct square numbers.")
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
messages=[
|
||||||
|
{"role": "system", "content": short_prompt},
|
||||||
|
{"role": "user", "content": image_url}
|
||||||
|
],
|
||||||
|
temperature=1,
|
||||||
|
max_tokens=256,
|
||||||
|
top_p=1,
|
||||||
|
frequency_penalty=0,
|
||||||
|
presence_penalty=0
|
||||||
|
)
|
||||||
|
return response.choices[0].message.content
|
||||||
|
|
||||||
|
def ask_text_to_chatgpt(image_url):
|
||||||
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
||||||
|
short_prompt = ("Act as a blind person assistant. Read the text from the image and give me only the text answer.")
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": short_prompt
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "image_url",
|
||||||
|
"image_url": {
|
||||||
|
"url": image_url
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": "Understand what is asked on the top instruction of the image. Give me the only correct squares with highest probability"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
temperature=1,
|
||||||
|
max_tokens=256,
|
||||||
|
top_p=1,
|
||||||
|
frequency_penalty=0,
|
||||||
|
presence_penalty=0
|
||||||
|
)
|
||||||
|
return response.choices[0].message.content
|
||||||
|
|
||||||
|
def ask_slide_to_chatgpt(image_url):
|
||||||
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
||||||
|
short_prompt = ("There is an slider button in the page and there is an empty gray space on puzzle. You should give "
|
||||||
|
"give me how many pixels should i slide to complete the puzzle. You can simulate the slider for "
|
||||||
|
"the exact fit before giving the answer.The total width is 210 pixels."
|
||||||
|
"Give me only number of pixels in integer 50 up to 210 pixels.")
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
messages=[
|
||||||
|
{"role": "system", "content": short_prompt},
|
||||||
|
{"role": "user", "content": image_url}
|
||||||
|
],
|
||||||
|
temperature=1,
|
||||||
|
max_tokens=256,
|
||||||
|
top_p=1,
|
||||||
|
frequency_penalty=0,
|
||||||
|
presence_penalty=0
|
||||||
|
)
|
||||||
|
return response.choices[0].message.content
|
||||||
|
|
||||||
|
def puzzle_test(driver):
|
||||||
|
driver.get("https://2captcha.com/demo/geetest")
|
||||||
|
time.sleep(5)
|
||||||
|
button = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable((By.CLASS_NAME, "geetest_radar_tip"))
|
||||||
|
)
|
||||||
|
button.click()
|
||||||
|
box = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.CLASS_NAME, "geetest_embed"))
|
||||||
|
)
|
||||||
|
time.sleep(1)
|
||||||
|
box.screenshot('geetest_box.png')
|
||||||
|
file_url = upload_image_to_imgur('geetest_box.png')
|
||||||
|
time.sleep(1)
|
||||||
|
all_results = []
|
||||||
|
while True:
|
||||||
|
slider = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.CLASS_NAME, "geetest_slider_button"))
|
||||||
|
)
|
||||||
|
time.sleep(2)
|
||||||
|
action = ActionChains(driver)
|
||||||
|
input_string = ask_slide_to_chatgpt(file_url)
|
||||||
|
numbers = re.findall(r'\d+', input_string)
|
||||||
|
if numbers:
|
||||||
|
result = int(numbers[0])
|
||||||
|
else:
|
||||||
|
result = None
|
||||||
|
if result < 110:
|
||||||
|
result = 90
|
||||||
|
all_results.append(result)
|
||||||
|
action.click_and_hold(slider).perform()
|
||||||
|
time.sleep(random.uniform(0.8, 1.2))
|
||||||
|
total_offset = average_of_array(all_results)
|
||||||
|
num_steps = 5
|
||||||
|
step_offset = total_offset / num_steps
|
||||||
|
for _ in range(num_steps):
|
||||||
|
action.move_by_offset(step_offset, 0).perform()
|
||||||
|
time.sleep(random.uniform(0.05, 0.1))
|
||||||
|
action.release().perform()
|
||||||
|
|
||||||
|
def complicated_text_test(driver):
|
||||||
|
driver.get("https://2captcha.com/demo/mtcaptcha")
|
||||||
|
time.sleep(5)
|
||||||
|
iframe = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.ID, "mtcaptcha-iframe-1"))
|
||||||
|
)
|
||||||
|
iframe.screenshot('captcha_image.png')
|
||||||
|
file_url = upload_image_to_imgur('captcha_image.png')
|
||||||
|
print(file_url)
|
||||||
|
response = ask_text_to_chatgpt(file_url)
|
||||||
|
|
||||||
|
print(response)
|
||||||
|
driver.switch_to.frame(iframe)
|
||||||
|
input_field = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.CLASS_NAME, "mtcap-noborder.mtcap-inputtext.mtcap-inputtext-custom"))
|
||||||
|
)
|
||||||
|
input_field.send_keys(response)
|
||||||
|
time.sleep(2)
|
||||||
|
driver.switch_to.default_content()
|
||||||
|
submit_button = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located(
|
||||||
|
(By.CLASS_NAME, "_actionsItem_1f3oo_41._buttonPrimary_d46vc_44._button_d46vc_1._buttonMd_d46vc_34"))
|
||||||
|
)
|
||||||
|
submit_button.click()
|
||||||
|
|
||||||
|
def text_test(driver):
|
||||||
|
driver.get("https://2captcha.com/demo/normal")
|
||||||
|
time.sleep(5)
|
||||||
|
captcha_image = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.CLASS_NAME, "_captchaImage_rrn3u_9"))
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
captcha_image.screenshot('captcha_image.png')
|
||||||
|
file_url = upload_image_to_imgur('captcha_image.png')
|
||||||
|
print(file_url)
|
||||||
|
response = ask_text_to_chatgpt(file_url)
|
||||||
|
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
input_field = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.CLASS_NAME, "_inputInner_ws73z_12"))
|
||||||
|
)
|
||||||
|
input_field.send_keys(response)
|
||||||
|
submit_button = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located(
|
||||||
|
(By.CLASS_NAME, "_actionsItem_1f3oo_41._buttonPrimary_d46vc_44._button_d46vc_1._buttonMd_d46vc_34"))
|
||||||
|
)
|
||||||
|
submit_button.click()
|
||||||
|
time.sleep(5)
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
def recaptcha_test(driver):
|
||||||
|
driver.get("https://patrickhlauke.github.io/recaptcha/")
|
||||||
|
def handle_recaptcha():
|
||||||
|
number_of_challenges = 0
|
||||||
|
recaptcha_frame = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.XPATH, "//iframe[@title='reCAPTCHA']"))
|
||||||
|
)
|
||||||
|
recaptcha_frame.screenshot('recaptcha_checkbox.png')
|
||||||
|
driver.switch_to.frame(recaptcha_frame)
|
||||||
|
checkbox = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable((By.CLASS_NAME, "recaptcha-checkbox-border"))
|
||||||
|
)
|
||||||
|
checkbox.click()
|
||||||
|
driver.switch_to.default_content()
|
||||||
|
time.sleep(2)
|
||||||
|
array = []
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
challenge_iframe = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located(
|
||||||
|
(By.XPATH, "//iframe[contains(@title, 'recaptcha challenge expires in two minutes')]"))
|
||||||
|
)
|
||||||
|
number_of_challenges += 1
|
||||||
|
filename = 'recaptcha_challenge_' + str(number_of_challenges) + '.png'
|
||||||
|
challenge_iframe.screenshot(filename)
|
||||||
|
image_url = upload_image_to_imgur(filename)
|
||||||
|
if image_url:
|
||||||
|
answer = ask_recaptcha_to_chatgpt(image_url)
|
||||||
|
if "," in answer:
|
||||||
|
array = answer.split(", ")
|
||||||
|
elif "-" in answer:
|
||||||
|
array = answer.split("-")
|
||||||
|
else:
|
||||||
|
exit(-1)
|
||||||
|
driver.switch_to.frame(challenge_iframe)
|
||||||
|
table = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.CLASS_NAME, "rc-imageselect-table-33"))
|
||||||
|
)
|
||||||
|
time.sleep(1)
|
||||||
|
all_images = table.find_elements(By.CLASS_NAME, "rc-image-tile-33")
|
||||||
|
for each_element in array:
|
||||||
|
all_images[int(each_element)].click()
|
||||||
|
submit_button = WebDriverWait(driver, 10).until(
|
||||||
|
EC.presence_of_element_located((By.ID, "recaptcha-verify-button"))
|
||||||
|
)
|
||||||
|
submit_button.click()
|
||||||
|
driver.switch_to.default_content()
|
||||||
|
time.sleep(5)
|
||||||
|
if len(driver.find_elements(By.CLASS_NAME, "recaptcha-checkbox-checkmark")) != 0:
|
||||||
|
break
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
handle_recaptcha()
|
||||||
|
time.sleep(5)
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Test various captcha types.")
|
||||||
|
parser.add_argument('captcha_type', choices=['puzzle', 'text', 'complicated_text', 'recaptcha'],
|
||||||
|
help="Specify the type of captcha to test")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
service = FirefoxService(GeckoDriverManager().install())
|
||||||
|
driver = webdriver.Firefox(service=service)
|
||||||
|
try:
|
||||||
|
if args.captcha_type == 'puzzle':
|
||||||
|
puzzle_test(driver)
|
||||||
|
elif args.captcha_type == 'text':
|
||||||
|
text_test(driver)
|
||||||
|
elif args.captcha_type == 'complicated_text':
|
||||||
|
complicated_text_test(driver)
|
||||||
|
elif args.captcha_type == 'recaptcha':
|
||||||
|
recaptcha_test(driver)
|
||||||
|
finally:
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
43
requirements.txt
Normal file
43
requirements.txt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
annotated-types==0.7.0
|
||||||
|
anyio==4.4.0
|
||||||
|
attrs==23.2.0
|
||||||
|
blinker==1.8.2
|
||||||
|
Brotli==1.1.0
|
||||||
|
certifi==2024.6.2
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
cryptography==42.0.8
|
||||||
|
distro==1.9.0
|
||||||
|
h11==0.14.0
|
||||||
|
h2==4.1.0
|
||||||
|
hpack==4.0.0
|
||||||
|
httpcore==1.0.5
|
||||||
|
httpx==0.27.0
|
||||||
|
hyperframe==6.0.1
|
||||||
|
idna==3.7
|
||||||
|
kaitaistruct==0.10
|
||||||
|
openai==1.33.0
|
||||||
|
outcome==1.3.0.post0
|
||||||
|
packaging==24.0
|
||||||
|
pillow==10.4.0
|
||||||
|
pyasn1==0.6.0
|
||||||
|
pycparser==2.22
|
||||||
|
pydantic==2.7.3
|
||||||
|
pydantic_core==2.18.4
|
||||||
|
pyOpenSSL==24.1.0
|
||||||
|
pyparsing==3.1.2
|
||||||
|
PySocks==1.7.1
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
requests==2.32.3
|
||||||
|
selenium==4.21.0
|
||||||
|
selenium-wire==5.1.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
sortedcontainers==2.4.0
|
||||||
|
tqdm==4.66.4
|
||||||
|
trio==0.25.1
|
||||||
|
trio-websocket==0.11.1
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
urllib3==2.2.1
|
||||||
|
webdriver-manager==4.0.1
|
||||||
|
wsproto==1.2.0
|
||||||
|
zstandard==0.22.0
|
Loading…
Reference in New Issue
Block a user