Monday, June 3, 2013

Codegate 2013 :: Web #2 (200 points)

This was the second challenge under the web category which was worth 200 points. It began with a short note from the organizer that read – “One Time Password..?” and a hyperlink to a Ca$h website where Captain Teemo was on duty.


The Ca$h website included the option to generate a One Time Password (OTP) that was needed during login. Option to download the (zipped) source code for the website was also available.

Contents of the zipped file:
  • index.html – Website index page
  • jquery-1.8.3.js – JQuery file
  • main.js – JQuery file
  • images – Folder containing css and image files
  • home.php – Homepage containing some description for the website
  • login.php – Login page
  • login_ok.php – Check the login credentials submitted
  • otp.php – Display the OTP and its validity period
  • otp_util.php – OTP generation page

Contents of “login_ok.php”:
Contents of “otp.php”:
Contents of “otp_util.php”:
From login_ok.php, it appears you need to submit a password value that matches the value generated by make_otp() and “127.0.0.1″ as the ID value in order to capture the flag for this challenge. A closer look at make_otp() reveals the OTP value is a sha1 hash of a string that is formed by concatenating $time (integer value of the current time divided by 20), $user (“127.0.0.1″), and $seed (md5 hash of the flag file contents concatenate with the md5 hash of the user-agent header) together.

One Time Password (Valid for 20 secs)

There are 2 obstacles to overcome. Let’s examine them in details here:
  1. $_SERVER["REMOTE_ADDR"]The IP address from which you are viewing the current page.
    Are you able to spoof this to be “127.0.0.1″?
  2. $_SERVER['HTTP_USER_AGENT']Contents of the User-Agent: header from the current request, if there is one. This is a string denoting the user agent being which is accessing the page.
    Are you able to match whatever string value used by the organizer?
Take a moment to think about overcoming these 2 obstacles and whether there is an alternative approach to this challenge.


  1. $_SERVER["REMOTE_ADDR"] – Even though it is possible to spoof this element with “127.0.0.1″, chances are you will not receive the response as the IP address is used in the IP protocol to route packets.
  2. $_SERVER['HTTP_USER_AGENT'] – It’s anybody’s guess what string was used by the organizer. It may be empty or random.
The 2 obstacles certainly look difficult to overcome. Another approach lies in line 10 of login_ok.php where $_POST["ps"] is compared against $password to determine if there is a match. Comparison between two strings will result in an error when one of the strings supplied is an array. This attack is known as array injection.

Array Injection PHP Script:
When the script (login_ok.php) received this POST request, it ran into an error, rendered the strcpy defunct and echoed the code within the scope of the if statement, together with the contents of the flag file! 200 points in the bag. Yay!

Flag Captured:

Cheers,
Braeburn Ladny

No comments:

Post a Comment