# Mechanical Turk (web)

###### PUBLISHED ON 15/04/2020 — EDITED ON 11/12/2023 — 247CTF, INFOSEC

This post was in “draft” version for more than three years, waiting for some neat words to be added. Maybe it is time to just dump it online and see where it goes.

I was the 13th person to solve this challenge :)

There were 33 sucessfull attempts at the date of publishing this article (11.12.2023). Lets see if this helps anyone.

## Intro

If you can solve our custom CAPTCHA addition equation 100 times in 30 seconds you will be rewarded with a flag.

## Sucessful attack

``````\$ time ./images_clean.py | grep alert-
KeyboardInterrupt

./images_clean.py  16.90s user 0.57s system 53% cpu 32.563 total
grep --color alert-  0.02s user 0.01s system 0% cpu 32.427 total
``````

## Solution

This is the script I have come up to solve the problem. It is far away from being optimal, but it did the job. Preparing the images was the hardest part.

``````#!/usr/bin/env python3

# ./images_clean.py | grep Valid

URL="https://0e11aa65af22276e.247ctf.com"
import requests

import cv2
# https://github.com/sirfz/tesserocr/issues/165
import locale
locale.setlocale(locale.LC_ALL, 'C')
from tesserocr import PyTessBaseAPI, PSM, OEM
import numpy as np
from PIL import Image

def clean_colors(img):
# Remove dark gray noise lines color 140,140,140
lower_black = np.array([140,140,140], dtype = "uint16")
upper_black = np.array([141,141,141], dtype = "uint16")

# Remove light gray background color 245,245,245
#lower_black = np.array([245,245,245], dtype = "uint16")
#upper_black = np.array([246,246,246], dtype = "uint16")

return img

def resize(img):
#img = cv2.resize(img, None, fx=10, fy=10, interpolation=cv2.INTER_LINEAR)
img = cv2.resize(img, None, fx=5, fy=5, interpolation=cv2.INTER_CUBIC)
return img

def thresh_binary(img):
th, img = cv2.threshold(img, 231, 255, cv2.THRESH_BINARY)
return img

def thresh_otsu(img):
th, img = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
return img

def brightness_contrast(img):
alpha = 1.0 # Contrast control (1.0-3.0)
beta = 1 # Brightness control (0-100)
img = cv2.convertScaleAbs(img, alpha=alpha, beta=beta)
return img

with PyTessBaseAPI(psm=PSM.SINGLE_WORD, oem=OEM.TESSERACT_ONLY) as api:
api.SetVariable("tessedit_char_whitelist", "0123456789+")
#api.SetVariable("user_patterns", "pattern.txt")
#api.SetVariable("tessedit_fix_fuzzy_spaces", "true")

sess = requests.session()
response = sess.get(URL)

for i in range(300):

#print (response)
#print (r.text)

img = clean_colors(img)

img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

img = brightness_contrast(img)

img = thresh_binary(img)
#img = thresh_otsu(img)

img = resize(img)
img = thresh_otsu(img)
#img = thresh_binary(img)

api.SetImage(Image.fromarray(img))

try:
sp = api.GetUTF8Text().replace(" ", "").rstrip().split('+')

#print(sp)
#cv2.waitKey()

rez = int(sp[0])+int(sp[1])
print (p.text)
except:

sp = api.GetUTF8Text().replace(" ", "").rstrip()
a = sp[:6]
b = sp[6:]
rez = int(a)+int(b)