picoCTF 2024 Writeup
2024年3月12日から3月26日に開催されたpicoCTF 2024 において、自身のチームが解けた問題の感想と解法を書きます。
writeupを初めて書くので足りないところがあるかもしれません。ご了承ください。
目次
-
General Skills
- Super SSH
- Commitment Issues
- Time Machine
- Collaborative Development
- binhexa
- endianness
- Blame Game
- Binary Search
- dont-you-love-banners
-
Web Exploitation
- Bookmarklet
- WebDecode
- IntroToBurp
- Unminify
-
Cryptography
- interencdec
-
Reverse Engineering
- なし
-
Forensics
- Scan Surprise
- CanYouSee
- Verify
- Secret of the Polyglot
- Mob psycho
- endianness-v2
-
Binary Exploitation
- heap 0
- heap 1
- format string 0
General Skills
この問題では問題文に記載されているようにsshで接続します。
% ssh ctf-player@titan.picoctf.net -p 65080
接続したらそのままコマンドライン上でpicoCTF{s3cur3_c0nn3ct10n_5d09a462}
と出力されました。
この問題ではchallenge.zipをダウンロードし、ターミナル上でunzipします。すると以下のようになります。
% unzip challenge.zip
Archive: challenge.zip
creating: drop-in/
creating: drop-in/.git/
creating: drop-in/.git/branches/
inflating: drop-in/.git/description
creating: drop-in/.git/hooks/
inflating: drop-in/.git/hooks/applypatch-msg.sample
inflating: drop-in/.git/hooks/commit-msg.sample
inflating: drop-in/.git/hooks/fsmonitor-watchman.sample
inflating: drop-in/.git/hooks/post-update.sample
inflating: drop-in/.git/hooks/pre-applypatch.sample
inflating: drop-in/.git/hooks/pre-commit.sample
inflating: drop-in/.git/hooks/pre-merge-commit.sample
inflating: drop-in/.git/hooks/pre-push.sample
inflating: drop-in/.git/hooks/pre-rebase.sample
inflating: drop-in/.git/hooks/pre-receive.sample
inflating: drop-in/.git/hooks/prepare-commit-msg.sample
inflating: drop-in/.git/hooks/update.sample
creating: drop-in/.git/info/
inflating: drop-in/.git/info/exclude
creating: drop-in/.git/refs/
creating: drop-in/.git/refs/heads/
extracting: drop-in/.git/refs/heads/master
creating: drop-in/.git/refs/tags/
extracting: drop-in/.git/HEAD
inflating: drop-in/.git/config
creating: drop-in/.git/objects/
creating: drop-in/.git/objects/pack/
creating: drop-in/.git/objects/info/
creating: drop-in/.git/objects/ba/
extracting: drop-in/.git/objects/ba/e247ddd9f730bb7a2a9425d4616b116bc7b07b
creating: drop-in/.git/objects/68/
extracting: drop-in/.git/objects/68/df36301019ecc05a65a4e87a754c83411ac925
creating: drop-in/.git/objects/87/
extracting: drop-in/.git/objects/87/b85d7dfb839b077678611280fa023d76e017b8
creating: drop-in/.git/objects/d5/
extracting: drop-in/.git/objects/d5/52d1ecd2d83fa2e65b6724d1ff73b45a7d59b7
creating: drop-in/.git/objects/0c/
extracting: drop-in/.git/objects/0c/1ab266b7a3a1cd099bb509f82b7a2d03aecd03
creating: drop-in/.git/objects/8d/
extracting: drop-in/.git/objects/8d/c51806c760dfdbb34b33a2008926d3d8e8ad49
inflating: drop-in/.git/index
extracting: drop-in/.git/COMMIT_EDITMSG
creating: drop-in/.git/logs/
inflating: drop-in/.git/logs/HEAD
creating: drop-in/.git/logs/refs/
creating: drop-in/.git/logs/refs/heads/
inflating: drop-in/.git/logs/refs/heads/master
extracting: drop-in/message.txt
とにかく量が多いです。また、この時GUI上では一番したのdrio-inディレクトリとmessage.txtファイルしか存在していなかった。そこでdrop-in % cat message.txt
をしてみるがどうやらmessage.txtは不完全のようでした。以上から、この問題を解く最初のヒントはdrop-in/.git/に移動することと予想。
ヒントにpicoCTFでのgitコマンドの使い方が書かれてあるWebページがあるのでそこでコマンドを調べていく。
https://primer.picoctf.org/#_git_version_control
gitでlogを見てみます。drop-in/.git/logs/にあります。
heads % git log
commit 8dc51806c760dfdbb34b33a2008926d3d8e8ad49 (HEAD -> master)
Author: picoCTF <ops@picoctf.com>
Date: Tue Mar 12 00:06:17 2024 +0000
remove sensitive info
commit 87b85d7dfb839b077678611280fa023d76e017b8
Author: picoCTF <ops@picoctf.com>
Date: Tue Mar 12 00:06:17 2024 +0000
create flag
create flagのcommitIDが87b85d7dfb839b077678611280fa023d76e017b8
であることが分かったため、このIDのログを頼りにロールバック(更新前状態に戻す)する。
ちなみにこの操作はトップディレクトリ(drop-in)でしか操作できませんでした。
そのためdrop-inに移動し、ログからcreate flagをしたときに戻ります。
drop-in % git checkout 87b85d7dfb839b077678611280fa023d76e017b8
Note: switching to '87b85d7dfb839b077678611280fa023d76e017b8'.
ここで更新されたかを確認します。drop-in/.git/logs/にあります。
logs % cat HEAD
0000000000000000000000000000000000000000 87b85d7dfb839b077678611280fa023d76e017b8 picoCTF <ops@picoctf.com> 1710201977 +0000 commit (initial): create flag
87b85d7dfb839b077678611280fa023d76e017b8 8dc51806c760dfdbb34b33a2008926d3d8e8ad49 picoCTF <ops@picoctf.com> 1710201977 +0000 commit: remove sensitive info
8dc51806c760dfdbb34b33a2008926d3d8e8ad49 87b85d7dfb839b077678611280fa023d76e017b8 <自身の名前> <自身の登録したメールアドレス> 1710356708 +0900 checkout: moving from master to 87b85d7dfb839b077678611280fa023d76e017b8
確認してみると新たに<自身の名前>が更新してることが分かります。
そのためログをcreate flagした状態に戻すことができたため
drop-in % cat message.txt
によりpicoCTF{s@n1t1z3_ea83ff2a}
が取得できました。
先ほどと同様にダウンロードしたzipファイルを解凍し、logを見ていく。
するとlog/HEADファイルを見てくと下記のようになった。
% cat HEAD
0000000000000000000000000000000000000000 89d296ef533525a1378529be66b22d6a2c01e530 picoCTF <ops@picoctf.com> 1710202042 +0000 commit (initial): picoCTF{t1m3m@ch1n3_186cd7d7}
これによりpicoCTF{t1m3m@ch1n3_186cd7d7}
が得られました。
challenge.zipをunzipして解凍するとdrop-inフォルダとflag.pyファイルがありました。
これを見てみると下図のように何やら文字が書かれていましたが、特に答えになるようなことはなかったです。
% cat flag.py
print("Printing the flag...")
また.git/logs/HEADを見てみると以下のようになっていました。
% cat HEAD
0000000000000000000000000000000000000000 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 commit (initial): init flag printer
6ce09adec311b859780caf89d993c58e34b53fa6 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 checkout: moving from main to feature/part-1
6ce09adec311b859780caf89d993c58e34b53fa6 74ae5215b93a82ddf3dd37df3d4c6b5aff0a93ed picoCTF <ops@picoctf.com> 1710018591 +0000 commit: add part 1
74ae5215b93a82ddf3dd37df3d4c6b5aff0a93ed 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 checkout: moving from feature/part-1 to main
6ce09adec311b859780caf89d993c58e34b53fa6 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 checkout: moving from main to feature/part-2
6ce09adec311b859780caf89d993c58e34b53fa6 b4612c914d8461d1b1a50652cc303b76813ee142 picoCTF <ops@picoctf.com> 1710018591 +0000 commit: add part 2
b4612c914d8461d1b1a50652cc303b76813ee142 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 checkout: moving from feature/part-2 to main
6ce09adec311b859780caf89d993c58e34b53fa6 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 checkout: moving from main to feature/part-3
6ce09adec311b859780caf89d993c58e34b53fa6 5c6d493ac583a95117d3a70eb5b10d9d76991c48 picoCTF <ops@picoctf.com> 1710018591 +0000 commit: add part 3
5c6d493ac583a95117d3a70eb5b10d9d76991c48 6ce09adec311b859780caf89d993c58e34b53fa6 picoCTF <ops@picoctf.com> 1710018591 +0000 checkout: moving from feature/part-3 to main
このログを分析していくと基本的に6ce09adec311b859780caf89d993c58e34b53fa6
がメインとなっていたのですが,feature/part-1,2,3の箇所のみ値が違うことに気づきました。
その為git checkout ~ でpart-1に移動してみると以下のようになりました。
% git checkout 74ae5215b93a82ddf3dd37df3d4c6b5aff0a93ed
Note: switching to '74ae5215b93a82ddf3dd37df3d4c6b5aff0a93ed'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 74ae521 add part 1
ここでflag.pyを見てみると以下のように出力されていました。
% cat flag.py
print("Printing the flag...")
print("picoCTF{t3@mw0rk_", end='')%
その為part -2, part -3も見てみることに
% git checkout b4612c914d8461d1b1a50652cc303b76813ee142
Previous HEAD position was 74ae521 add part 1
HEAD is now at b4612c9 add part 2
% cat flag.py
print("Printing the flag...")
print("m@k3s_th3_dr3@m_", end='')%
% git checkout 5c6d493ac583a95117d3a70eb5b10d9d76991c48
Previous HEAD position was b4612c9 add part 2
HEAD is now at 5c6d493 add part 3
% cat flag.py
print("Printing the flag...")
print("w0rk_4c24302f}")
以上から繋げるてpicoCTF{t3@mw0rk_m@k3s_th3_dr3@m_w0rk_4c24302f}
が得られました。
問題文は以下の通りです。
本問題ではncコマンドで指定のアドレスにアクセスするとプログラムが開始されます。
以下にはやり取りの様子です。
% nc titan.picoctf.net 62817
Welcome to the Binary Challenge!"
Your task is to perform the unique operations in the given order and find the final result in hexadecimal that yields the flag.
Binary Number 1: 00100001
Binary Number 2: 11111011
Question 1/6:
Operation 1: '>>'
Perform a right shift of Binary Number 2 by 1 bits .
Enter the binary result: 011111011
Incorrect. Try again
Enter the binary result: 01111101
Correct!
Question 2/6:
Operation 2: '|'
Perform the operation on Binary Number 1&2.
Enter the binary result: 11111011
Correct!
Question 3/6:
Operation 3: '*'
Perform the operation on Binary Number 1&2.
Enter the binary result: 10000001011011
Correct!
Question 4/6:
Operation 4: '<<'
Perform a left shift of Binary Number 1 by 1 bits.
Enter the binary result: 01000010
Correct!
Question 5/6:
Operation 5: '&'
Perform the operation on Binary Number 1&2.
Enter the binary result: 00100001
Correct!
Question 6/6:
Operation 6: '+'
Perform the operation on Binary Number 1&2.
Enter the binary result: 100011100
Correct!
Enter the results of the last operation in hexadecimal: 11C
Correct answer!
The flag is: picoCTF{b1tw^3se_0p3eR@tI0n_su33essFuL_aeaf4b09}
この問題は2つの2進数の数字と演算を行なった結果を答える問題です。
間違えるともう一度解答を入力できるようになっています。
最後は2進数から16進数に変換する問題でした。
|が論理和 &が論理積 +が足し算 *が掛け算 >>が右論理シフト <<が左論理シフトでした。
この問題ではncで上記のところに接続します。
するとプログラムが開始され、何か入力を求められます。
% nc titan.picoctf.net 61706
Welcome to the Endian CTF!
You need to find both the little endian and big endian representations of a word.
If you get both correct, you will receive the flag.
Word: aqntu
Enter the Little Endian representation:
ちなみにSourceをクリックするとflag.cと言うプログラムソースコードが入手できます。
その為このflag.cを解読していく。
一旦pythonに変換して解読していきます。
するとこのプログラムではwordと言う変数で5文字のランダムな文字列を出力するらしい。
そして今コマンドライン上で求められているのはLittele Endian representationなので
同じ名前の関数にwordを代入して出力するプログラムを抜き取りました。
import random
import string
def generate_random_word():
print("Welcome to the Endian CTF!")
print("You need to find both the little endian and big endian representations of a word.")
print("If you get both correct, you will receive the flag.")
word_length = 5
word = ''.join(random.choices(string.ascii_lowercase, k=word_length))
return word
def find_little_endian(word):
little_endian = ''.join(format(ord(c), '02X') for c in word[::-1])
return little_endian
def find_big_endian(word):
big_endian = ''.join(format(ord(c), '02X') for c in word)
return big_endian
def main():
challenge_word = generate_random_word()
print("Word:", challenge_word)
correct_flag = False
while not correct_flag:
user_little_endian = input("Enter the Little Endian representation: ").strip().upper()
if user_little_endian == find_little_endian(challenge_word):
print("Correct Little Endian representation!")
correct_flag = True
else:
print("Incorrect Little Endian representation. Try again!")
final_flag = False
while not final_flag:
user_big_endian = input("Enter the Big Endian representation: ").strip().upper()
if user_big_endian == find_big_endian(challenge_word):
print("Correct Big Endian representation!")
final_flag = True
else:
print("Incorrect Big Endian representation. Try again!")
with open("flag.txt", "r") as flag:
flag_content = flag.readline().strip()
print("Congratulations! You found both endian representations correctly!")
print("Your Flag is:", flag_content)
if __name__ == "__main__":
main()
上記のpythonプログラムから入力が求められている関数だけを抜き取ります。そして5文字のwordを入力して結果を返します。
def find_little_endian(word):
little_endian = ''.join(format(ord(c), '02X') for c in word[::-1])
return little_endian
print(find_little_endian("aqntu"))
これがwordを代入して値を返すための抜き取ったプログラムです。
これを実行すると75746E7161
が得られたのでCUIにぶち込みます。
すると以下のようになります。
Enter the Little Endian representation: 75746E7161
Correct Little Endian representation!
Enter the Big Endian representation:
今度はBig Endian representationを入力するように求められました。
その為これもプログラムを抜き取ってきます。
def find_big_endian(word):
big_endian = ''.join(format(ord(c), '02X') for c in word)
return big_endian
print(find_big_endian("aqntu"))
この抜き取ってきたプログラムを出力した結果は61716E7475
これで,この値をCUI上に入力すると以下のようになりました。
Enter the Big Endian representation: 61716E7475
Correct Big Endian representation!
Congratulations! You found both endian representations correctly!
Your Flag is: picoCTF{3ndi4n_sw4p_su33ess_d58517b6}
これによりpicoCTF{3ndi4n_sw4p_su33ess_d58517b6}
が得られました。
問題文は以下の通りです。
ダウンロードしたzipファイルを解答し、logを確認します。
% cat HEAD
0000000000000000000000000000000000000000 7e8a2415b6cca7d0d0002ff0293dd384b5cc900d picoCTF <ops@picoctf.com> 1710018565 +0000 commit (initial): create top secret project
7e8a2415b6cca7d0d0002ff0293dd384b5cc900d 0fe87f16cbd8129ed5f7cf2f6a06af6688665728 picoCTF{@sk_th3_1nt3rn_ea346835} <ops@picoctf.com> 1710018565 +0000 commit: optimize file size of prod code
0fe87f16cbd8129ed5f7cf2f6a06af6688665728 ccf857444761e8380204eafd76e677f9e7e71a94 picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
ccf857444761e8380204eafd76e677f9e7e71a94 90652256748b75c442eef5c29ce88d4add9af7a2 picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
90652256748b75c442eef5c29ce88d4add9af7a2 204409fde33b57427db82d585212879189b55012 picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
204409fde33b57427db82d585212879189b55012 a85cb0c5b456fe696f214fa0e3d289b20aba9cca picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
a85cb0c5b456fe696f214fa0e3d289b20aba9cca ef24e924daff4ba24bd713d95bfc7242058a1cba picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
ef24e924daff4ba24bd713d95bfc7242058a1cba 5cb0dd389662aa66c2e29d77dc3ef83524ccb3e3 picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
5cb0dd389662aa66c2e29d77dc3ef83524ccb3e3 d9b99be4a24a50d58ff02853fcb6765c43bfdbd6 picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
d9b99be4a24a50d58ff02853fcb6765c43bfdbd6 30366f8537d780c8ce39cb1049b1281a6df17e4c picoCTF <ops@picoctf.com> 1710018565 +0000 commit: important business work
30366f8537d780c8ce39cb1049b1281a6df17e4c ae25484a3de59172861f06d1b503e21e05b13df3 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
ae25484a3de59172861f06d1b503e21e05b13df3 469df48f9f91186af8e703eaee28bc5dc218f51a picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
469df48f9f91186af8e703eaee28bc5dc218f51a bf62814aa10b702e5ff580a3539f93f5c904b8b3 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
bf62814aa10b702e5ff580a3539f93f5c904b8b3 31b128d753e690f7ec363c91945f57032549d828 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
31b128d753e690f7ec363c91945f57032549d828 af1f1b3feb4b3401a0e9985a304115df393f33ef picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
af1f1b3feb4b3401a0e9985a304115df393f33ef f0b55d6be4cc2e4d7977c7d45f3683360d673bd0 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
f0b55d6be4cc2e4d7977c7d45f3683360d673bd0 5b002267cf0e873a7ee625a6a39563d2f6d625b7 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
5b002267cf0e873a7ee625a6a39563d2f6d625b7 f4a800fca08080dc5d6a7edb1f45dc4f5eed3af5 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
f4a800fca08080dc5d6a7edb1f45dc4f5eed3af5 7c635dff4fa8d001cc2e47894be53e4e50f4c263 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
7c635dff4fa8d001cc2e47894be53e4e50f4c263 f9ea685bbf2bcbd84f7fc014e7223444af9e8e20 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
f9ea685bbf2bcbd84f7fc014e7223444af9e8e20 ef752b40a172fbf59e80ca1e6584cff9cc65f45b picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
ef752b40a172fbf59e80ca1e6584cff9cc65f45b 7374ba875e847e07e3ccd786146d5226761786cd picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
7374ba875e847e07e3ccd786146d5226761786cd 0c3627bf339b100db190a5a6ceca3158d9e4698b picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
0c3627bf339b100db190a5a6ceca3158d9e4698b 9501cd16462583cb490f17dd4818211818ff1b33 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
9501cd16462583cb490f17dd4818211818ff1b33 374db99bab73c94528148b87765a51dc990a6dfd picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
374db99bab73c94528148b87765a51dc990a6dfd 5085b73a3d4b4870a4224d9e72c4735279bc8d3f picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
5085b73a3d4b4870a4224d9e72c4735279bc8d3f fa5db4f9487ba54a774ce4e27b9b13d1723ccbeb picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
fa5db4f9487ba54a774ce4e27b9b13d1723ccbeb ea3f2bb9dd9506a71b514a3c694d65de04e6b19c picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
ea3f2bb9dd9506a71b514a3c694d65de04e6b19c 45e85a5af0efb5cc3d1ade154f8c850f88f66539 picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
45e85a5af0efb5cc3d1ade154f8c850f88f66539 e48c7c3f27d596d75114af99381c4d95ca45f65c picoCTF <ops@picoctf.com> 1710018566 +0000 commit: important business work
・・・
・・・
・・・
つらつら書かれていたが上から2番目の変更者のユーザ名がpicoCTF{@sk_th3_1nt3rn_ea346835}
となってるので入力してみることに...
成功!?
問題文よりsshに繋げると以下のようになります。
繋げると1から1000の間のどこかに答えがあるようです。
また解答した数値に対してLowerかHigherを返してくれるので数撃ちでいけます。
効率良くいくために2分探索で調べていく。
以下はその様子になります。
最後の方は綺麗に1/2倍せずにテキトーにしています。
% ssh -p 60326 ctf-player@atlas.picoctf.net
The authenticity of host '[atlas.picoctf.net]:60326 ([18.217.83.136]:60326)' can't be established.
ED25519 key fingerprint is SHA256:M8hXanE8l/Yzfs8iuxNsuFL4vCzCKEIlM/3hpO13tfQ.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[atlas.picoctf.net]:60326' (ED25519) to the list of known hosts.
ctf-player@atlas.picoctf.net's password:
Welcome to the Binary Search Game!
I'm thinking of a number between 1 and 1000.
Enter your guess: 500
Lower! Try again.
Enter your guess: 250
Lower! Try again.
Enter your guess: 125
Higher! Try again.
Enter your guess: 185
Lower! Try again.
Enter your guess: 150
Lower! Try again.
Enter your guess: 140
Lower! Try again.
Enter your guess: 130
Congratulations! You guessed the correct number: 130
Here's your flag: picoCTF{g00d_gu355_de9570b0}
Connection to atlas.picoctf.net closed.
以上からpicoCTF{g00d_gu355_de9570b0}
が得られました。
問題文は以下の通りです。
この問題でははじめにnc tethys.picoctf.net 52937を行います。
するとこのtethys.picoctf.net 52937自体が欠陥があるようでMY_PASSW@RD_@1234
と出力していました。
次にnc tethys.picoctf.net 55591に接続するとパスワードが求められました。そこで先ほど取得したMY_PASSW@RD_@1234
を入力してみると成功し、次の質問になりました。
次の質問ではWhat is the top cyber security conference in the world?という問題でした。色々答えた結果DEF CON
が正解のようでした。
次の質問ではthe first hacker ever was known for phreaking(making free phone calls), who was it?という問題でJohn Thomas Draper
が正解のようです。
これにて質問は終了しログインすることができました。
ログインしてはじめに現在のディレクトリから問題文にあったように/rootディレクトリに移動します。するとflag.txtとscript.pyが存在していました。
まずはflag.txtを見てみます。しかし下記のように権限がないため見れませんでした。
またlessやstrings ,vim ,nano ,更にはchown,sudoなどして権限の交換などをしてみましたができませんでした。
/root$ cat flag.txt
cat flag.txt
cat: flag.txt: Permission denied
そこでもう一方のscript.pyを見てみます。
するとはじめにncで繋げた際の質問の流れがプログラムされていることがわかったので、ncで繋げた際にはこのプログラムが実行されていることがわかります。
また3つの問いに成功した時に権限をsuからplayerにしているため管理者権限に戻すことはできないこともわかりました。
しかし、このプログラムを実行した時には/home/player/bannerというファイルを読み取っているらしいのでこの仕組みを使ってみる
ヒントにシンボリックリンクとあったので調べてみると特定のファイルなどを他のファイルからアクセスできるようにするものだった。
$ cat script.py
import os
import pty
incorrect_ans_reply = "Lol, good try, try again and good luck\n"
if __name__ == "__main__":
try:
with open("/home/player/banner", "r") as f:
print(f.read())
except:
print("*********************************************")
print("***************DEFAULT BANNER****************")
print("*Please supply banner in /home/player/banner*")
print("*********************************************")
try:
request = input("what is the password? \n").upper()
while request:
if request == 'MY_PASSW@RD_@1234':
text = input("What is the top cyber security conference in the world?\n").upper()
if text == 'DEFCON' or text == 'DEF CON':
output = input(
"the first hacker ever was known for phreaking(making free phone calls), who was it?\n").upper()
if output == 'JOHN DRAPER' or output == 'JOHN THOMAS DRAPER' or output == 'JOHN' or output== 'DRAPER':
scmd = 'su - player'
pty.spawn(scmd.split(' '))
else:
print(incorrect_ans_reply)
else:
print(incorrect_ans_reply)
else:
print(incorrect_ans_reply)
break
except:
KeyboardInterrupt
では実際にシンボリックリンクを作成していく。
はじめにbannerを読見込んでほしい/root/flag.txtに変換していく。しかし、bannerというファイルがもうすでに存在しているということで注意を受けました。
player@challenge:~$ ln -s /root/flag.txt banner
ln -s /root/flag.txt banner
ln: failed to create symbolic link 'banner': File exists
そこでbannerを一度消します。すると消せました。
player@challenge:~$ rm banner
rm banner
player@challenge:~$ ls -l
ls -l
total 4
-rw-r--r-- 1 root root 13 Feb 7 17:25 text
そこでもう一度チャレンジしてみると、できました。
player@challenge:~$ ln -s /root/flag.txt banner
ln -s /root/flag.txt banner
player@challenge:~$ ls -l
ls -l
total 4
lrwxrwxrwx 1 player player 14 Mar 17 16:32 banner -> /root/flag.txt
-rw-r--r-- 1 root root 13 Feb 7 17:25 text
では実際にsacript.pyを実行すると今までとは違う出力結果となりました。(下図)
しかし正しく/home/player/bannerを読まれていませんでした。
player@challenge:/root$ python3 script.py
python3 script.py
*********************************************
***************DEFAULT BANNER****************
*Please supply banner in /home/player/banner*
*********************************************
what is the password?
q
q
Lol, good try, try again and good luck
player@challenge:/root$ ^C
理由はすでにログインしている状態では権限者がsuからplayerに変更されていたからです。そのため一度接続を切って再度繋げてみます。
すると繋げた瞬間にflag.txtが読み込まれたらしくフラグが出力されました。
% nc tethys.picoctf.net 55591
picoCTF{b4nn3r_gr4bb1n9_su((3sfu11y_8126c9b0}
これによりpicoCTF{b4nn3r_gr4bb1n9_su((3sfu11y_8126c9b0}
が得られました。
Web Exploitation
問題文は以下の通りです。
この問題はhereを押したら以下のようなサイトに飛びます
ここでソースコードを読んでjavascriptで書かれてあるコードを読み取ります。
javascript:(function() {
var encryptedFlag = "àÒÆަȬëÙ£ÖÓÚåÛÑ¢ÕÓÉÕËÆÒÇÚËí";
var key = "picoctf";
var decryptedFlag = "";
for (var i = 0; i < encryptedFlag.length; i++) {
decryptedFlag += String.fromCharCode((encryptedFlag.charCodeAt(i) - key.charCodeAt(i % key.length) + 256) % 256);
}
alert(decryptedFlag);
})();
JavaScriptのプログラムをpythonで書き直して実行する
def decrypt_flag(encrypted_flag, key):
decrypted_flag = ""
for i in range(len(encrypted_flag)):
decrypted_flag += chr((ord(encrypted_flag[i]) - ord(key[i % len(key)]) + 256) % 256)
return decrypted_flag
if __name__ == "__main__":
encrypted_flag = "àÒÆަȬëÙ£ÖÓÚåÛÑ¢ÕÓÉÕËÆÒÇÚËí"
key = "picoctf"
decrypted_flag = decrypt_flag(encrypted_flag, key)
print(decrypted_flag)
このプログラムは特定の文字列を指定されたkeyでデコードするプログラムでした。
単純にこれを実行することでflagゲットです。
picoCTF{p@g3_turn3r_cebccdfe}
問題文は以下の通りです。
このhereをクリックすると以下のようなサイトに飛びます。
このサイトのHOME,ABOUT,CONTACTそれぞれのWebページのソースコードを見ていくと,ABOUTのところで少々引っかかる文字列があった。いかに気になったソースコードを表します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta content="IE=edge" http-equiv="X-UA-Compatible"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<link href="style.css" rel="stylesheet"/>
<link href="img/favicon.png" rel="shortcut icon" type="image/x-icon"/>
<!-- font (google) -->
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet"/>
<title>About me</title>
</head>
<body>
<header>
<nav>
<div class="logo-container">
<a href="index.html">
<img alt="logo" src="img/binding_dark.gif"/>
</a>
</div>
<div class="navigation-container">
<ul>
<li>
<a href="index.html">
Home
</a>
</li>
<li>
<a href="about.html">
About
</a>
</li>
<li>
<a href="contact.html">
Contact
</a>
</li>
</ul>
</div>
</nav>
</header>
<section class="about" notify_true="cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMjgzZTYyZmV9">
<h1>
Try inspecting the page!! You might find it there
</h1>
<!-- .about-container -->
</section>
<!-- .about -->
<section class="why">
<footer>
<div class="bottombar">
Copyright © 2023 Your_Name. All rights reserved.
</div>
</footer>
</section>
</body>
</html>
このうちのnotify_true=cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMjgzZTYyZmV9
が怪しいのでhttps://dencode.com/ja/
というサイトでデコードするとbase64でpicoCTF{web_succ3ssfully_d3c0ded_283e62fe}
が取得できた。
問題文は以下の通りです。
開始するとhereという指定したURLに飛ぶことができます。
ここを押してみると以下のようなページに飛びます。
次にBurpを開きます。開いてInterceptをonにして先ほどのURLに飛びます。
そしてとりあえず入力してRegisterを押してみます。
すると以下のようにやり取りの内容が見れます。ここで内容を書き換えることが可能です。ちなみにこれはブラウザからburpに行き、burpからサーバに行く中間者攻撃のような物です。
次に2段階認証の画面が出てきました。
ここでとりあえず何か入力してSubmitを押すと以下のようになりました。
そもそも2段階認証をなくしてみることにします。
ここで2段階認証のotp="入力した文字"を消してForwardを押してみます。
これによりpicoCTF{#0TP_Bypvss_SuCc3$S_b3fa4f1a}
が得られました。
問題文は以下の通りです。
このhereをクリックすると以下のようなWebサイトに飛ぶ
このページのソースを見ていくとHTMLが横一列にバーっとなっていました。
ブワーッと右にいくとありました。
<p class="picoCTF{pr3tty_c0d3_743d0f9b}"></p>
以上よりpicoCTF{pr3tty_c0d3_743d0f9b}
が得られました。
Cryptography
問題文は以下の通りです。
この問題はhereを押すとenc_flagと言うファイルがダウンロードされます。
開くとYidkM0JxZGtwQlRYdHFhR3g2YUhsZmF6TnFlVGwzWVROclgyZzBOMm8yYXpZNWZRPT0nCg==
と言う文字列がありました。
文末に==
があるのでbase64でデコードしてみます。
(ちなみにCTFの豆知識なのですが、==があると大体base64だと思って大丈夫です。理由は=を追加することで文字数を調整しているからです。)
するとb'd3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrX2g0N2o2azY5fQ=='
こんな結果が出ました。
ここでも文末に==
があるのでd3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrX2g0N2o2azY5fQ==
をbase64でデコードする。
するとwpjvJAM{jhlzhy_k3jy9wa3k_h47j6k69}
と言う文字列が出力されました。
flagであるpicoCTF{}の形に似ているのでこれをシーザー暗号でデコードすると...
-19の変換でpicoCTF{caesar_d3cr9pt3d_a47c6d69}
が出力されました。
Reverse Engineering
解けませんでした。申し訳ないです。
Forensics
問題文は以下の通りです。
これは下記のsshに接続するとflag.pngと言うQRコードが出力されました。
cat flag.pngで画像ファイルを見ましたが特に何もない。
そこでQRコードを読み取ってみるとあっさりpicoCTF{p33k_@_b00_d4ca652e}
が出力された。
問題文は以下の通りです。
これはzipファイルをダウンロードし、解凍する。
するとukn_reality.jpgと言う画像ファイルが出てくる。
これをターミナル上で以下のようなコマンドを打つ。
% strings -10 ukn_reality.jpg
7http://ns.adobe.com/xap/1.0/
<?xpacket begin='
' id='W5M0MpCehiHzreSzNTczkc9d'?>
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 11.88'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<rdf:Description rdf:about=''
xmlns:cc='http://creativecommons.org/ns#'>
<cc:attributionURL rdf:resource='cGljb0NURntNRTc0RDQ3QV9ISUREM05fM2I5MjA5YTJ9Cg=='/>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end='w'?>
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
]qQH>cRB~cL
以下略・・・・
ここで<cc:attributionURL rdf:resource='cGljb0NURntNRTc0RDQ3QV9ISUREM05fM2I5MjA5YTJ9Cg=='/>
と言う不思議な文字列の存在に気づきました。
この文字列cGljb0NURntNRTc0RDQ3QV9ISUREM05fM2I5MjA5YTJ9Cg==
が==
で終わっているためbase64でのデコードの可能性が生まれます。
その為base64でデコードしてみるとpicoCTF{ME74D47A_HIDD3N_3b9209a2}
が取得できました。
問題文は以下の通りです。
launch instanceを開始して、指定されたところに接続します。
接続後にlsをすると以下の通りになります。また、そこからfileフォルダに移動してlsを行うと以下のようになります。
ctf-player@pico-chall$ ls
checksum.txt decrypt.sh files
ctf-player@pico-chall$ cd files
ctf-player@pico-chall$ ls
00011a60 2emuPVOb 5gxjbRbh 9KIFXofB Bh5xju3q FJBePm2b HqxLJgMp KbGMgDus OIYZeUCB RPVIP1xx U3BoYTr9 YKQLrxBm c3Z3JN0m fZHEnAvZ jcMzi4VO m3bsNhyN pb1E0Y3Z sAy34VP4 vsGKdf0J
022cvpdN 2gP5wDgq 5rHRNllE 9pluLfgA C1kYNpjq FLsBEmlR IDQQR4nq KlqDh1ZQ OPqDbOIH RQWaIGxG UDI6pN8S YdTZkUcM cIDWC9cb g2E6RkkX jdYv9CQ3 mWWBZCgt pnycz11G sKi8TaSn w1XGgnr9
04nLilRD 2w5vJlLG 63MqIIVV ADMuzktV CF4c5xR8 FOxKdaVP IITtRrrR L58tTvhF Oe0SOw16 RVejZvvP UF1urDfG Z2rLXuyp dDoFZTXh g2nu6vlR jzmPaO2D mdFDpW9k q53EoTzu sNI2Q6oa w8DmFhfg
0MT2Wrui 2yMtx5qd 64nJlBLv AEJxVlNY CGkVyMxT FtMorZ65 IbMiqCHJ L7gltlCF OnCx4O4u RdYwRe68 UUiDNDlO ZWIiY84t dKYP6pnk gLAo3J0D kDPV8ASY n2XnM9Nc qCTrc9yM sRaKyq1f woaiQu5g
0SGMttmR 303DzMmf 69JSHBh1 AGOEyD4N CLCyTz85 G7enzzui Ie0xOcl5 LCLocE1C P7orF8IR Rgs7l9CZ UuC7t9JQ ZXqAvkcE dKisxYdK gem657x8 kKVvPy8S n7Vs8Bjh qHwcKaSC svmptIxV wvhWmTPt
0fCDySFB 33CFCJ0y 6vgioqew AVdbk5eX CNvsyU3W Gcv1H8Qs IikIpp05 LMavH6jA PECjZnzJ ScOtAOiZ V2eK2wiC ZdPbKJh1 deppMJSV hNqXyUX2 kWjYWiLD n8r2Ejk9 qK35XlHM tFGQywwr xQJV5GcG
0hHVJSPh 36tjTWoF 76rj6cv7 AXFWLqwI Cb22Z7FO GhrShrXN IlQwVZcY Lq3dNalV PpktRW9a SwrcVnay V4VMSZd9 ZyNsHVFW dv0Mm4vr hZxbAqts kZ6DTcql nldOsSfJ qSn3WAyi tY2epsSy xlqXOqhL
0mPyFlda 3KZwXc8s 7j2g9w9w AdzCNBlC Ce5TrzJu Gtk4Kn9w ItYR0Da2 LrYo1dnu QHv46Plh T5IkmqtJ VhBNGSYV aGVRRt1d e1x51vcc haNCaZmC kbumrMcy nnZ33FAt qV83Dmye tuma818A yACAaKqG
0xknvebh 3Vs8v8kW 7ye3lPVb AiUxYmz8 ClWGbsxu GufDk3Mb Izq2bmb5 MPeS8YHI QbiQCWZr T6AHhqdE WBpZ7iz6 aHFaEXKf e2umkBxy iGwCDzaU knHTEYup nrwKQbJk qWv24Da7 uMpXxbqr yYRsKiUO
1kTWMoOI 3qDKN57P 870YaC5g AmsN0Lkj DCn7KnqG HDLWGApz J16J63tC N8vFOGDF QcIkjhJ0 TPBDRCiJ WjY12GNe aIz8E0Iy e5b74XZq iILvZZya ksIZWNZR oNnB9jru qZ7TLGA0 uUI8gJNi yg7uBent
1mGlW6Ts 4CwloraZ 8Shyigig ArUDDIQ3 DSKHZ66z HIeYL84k JVEoV1Bn NC6PZdoL QgmCuMSV TRyxUwzw Ww6oTYL8 afLk75aO eFlmUkb6 ih6levXk lZiPMwX4 oi96tAtc qojIz6XF ugeJ5RN3 zYz6howf
2JKdkggW 4XqPqs6B 8d0Ncqme Azqf6EEw Dmsex2Ug HJIPzwjJ Jcwq4RxP NS9xPzIA Qxrlj2uk TXsLzqsp X5rRZ32p b9YCg3Tz eNfM7vPK j1v0LBVe lcYptJNC oiy29oCW r3HVTaJd vJDrHtxo zjkul95p
2Jr8UtbZ 4k4veVKp 8hKIvq38 B8pBCEvG EBBoQm7M HMq6348V Jk8UBmcS Ndyi6bnx R3rVsQa8 TeaXjOeh XGTpUJIw bDK7A26M eZ4ehccg jIlhVDLw ld12od7V p1LgEQdu r3Pw8pFI vMv1M1qs zoz7gvVr
2K4XCmfE 4sczhCZl 8rIuGenM BN0HxLxE EG1lW2KR HUjCgnh4 KCL5hW02 NxdIqu0S RAXeLvjl TeyHF78l XJiFKTlc bDZN0f4B efpcZmHN jObn0z94 lmr9cGCE p5INCxLV r8vIZE1F vWguQ8rQ
2MYWkWLC 58BnWcOc 91cLOGeN BOeN3lXR EXQ6DiO5 HWRVc59e KKRWbrqC O5tEUFhw RFLWtody ToT9QPKf XcmGmkwD bcZupFpi ekSs7xW4 jVkxEmtq lxv6mvZ6 p5INQHq8 rzYX4BnS vc1wGQhn
2QpRnoZQ 5bSdd2sp 9DNfzhUK BdO65Tk4 F6yHlWpt Hmr54gXd KUIfl2m7 OH3906gp RHjAw3hj TtPblPd6 YAZlvEou bjtBJwTc eknrQKQh jVlaDg4q m1NnTZoo pXJHJUbH s9TOeOaJ vjypfsoh
ctf-player@pico-chall$ cd ../
ctf-player@pico-chall$ ./decrypt.sh files/00011a60
picoCTF{trust_but_verify_00011a60}
ctf-player@pico-chall$ Connection to rhea.picoctf.net closed by remote host.
Connection to rhea.picoctf.net closed.
filesフォルダにクソ大量のファイルが存在していました。
./decrypt.sh files/<filename>
で実行できるっぽいのでテキトーに一つ目(00011a60)を実行したら。picoCTF{trust_but_verify_00011a60}
なんか見覚えのある感じ。
これを回答すると... 成功!?
問題文は以下の通りです。
hereをクリックするとflag2of2-final.pdfというファイルがダウンロードされます。
このファイルは開くと以下のようになっていました。
このpdfファイルをfileコマンドで見てみると以下のような情報が得られました。
flag2of2-final.pdf: PNG image data, 50 x 50, 8-bit/color RGBA, non-interlaced
つまりこのファイルは拡張子がpdfにも関わらず情報はpng画像ファイルであることがわかった。
ちなみにstringsやcat,less,xxdなどさまざまな方法でこのpdfを開いてみたが得られる情報は特になかった。
そこでこのpdfをpngに変換してみることにする。
サイトで行ったり、pdftoppmでやってみたが特に効果がなかった。
そこでシンプルにcpコマンドでpdfをコピーし、その時に拡張子を無理やりpngにしてみたら(% cp flag2of2-final.pdf flag2of2-final.png
)以下のような画像ファイルが出力された。
これによりpng画像とpdfに書いてある文字列を組み合わせて一つの文字列にすると以下のようになった。
picoCTF{f1u3n7_1n_pn9_&_pdf_7f9bccd1}
これで成功した。
問題文は以下の通りです。
ダウンロードしたapkファイルをunzipすると、ブワーッとファイルが開かれたので、
% nano test.txt
% cat test.txt| grep -i flag
inflating: res/color/flag.txt
上記のようにtest,txtというファイルを作成して、unzipで開かれたフォイルをtxtファイルにコピペしてファイル名で検索すると、flagという文字列でヒットし、res/colorにflag.txtが存在していた。
file.txtを開くと、以下のような文字列がありました。
% cat flag.txt
7069636f4354467b6178386d433052553676655f4e5838356c346178386d436c5f35653637656135657d
よくわからないので、cyberchefを開いてmagicをすることで出力されました。
https://gchq.github.io/CyberChef/
cyberchefの使い方ははじめにInputに文字列を入れます。
続いてOperationsからMagicを選択しRecipeにドラッグします。
するとこのように入力された文字列がデコード可能な物であれば勝手に処理をしてくれるツールになっています。
このresultによりpicoCTF{ax8mC0RU6ve_NX85l4ax8mCl_5e67ea5e}
が得られました。
これはbase85でエンコードされていたようです。
[解法1]
ダウンロードしたchallengeファイルをfileコマンドで確認してみるとdataとしか出力されませんでした。
本来fileコマンドなどで出力される(例, PNG,JEPGなど)ものはファイルのデータを確認していき、「マジックバイト」と呼ばれる場所にあるデータを読み取ることによってfileの形式を判断するものです。
しかし今回はdataとしか出力されていない理由としては今回のchallengeファイルのマジックバイトが特に意味をないていないor何もないということなので、問題文にも合った通り、ファイルのデータがバラバラになっていることがわかる。
次に
問題文のendianを調べてみる.
endianにはlittle endianとbig endianが存在する。
これらを調べてみたらアドレス番地を昇順や降順に並べ直すものである。
これをchatgptに生成してもらった。
# endian_swap.py
import sys
def swap_bytes(file_path):
with open(file_path, 'rb') as original_file:
data = original_file.read()
swapped_data = bytearray()
# 4バイト単位でエンディアンを変更
for i in range(0, len(data), 4):
swapped_data += data[i:i+4][::-1]
with open(file_path + '_swapped', 'wb') as modified_file:
modified_file.write(swapped_data)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python endian_swap.py <file_path>")
sys.exit(1)
swap_bytes(sys.argv[1])
これによりendianされたファイルが生成されました。
このファイルをfileコマンドで調べてみると、JPEG image data....
となっていたため画像ファイルが生成されたことがわかりました。
このファイルを開こうとすると32bit形式のPCのファイルであるため開けません。
そこでブラウザから開いてみると以下のように表示されました。
解答としてpicoCTF{cert!f1Ed_iNd!4n_s0rrY_3nDian_76e05f49}
[解法2]
ダウンロードしてマジックバイトを見てデータがバラバラであることを確認するまでは同じです。
そこでchatGPTにプログラムを生成してもらうのではなくcyberchefでリトルorビッグエンディアンを行う手法になります。
https://gchq.github.io/CyberChef/
初めにInputにダウンロードしたファイルをアップロードします。
次に左のレーンから To Hex と Swap endianness と From Hex を選択します。
これはIntpuしたものをHexに変換して次に順番を変更しています(endian)。最後に変換したものをHexからdataに変更します。
以上から変換を行うことができましたので、Outputからファイルをダウンロードします。
ダウンロードしたファイルをブラウザから開くと以下のようになります。
以上からpicoCTF{cert!f1Ed_iNd!4n_s0rrY_3nDian_76e05f49}
が得られました。
Binary Exploitation
ここではncコマンドで指定されたところにアクセスして何かをする問題。
アクセスすると以下の画面が出力される。
% nc tethys.picoctf.net 50313
Welcome to heap0!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.
Heap State:
+-------------+----------------+
[*] Address -> Heap Data
+-------------+----------------+
[*] 0x5630f47502b0 -> pico
+-------------+----------------+
[*] 0x5630f47502d0 -> bico
+-------------+----------------+
1. Print Heap: (print the current state of the heap)
2. Write to buffer: (write to your own personal block of data on the heap)
3. Print safe_var: (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag: (Try to print the flag, good luck)
5. Exit
Enter your choice:
ここで4のprint flagを選んでみると以下のようになった。
Enter your choice: 4
Looks like everything is still secure!
No flage for you :(
ここで2ではbufferに何かを書き込めるようなので、バッファオーバーフローをしてみることに。。。
Enter your choice: 2
Data for buffer: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
この後に4のprint flagを選択して、
Enter your choice: 4
YOU WIN
picoCTF{my_first_heap_overflow_76775c7c}
これによりflagが得られました。
問題文は以下の通りです。
この問題ではncコマンドで指定されたところにアクセスする。
% nc tethys.picoctf.net 64477
Welcome to heap1!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.
Heap State:
+-------------+----------------+
[*] Address -> Heap Data
+-------------+----------------+
[*] 0x55c33bf342b0 -> pico
+-------------+----------------+
[*] 0x55c33bf342d0 -> bico
+-------------+----------------+
1. Print Heap: (print the current state of the heap)
2. Write to buffer: (write to your own personal block of data on the heap)
3. Print safe_var: (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag: (Try to print the flag, good luck)
5. Exit
Enter your choice:
アクセスすると先ほどと同じようになる。
基本的に2に何か文字列を入れて3を確認するも以下のようになるようだ。
Enter your choice: 3
Take a look at my variable: safe_var = bico
ここで2を選んでaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(何か32文字)を入力して、3で確認するとちょうどバッファを溢れさせることができました。
そこでaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapico
とすると以下のようになります。
Enter your choice: 3
Take a look at my variable: safe_var = pico
これによりsafe_varはbicoからpicoに変更され4を選択するとpicoCTF{starting_to_get_the_hang_c588b8a1}
取得できました。
問題文は以下の通りです。
この問題ではncで上記のところに接続します。
するとCUI上で入力が求められました。
% nc mimas.picoctf.net 60777
Welcome to our newly-opened burger place Pico 'n Patty! Can you help the picky customers find their favorite burger?
Here comes the first customer Patrick who wants a giant bite.
Please choose from the following burgers: Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe
Enter your recommendation:
ちなみにsourceコードをダウンロードしてみるとformat-string-0.cと言うプログラムファイルが取得できます。
これを解読していきます。
pythonに変換したものを以下に載せます。
import os
FLAGSIZE = 64
def on_menu(burger, menu):
return burger in menu
def serve_patrick():
print("Welcome to our newly-opened burger place Pico 'n Patty!")
print("Can you help the picky customers find their favorite burger?")
print("Here comes the first customer Patrick who wants a giant bite.")
print("Please choose from the following burgers:")
print("Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe")
choice1 = input("Enter your recommendation: ")
menu1 = ["Breakf@st_Burger", "Gr%114d_Cheese", "Bac0n_D3luxe"]
if not on_menu(choice1, menu1):
print("There is no such burger yet!")
else:
if len(choice1) > 2 * FLAGSIZE:
serve_bob()
else:
print("Patrick is still hungry!")
print("Try to serve him something of larger size!")
def serve_bob():
print("Good job! Patrick is happy!")
print("Now can you serve the second customer?")
print("Sponge Bob wants something outrageous that would break the shop")
print("(better be served quick before the shop owner kicks you out!)")
print("Please choose from the following burgers:")
print("Pe%to_Portobello, $outhwest_Burger, Cla%sic_Che%s%steak")
choice2 = input("Enter your recommendation: ")
menu2 = ["Pe%to_Portobello", "$outhwest_Burger", "Cla%sic_Che%s%steak"]
if not on_menu(choice2, menu2):
print("There is no such burger yet!")
else:
print(choice2)
def main():
try:
with open("flag.txt", "r") as f:
flag = f.readline().strip()
except FileNotFoundError:
print("Please create 'flag.txt' in this directory with your own debugging flag.")
return
serve_patrick()
if __name__ == "__main__":
main()
これを見ていくとserve_patrick()で初めに分岐がきます。これは入力された文字がFILESIZE*2 より大きい時にまた違った処理を行うっぽいので、FILESIZE*2より大きい129文字数の文字列を入力していくと以下のようになりました。
Enter your recommendation: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
There is no such burger yet!
picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_dc0f36c4}
バッファオーバーフローのようでした。
以上からpicoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_dc0f36c4}
が取得できました。
感想
今回が初参加となるpicoCTFでしたが、初心者でも意外と解ける問題があり、非常に楽しめました。また、知らなかった知識や断片的だった知識を身につける良い機会となりました。
しかし一つ残念なことに、「Bookmarklet」という問題にて不正があったとして失格となってしまいました。
何が失格の要因だったのかは分かりませんが、もし今回のwriteupに記載する方法が不正扱いとなるのであれば、皆さんは気をつけて参考にしてしてください。