Legend has it there's a flag at the end when you have a perfect score
http://timesink.be/quizbot
So they set up a Quizbot with a hint Can you beat the 1000 questions?
which tells us that maybe we can get a reward if we manage to answer all the 1000
questions the Bot is going to ask us!
Without wasting any time I jumped into the Source code. This was fairly simple so I checked the cookies and got the PHPSESSID
is set!
I thought I'll use python + Selenium to automate the whole thing but I faced the following issues,
- There were too many answers on Google
- Lots of things to parse
- It's slow
Hmmmmmm..... to think from a technical point of view, all Quizbots must have a Database of Q&As and if we can find that we're almost done. After searching for a while I found this site - Questions quiz test answers general knowledge which has all the question answers (tested manually for a couple of questions). Then I saved all the Q&As in a file named all_10000qs.txt. Now, we just need the parser!
The best idea that came to my mind was python for it's amazing module called requests. Here's a sneak peek!
import requests
import re
[snip]
def find_answer(question):
qna = open('all_10000qs.txt').read().strip().split('\n')
for qa in qna:
if question in qa:
ans = qa.split(' : ')[2]
return ans
### gimme flag ###
url = 'http://timesink.be/quizbot/index.php'
session = requests.Session()
[snip]
while score!=1001:
# GET question
res = session.get(url)
[snip]
query = get_question(res.text)
# print(query[1])
sanitized = sanitize(query[1])
# print(sanitized)
ans = find_answer(sanitized)
# POST answer
d = {'insert_answer': ans}
a = session.post(url, data=d)
[snip]
Now I have the parser but I ran into some weird problems!
Basically my script worked fine for ~600 questions and then it stopped! After debugging a lot I figured out that there were two issues,
- My Internet was shitty.
- The Bot Server was down.
- The Query text had some weird double spaces and Unicode chars.
- The Answer comparison was Case sensitive (this was the major bug).
So I modified the Script,
- Sanitized the Query text.
- Added the Manual Feed data mode.
- Added Auto-correct mode.
- Added Score count.
And then tried it again. When they fixed the Server, it worked finally and I got the flag!!!
Full Script - quizbot_hack.py
import requests
import re
"""
https://www.riassuntini.com/questions-quiz-test-answers/questions-quiz-test-answers-general-knowledge.html
"""
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
def get_question(text):
stripped = remove_tags(text).split('\n')
# print(stripped)
score = stripped[0][stripped[0].index('?')+1 : stripped[0].index(' ')]
for i, sen in enumerate(stripped):
if 'Question' in sen:
return [sen, stripped[i+1], score]
def find_answer(question):
qna = open('all_10000qs.txt').read().strip().split('\n')
for qa in qna:
if question in qa:
ans = qa.split(' : ')[2]
return ans
def sanitize(text):
s1 = text.replace(' ', ' ')
return s1
def autocorrect(text, q):
correct_ans = text.split('\n')[0].split(': ')[1]
# print("[+] CA:", correct_ans, q)
qna = open('all_10000qs.txt').read().strip().split('\n')
for i in range(len(qna)):
if q in qna[i]:
idx = qna[i].index(' Answer : ')
qna[i] = qna[i][:idx] + ' Answer : ' + correct_ans # replace the answer with the correct one
new = open('all_10000qs.txt', 'w')
for line in qna:
new.write(line + '\n')
### gimme flag ###
# qna = open('all_10000qs.txt').read().split('\n')
url = 'http://timesink.be/quizbot/index.php'
session = requests.Session()
score = 0
i = 0
# for i in range(1000+1):
while score!=1001:
# GET question
res = session.get(url)
if i == 0:
print(f"(0-0) Cookie: {res.cookies}\n")
query = get_question(res.text)
# print(query[1])
sanitized = sanitize(query[1])
# print(sanitized)
ans = find_answer(sanitized)
score = int(query[2].split(': ')[1])
# failed to find the ques in the db / feed manual data
if ans==None:
print("(x-x)", query[1])
ans = input("> ")
open('all_10000qs.txt', 'a').write(f"\nQuestion : {query[1]} Answer : {ans}")
# ques_no = int(query[0].split(' ')[2])
# print(ques_no)
# if ques_no != score
print(f"(^-^) Solved {query[0]} [Score: {score}]")
# POST answer
d = {'insert_answer': ans}
a = session.post(url, data=d)
# check if the answer was correct / get the correct answer and store in db
data = remove_tags(a.text)
if 'Correct!' not in data:
autocorrect(data, sanitized)
print('-'*20)
print("[+] Q:", sanitized)
print("[+] Corrected!!!")
print('-'*20)
# break
if score==1000:
print(a.text)
i += 1
# print(session.get(url).text)
This is the raw script I used. Please ignore the silly stuffs...
brixelCTF{kn0wl3dg3}