OverTheWire: Natas

Level 18 > Level 19


Note: I cleaned up some of the unusual /* */ comments in the source that follows and fixed the indentation, hopefully not affecting the meat of the code.

<div id="content">

$maxid = 640; // 640 should be enough for everyone

function isValidAdminLogin() { 
    if($_REQUEST["username"] == "admin") {
    /* This method of authentication appears to be unsafe and has been disabled for now. */
        //return 1;

    return 0;

function isValidID($id) { 
    return is_numeric($id);

function createID($user) { 
    global $maxid;
    return rand(1, $maxid);

function debug($msg) { 
    if(array_key_exists("debug", $_GET)) {
        print "DEBUG: $msg<br>";

function my_session_start() { 
    if(array_key_exists("PHPSESSID", $_COOKIE) and isValidID($_COOKIE["PHPSESSID"])) {
        if(!session_start()) {
            debug("Session start failed");
            return false;
        } else {
            debug("Session start ok");
            if(!array_key_exists("admin", $_SESSION)) {
                debug("Session was old: admin flag set");
                $_SESSION["admin"] = 0; // backwards compatible, secure
            return true;

    return false;

function print_credentials() { 
    if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) {
        print "You are an admin. The credentials for the next level are:<br>";
        print "<pre>Username: natas19\n";
        print "Password: <censored></pre>";
    } else {
        print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19.";

$showform = true;
if(my_session_start()) {
    $showform = false;
} else {
    if(array_key_exists("username", $_REQUEST) && array_key_exists("password", $_REQUEST)) {
        $_SESSION["admin"] = isValidAdminLogin();
        debug("New session started");
        $showform = false;

if($showform) {

Please login with your admin account to retrieve credentials for natas19.

<form action="index.php" method="POST">
Username: <input name="username"><br>
Password: <input name="password"><br>
<input type="submit" value="Login" />
<? } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>

I was in the middle of walking through all this step by step, trying to understand it when I noticed the page wasn’t using the typical PHP-provided PHPSESSID, but something much simpler. From a sample request,


From the code,

$maxid = 640; // 640 should be enough for everyone

Looks like the perfect thing for Burp Intruder. Since it doesn’t appear we can set the admin key to 1 ourselves, maybe someone else has it. Iterating through a range of numbers is very easy in Intruder.


As in a previous natas challenge, we see one response which is suspiciously different in length.