Hackvens
<-- home

Sthack 2022 / Catch the bird

May 20, 2022

STHACK 2022

Épreuve “Catch the bird, a trip from web to IRL”

Le 20/05/2022

Cette Ă©preuve indiquĂ©e dans la catĂ©gorie web et physique a intriguĂ© notre Ă©quipe qui s’est penchĂ©e dessus durant plus de 5h.

En prĂ©misse de cette Ă©preuve, nous avons pour Ă©noncĂ© un scĂ©nario entre deux personnages ainsi qu’une carte postale avec un but prĂ©cis, mettre la main sur une statuette d’oiseau:

img

Ecoute radio

Les termes “Marconi” et “Guglielmo” Ă©tant soulignĂ©s, nous dĂ©couvrons qu’ils font rĂ©fĂ©rence Ă  l’un des prĂ©curseurs de la radio. Le numĂ©ro de rue “101.10” semble nous inviter Ă  Ă©couter sur cette frĂ©quence FM. Nous devons donc nous munir d’un tĂ©lĂ©phone ainsi que d’écouteurs filaires pour Ă©couter un message diffusĂ© en boucle.

L’orateur utilise l’alphabet phonĂ©tique pour transmettre son message.

image-20220602100444065

Nous obtenons alors le lien suivant:

STHACKMDBIDWKYEBHKLNFNWMQHJ3OXNKE5INYLZRTWZENR752TN77OAD.ONION

AccĂšs au compte adminsitrateur

Via le navigateur Tor, nous arrivons sur ce qui semble ĂȘtre un marchĂ© du darknet, nous y retrouvons la statuette d’oiseau dans la liste des articles vendus:

img

Une page nous indique que nous devons trouver le moyen d’effectuer un achat afin d’obtenir des coordonnĂ©es GPS. Cependant, afin d’effectuer une commande nous devons ĂȘtre authentifiĂ©s, l’administrateur est indiquĂ© comme Ă©tant trĂšs pointilleux.

Nous dĂ©couvrons une interface d’authentification au compte d’administration. Nous cherchons donc Ă  usurper l’identitĂ© de cet administrateur.

img

La page de login suivante divulgue un message d’erreur en base64 lorsque la tentative d’authentification n’est pas correcte.

Nous obtenons l’erreur suivante une fois le message dĂ©chiffrĂ© :

An exception occured on line 31 of /www/src/Controller/LoginController.php --- Invalid password. ---

                return $this->render('login/index.html.twig', [
                    'controller_name' => 'LoginController',
                ]);
            }
            if ($request->request->get('password') === self::PASSWORD)
            {
                $session = new Session();
                $session->set('is_admin', true);
                return $this->redirectToRoute('admin');
            } else { sleep(rand(3, 5)); throw new Exception('Invalid password.'); }
        }
        #[Route('/logout', name: 'app_admin_logout')]
        public function logout (Request $request): Response
        {

            $session = new Session();
            $session->clear();
            return $this->redirectToRoute('app_admin_login');

Ici nous avons dĂ©duit qu’il fallait rĂ©cupĂ©rer le contenu de la variable ‘self::PASSWORD’.

Nous obtenons un autre morceau de code lié à une erreur au niveau de la page listant les articles:

An exception occured on line 86 of /www/vendor/symfony/expression-language/Lexer.php --- Unexpected character "'" around position 0 for expression ' OR 1=1# && true. ---

                } elseif (str_contains('.,?:', $expression[$cursor])) {
                    // punctuation
                    $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1);
                    ++$cursor;
                } elseif (pregmatch('/[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $expression, $match, 0, $cursor)) {
                    // names
                    $tokens[] = new Token(Token::NAME_TYPE, $match[0], $cursor + 1);
                    $cursor += \strlen($match[0]);
                } else {
                    // unlexable
                    throw new SyntaxError(sprintf('Unexpected character "%s".', $expression[$cursor]), $cursor, $expression);
                }
            }
            $tokens[] = new Token(Token::EOF_TYPE, null, $cursor + 1);
            if (!empty($brackets)) {
                [$expect, $cur] = array_pop($brackets);
                throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression);
            }

Nous remarquons la mention de “expression-language” dans le message de l’erreur ce qui nous pousse à consulter la documentation suivante :

https://symfony.com/doc/current/components/expression_language/syntax.html#component-expression-functions

La partie “Working with Functions” attire notre Ɠil, car il semble possible de rĂ©cupĂ©rer le contenu d’une variable via la fonction “constant()”. De plus, il est possible d’influencer le message d’erreur en jouant sur un paramĂštre POST. Une injection semble donc possible.

AprĂšs quelques tentatives et Ă  l’aide des messages d’erreurs, nous identifions le contexte liĂ© Ă  notre variable “self::PASSWORD”.

img

Nous avons donc “constant(‘App\Controller\LoginController::PASSWORD’)”.

NĂ©anmoins, aprĂšs avoir rĂ©cupĂ©rĂ© le contenu du mot de passe administrateur nous devons trouver un moyen de l’afficher ou de le rĂ©cupĂ©rer en clair.

Nous utilisons alors une autre fonction basique de symfony : matches afin de vérifier les caractÚres un à un.

constant('App\\Controller\\LoginController::PASSWORD') matches '/a*/'

Ce qui nous permet d’identifier manuellement le mot de passe comme Ă©tant : Ybhr5vmjJD

RĂ©cupĂ©rer et dĂ©chiffrement d’un fichier

Nous accĂ©dons ensuite Ă  la liste des ventes effectuĂ©es, et obtenons les Ă©lĂ©ments tant attendus, Ă  savoir les coordonnĂ©es GPS du point oĂč se trouvent un cadenas et une clĂ© secrĂšte.

img

Le point GPS nous emmĂšne dans les jardins de la mairie de Bordeaux, oĂč nous dĂ©couvrons un cadenas verrouillĂ© auquel est attachĂ© une clĂ© USB.

img

L’usage de compĂ©tence de lock-picking est utile pour rĂ©cupĂ©rer la clĂ© USB, cependant dans notre cas nous manquions de temps et avons dĂ©placĂ© directement notre pc afin de brancher la clĂ© USB sans avoir besoin d’ouvrir le cadenas.

Une fois le fichier rĂ©cupĂ©rĂ©, une simple commande permet de le dĂ©chiffrer Ă  l’aide de la clĂ© prĂ©cĂ©demment retrouvĂ©e lors de l’achat ci-dessus :

openssl enc -d -aes-256-cbc -in maltesefalcon.txt.aes256cbc -out file.dec

Nous obtenons alors un autre lien ONION:

The auction will take place at the address : maltapyzyfnwvgkl4se7tlhlrohule77cgnaguy2nouxyvosovjldbyd.onion

All bid will be made in $ only, you will be asked to provide an bank account address on auction start. You will only be able to bid up to this account available balance, so be sure to gather sufficients funds on this account before auction start.

Auction admittance will start at 2022-05-23 20:00:00 UTC and entree will remain open up to 2022-05-23 20:15:00 UTC. Past that, nobody will be accepted and auctions will start.

---------
Falcon

Récupération du flag

La vente aux enchĂšres semble commencer deux jours aprĂšs la fin du CTF. En effet, un compte Ă  rebours est prĂ©sent sur la page d’accueil du nouveau site.

Nous changeons donc la date de notre pc afin de rĂ©duire ce dĂ©lai Ă  0. Ceci n’était pas la mĂ©thode dĂ©sirĂ©e par le crĂ©ateur du challenge, mais une mĂ©thode qui fonctionne tout de mĂȘme. C’est ainsi que nous avons obtenu le flag et validĂ© l’épreuve :

img

img