ThaySan
  • πŸ‘‹Bienvenue
    • Avant-propos
  • 🚩CTF & Writeups
    • 2025 | EC2
      • Let's Crax
    • 2025 | HackDay
      • πŸ”‘Cryptographie
        • Drunk Christmas
        • Find Eve 1
        • Well hidden message - Standard Code Encryption
      • πŸ”ŽForensic
        • Copperwire Extraction
        • Distracted user
        • I believe you can't fly
      • 🧠Misc
        • Hello Steve
      • πŸ’ΎProgrammation
        • Lonely bot
        • Lonely bot #2
        • Lonely bot #3
        • Useless Animals Sorting
        • Who cares about SSI anyway ?
      • βš™οΈReverse
        • Just dig
        • Rusty_rev
        • The Cogs of Blackmail
      • 🎭Steganographie
        • It says a lot when there is no music
        • Mona LSB
        • Well hidden message - Insignificant blue
      • 🌐Web
        • Super Website Verificator 3000
        • The analytical engine leak
        • The Watchful Gears: Uncover the Secrets Within
        • Your region's finest
    • 2024 | Efrei - CyberNight
      • πŸ”‘Cryptographie
        • Clavier spΓ©cial
        • Le futur
        • Securechain 30.0
        • Cascade
        • Shared Flag
        • Weird Algorithm
      • 🧊Minecraft
        • Introduction
        • Non aux Bouquins TrafiquΓ©s
        • Redstone Gold Block
      • πŸ’ΎProgrammation
        • Captcha 1.0
        • Intro Γ  la prog
        • Captcha 2.0
      • βš™οΈReverse
        • Reverse the Reverse
        • Find me if you can
        • HuGO Decrypt
        • Kitten eXORcism
        • M30W Vault Tech
        • The Ugandan Labyrinth
      • 🎭StΓ©ganographie
        • Le message
        • bon Le ordre
        • COD FORFLAG
        • Mauvaise note
        • Bruit
        • Un (un ?) drΓ΄le de QR code
        • RandonnΓ©e Guillerette Γ  Bordeaux
      • πŸ’»SystΓ¨me
        • Marche-pied
        • Escabot
        • rΓ©gulation des DonnΓ©es et des Normes de SΓ©curitΓ©
      • 🌐Web
        • cybernight.zip
        • Mon champion prΓ©fΓ©rΓ©
        • Co(mpressed)okies
        • Gitty Mistake
        • JWT Kiddo
        • Parseur Farceur
      • L'enquΓͺte
        • L'enquΓͺte 2/6
        • L'EnquΓͺte 1/6
        • Bienvenue, enquΓͺteur
    • 2024 | Star-Hack
      • πŸ”‘Cryptographie
        • CΓ©sar, mais pas CΓ©sar
        • Double ennui
        • Langage secret
        • Quadratique MystΓ©rieuse
        • ReSultAt
        • Sup3r S3cr3t
        • Warmup
      • πŸ”ŽForensic
        • Cache-cache
        • Fichier ZIP protΓ©gΓ© par mot de passe
        • HEADER
        • Investigation 1
        • Investigation 2
      • 🧠Misc
        • B4l4d3 Urb41n3
        • Bruhh, c'est quoi Γ§a ?
        • Cut13
        • Pika Pika
      • 😈Pwn
        • Pwn0x01
        • Pwn0x02
        • Pwn0x03
      • βš™οΈReverse
        • Assembly
        • Rev0x00
        • Rev0x01
        • Rev0x02
      • 🌐Web
        • Clone Udemy
        • Flask
        • Guess_The_Passcode
        • PHP
        • Tickets
        • Usine de Cookies
    • 2024 | ECW
      • πŸ”‘Cryptographie
        • Course hipPIN
    • 2024 | CTFREI Intro
      • πŸ”‘Cryptographie
        • AES Intro
        • AlΓ©atoire
        • Game of Luck
        • RSA Intro
        • RSA2
        • RSA3
      • πŸ”ŽForensic
        • Mais qui est le photographe ?
        • Mais oΓΉ est passΓ© mon flag ?
        • MΓ©moire 1/4
        • MΓ©moire 2/4
        • MΓ©moire 3/4
        • MΓ©moire 4/4
        • My computer is talking
      • πŸ“šOSINT
        • Avion ✈
        • Geoint
        • Google!
        • Googlint
        • Le pivot
        • Le temps commence maintenant
        • SacrΓ© dossier
        • Socint
      • πŸ’ΎProgrammation
        • Try Me
        • Answer Me
        • Eval Me
        • Time Based
      • 😈Pwn
        • BOF Intro
        • Shop
        • BOF 2
        • BOF win()
      • βš™οΈReverse
        • CrackMe1
        • CrackMe2
        • CrackMe3
        • Hidden...
        • Something changed?
        • ZZZ
      • 🎭StΓ©ganographie
        • Cybernight Γͺtre comme
        • Joli paysage
        • Petit poisson
        • StegHide 'n' Seek
        • Un canard pas comme les autres
      • πŸ’»SystΓ¨me
        • Bash Jail
        • Bash Jail Revenge
        • BrokenBin
        • GTFO Of Here
        • Pyjail
        • Pyjail Revenge
        • Strange input, right?
      • 🌐Web
        • SQLi
        • POST This Money
        • Give me my Flask PIN
        • Access
        • Render
        • RenderV2
        • Touchy
    • 2024 | DefCamp
      • πŸ”‘Cryptographie
        • conv
        • oracle-srl
        • ctr
      • πŸ”ŽForensic
        • i-got-a-virus
        • Alternating
        • call-me-pliz
      • 🧠Misc
        • pyterm
      • πŸ“±Mobile
        • mobisec
      • πŸ“šOSINT
      • 😈Pwn
      • βš™οΈReverse
      • πŸ•΅οΈTraque
      • 🌐Web
        • noogle
        • production-bay
    • 2024 | 404CTF
      • πŸ”‘Cryptographie
        • BΓ©bΓ© nageur
        • Le petit bain
        • Poor Random Number Generator [1/2]
        • Plongeon Rapide Super Artistique
        • J'Γ©ponge donc j'essuie
        • Poor Random Number Generator [2/2]
        • La Seine
        • J'ai glissΓ© chef !
        • SEA - La face cachΓ©e de l'Iceberg
      • πŸ”ŽForensic
        • Le tir aux logs
        • Darts Bank
        • Vaut mieux sΓ©curiser que guΓ©rir
        • De bons croissants au beurre
        • Poids Raw vs. Cours Jette [1/3]
      • πŸ”ŒHardware
        • Serial killer
        • Le soulevΓ© de GND
        • Comment est votre modulation ? [1/2]
        • Sea side channel [1/4] - Introduction
        • Comment est votre modulation ? [2/2]
        • Sea side channel [2/4] - Reconnaissance
        • Sea side channel [3/4] - Mais oΓΉ sont les triggers ?
      • πŸ€–IA
        • Du poison [1/2]
        • Du poison [2/2]
        • Des portes dΓ©robΓ©es
      • 🧠Misc
        • Discord
        • De la friture sur la ligne
        • Bienvenue
        • Revers(ibl)e Engineering [0/2]
      • πŸ“šOSINT
        • LΓ©gende
        • Not on my watch
        • Secret Training [1/2]
      • 😈Pwn
        • Pseudoverflow
        • Jean Pile
        • Mordu du 100m
        • Antismash
      • πŸˆβ€β¬›Quantique
        • Des trains superposΓ©s
        • De l'Γ©coute, pas trΓ¨s discrΓ¨te
        • De la multiplicitΓ© des problΓ¨mes
      • βš™οΈReverse
        • ⭐Échauffement
        • ⭐Intronisation du CHAUSSURE
        • ⭐Bugdroid Fight [1/2]
        • ⭐Revers(ibl)e Engineering [1/2]
        • ⭐Bugdroid Fight [2/2]
        • ⭐Nanocombattants
        • ⭐Revers(ibl)e Engineering [2/2]
        • Le Tableau Noir
      • 🎭StΓ©ganographie
        • ⭐L'absence
        • ⭐Regarder en stΓ©rΓ©o
        • ⭐La Barre Fixe
        • ⭐Le grand Γ©cart
        • ⭐La chute
      • 🌐Web
        • ⭐Vous Γͺtes en RETARD
        • ⭐Le match du siΓ¨cle [1/2]
        • ⭐Exploit mag
        • ⭐Le match du siΓ¨cle [2/2]
        • ⭐LE GORFOU 42
        • ⭐La boutique officielle
    • 2024 | CTFREI - Bordeaux
      • πŸ”‘Cryptographie
        • zzz
      • πŸ“šOSINT
        • Alexis Dumas
        • Back to the bureau
        • Dr Octopus
        • Folie et ambition
        • GeoGuessr
        • Hugo Nelots : prΓ©lude
        • La fin ?
        • La fuite Dumas
        • Un rΓ©seau suspect
      • πŸ’ΎProgrammation
        • Eval me 1
        • Eval me 2
        • Time Based
      • πŸ’»SystΓ¨me
        • Broken Binary 1
        • Broken Binary 2
        • GTFO of here
        • Pyjail 1
        • Pyjail 2
        • Pyjail 3
        • Pyjail 4
      • 🌐Web
        • Au commencement Γ©tait le verb
        • Becadmin
        • PHP Juggler
    • 2024 | HTB - Cyber Apocalypse Challenges
      • πŸ”—Blockchain
        • Lucky Faucet
        • Recovery
        • Russian Roulette
      • πŸ”‘Cryptographie
        • Blunt
        • Dynastic
        • Iced TEA
        • Makeshift
        • Primary Knowledge
      • πŸ”ŽForensic
        • An unusual sighting
        • Data Siege
        • Fake Boost
        • Game Invitation
        • It Has Begun
        • Phreaky
        • Pursue The Tracks
        • Urgent
      • πŸ”ŒHardware
        • BunnyPass
        • Flash-ing Logs
        • Maze
        • Rids
        • The PROM
      • 🧠Misc
        • Character
        • Cubicle Riddle
        • Path of Survival
        • Stop Drop and Roll
        • Unbreakable
        • Were Pickle Phreaks
        • Were Pickle Phreaks Revenge
      • 😈Pwn
        • Delulu
        • Pet Companion
        • Tutorial
        • Writing on the Wall
      • βš™οΈReverse
        • BoxCutter
        • Crushing
        • FollowThePath
        • LootStash
        • MazeOfPower
        • Metagaming
        • PackedAway
        • QuickScan
      • 🌐Web
        • Flag Command
        • KORP Terminal
        • Labyrinth Linguist
        • LockTalk
        • Testimonial
        • TimeKORP
    • 2024 | UNbreakable
      • πŸ”‘Cryptographie
        • start-enc
        • traffic-e
      • πŸ”ŽForensic
        • easy-hide
        • password-manager-is-a-must
      • 🧠Misc
        • rfc-meta
      • πŸ“±Mobile
        • flagen
        • improper-configuration
      • πŸ“‘Network
        • wifi-basic
        • wifiland
      • πŸ“šOSINT
        • persistent-reccon
        • safe-password
      • 😈Pwn
        • intro-to-assembly
      • βš™οΈReverse
        • fake-add
      • 🎭StΓ©ganographie
        • secrets-of-winter
      • 🌐Web
        • pygment
        • sided-curl
        • you-can-trust-me
    • 2023 | EFREI - CyberNight
      • πŸ“šOSINT
        • Invest Now !
      • 😈Pwn
        • NSA Call Converter
      • βš™οΈReverse
        • CryptoVirus
        • WebChaussettes
      • 🌐Web
        • DoctoLeak
    • 2023 | Flag4All
      • πŸ”‘Cryptographie
        • Aes IV
        • Crypt my loop
        • Kentucky fried chicken
        • RSA primes
        • Xor
    • 2022 | EFREI - CyberNight
      • πŸ”‘Cryptographie
        • CoupΓ©-dΓ©calΓ©
        • ExFILEtration
        • Il s'est baissΓ© ou pas
        • J'ai pas rotΓ©
        • Les allemands !
        • RSA Strong Prime generator
      • πŸ”ŽForensic
        • Bomberman 1/2
        • Bomberman 2/2
        • Magic
        • Peu importe le chemin
        • Sniff sniff
        • Souvenir
        • Xray
      • πŸ”ŒHardware
        • Class4
        • Find me 2/3
        • Identify 1/3
        • Yo listen 3/3
      • 🧠Misc
        • Et je tombe tombe tombe
        • Des yeux partout
        • RiGOLe
        • Roomba tricheur
        • Survey
        • Tinder
      • πŸ’ΎProgrammation
        • Repeat
        • Startup
        • Timing
      • βš™οΈReverse
        • Auth 1
        • Auth2
        • Auth3
        • Cryptoroomba
        • Tenet
      • 🎭StΓ©ganographie
        • 50 shades of stephane legar
        • Chess master
        • Deviens champion sers toi de tout ce que tu as appris
        • Drifting in the bits
        • Pyramide
        • Spirale
      • 🌐Web
        • Ah bah c'est du propre
        • Cooking roomba
        • Leaderboard
        • vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
PropulsΓ© par GitBook
Sur cette page
  • Challenge
  • Analyse du binaire
  • Challenge Proof of Work
  • Calculer la seed de l’alΓ©atoire
  • RΓ©soudre le labyrinthe
  • Script de rΓ©solution

Cet article vous a-t-il Γ©tΓ© utile ?

  1. CTF & Writeups
  2. 2024 | HTB - Cyber Apocalypse Challenges
  3. Reverse

MazeOfPower

PrΓ©cΓ©dentLootStashSuivantMetagaming

Dernière mise à jour il y a 1 an

Cet article vous a-t-il Γ©tΓ© utile ?

CatΓ©gorie: Reverse DifficultΓ©: insane Flag: HTB{by_th3_p0w3r_0f_th3_m4z3!!1}

Challenge

Description


MazeOfPower is an Insane reversing challenge. Players will first reverse engineer a Golang binary containing a maze game. They must identify a backdoor built into the game, and abuse it to win on the server.

Ce challenge tourne sur un docker, disponible sur

Analyse du binaire

Dans un logiciel de dΓ©compilation, direction main.main car c’est du Go.

Challenge Proof of Work

On trouve un appel Γ  la fonction GenerateChallenge du module github.com/redpwn/pow

Si l’on se rend sur le github, on y trouve l’objectif du module et son fonctionement. On ne va pas rΓ©inventer la roue et regarder comment le challenge se rΓ©sout.

// Solve solves the challenge and returns a solution proof that can be checked by Check.
func (c *Challenge) Solve() string {
	x := gmp.NewInt(0).Set(c.x) // dont mutate c.x
	for i := uint32(0); i < c.d; i++ {
		x.Exp(x, exp, mod)
		x.Xor(x, one)
	}
	return fmt.Sprintf("%s.%s", version, base64.StdEncoding.EncodeToString(x.Bytes()))
}

Le module utilise gmp, comme je suis sur Windows et que c’est une galΓ¨re Γ  installer, j’ai recoder la fonction rapidemment en Python. (Sans module pour optimiser le traitement, mon ordi prend environ 20s Γ  le rΓ©soudre)

from base64 import b64encode, b64decode
from Crypto.Util.number import bytes_to_long, long_to_bytes

class Challenge:
    VERSION = "s"
    MOD = (1 << 1279) - 1
    EXP = 1 << 1277

    @staticmethod
    def decode(challenge: str):
        version, raw_d, raw_x = challenge.split('.')
        if version != Challenge.VERSION:
            raise ValueError('Version not supported')
        d = bytes_to_long(b64decode(raw_d))
        x = bytes_to_long(b64decode(raw_x))
        if d.bit_length() > 16:
            raise ValueError('Difficulty too long')
        return d, x

    @staticmethod
    def solve(challenge: str):
        d, x = Challenge.decode(challenge)
        for i in range(d):
            x = pow(x, Challenge.EXP, Challenge.MOD)
            x ^= 1
        return f"{Challenge.VERSION}.{b64encode(long_to_bytes(x)).decode()}"

Calculer la seed de l’alΓ©atoire

Si l’on fait bien attention, quelques lignes aprΓ¨s, un appel Γ  math/rand.Seed est effectuΓ©, et cet appel est prΓ©cΓ©dΓ© Γ©trangement de :

  • ReadString pour rΓ©cupΓ©rer notre solution au challenge PoW

  • stringtoslicebyte pour transformer une string en bytes

  • hash/crc32.ChecksumIEEE pour calculer un checksum de bytes et qui retourne un entier

Effectivement, quel hasard.

Un petit tour dans GDB avec des breakpoint juste avant ces fonctions nous confirme les paramètres qui leur sont passés.

  1. On commence avec un break sur stringtoslicebyte qui confirme que c’est bien la solution au challenge PoW qui est passΓ©e en paramΓ¨tre :

  1. Ensuite on passe bien le rΓ©sultat de stringtoslicebyte Γ  la fonction de checksumIEEE, Γ  noter le ajoutΓ© Γ  la fin :

  1. Enfin, rand.Seed qui est appelΓ©. La fonction utilise RAX et dans RAX on a bien le rΓ©sultat du checksumIEEE

On en conclu donc que la seed est le rΓ©sultat du checksumIEEE sur la solution de notre challenge (avec \n un Γ  la fin)

En python Γ§a nous donne :

import zlib

def calculate_checksum(input_string: str) -> int:
    input_bytes = input_string.encode('utf-8')
    return zlib.crc32(input_bytes)

RΓ©soudre le labyrinthe

Une fois le PoW passΓ© et la seed de l’alΓ©atoire cassΓ©e, on termine dans un labyrinthe sans voir les murs. Heureusement, on voit que celui-ci est gΓ©nΓ©rΓ© grΓ’ce au module github.com/itchyny/maze

On peut alors explorer le github et voir que le crΓ©ateur implΓ©ment Γ©galement une fonction de rΓ©solution. On va simplement la copier coller et la modifier un peu pour rΓ©cupΓ©rer le chemin Γ  faire en texte.

On en profite aussi pour prendre en argument la seed de l’alΓ©atoire et gΓ©nΓ©rer le mΓͺme labyrinthe.

package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"github.com/itchyny/maze"
)

func Solve(maze_in *maze.Maze) {
	if maze_in.Solved {
		return
	}
	point := maze_in.Start
	stack := []*maze.Point{point}
	solution := []*maze.Point{point}
	visited := 1 << 12
	// Repeat until we reach the goal
	for !point.Equal(maze_in.Goal) {
		maze_in.Directions[point.X][point.Y] |= visited
		for _, direction := range maze.Directions {
			// Push the nearest points to the stack if not been visited yet
			if maze_in.Directions[point.X][point.Y]&direction == direction {
				next := point.Advance(direction)
				if maze_in.Directions[next.X][next.Y]&visited == 0 {
					stack = append(stack, next)
				}
			}
		}
		// Pop the stack
		point = stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		// We have reached to a dead end so we pop the solution
		for last := solution[len(solution)-1]; !maze_in.Connected(point, last); {
			solution = solution[:len(solution)-1]
			last = solution[len(solution)-1]
		}
		solution = append(solution, point)
	}
	// [MODIFICATION] c'est là dedans qu'on récupèrera le chemin à faire
	path := []int{}
	for i, point := range solution {
		if i < len(solution)-1 {
			next := solution[i+1]
			for _, direction := range maze.Directions {
				if maze_in.Directions[point.X][point.Y]&direction == direction {
					temp := point.Advance(direction)
					if next.X == temp.X && next.Y == temp.Y {
						// [MODIFICATION] et ici que l'on ajoute dedans
						path = append(path, direction)
						maze_in.Directions[point.X][point.Y] |= direction << maze.SolutionOffset
						maze_in.Directions[next.X][next.Y] |= maze.Opposite[direction] << maze.SolutionOffset
						break
					}
				}
			}
		}
	}
	maze_in.Solved = true
	// [MODIFICATION] on le print pour le rΓ©cupΓ©rer avec notre Python
	println(strings.Trim(strings.Join(strings.Fields(fmt.Sprint(path)), ", "), "[]"))
}

func main() {
	seed, err := strconv.Atoi(os.Args[1])
	if err != nil {
		panic(err)
	}

	rand.Seed(int64(seed))

	m := maze.NewMaze(0x19, 0x32)
	m.Generate()
	Solve(m)
}

Concernant la taille du labyrinthe, soit on le calcul Γ  la main avec ce que le binaire affiche, soit on le trouve dans le code, c’est 0x19 et 0x32 , autrement dit 25 de hauteur par 50 de largeur


Script de rΓ©solution

Pour rΓ©soudre le challenge, je suis parti sur du python qui appelle le Go pour rΓ©cupΓ©rer la solution au labyrinthe

from challenge import Challenge
from utils import calculate_checksum
import subprocess
from pwnlib.tubes.remote import remote

DIRECTIONS = {1: 'k', 2: 'j', 4: 'h', 8: 'l'}

def parse_maze_solution(raw: str) -> str:
    return ''.join([DIRECTIONS[int(n)] for n in raw.split(', ')])

def solve(host, port):
    client = remote(host, port)

    data = client.recvuntil(b'solution: ').decode()
    challenge = data.split('sh -s ')[1].split('\n')[0]
    print(f"Challenge: {challenge}")

    solution = Challenge.solve(challenge)
    print(f"Solution: {solution}")
    checksum = calculate_checksum(solution + '\n')
    print(f"Checksum: {checksum}")

    cmd = ["go", "run", "./solve.go", str(checksum)]
    output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, universal_newlines=True)
    maze_solution = parse_maze_solution(output)
    print(f"Maze: {maze_solution}")

    client.sendline(solution.encode())
    client.recvuntil(b'\n\n\n')
    client.sendline(maze_solution.encode())
    data = client.recvall(timeout=1)
    flag = data.splitlines()[-2].split(': ')[1]
    print(f"Flag: {flag}")

if __name__ == "__main__":
    solve('83.136.254.221', 36588)
🚩
βš™οΈ
Github
1MB
rev_mazeofpower.zip
archive