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ゲットです。
この記事がめちゃくちゃ参考になりました。