0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Daily AlpacaHack】a fact of CTF writeup

0
Posted at

解法

output.txtにある16進数の値を10進数に変換後、素因数分解。
素因数分解の指数部分だけを取り出して、それらをUnicodeで文字にした後、結合してFLAGを得る。

過程

CTF初心者ということもあり、outputとは何だ・・・?と思いながら、pythonのコードを実行。
なんかクソ長い16進数の値が得られた。
これを復号するのかな?と思って配られたコードの解析に取り掛かった。

flag = os.environ.get("FLAG","not_a_flag")

pythonのライブラリ?かなんかで、OSにアクセスできるやつ。今回はFLAGという環境変数を参照して取得。環境変数がなければ、後ろの引数を利用する。

assert 式

式が成り立っていなかったら例外を投げる。(アサーションエラー)

for i, c, in enumarate(flag):

enumarate()は配列のインデックスと値を取得できるらしい。マップ?

ord(c)

文字cをUnicodeの数字に変換してくれる。

地道に読み取っていたところ、暗号文ctについて、
image.png
みたいな関係が成り立っていそう。

そして、その計算結果がoutput.txtに出力されているのではないかと推測。
ローカルでやってもnot_a_flagが変換されて、多分意味はなさそう。

なので、やることは、output.txtにある16進数の値を引っ張ってきて復号。
10進数に変換(もしかしたらいらないかも)→素因数分解→指数部の抽出→Unicodeの文字変換ができればよい。

というわけでこんなコードを書いてみた。
実行環境:Google colaboratory

import sympy

ct_10 = int('(output.txt内の数字)',16)
print(sympy.factorint(ct_10))

indexes = list(sympy.factorint(ct_10).values())

print(indexes)

pt = []

for i in range(0,len(indexes)):
  pt.append(chr(indexes[i]))

print(''.join(pt))

素因数分解をいちいち実装したくないので調べたところ、sympyというライブラリのfactorint()関数で素因数分解ができることを知る。
どうやらマップ{基数:指数}で返しているらしいので、.values()で値の部分のみ抽出。文字列にしたいので、配列の中にいれる。
最後に''.join()で結合させて終わり。目当てのフラグを得る。

余談

ローカルで値を出して、それを復号したとて意味はなさそうと考えた。
実際に確かめてみると、
image.png
その通りだった。

## 感想
2日目にして色々考えて、自分で復号ツールまで作って解いたので、結構パワーを使った。でもかなり面白かった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?