CyberRebeatCTF2018 Write-up
- CyberRebeatCTFとは
- 成績
- [Exercise]
- [Crypto]
- [Misc]
- [Programming]
- [Recon]
- [Stegano]
- [Trivia]
- [Web]
- [Binary]
- まとめ
CyberRebeatCTFとは
CyberRebeatは、サークルE.N.Nachが制作したノベルゲームのタイトルです。 この作品はサイバーセキュリティや、ハッカー、CTFなどを題材としており、 その題材の珍しさや高いクオリティが評価され、日本国内で各種の賞を受賞しました。 本イベントは当該作品の英語版がSteamにてリリースされたことを記念して、より多くの方にCTFを楽しんでいただこうと企画されました。
成績
1人で参加してこんな感じでした.
32位/177チーム(参加人数:270人)
[Exercise]
Exercise
CRCTF{CyberRebeatCTF}
CRCTF{CyberRebeatCTF}
を提出するだけです.
[Crypto]
Rotation
P4P6S{9RN4RUNPXR45}
アプローチ:rot13 -> 換字式暗号
問題文的にrot13だと思ったのでrot13
してみるとC4C6F{9EA4EHACKE45}
になります.
次に数字は換字式暗号っぽいなと思ったので4 -> R
, 6 -> T
, 9 -> W
, 5 -> S
に変換します.
最終的にflag
はCRCTF{WEAREHACKERS}
になります.
[Misc]
Readme
Readme.
アプローチ:Electroharmonixを頑張って読む
image.jpg
を見るとElectroharmonix
というフォントを使ったものだと分かるので下記のサイトの変換表?を見ながらflag
を読み解きます.
最終的なflag
はCRCTF{YOUCANPLAYCYBERREBEATINBOTHLANGUAGES}
です.
[Programming]
Calculation
nc 59.106.212.75 8080
アプローチ:Pythonで自動化
nc 59.106.212.75 8080
をすると四則演算が降ってくるタイプので問題です.
手でやるのはめちゃくちゃしんどいのでPythonで自動化します.
20問解くとflag
がでます.
CRCTF{She calls herself a human calculator}
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from socket import * s = socket(AF_INET, SOCK_STREAM) s.connect(('59.106.212.75', 8080)) def read(): res = s.recv(4096).decode('utf-8') # print(res) return res for i in range(100): print('count: {}'.format(i)) res = read() problem = res.split('\n')[0] print(problem) if res == '\ufeff': continue ans = str(eval(problem)) s.send(ans.encode('utf-8')+b'\n') print(ans)
Prime Factor
Answer the maximum prime factor.
nc 59.106.212.75 8081
example:
Question:120
Answer:5 (Prime Factors: 2, 3, 5)
アプローチ:そこそこ速い素因数分解アルゴリズムを使う
基本的な流れはCalculation
と同じですが,弱い(遅い)素因数分解アルゴリズムを使うと計算が終わらないので注意する必要があります.
自分はsympy
というPythonのライブラリを使いました.
25問解くとflag
がでます.
CRCTF{I'm a calculating type by nature.}
Number Theory — SymPy 1.4 documentation
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from sympy import factorint from socket import * s = socket(AF_INET, SOCK_STREAM) s.connect(('59.106.212.75', 8081)) def read(): res = s.recv(4096).decode('utf-8') # print(res) return res for i in range(100): print('count: {}'.format(i)) res = read() print(res) if res == '\ufeff': continue number = res.split('\n')[0] print(number) prime_dict = factorint(int(number)) ans = str(max(prime_dict.keys())) print(ans) s.send(ans.encode('utf-8')+b'\n')
Visual Novels
nc 59.106.212.75 8082
あるユーザーは"Reading Power"を持っている。
これはVisualNovelを月にどのくらい読めるかを示している。
彼がたくさんのVisualNovelを持っているとき、彼はどの組み合わせでプレイすればその月の満足度を最大にできるか。
最大の満足度を答えよ。example:
Reading Power = 30
Games([size, satisfaction]) =
[10, 1],
[21, 2],
[12, 3],Answer : 4
アプローチ:パースしてDPする
基本的に前の2問と同じですが,典型的なナップサック問題を解く必要があるので条件をパースしてDPします.
10問解くとflag
がでます.
CRCTF{Believe in the high efficiency processor installed in your head.}
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from socket import * import re import numpy as np s = socket(AF_INET, SOCK_STREAM) s.connect(('59.106.212.75', 8082)) def read(): res = s.recv(4096).decode('utf-8') # print(res) return res def dp(power, sizes, satisfactions): dp_table = [[0 for j in range(power + 2)] for i in range(len(sizes))] backtrack = [[0 for j in range(power + 2)] for i in range(len(sizes))] # initialization for y in range(power + 1): if sizes[0] <= y + 1: dp_table[0][y] = satisfactions[0] backtrack[0][y] = 1 else: backtrack[0][y] = 0 # DP construction for k in range(1, len(satisfactions)): for y in range(power + 1): if y - sizes[k] < 0: # out of range dp_table[k][y] = dp_table[k - 1][y] backtrack[k][y] = 0 continue left = dp_table[k - 1][y] right = dp_table[k - 1][y - sizes[k]] + satisfactions[k] if left < right: # update dp_table[k][y] = right backtrack[k][y] = 1 else: dp_table[k][y] = left backtrack[k][y] = 0 argmax = [] prev = backtrack[len(satisfactions) - 1][power - 1] argmax.append(prev) tmp_power = power - 1 for k in range(len(satisfactions) - 2, -1, - 1): if prev is 1: # case previous item was selected tmp_power -= sizes[k + 1] prev = backtrack[k][tmp_power] else: prev = backtrack[k][tmp_power] argmax.append(prev) argmax.reverse() # print(dp_table) # print(backtrack) print(argmax) arr_argmax = np.array(argmax) arr_satisfactions = np.array(satisfactions) ans = np.dot(arr_argmax, arr_satisfactions) print(ans) return ans for i in range(100): print('count: {}'.format(i)) sizes = [] satisfactions = [] res = read() if res == '\ufeff' or res == '\n': continue print(res) lines = res.split('\n') for line in lines: if 'Power' in line: power = int(line.split(' ')[-1]) if '?' in line: break if line.count(',') > 1: num_list = [ x for x in re.split('[, ]', line) if len(x) > 0] sizes.append(int(num_list[0][1:])) satisfactions.append(int(num_list[1][:-1])) ans = str(dp(power, sizes, satisfactions)) s.send(ans.encode('utf-8')+b'\n') print('send')
[Recon]
Tweet
アプローチ:Twitterを見に行く
CRCTF{CyberRebeatCTF_has_started!}
CRCTF{CyberRebeatCTF_has_started!}
— CyberRebeat (@CyberRebeat) 2018年9月8日
CyberRebeatScripts
Do you know Github?
アプローチ:Githubのリポジトリを見に行く
delete FLAG
というcommit
があるので編集差分を確認します.
CRCTF{I cut down her gag in a single strike}
ChangeHistory
アプローチ:gitの使い方のお勉強
当該リポジトリに行ってみると怪しいissue
がたってる.
とりあえずgit clone
してgit log
とgit reflog
をしてみるが手がかりなし.
git reflog
でlocal log
しか取得できなかったのでなんとかremote log
を取得する方法を調べる.
上記サイトによるとcurl https://api.github.com/repos/ennach/ChangeHistory/events
してcommit id
がc476614bc439fe1910e494422b3aa207b776d486
のURLを見つけるといいらしい.
https://api.github.com/repos/ennach/ChangeHistory/commits/c476614bc439fe1910e494422b3aa207b776d486
上記サイトで変更前のデータが見れるのでflag
がとれる
CRCTF{the timer is set to 120 seconds}
[Stegano]
Secret.pdf
It's a secret pdf!
アプローチ:とりあえずopen
とりあえずopen secret.pdf
する
flag
部分が黒塗りされてるが文字選択でぬける.
CRCTF{I don't know of a time without the internet}
Alpha
アプローチ:alpha.pngのα値を調べる
問題名的にpngのα値を調べろということっぽいので簡単なスクリプトを書いて調べる(スクリプト書くよりも既存のツールを使ったほうが速いです).
ほとんどのPixelのα値が253であることが分かる.
怪しいのでα値が253以外のPixelを抜き出すスクリプトを書く.
CRCTF{ALPHA_IS_THE_NAME_OF_A_HACKER_IN_CYBERREBEAT}
#!/usr/bin/env python # -*- coding: utf-8 -*- from PIL import Image import numpy as np img = Image.open('./alpha.png') size = img.size flag_img = Image.new('RGBA',size) for x in range(size[0]): for y in range(size[1]): rgba = img.getpixel((x,y)) if rgba[3] != 253: flag_img.putpixel((x,y),(255,255,255,255)) else : flag_img.putpixel((x,y),(0,0,0,255)) flag_img.show() flag_img.save('./flag_img.png')
[Trivia]
Monero
ウェブ上からMoneroを発掘するソフトウェア。
日本で、自身のウェブサイト上にこのソフトを設置した何人かのユーザが逮捕されている。
フラグはすべて小文字。
例: CRCTF{abcdefgh}
アプローチ:日頃からセキュリティ関連のニュースをチェックしておく
これはcoinhive
のことですね.
CRCTF{coinhive}
Crossword
crossword_text.txt
FLAG:CRCTF{ABCDEFGH}
Flag format: all lowercase
横 1. ___ はCyberRebeatにおける特殊なコードネーム。CyberRebeatは、ハッカーたちがこれを打倒する物語。『ぴったりだと思わないか、ええっ、英雄(ヒーロー)?』 5. CyberRebeat作中における、とあるハッカーの切り札。______はネットに接続された多数のデバイスで、それぞれがひとつあるいは複数のBOTを実行している。 8. heroine.png / 彼女の名前:____ Amamiya 10. CyberRebeatシナリオライターの代表作:__:____ ~親愛なるあなたへ~ 11. CyberRebeatのキャッチフレーズ:We are h_____. 15. W_______はWindowsを実行しているコンピュータをターゲットとした、データを暗号化しBitcoinでの身代金支払いを要求するランサムウェアです。 16. CyberRebeatのシナリオライター 18. CRCTFを主催している同人サークル 19. 運営協力 : __________ Institute, Ltd., Aqutras Inc. 20. ______ はインターネットとセキュリティソフトウェアのクライアントのSSL 3.0へのフォールバックを利用した中間者攻撃です。 21. __________はBashdoorとも呼ばれ、Unix Bashシェルのセキュリティバグの一種であり、2014年9月24日にはじめて公表されました。 縦 2. Operation ______は、中国北京のElderwood GroupのようなAPTが人民解放軍と連携して行った一連のサイバー攻撃のこと。 3. CyberRebeatで利用しているゲームエンジン 4. CyberRebeatのイラストレーター:Kikyo ______ 6. smile.min.svg 7. _____ Rain は、米国連邦政府が定義した2003年からのアメリカのコンピュータシステムに対する一連の組織的な攻撃のこと。 9. CyberRebeatのデザインおよび背景イラスト担当 12. 翻訳協力 : __________ 13. CRCTFを主催している同人サークルが制作したノベルゲームの名称 14. https://store.____________.com/app/825320/CyberRebeat_The_Fifth_Domain_of_Warfare/ 17. heart.png
アプローチ:クロスワードを解く
2. Aurora 3. Unity 4. Manose 10. Re:LieF 11. hackers 12. SekaiProject 13. CyberRebeat 14. steampowered 15. wannacry 18. e.n.nach 19. activedefence 20. poodle 21. Shellshock CRCTF{ABCDEFGHI} CRCTF{submarine}
フラグはCRCTF{submarine}
になります.
[Web]
White page
http://hidden-field.cyberrebeat.adctf.online/index.php
id: Hiro
password: LittleGarden
アプローチ:curlでid,passをPost
Webサイトにアクセスしてみると問題名の通り,White pageになっています(Loginボタンがあるだけ).
ソースコードを確認しみてると以下のようになっています.
<body> <form action="index.php" method="post"> <input type="text" name="id" style="visibility:hidden" /> <input type="text" name="password" style="visibility:hidden" /> <button>LOGIN</button> </form> </body>
id,passwordの入力フォームがvisibility:hidden
になっているため,このままでは入力できないことがわかります.
そのため,curl
を使用してid
, password
をPOST
します.
curl http://hidden-field.cyberrebeat.adctf.online/index.php -X POST -d "id=Hiro&password=LittleGarden"
ログインに成功してflag
がとれます.
CRCTF{All I typed were four letters.}
Let's Tweet!
http://tweet.cyberrebeat.adctf.online/LetsTweet.php
LetsTweet.php
アプローチ:ついーとする
この問題は正直よく分かりませんでした.
php
のソースコードを確認するとtest.db
を読み込んでいることが分かるのでディレクトリトラバーサルでtest.db
を抜こうとしたのですが,Not Foundが返ってきて詰みました.
仕方なく,ツイートのリンクを使ってflag
をとりました.
CRCTF{Thank_you_for_your_tweet!}
Uploader
Find the secret file.
http://sqli.cyberrebeat.adctf.online/index.php
id: guest
pass: guest
アプローチ:SQLi -> Blind SQLi
とりあえずFile Name :
でSQLi
してみるとharada
というユーザがsecret.zip
をアップロードしていることが分かります.
次に問題文にあったid
,pass
でログインしてみるとsample.zip
のpassword
を閲覧できることがわかります.
そのため,harada
のpass
を探し出し,ログインに成功したらsecret.zip
をunzip
できることがわかります.
harada
のpass
を探すためにBlind SQLi
しなければいけないのですが,自分はSQLi Beginner
なのでsqlmap
に頼りました.
上記のサイトを参考にUsersテーブル
をdump
します.
sqlmap -u 'http://sqli.cyberrebeat.adctf.online/index.php' --data 'file_name=aaa&search=search' --dump -T Users
userid | password |
---|---|
guest | guest |
harada | seishin0129 |
pass:seishin0129
を使ってuser:harada
としてログインするとzippassword
を得ることができます.
上記のpass
でsecret.zip
をunzip
してあげるとflag
がとれます.
CRCTF{Today's_internet_is_full_of_concerning_vulnerabilities}
[Binary]
0完
1問目のSimpleBinaryを解きながら「これのどこがシンプルなんだよ???」とキレてた.
Binary全然わからん…Binary強くなりたい…
まとめ
- 土日を持っていかれた
- 生活リズムが崩壊した(現在インターン中なので月曜の朝がつらそう)
- Binaryぜんぜんわからん
- CTFを始めて数ヶ月経って少しずつ解ける問題が増えてきたことを実感できたので嬉しかった
- CyberRebeatめっちゃ気になる