Skip to content

Commit

Permalink
add 12/09
Browse files Browse the repository at this point in the history
  • Loading branch information
YusukeKato committed Dec 8, 2024
1 parent d8edcaf commit f0a8a1d
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
7 changes: 7 additions & 0 deletions markdown/2024/1014.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,10 @@ LAB_001016e0:
また、ChatGPTがあればとっかかりは掴めるのでとても助かっています。
これからもAlpacaHackを通じてCTFを楽しんでいたけたら嬉しいなと思います。
それでは、また。
## 次回の記事
2024年12月9日の記事です。
https://yusukekato.jp/html/2024/1209.html
AlpacaHackで始めるCTF入門7:AlpacaHack Round 5 - XorshiftStreamに挑戦
130 changes: 130 additions & 0 deletions markdown/2024/1209.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# メタデータ
- title=AlpacaHackで始めるCTF入門7:AlpacaHack Round 5 - XorshiftStreamに挑戦
- description=個人戦CTFを開催するプラットフォーム「AlpacaHack」を通じてCTFに入門してみようと思います。今回はAlpacaHack Round 5に挑戦します。
- date=2024年12月9日(月)
- update=2024年12月9日(月)
- math=false
- tag=alpacahack

## はじめに

### 概要

かなり遅れてにはなりますが、今回はAlpacaHack Round 5の問題に挑戦してみます。
今回は一問目の「XorshiftStream」を解いてみます。
ジャンルとしては「Crypto」とのことで、すなわち暗号解読みたいな問題ということになります。
今回もChatGPTに教えてもらいながら挑戦できたらと思います。

※ 注意:解けていません!

https://alpacahack.com/ctfs/round-5

AlpacaHack Round 5のトップページ

### AlpacaHack

AlpacaHackへのリンクはこちら

https://alpacahack.com/

AlpacaHackのサイトへのリンク

### 私のCTF環境

- Windows 11/WSL2
- Ubuntu 24.04 LTS

## 前回の記事

2024年10月14日の記事です。

https://yusukekato.jp/html/2024/1014.html

AlpacaHackで始めるCTF入門6:AlpacaHack Round 4 - Simple Flag Checkerに挑戦

## 問題内容
XorshiftStreamの問題ページを開くと「tar.gz」ファイルが取得できます。
これを下記のようなコマンドで展開すると「chall.py」「output.txt」が取得できます。
chall.pyを実行してoutput.txtが出力された場合、chall.pyの中に書かれているflagはどういう文字列になるか求める問題っぽいです。

```
tar -zxvf xorshift-stream.tar.gz
```

## chall.pyを読んでみる
output.txtは一つの文字列が書かれているだけなので、
読み解くべきものはchall.pyだけです。
chall.pyには`XorshiftStream`というクラスが用意されていて、このクラスの中の`encrypt`という関数を実行して得られた出力がoutput.txtとなるみたいです。

まず`XorshiftStream`クラスではインスタンス化の際に引数として受け取ったkeyを2の64乗で割った余り(64ビットの範囲におさめるため?)をstateという変数に格納しています。

```
def __init__(self, key: int):
self.state = key % 2**64
```

次に`_next`関数では問題のタイトルにも含まれているXORShiftを使って疑似乱数的なものを生成しているようです。
`^`がXOR、`<<``>>`がシフト演算となります。

```
def _next(self):
self.state = (self.state ^ (self.state << 13)) % 2**64
self.state = (self.state ^ (self.state >> 7)) % 2**64
self.state = (self.state ^ (self.state << 17)) % 2**64
return self.state
```

そして肝心の`encrypt`関数では引数で受け取ったdataを8バイトずつ切り出して、`_next`関数で生成した疑似乱数とのXORを取っているようです。
そしてその結果を`ct`という変数にバイト形式の文字列として連結しているようです。

```
def encrypt(self, data: bytes):
ct = b""
for i in range(0, len(data), 8):
pt_block = data[i : i + 8]
ct += (int.from_bytes(pt_block, "little") ^ self._next()).to_bytes(
8, "little"
)[: len(pt_block)]
return ct
```

最後に`XorshiftStream`クラスを使用しています。

`FLAG`が求めるべき文字列っぽいです(`encode`でバイト形式に変換されているっぽい)。

```
FLAG = os.environ.get("FLAG", "fakeflag").encode()
```

`xss`ではランダムな初期値(`secrets.randbelow(2**64)`、keyとなる)を渡してクラスをインスタンス化しています。

```
xss = XorshiftStream(secrets.randbelow(2**64))
```

`key`では`FLAG`と同じ長さのランダムなバイト列を取得しています。

```
key = secrets.token_bytes(len(FLAG))
```

最後に、`encrypt`関数に`FLAG`を含んだバイト列を渡して暗号化した結果の`c`を取得しています。
`hex()`は16進数として扱うためのものらしいです。
`strxor()`は二つの引数をXORするための関数らしいです。

```
c = xss.encrypt(key.hex().encode() + strxor(key, FLAG))
print(c.hex())
```

## 解法の方針

chall.pyの暗号化の手順を逆方向に辿っていけば解けそうな気はしますが、
そんなに簡単な話なのかは分かりません。
この後は時間がかかりそうなので他の方のwriteupなどを参考にしながら進めてみます。

## おわりに
今日もAlpacaHackに挑戦させていただきました。
Cryptoジャンルの問題はどこから手を付けたらよいのか分からないぐらい理解できていないので、
やっぱりAlpacaHack以外(DreamHackなど)でも勉強が必要そうな感じです。
それでは、また。

0 comments on commit f0a8a1d

Please sign in to comment.