💻

picoCTF 2023 writeup

2023/04/05に公開

はじめに

picoCTF2023にリアルタイムで参加したので解けた問題の解答を記録。
いくつか正攻法なのか怪しい解き方もある気がするので悪しからず。

解けた問題

Binary Exploitation
 two-sum / 100 points
Cryptography
 rotation / 100 points
 ReadMyCert / 100 points
Forensics
 hideme / 100 points
 PcapPoisoning / 100 points
 FindAndOpen / 200 points
General Skills
 Rules 2023 / 100 points
 money-ware / 100 points
 repetitions / 100 points
 chrono / 100 points
 Permissions / 100 points
Reverse Engineering
 Reverse / 100 points
 Safe Opener 2 / 100 points
 Ready Gladiator 0 / 100 points
Web Exploitation
 MatchTheRegex / 100 points
 findme / 100 points
 SOAP / 100 points
 More SQLi / 200 points
 Java Code Analysis!?! / 300 points

writeup

chrono

・Category:General Skills
・Score:100 points

How to automate tasks to run at intervals on linux servers?
Additional details will be available after launching your challenge instance.

問題文から「間隔を置いてタスクを実行する方法」のとことなので、インスタンス起動後に/etc/crontabを確認するとフラグが取得できる。

findme

・Category:WebExploitation
・Score:100 points

Help us test the form by submiting the username as test and password as test!
Additional details will be available after launching your challenge instance.

ログイン画面にてID/PW=test/test!を入れると入力フォームがある。いろいろ試したがフラグが見つからないため方針変更。ディベロッパーツールにてどこへ通信をしているかを確認すると、一瞬Base64みたいなものが見える。あらためてwiresharkでPCAPを取りながらログインからやり直す。http通信を確認するとBase64の一部がnext-pageのRedirectingのidの中や、GETメソッドの中に見つかる。組み合わせてcyberchefに入れることでフラグを得ることができる。

hideme

・Category:Forensics
・Score:100 points

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.

ダウンロードしたファイルはpicoCTFのロゴであることがわかる。fileコマンドで確認するとPNGファイルであることがわかる。PNGファイルに何か埋め込まれていないかを確認するためにbinwalkにかける。するとsecretディレクトリの中にフラグが見つかる。
※地味に画像ファイルが見切れててフラグ入力ミス多発した

MatchTheRegx

・Category:Web Exploitation
・Score:100 points

How about trying to match a regular expression
Additional details will be available after launching your challenge instance.

インスタンスを立ち上げてWebサイトにアクセスすると「Valid Input」と表示され、入力フォームが出てくる。「Valid Input」から推測すると、フラグ文字に一致する入力をすることでフラグを得られると考えられる。「picoCTF{}」と入力するとフラグが取得できる。
※「
」「pico*」「picoCT*」ではフラグが出力されず「picoCTF*」であれば出力される。

money-ware

・Category:General Skills
・Score:100 points

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?

問題文に記載のウォレット番号とMalwareやランサムウェアなどでググる。NTTDATAの記事などでPetyaの記事がヒットするためこれを入力。

PcapPoisoning

・Category:Forensics
・Score:100 points

How about some hide and seek heh?
Download this file and find the flag.

ダウンロードしたPCAPファイルを確認するとFTPに関する通信が多く見える。中でもパケット番号4を確認するとuernameとpasswordを入力していることがわかる。これに紐づくパケットを追跡で確認するとパケット番号507にTCPのパケットが見つかる。TCP payloadを確認するとフラグが見つかる。

Permissions

・Category:General Skills
・Score:100 points

Can you read files in the root file?
Additional details will be available after launching your challenge instance.

sshでログイン後ルートのファイルが読めるかとのことだったので、ルートディレクトリに移動後challengeの中のjsonファイルを確認するとフラグがある。

ReadMyCert

・Category:Cryptography
・Score:100 points

How about we take you on an adventure on exploring certificate signing requests
Take a look at this CSR file here.

配布されたcsrファイルの中身をCSRの内容確認ツールなどで確認するとフラグが見つかる。

Ready Gladiator 0

・Category:Reverse Engineering
・Score:100 points

Can you make a CoreWars warrior that always loses, no ties?
Additional details will be available after launching your challenge instance.

配布されたファイルのパラメータを1,1に変更したらフラグが出た。

┌──(kali㉿kali)-[~/…/ctf/pico/picoCTF2023/ReadyGladiator0]
└─$ nc saturn.picoctf.net 61316 < imp.red
;redcode
;name Imp Ex
;assert 1
mov 1, 1
end
Submit your warrior: (enter 'end' when done)

Warrior1:
;redcode
;name Imp Ex
;assert 1
mov 1, 1
end

Rounds: 100
Warrior 1 wins: 0
Warrior 2 wins: 100
Ties: 0
You did it!
picoCTF{h3r0_t0_z3r0_4m1r1gh7_7c030e56}
                                                                     
┌──(kali㉿kali)-[~/…/ctf/pico/picoCTF2023/ReadyGladiator0]
└─$ 

repetation

・Category:General Skills
・Score:100 points

Can you make sense of this file?
Download the file here.

ダウンロードしたファイルを開くといかにもBase64でエンコードされた文字の羅列が見つかる。複数回Base64にかけるとフラグが取得できる。

Reverse

・Category:Reverse Engineering
・Score:100 points

Try reversing this file? Can ya?
I forgot the password to this file. Please find it for me?

ダウンロードした実行ファイルにをGhidraで解析する。プログラムの動作を追うためにmain関数を確認するとフラグ出力用のパスワードが見つかる。これを入力してフラグを取得する。

rotation

・Category:Cryptography
・Score:100 points

You will find the flag after decrypting this file
Download the encrypted flag here.

ダウンロードしたファイルを開くといかにもROT13でエンコードされた文字の羅列が見つかる。CyberchefでROT13にかけるとフラグが取得できる。

Rule2023

・Category:General Skills
・Score:100 points

picoCTF 2023のルールページに画像でフラグが書かれている。
とりあえず、見つかったけど、正攻法が、わかりません笑

SafeOpener2

・Category:Reverse Engineering
・Score:100 points

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?

ダウンロードしたファイルをGhidraで解析にかける。main関数やその他の関数を見ていくとopenSafe_java.log.String_boolean関数にフラグが書き込まれているのが見つかる。

two-sum

・Category:Binary Exploitation
・Score:100 points

Can you solve this?
Additional details will be available after launching your challenge instance.

配布されているソースのプログラムを読むとmain関数とaddIntOvf関数で作られていることがわかる。

flag.c
static int addIntOvf(int result, int a, int b) {
    result = a + b;
    if(a > 0 && b > 0 && result < 0)
        return -1;
    if(a < 0 && b < 0 && result > 0)
        return -1;
    return 0;
}

大まかな挙動を把握するためにインスタンスを起動させて適当に値を入力する。すると「No overflow」が基本的には出力されることがわかる。ここでソースコードを改めて確認し「No overflow」に分岐している個所を確認する。該当する部分としてaddIntOvf関数にて該当の処理がされているように見える。addIntOvf関数では各パラメータがint型で渡されており、渡されたパラメータを評価し0か-1を返す関数になっている。ここでif文の条件式がint型の変数に対して記載されていることを考えるとint型の上限値を利用したoverflowを起こさせるように考えられる。
そこでパラメータ1として2147483647、パラメータ2として1を入力する。これによりフラグが取得できる。

FindAndOpen

・Category:Forensics
・Score:200 points

Someone might have hidden the password in the trace file.
Find the key to unlock this file. This tracefile might be good to analyze.

ダウンロードしたZIPファイルのパスワードをPCAPファイルから探す。pcapファイルEthernetⅡとDNS関係のパケットがあることがわかる。全体的に俯瞰してみると48パケット目のパケットサイズのみ少し大きいことがわかる。パケットの中身を確認すると、Base64で何かが書かれていることがわかるので変換にかけるとフラグもどきが手に入る。これをZIPファイルのパスワードとして入力することでフラグが取得できる。

More SQLi

・Category:Web Exploitation
・Score:200 points

Can you find the flag on this website.
Additional details will be available after launching your challenge instance.

WebサイトへアクセスするとUsernameとPasswordの入力を求められる。何か適当に入れるとusernameとpasswordに加えてSQL文が出力されていることがわかる。PasswordとしてSQL文を入れることでインジェクションできそうなので、Usernameを適当に、Passwordに以下SQL文を入力してログインする。

' or 1=1;

するとログインでき、Search Officeが見つかる。入力フォーム形式のサイトなので何かしらのSQLインジェクションをかけていく必要があると考えられる。いろいろこねくり回してそれっぽいテーブルからフラグを見つける。

' union select 1,1,1 --
' union select 1,name,1 from sqlite_master --
' union select 1,sql,1 from sqlite_master --
' union select 1,flag,1 from more_table --

SOPE

・Category:Web Exploitation
・Score:100 points

The web project was rushed and no security assessment was done. Can you read the /etc/passwd file?
Additional details will be available after launching your challenge instance.

Webサイトにアクセスするし各Detailsへのアクセスを確認すると、xmlの記載が見つかる。そこでXXEを使って/etc/passwdの中身の閲覧を試みる。WEBサイトへのアクセスをBurp suiteでプロキシする。アクセスする際に以下XXEを追記してアクセスするとフラグを取得することができる。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [ 
    <!ENTITY xxeattack SYSTEM "file:///etc/passwd"> 
]>
<data>
	<ID>
		&xxeattack;
	</ID>
</data>

Java Code Analysis!?!

・Category:Web Exploitation
・Score:300 points

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!
Additional details will be available after launching your challenge instance.

Webページに指定されたID/PWでログインをすると、閲覧できる本と閲覧できない本があることがわかる。Adminファイルを閲覧できればフラグが取得できると想像できる。
Webページの調査をディベロッパーツールで行うと、Local Storage内にJWTトークンが見つかる。

このJWTトークンのauth-tokenとtoken-payloadをAdminユーザのトークンに差し替えることができればフラグが取得できそうに見える。

token-payload
{"role":"Free","iss":"bookshelf","exp":1681221799,"iat":1680616999,"userId":1,"email":"user"}

配布されているソースコードの調査を地道に行う。まずはJWTトークンを差し替えるにあたり、秘密鍵がないことには差し替えることができないため、ソースコードに秘密鍵の記載がないか確認する。ソースファイルのフォルダ名からあたりをつけてsrc/main/java/io/github/nandandesai/pico/securityフォルダのSecretGenerator.javaを調べる。するとgenerateRandomString関数に直接秘密鍵「1234」が記載されているのが見つかる。

SecretGenerator.java
    private String generateRandomString(int len) {
        // not so random
        return "1234";
    }

次にtoken-payloadを書き換えるためのパラメータが何か調べていく。security/modelsフォルダ内にあるJwtUserInfo.javaを確認するとユーザ情報として用いられるものがInt型のuserId、String型のemail、String型のroleの三つであることがわかる。引き続きソースコードから各値を調べていく。※なんとなく値想像できなくもない…

user admin
role Free ?
userId 1
email user ?

各パラメータの調査で、modelsフォルダ内のRole.java内に、値が高いほど特権が付与されるとのコメントが記載されている。

Role.java
public class Role {
    @Id
    @Column
    private String name;

    @Column
    private Integer value; //higher the value, more the privilege. By this logic, admin is supposed to
    // have the highest value
}

値が高いということなので、各ロールに対して値が決められていて、それがuserIdと紐づいていると考えられる。ソースコードを調べるとsrc/main/resources/data.sql内に各ロールの定義が見つかる。

data.sql
INSERT INTO roles VALUES ('Free', 1);
INSERT INTO roles VALUES ('Basic', 2);
INSERT INTO roles VALUES ('Premium', 3);
INSERT INTO roles VALUES ('Admin', 4);

よって、Admin権限の場合のroleはAdmin、userIdは4だということが分かった。emailに関してはuserがuserなのでadminはadminだろうと推測。※ソースコード読んだら書いてると思います。

user admin
role Free Admin
userId 1 4
email user admin

以上より、JWTトークンの作成に必要な秘密鍵と各種パラメータが明らかになったのでjwt.ioなどでトークンを発行していく。

発行したトークンと判明したパラメータでauth-tokenとtoken-payloadを変更しページのリロードをかける。するとadminユーザでログインしたことになっており、右上のプロフィールボタンにAdmin Dashboardが追加されているのが見つかる。あとはuserに対してadmin権限を付与し、ログアウト後に再度userでログインし、フラグファイルを閲覧することでフラグを取得することができる。

おわりに

初めてリアルタイムでpicoCTFに参加してみたけれど、まだまだ解けない問題だらけでした。CTF始めてそろそろ一年、成長があんまりできてない…
常設で過去問にいつでもチャレンジする環境があるのだから、うだうだ言ってないで全部解いてからチャレンジしたらもうちょい解けたんだろうなと反省です。(いや、夜間対応とかいろいろ仕事が忙しかったんですよ、ええ…)
個人的にはWeb問のSQLiやJWTが解けたのは良かったのかなと。良い意味でやる気が再熱できたので来年もチャレンジ出来たらと思います。

Discussion