強エンジニアになりたい大学生の日記

その日学んだことを日記程度に発信します。

ksnctf(8) length-extension attack

KanGacha 130点

<?php

$salt = 'FLAG_????????????????';

$shipname = array(
    'Nagato',
    'Mutsu',
    'Kongo',
    'Hiei',
    'Haruna',
    'Kirishima',
    'Fuso',
    'Yamashiro',
    'Ise',
    'Hyuga',
    "Yamato [Congratulations! The flag is $salt. ??????????????????????????????????????.]"
);

//  Check signature and read
if (isset($_COOKIE['ship']) and
    isset($_COOKIE['signature']) and
    hash('sha512', $salt.$_COOKIE['ship']) === $_COOKIE['signature'])
    $ship = explode(',', $_COOKIE['ship']);
else
    $ship = array();

if (isset($_POST['submit']))
{
    //  Gacha
    if ($_POST['submit'] === 'Gacha')
    {
        //  Yamato is ultra rare
        $ship[] = mt_rand(0, count($shipname)-2);

        $s = implode(',', $ship);
        $sign = hash('sha512', $salt.$s);

        setcookie('ship', $s);
        setcookie('signature', $sign);
    }

    //  Clear
    if ($_POST['submit'] === 'Clear')
    {
        setcookie('ship', '', 0);
        setcookie('signature', '', 0);
    }

    header("Location: {$_SERVER['REQUEST_URI']}");
    exit();
}

?>
<!DOCTYPE html>
<html>
  <head>
    <title>KanGacha</title>
  </head>
  <body>
    <h1>KanGacha</h1>
    <form method="POST">
      <input type="submit" name="submit" value="Gacha">
      <input type="submit" name="submit" value="Clear">
    </form>
    <ul>
<?php
for ($i=0; $i<count($ship); $i++)
    echo "<li>{$shipname[$ship[$i]]}</li>\n";
?>
    </ol>
  </body>
</html>

shipに10を入れ、salt + COOKIE['ship'] の sha512 によるハッシュ値が、 COOKIE['signature']と一致させればいいことがわかる。

length-extension attackという攻撃手法があります。これは、ハッシュ関数Hによっては、y=H(secret+x)について、xとyが既知であるとき、secretの逆算はできなくても、H(secret+x+z)が求められるというものです。

今回の場合、一回「Gacha」をすることで、xとyを入手できるため、H(salt + x + 10)の値が入手できます。

hashpumpを使えば簡単に求められます。

hashpumpのinstall
$ git clone https://github.com/bwall/HashPump.git
$ apt-get install g++ libssl-dev
$ cd HashPump
$ make
$ make install
$ hashpump
Input Signature: 662c1f9223674b42a1ac767aea7096a7eefe55f7f8ef99ba441ce61b065bda6b9b9c242a18bf17aea164aa76aed60e9cb586812a74d346b0f17bb61b5dbba988
Input Data: 4
Input Key Length: 21
Input Data to Add: ,10

68f7d1fb28f4428f6e6589e374bc4d21ed111a009129ae38190a556a948c2f4e647c0f372ce8e115650280df9234b298ac45a5367d4c639a8ea162c1db0729f6
4\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0,10

これで、signatureとshipの値が入手できました。shipのほうはエンコードしておきます。

これをdevtoolからcookie1に代入して、「Gacha」を押せばFLAGゲットです。

qiita.com

この記事がめちゃくちゃ参考になりました。