プライベートの小規模開発のチケット管理をNotionでやった話
はじめに
この記事では、自分がプライベートで行っている小規模開発のチケット管理をNotionを使って管理するように変更したので、その経緯と設定を備忘録として残す。
開発まわりの前提
開発人数
- 二人
開発内容
- 簡単なウェブアプリ
なぜNotionを使用したのか
自分は、プライベートにおいて主体的に扱うべき情報をすべて以下のように管理している。
自分の認知不可を下げるため、見るべき箇所をできるだけ増やしたくなかった。よって、使用するツールとしてはGithubかNotionのほぼ二択として考えていた。
従来の方法とその問題点
過去手法その1:Github Issueを使ったチケット管理
最初に試したのはこの方法だった。
Issue駆動開発の手法を取り入れていたということもあって試してみたのだが、以下の問題で断念することになった。
- Issueだけだとチケットに関する詳細が醜い
- Github Projectも使ってみたけど使用感が悪い
- 普段はNotionを開いているので、チケットの状況確認でわざわざGithubを見に行くのが面倒になった。
過去手法その2:NotionDB(Integrationなし)を使ったチケット管理
過去手法その1を受けて、チケットの状況確認をNotionで行えるようにした構成。
この手法を採用するときに自動化フローを組むことを考えていたのだが、GithubのIssue連携機能はGithub→Notionの一方通行だったので断念。
開発の目標納期との兼ね合いで、一旦単純にDBを使うことにした。
見る場所が基本的にNotionメインになったので楽だったのだが、早いうちに他の手法に移ることになるだろうなと思っていた。案の定数ヶ月も持たずに今回の手法にやり方を変えることになった。
この手法の問題点は以下
- Githubの状況とNotionDBが連動していないので、カンバンボードを自分で動かす必要がある。
- 共同開発者がカンバンボードを動かし忘れると、状況確認の手間が発生する。
- Issue駆動開発の考えを残していたので、Issueとカンバンボードの二重起票になる。
今回採用したチケット管理の方法
NotionDBをベースにGithub Integrationを使用した。
このタイミングでIssue駆動開発の考え方を一旦捨てて、チケットはすべてNotionに一元化している。
Issue連携しか知らなかったのだが、Pull Request(以下PR)ベースの連携があるのでこれを試してみた。
実現できたこと
- Notionでチケットを起票
- チケットの詳細やPRのコメントをNotion上で確認
- チケットに基づくPRをopen/closeしたタイミングでチケットのステータスを自動変更
制約
- PRのタイトルにNotionDBで払い出されるIDを含める必要がある
- Githubのデフォルトブランチに対するPRしか自動化が発火しない
実装方法
Githubとの連携方法
PRの送り方
- タイトルにNotionDBで自動発行されたIDを記載する

- タイトルにNotionDBで自動発行されたIDを記載する
デフォルトブランチの変更
自分が手動している開発ではGit-flowをベースとしてブランチマネジメントを行っている。
いままではmasterブランチがデフォルトブランチだったのだが、Notion連携のためにdevelopブランチ相当をデフォルトブランチに変更した。
build&deployにはCloudflareを使用していて、そこの設定上Productionブランチを任意指定できることは確認済み。
デフォルトブランチを変更することによる悪影響は自分の知見が足りずわからなかったので、発覚したタイミングで対処することにした。
実際に使ってみた感想
現状、Notionにほぼ完結して情報を整理できるようになったので、とてもよい。
制約として存在しているPRのタイトルにNotionDBで払い出されるIDを含める必要がある は、コミットメッセージにIDを含めることで対応している。
Issue駆動開発をベースにしていたときの名残でこの方法を採用しているが、もっといい方法があるかもしれないので、見つかったらアップデートしたい。
以上。
DIVER OSINT CTF Writeup

主に自分で解いた問題と、特に学びがあった問題を備忘録として記す。
最終順位は38位だった。OSINTの練習をしたいというモチベーションから参加を決定したが、そこそこ頑張れたし学びも得られたので良かったと思う。
misc
label

宛名の所が剥がされている。
中国からの発送なので、チャイナポストの追跡コードから宛先を探すのかと思ったが、そのようなコードは見つからず。
その過程で読んでいたQRコードに宛先の情報が入っていた。
横長のQRコードはrMQRコードというものらしい。
https://www.watch.impress.co.jp/docs/news/1411866.html
wumpus

サーバーIDとチャンネルIDが見えている状態。
サーバーIDから招待リンクを生成するのかと思って色々調べていたが、
サーバーへの招待リンクは直接はサーバーIDは仕込まれていないし、ローカルプロキシで招待リンク踏んだときの動きを観察してみたら一回目の応答でサーバーに関する情報が帰ってきているから、ディスコードの仕組み側で登録されていそうだった。
結局チームメイトが解いてくれた。普通にgoogle検索で「discord {サーバーID}」で招待リンクが埋め込まれているサイトが出たらしい。
どうやらDiscordのPublic Serverはポータルサイト的なものに登録されているらしい。初めて知った。
introduction
246

自動車のナンバープレートとかの情報から橋が関門橋だと特定してくれたので、橋がいい感じに見えて県道246沿いを探していたのだが、
そもそもflagが交差点名を答えよとのことだったので、県道246の交差点を調べたら数えるほどしかなかったとのこと。
逆引きで特定可能だった。(らしい)
office
めずらしく他のCTFでもありそうな問題。とりあえずunzipして中身みたらoffice形式のときは隠されていたフラグ文字列が含まれたpngが存在した。
chain

鳥貴族が見える。
鳥貴族の公式HPに行って、ビルの4Fにある店を洗う。
多分想定解はストリートビューとかで特定すること。入力回数制限に気づかず総当たりしにいったところ正解したらしい。
dream

パイプオルガンと夢と書かれた額縁を入れるようにしてGoogle Lensに突っ込んだら施設名が出てきた。
Google Lens最強。
serial
動画を見ると、JA222[多分A]という番号が見える。
上記サイトでJA222で検索すると、ANA所有の飛行機は222Aしかなかった。
ついでに製造番号も書かれていて、これがflagだった。

ad_directiare

謎にハマった問題。
yone名義で0727生まれのTwitter鍵垢を見つけて、リプライ検索とかで色々やろうとしていた。
結局GHuntを使ってgmailから検索する方法だった。(チームメイトが気づいた)
GHuntが頭から抜けていたのは悔しい。
geo
imagetrack

画像のビールの製造元から、卸先業者を調べるのかと思ってしばらく時間を浪費した。
結局見つからず、ふとこの問題だけ画像ファイルの名前が編集されていなくてデジカメとかの命名規則っぽいなと気づく。
もしかしてexif削除してないのでは?と勘ぐってexiftoolにかけたらGPS情報が出てきた。

championships

光華商場でGoogle mapを見る。それらしい建物は見つかったが、肝心の入口を完全に同定することができなかった。
Google Mapの過去の画像を見る機能で遡っても空振り。
history
promorter

検索の結果入鹿池っぽいことを特定。
発起人のリーダーは江崎善左衛門了也という人で、父は江崎善左衛門宗度という名前らしい。
命日をgoogleで探すも江崎善左衛門了也のほうが有名すぎてそっちばっかり出てくる。
江崎善左衛門宗の墓が存在するらしく、画像検索にも引っかかってきたが、
読める立て看板には没年の情報しかなく、ストリートビューからは文字は読めなかった。
墓の裏とか読みたいなーとか思いながら検索を続けていたら、論文を発見。そこに命日まで書いていた。
この手の問題は論文レベルまで掘ったら新しい情報が出てくるときもあるらしい。
https://www.jstage.jst.go.jp/article/jjsidre1965/49/7/49_7_630/_pdf
paddy
108号線が直角に曲がっているのが特徴的なので、ここから場所を特定できると推測。
国土地理院の地図から調べる。するとここが石巻市広渕であることがわかる。
色々検索していると過去に干拓事業が行われていることがわかる。
ヒントに「Monument speaks.」とあったので、石碑を探していた。地図真ん中にある神社の中にあるのではと狙って神社の紹介動画を見たりしたが空振り。
最初は石碑をキーワードにしていたが、色々断片的な情報があつまってきて広渕沼干拓記念碑という名前の石碑があることを発見。
しかし、これで検索しても表面しか見れず、知りたい情報は載っていない。
最終的に石碑の語る治水・利水・災害の歴史というサイトが見つかり、その中に広渕沼干拓記念碑の文章が保存されていた。
http://www.kasen.net/@2/kitakami/kyukita/hirobuch/index.htm
なお、この問題でFirstBloodを獲得できた。やったね。

investigation_request
mapper
一番時間を使って解けなかった問題。
画面中央左の「ファッションポート東京」の看板から場所を特定。
影の向きから時間が計算できることは知っていたのでその方向で検討開始(多分これが沼った原因)
https://www.suncalc.org/のサイトで結構詳細に影の計算ができることを知り、大体の時間帯は計算できる状態に。
だがしかし、日がわからない。
最終的には、波型ブロックの規格から歩道の橋と点字ブロックまでの長さを計算して、街頭の高さを規格通り5mと仮定したとき、街頭の直角の部分までの影の長さが約3mになることから無理やり日時を求めにかかっていた。
途中で運営から「とにかく、チャレンジ全体を注意深くよく読んで考えてください」をいうヒントもあり、問題文の「彼が撮ってアップロードした写真を見つけた」という文言が引っかかり始めるも、
画像をアップロードできるようなサイト?アプリ?がわからず断念。(ingressとかを調べていたけどあればポータルになるものだけだもんね。。)
結局、「mapper image upload」で検索したらそういう地図をupできるサイトが見つかったらしい。
解けなかったけど、SunCalcツールの使い方を練習できたから良しとする。
おまけ

瞬間風速が3位だった。この後上位陣にぼこぼこにされることになる。
TerraformでProxmoxのLXCコンテナを建ててみた
概要
最近自宅ラボの構成が大きくなってきたので、管理の煩雑さを回避するための技術を導入し始めている。
そのための一策として、みながすなるIaCといふものを我もしてみむとすなり。ということでterraformを導入した。
その時の作業や設定を備忘録として残す。
やったこと
- terraformのインストール
- 環境変数への登録
- tfファイルの作成
- 実行
terraformのインストール~初期設定
以下のインストールコマンドを実行する。
Dockerのように、GPGキーを追加してリポジトリに追加する必要がある。
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" sudo apt update sudo apt install terraform
次に、今回使用するAPItokenを環境変数に登録する。
どうせIaCで管理するなら構成ファイルをGithubで管理しようとしているので、secret情報だけは別で管理する必要がある。
今回は一旦実行環境の構成ファイルに仕込むことにした。
export PM_API_TOKEN_ID='YOUR-ID@pam!YOUR-TOKEN-ID’ export PM_API_TOKEN_SECRET="YOUR-SECRET-TOKEN-ID"
ここで、proxmoxのTOKENIDには!が使用されるのだが、シェルの仕様上!は予約文字であり、ヒストリを表す。
よって''で囲まずに""で囲むとエスケープされずに直前に打ち込んだコマンドに変換されてしまう。気をつけよう。(一敗)
tfファイルの作成~実行
terraformの構成ファイルとして、main.tfを以下で作成した。
terraform {
required_providers {
proxmox = {
source = "Telmate/proxmox"
version = "2.9.11"
}
}
}
provider "proxmox" {
pm_api_url = "https://10.1.1.118:8006/api2/json"
# pm_api_token_id = "{トークンID}"
# pm_api_token_secret = "{シークレット}"
# 環境変数に格納するためコメントアウト
}
resource "proxmox_lxc" "basic" {
target_node = "sv-proxmox"
hostname = "cnt-tst-terraform-dev-prxmx-01"
ostemplate = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"
password = "terraform"
unprivileged = true
rootfs {
storage = "local-lvm"
size = "8G"
}
network {
name = "eth0"
bridge = "vmbr0"
ip = "dhcp"
}
}
tfファイルができたらterraform initとterraform applyを実行する。
terraformの基本的なコマンドの使い分けは以下の通り。
| コマンド | 説明 |
|---|---|
| terraform init | Terraform構成の初期化を実施する。モジュール等をDLしている。使用しているプロバイダーが増えた場合もこのコマンドを実行する必要がある。 |
| terraform plan | 実行された場合にTerraformが行う予定の変更を表示する。確認のためのコマンドなので、インフラへの実行はされない。 |
| terraform apply | 構成ファイルに基づいて実際にインフラを変更する。 |
実行した結果は以下。
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding telmate/proxmox versions matching "2.9.11"...
- Installing telmate/proxmox v2.9.11...
- Installed telmate/proxmox v2.9.11 (self-signed, key ID A9EBBE091B35AFCE)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ ll
total 20
drwxr-xr-x 3 zaki zaki 4096 Apr 5 00:14 ./
drwxr-xr-x 3 zaki zaki 4096 Apr 5 00:03 ../
drwxr-xr-x 3 zaki zaki 4096 Apr 5 00:13 .terraform/
-rw-r--r-- 1 zaki zaki 1333 Apr 5 00:14 .terraform.lock.hcl
-rw-r--r-- 1 zaki zaki 391 Apr 5 00:08 main.tf
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ terraform plan
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ terraform plan
Planning failed. Terraform encountered an error while generating this plan.
╷
│ Error: your API TokenID username should contain a !, check your API credentials
│
│ with provider["registry.terraform.io/telmate/proxmox"],
│ on main.tf line 10, in provider "proxmox":
│ 10: provider "proxmox" {
│
╵
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ export PM_API_TOKEN_ID="root@pam!terraform"
export PM_API_TOKEN_ID="root@pamterraform plan"
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ export PM_API_TOKEN_ID="root@pam!terraform"
export PM_API_TOKEN_ID="root@pamterraform plan"
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ export PM_API_TOKEN_ID='root@pam!terraform'
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# proxmox_lxc.basic will be created
+ resource "proxmox_lxc" "basic" {
+ arch = "amd64"
+ cmode = "tty"
+ console = true
+ cores = 1
+ cpulimit = 0
+ cpuunits = 1024
+ hostname = "cnt-tst-terraform-dev-prxmx-01"
+ id = (known after apply)
+ memory = 512
+ onboot = false
+ ostemplate = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"
+ ostype = (known after apply)
+ password = (sensitive value)
+ protection = false
+ start = false
+ swap = 0
+ target_node = "sv-proxmox"
+ tty = 2
+ unprivileged = true
+ unused = (known after apply)
+ vmid = (known after apply)
+ network {
+ bridge = "vmbr0"
+ hwaddr = (known after apply)
+ ip = "dhcp"
+ name = "eth0"
+ tag = (known after apply)
+ trunks = (known after apply)
+ type = (known after apply)
}
+ rootfs {
+ size = "8G"
+ storage = "local-lvm"
+ volume = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
zaki@DESKTOP-9SJJCLK:~/homelab/proxmox/lxc$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# proxmox_lxc.basic will be created
+ resource "proxmox_lxc" "basic" {
+ arch = "amd64"
+ cmode = "tty"
+ console = true
+ cores = 1
+ cpulimit = 0
+ cpuunits = 1024
+ hostname = "cnt-tst-terraform-dev-prxmx-01"
+ id = (known after apply)
+ memory = 512
+ onboot = false
+ ostemplate = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"
+ ostype = (known after apply)
+ password = (sensitive value)
+ protection = false
+ start = false
+ swap = 0
+ target_node = "sv-proxmox"
+ tty = 2
+ unprivileged = true
+ unused = (known after apply)
+ vmid = (known after apply)
+ network {
+ bridge = "vmbr0"
+ hwaddr = (known after apply)
+ ip = "dhcp"
+ name = "eth0"
+ tag = (known after apply)
+ trunks = (known after apply)
+ type = (known after apply)
}
+ rootfs {
+ size = "8G"
+ storage = "local-lvm"
+ volume = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
proxmox_lxc.basic: Creating...
proxmox_lxc.basic: Still creating... [10s elapsed]
proxmox_lxc.basic: Creation complete after 11s [id=sv-proxmox/lxc/106]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
やり残したこと
Proxmox、フルDHCP運用への道
概要
自宅サーバー環境にIP端末が増えてきた関係で、その管理が徐々に煩雑になってきた。
そこで、IPアドレスの管理をより効率的に行うため、DHCP運用へと移行したくなった。
まずは手始めにProxmox本体をDHCP運用にした設定を備忘録として残す。
やったこと
/etc/network/interfacesファイルの更新
最終的にProxmoxのコンソールに入って/etc/network/interfaces を書き換えることでこれを実現した。
変更前config
auto lo
iface lo inet loopback
iface enp2s0 inet manual
auto vmbr0
iface vmbr0 inet static
address 192.168.11.29/24
gateway 192.168.11.1
bridge-ports enp2s0
bridge-stp off
bridge-fd 0
iface wlo1 inet manual
変更後config
auto lo
iface lo inet loopback
iface enp2s0 inet manual
auto vmbr0
iface vmbr0 inet dhcp
bridge-ports enp2s0
bridge-stp off
bridge-fd 0
iface wlo1 inet manual
はまりポイント
GUIでの設定ミス

最初はGUIから設定変更をしようと試みた。
調べたところIPの入力欄を空白にすればいいときいたのでやってみたら、ただ単にIPが振られていないサーバーが出来上がってNWからの疎通が失われた。
(おかげでわざわざサーバーにディスプレイやらキーボードやらを繋いでコンソールを見に行く羽目になった。)
configの書き方ミス
最初は以下のようにconfigを書いていた。
auto vmbr0 iface vmbr0 inet dhcp
このvmbr0というインターフェースは仮想インターフェースで、実体はenp2s0という物理インターフェースを継承している。
これを示す設定がbridge-ports enp2s0なのだが、これを消してしまったことによってインターフェース一覧にすら載らない状態になってしまった。
ついでに、上記の継承設定さえできていればインターフェースは見えるようになるみたい。
その状態でdhclient vmbr0コマンドを実行すると無理やりdhcpを取ってくることは可能だった。
再起動したタイミングで取得に失敗するのであまり意味はない。
まとめ
自宅サーバー郡全DHCP管理計画の一手目として、まずはProxmox本体のIPをDHCPから取ってくるようにした。
ただし、コンソールのwelcomeメッセージやら証明書設定やらに元のIPが直書きで残っているのが見えているので、ここらへんもいいようにする必要がありそう。
次回の課題とする。
picoCTF 2024[General Skills] 400pts SansAlpha WriteUp
概要
2024年3月に実施されたpicoCTFに参加してきたので、備忘録がてらwriteupを書きます。 今回はgeneral問題の一番点数の高かった400pts問題のwirteupです。
問題
The Multiverse is within your grasp! Unfortunately, the server that contains the secrets of the multiverse is in a universe where keyboards only have numbers and (most) symbols. Additional details will be available after launching your challenge instance.
多元宇宙はあなたの手の中にあります! 残念なことに、多元世界の秘密が含まれるサーバーは、キーボードに数字と (ほとんどの) 記号しかない世界にあります。
解法
ssh先のサーバーでは英文字が使えないらしい。
多分英文字を使わずにコマンドを打ってディレクトリを見たらflagのテキストかなんかがあるだろうと推測。
シェル芸という世界を耳にしたことはあったものの、全然詳しくなかったので以下のサイトを参考にペイロードを組み立てた。
参考サイトとは違い、今回は数字の使用が許されているので多少助かった。
まず最初にlsを打ってみる。
.>&$
"$(<$)"
__="${_##*. ??}"
これは. コマンドの結果をファイル$に格納したあと、ファイルを読み出して変数__にトリミングしながら格納している。
これで__に文字列lename [arguments]が入る
___***=${__**:0:1}${*__: -2:1}
これでlsが作れた。__の文字列からlとsを抜き出して文字を作っている。
問題サーバーで実行してみる。
SansAlpha$ $___ '$' blargh on-calastran.txt
怪しいtxtがあるので、txtを見たい。あとblarghってなに?catとか打ちたいけど、あまりコマンドつくるのはだるいなと思案。とりあえずファイルの種類を見たいのでls -lを実行する(llは問題サーバー上で実行できなかった。)
$___ -${__:0:1}
これでls -lが打てた。
SansAlpha$ $___ -${__:0:1}
total 8
-rw-rw-r-- 1 ctf-player ctf-player 69 Mar 19 15:37 '$'
drwxr-xr-x 1 ctf-player ctf-player 22 Mar 12 00:10 blargh
-rw-r--r-- 1 root root 1160 Feb 7 17:25 on-calastran.txt
ディレクトリだる。cd作ることも視野にいれる。
とりあえず引数にblarghやらon-calastran.txtやらを簡単に取れるようにしたいから、lsからなんとかしたい
変数__ にcの文字がないのでcatが作れない。nlコマンドで一旦代用する。
最終的には以下のコマンドを打ちたい。lsの結果を使ってnlするコマンド。
____=($(${___}))
$_____ "${____[2]}"
このとき
$___ = ls $____ = ls結果の受け皿 $_____ = nl
を目指す。
実行してテキストファイルの中身を見ると以下だった。フラグここにないんかい。
SansAlpha$ .>&$
SansAlpha$ "$(<$)"
bash: $'bash: .: filename argument required\n.: usage: . filename [arguments]': command not found
SansAlpha$ __="${_##*. ??}"
SansAlpha$ ___=${__:0:1}${__: -2:1}
SansAlpha$ $___
'$' blargh on-calastran.txt
SansAlpha$ _____=${__:2:1}${__:0:1} ____=($(${___}))
SansAlpha$ _____=${__:2:1}${__:0:1}
SansAlpha$ ____=($(${___}))
SansAlpha$ $_____ "${____[2]}"
1 The Calastran multiverse is a complex and interconnected web of realities, each
2 with its own distinct characteristics and rules. At its core is the Nexus, a
3 cosmic hub that serves as the anchor point for countless universes and
4 dimensions. These realities are organized into Layers, with each Layer
5 representing a unique level of existence, ranging from the fundamental building
6 blocks of reality to the most intricate and fantastical realms. Travel between
7 Layers is facilitated by Quantum Bridges, mysterious conduits that allow
8 individuals to navigate the multiverse. Notably, the Calastran multiverse
9 exhibits a dynamic nature, with the Fabric of Reality continuously shifting and
10 evolving. Within this vast tapestry, there exist Nexus Nodes, focal points of
11 immense energy that hold sway over the destinies of entire universes. The
12 enigmatic Watchers, ancient beings attuned to the ebb and flow of the
13 multiverse, observe and influence key events. While the structure of Calastran
14 embraces diversity, it also poses challenges, as the delicate balance between
15 the Layers requires vigilance to prevent catastrophic breaches and maintain the
16 cosmic harmony.
ここで、もう一個のディレクトリの中身をみたいのでcdを考える。
というかtreeでもいいかも。treeでええやん。
というわけで以下の形にして実行
$___ = ls $____ = ls結果の受け皿 $_____ = nl $______ = tree
treeはいってないやん。ふぁっきん。
SansAlpha$ ______=${__: -3:1}${__:9:1}${__:1:1}${__:1:1}
SansAlpha$ $______
bash: tree: command not found
よって、使える文字を追加してシェルを作り直す。目的はcdを使うこと。(これはローカルでテストしている。後述するが問題サーバーではこの方法はできなかった。)
┌──(kali㉿kali)-[~/ctf/pico]
└─$ .1>>&$
┌──(kali㉿kali)-[~/ctf/pico]
└─$ cat \$
bash: .: filename argument required
.: usage: . filename [arguments]
.1: command not found
treeはいらないので以下の形にする。ついでにlsの-指定が崩れるので書き直す。
$___ = ls $____ = ls結果の受け皿 $_____ = nl $______ = cd
これを実現するためのコマンドを今一度改めてまとめる。これを実行すれば次に進めるはず。
**.>&$
.1>>&$
"$(<$)"
__="${_##*. ??}"
# このときの__の中身は以下
# $ echo $__
# lename [arguments
# .1: command not found**
___***=${__**:0:1}${*__:16:1} # lsの作成
$___ -${__:0:1} # ls -lを実行してファイル確認
____=($(${___})) # ls結果を格納する配列の作成
_____=${__:2:1}${__:0:1} # nlの作成
$_____ "${____[2]}" # nlでファイルを表示
______=${__:23:1}${__:29:1} # cdの作成
$______ "${____[1]}" # cdの実行
$___ -${__:0:1} # ls -lを実行してファイル確認
$______ "${____[3]}"
ところがどっこい。問題サーバーでは>>が使えないらしい。よって別の変数を使って回避する。
**.1>&$
"$(<$)"
_______="${_##*.}"
# $ echo $_______
# 1: command not found**
______=${**_______**:3:1}${**_______**:9:1} # cdの作成
$______ "${____[1]}" #cdの実行
$___ -${__:0:1} # ls -lを実行してファイル確認
これにともない、前段の手順を修正。
**.>&$
"$(<$)"
__="${_##*. ??}"
# このときの__の中身は以下
# $ echo $__
# lename [arguments]**
___***=${__**:0:1}${*__:16:1} # lsの作成
$___ -${__:0:1} # ls -lを実行してファイル確認
____=($(${___})) # ls結果を格納する配列の作成
_____=${__:2:1}${__:0:1} # nlの作成
$_____ "${____[2]}" # nlでファイルを表示
現状の変数状況をまとめると以下。
$__ = **文字列「lename [arguments]」 $___ = ls $____ = ls結果の受け皿 $_____ = nl $______ = cd $_______ = 文字列「1: command not found」
ディレクトリを見るとflagがあった。
SansAlpha$ $______ "${____[1]}" # cd blargh
SansAlpha$ $___ -${__:0:1} # ls -l
total 8
-rw-r--r-- 1 root root 53 Mar 12 00:10 flag.txt
-rw-r--r-- 1 root root 1090 Feb 7 17:25 on-alpha-9.txt
あとはさっき作ったlsの配列を更新してflagをみるだけ。
SansAlpha$ ____=($(${___}))
SansAlpha$ $_____ "${____[1]}"
1 Alpha-9, a distinctive layer within the Calastran multiverse, stands as a
2 sanctuary realm offering individuals a rare opportunity for rebirth and
3 introspection. Positioned as a serene refuge between the higher and lower
4 Layers, Alpha-9 serves as a cosmic haven where beings can start anew,
5 unburdened by the complexities of their past lives. The realm is characterized
6 by ethereal landscapes and soothing energies that facilitate healing and
7 self-discovery. Quantum Resonance Wells, unique to Alpha-9, act as conduits for
8 individuals to reflect on their past experiences from a safe and contemplative
9 distance. Here, time flows differently, providing a respite for those seeking
10 solace and renewal. Residents of Alpha-9 find themselves surrounded by an
11 atmosphere of rejuvenation, encouraging personal growth and the exploration of
12 untapped potential. While the layer offers a haven for introspection, it is not
13 without its challenges, as individuals must confront their past and navigate
14 the delicate equilibrium between redemption and self-acceptance within this
15 tranquil cosmic retreat.
SansAlpha$ $_____ "${____[0]}"
1 return 0 picoCTF{7h15_mu171v3r53_15_m4dn355_8b3d83ad}
ペイロードすべてをまとめると以下のようになる。
SansAlpha$ .
bash: .: filename argument required
.: usage: . filename [arguments]
SansAlpha$ .>&$
SansAlpha$ __="${_##*. ??}"
SansAlpha$ ___=${__:0:1}${__:16:1}
SansAlpha$ $___
bash: .: filename argument required
.: usage: . filename [arguments]
SansAlpha$ "$(<$)"
bash: $'bash: .: filename argument required\n.: usage: . filename [arguments]': command not found
SansAlpha$ ___=${__:0:1}${__:16:1}
SansAlpha$ $___
bash: .: filename argument required
.: usage: . filename [arguments]
SansAlpha$ $___ -${__:0:1}
bash: .: -.: invalid option
.: usage: . filename [arguments]
SansAlpha$ .>&$
SansAlpha$ "$(<$)"
bash: $'bash: .: filename argument required\n.: usage: . filename [arguments]': command not found
SansAlpha$ __="${_##*. ??}"
SansAlpha$ ___=${__:0:1}${__:16:1}
SansAlpha$ $___ -${__:0:1}
total 8
-rw-rw-r-- 1 ctf-player ctf-player 69 Mar 20 04:39 '$'
drwxr-xr-x 1 ctf-player ctf-player 22 Mar 12 00:10 blargh
-rw-r--r-- 1 root root 1160 Feb 7 17:25 on-calastran.txt
SansAlpha$ $___
'$' blargh on-calastran.txt
SansAlpha$ ____=($(${___}))
SansAlpha$ _____=${__:2:1}${__:0:1}
SansAlpha$ .1>&$
SansAlpha$ "$(<$)"
bash: bash: .1: command not found: command not found
SansAlpha$ _______="${_##*.}"
SansAlpha$ ______=${_______:3:1}${_______:9:1}
SansAlpha$ $______ "${____[2]}"
bash: cd: on-calastran.txt: Not a directory
SansAlpha$ $______ "${____[1]}"
SansAlpha$ $___ -${__:0:1}
total 8
-rw-r--r-- 1 root root 53 Mar 12 00:10 flag.txt
-rw-r--r-- 1 root root 1090 Feb 7 17:25 on-alpha-9.txt
SansAlpha$ ____=($(${___}))
SansAlpha$ $_____ "${____[1]}"
1 Alpha-9, a distinctive layer within the Calastran multiverse, stands as a
2 sanctuary realm offering individuals a rare opportunity for rebirth and
3 introspection. Positioned as a serene refuge between the higher and lower
4 Layers, Alpha-9 serves as a cosmic haven where beings can start anew,
5 unburdened by the complexities of their past lives. The realm is characterized
6 by ethereal landscapes and soothing energies that facilitate healing and
7 self-discovery. Quantum Resonance Wells, unique to Alpha-9, act as conduits for
8 individuals to reflect on their past experiences from a safe and contemplative
9 distance. Here, time flows differently, providing a respite for those seeking
10 solace and renewal. Residents of Alpha-9 find themselves surrounded by an
11 atmosphere of rejuvenation, encouraging personal growth and the exploration of
12 untapped potential. While the layer offers a haven for introspection, it is not
13 without its challenges, as individuals must confront their past and navigate
14 the delicate equilibrium between redemption and self-acceptance within this
15 tranquil cosmic retreat.
SansAlpha$ $_____ "${____[0]}"
1 return 0 picoCTF{7h15_mu171v3r53_15_m4dn355_8b3d83ad}
SansAlpha$ Connection to mimas.picoctf.net closed by remote host.
Connection to mimas.picoctf.net closed.
おわり。
BIND DNSサーバーのconfigあれこれ
自宅DNSサーバーを建てるに当たって、configの書き方を調べた&何回かエラーを起こしたので備忘録として記します。 bindはconfigの構文を間違っていると起動しないので注意しましょう。
主要な設定ファイル
- named.conf: BINDの主設定ファイル。BINDサーバーの基本的な動作設定、ゾーンの定義、セキュリティポリシー、その他のオプションを含む。
- named.conf.local: カスタムのゾーン定義など、ローカルで特有の設定を含むことが推奨される追加設定ファイル。これは
named.confからインクルードされる。 - named.conf.options: BINDサーバーのオプション設定を含むファイル。一般的には転送設定、リスニングポート、キャッシュの設定など。
- named.conf.default-zones: デフォルトで提供されるゾーン(例えば、ルートヒントファイル、ローカルホストゾーンなど)の定義を含むファイル。これも
named.confからインクルードされることが多い。
設定ファイルの構成要素
- options { ... }: サーバー全体のオプションを設定します。ここにはディレクトリパス、転送設定、レートリミット、キャッシングポリシーなどが含まれます。
- acl "name" { ... }; アクセスコントロールリスト(ACL)を定義します。特定のネットワークやホストへのアクセス許可や拒否を指定できます。
- zone "name" { ... }; ゾーンを定義します。ゾーンはドメイン名に関連する情報(例えば、Aレコード、MXレコード)を含むDNSの単位です。ゾーンはプライマリ(マスター)またはセカンダリ(スレーブ)に設定できます。
- key "name" { ... }; TSIG(Transaction SIGnature)キーまたはDNSSEC(DNS Security Extensions)のキー設定を含みます。これらはセキュリティ強化のために使用されます。
- logging { ... }; ログ出力の設定を含みます。異なるカテゴリのログを異なるチャネルにルーティングするために使用されます。
ゾーンファイル
- ゾーン定義の一部として、ゾーンデータファイルのパスが指定されます。これらのファイルには、ドメインに関連するレコード(A、MX、CNAME、NSレコードなど)が含まれます。
カテゴリの役割と使用方法
BIND DNSサーバーにおけるcategoryは、ログの種類やソースを分類するための概念です。ログをカテゴリごとに分けて管理することで、情報を適切にフィルタリングし、重要なイベントを見逃さないようにすることができます。
定義されているカテゴリ一覧
- default: 特定のカテゴリに分類されない全てのメッセージ。
- client: クライアントからのリクエストに関連するメッセージ。
- network: ネットワーク関連のイベント。
- queries: 受信したクエリに関するメッセージ。
- lame-servers: Lame delegation(応答不能な名前サーバーからの応答)に関する警告。
- config: 設定ファイルの読み込みや解析に関するメッセージ。
- security: セキュリティ関連のイベントや警告。
- resolver: 名前解決プロセスに関連するメッセージ。
- xfer-in: ゾーン転送(受信)に関するメッセージ。
- xfer-out: ゾーン転送(送信)に関するメッセージ。
- notify: NOTIFYメッセージ処理に関するメッセージ。
- update: ダイナミックアップデートに関するメッセージ。
- dispatch: メッセージディスパッチシステムに関するメッセージ。
- dnssec: DNSSEC(DNSセキュリティ拡張)操作に関するメッセージ。
- delegation-only: "delegation-only" ゾーンに関する警告。
- edns-disabled: EDNS(拡張DNS)が無効にされた際のメッセージ。
- cname: CNAME関連の処理に関するメッセージ。
- rate-limit: レートリミット機能に関するメッセージ。
- rpz: 応答ポリシーゾーン(Response Policy Zone)に関するメッセージ。
カテゴリの使用方法
カテゴリはnamed.confのloggingセクションで定義され、各カテゴリに対してどのログチャネルを使用するかを指定します。
logging {
channel my_log_channel {
file "path/to/logfile.log";
severity info;
print-time yes;
};
category queries {
my_log_channel;
};
};
チャネルの役割と定義方法
channelは、ログの出力方法や出力先を定義するための構成要素です。ログチャネルを使用することで、ログデータがどのように処理され、どこに記録されるかを細かく制御できます。
チャネルに指定できる項目
- file: ログを記録するファイルのパス。
- severity: 記録するログの重要度レベル。
- print-time: ログエントリにタイムスタンプを含めるかどうか。
- print-severity: ログエントリに重要度レベルを含めるかどうか。
- print-category: ログエントリにカテゴリ情報を含めるかどうか。
- versions: ログファイルのローテーションにおいて保持するファイルの数。
- size: ログファイルがローテートされる前の最大サイズ。
- syslog: システムログとして出力するかどうか。
- stdout: 標準出力にログを出力するかどうか。
- stderr: 標準エラーにログを出力するかどうか。
チャネルの定義方法
ログチャネルはnamed.confのloggingセクションで定義します。
logging {
channel example_channel {
file "/var/log/named/example.log" versions 3 size 5m;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};
};
Severityの役割と使用方法
channel内で定義できるseverityは、ログエントリの重要度を指定するパラメータです。BINDで指定できるレベルは以下の通りです。
- critical: 致命的な問題が発生したことを示す。
- error: エラーが発生したが、サーバーは引き続き動作可能な状態。
- warning: 注意が必要な問題が発生した。
- notice: 通常の動作ですが、注目に値する事象が発生した。
- info: 情報提供のみ。
- debug: デバッグ情報。開発者やトラブルシューティング用。
- dynamic: ランタイムにおいて動的にログレベルを変更することができる。このレベルは、状況に応じてログの詳細度を調整する。
ログチャネルで指定されたレベル以上のメッセージのみが記録されます。
注意点
- ログファイルは手動で作成し、BINDが実行されているユーザーがファイルに書き込めるように適切なパーミッションを設定しておく必要があります。
- configファイルの構文が間違っているとbindの起動に失敗します。このとき、具体的にどこが間違っているかかがログに出ないのでトラブルシューティングに苦労しました。
- configファイルの構文のチェックは
named-checkconfコマンドや、named-checkzone [ゾーン名] /etc/bind/db.zone.pathコマンドで可能です。
結論
bindむずい。
CND(Certified Network Defender)に合格したので記録する
はじめに

CND資格とは
CND(Certified Network Defender)資格は、ネットワークセキュリティの専門家としてのスキルと知識を証明する国際的な認証です。
CND資格はあまり取得している人が多い印象はないものの、特にセキュリティ業界での要件として急速に重要視されるようになっています。
実際に、最近はIPAの入札要項にも盛り込まれるようになり、その需要は確実に増加していると感じられます。
この資格を取得することで、Network防衛における網羅的な知識の整理が期待されるだけでなく、業界全体での信頼性と専門性を高める手段でもあります。
自身のバックグラウンド
自分はセキュリティエンジニアとして数年業務に従事しています。
経験のある業務種別は以下です。
資格取得への動機
大本の受験動機としては、会社がお金を払って研修に行かせてくれたからです。
とはいいつつ、EC-Council系の資格は最近話題になり始めているため、興味があったというのも大きいです。
ただ、試験の範囲があまりにも広かったため、しばらくは勉強する気力が湧きませんでした。
その結果研修から半年以上経過してからの受験となります。
学習計画について
使用した参考書、オンラインリソースなど
使用したリソースは主に以下です。
- 公式の教科書(800ページ弱あります。。。)
- Udemyの模擬問題
- examTopicsの模擬問題
やったこと
CND資格の勉強を始めるにあたり、まずはEC-Council公式の教科書をベースにしました。
この教科書の内容がそのまま試験範囲となるので、全体感がつかみやすくなって効果的だったと思います。
さらに、模擬問題を使用し、公式教科書の根拠となる部分に手書きで追記を入れていました。
合計500問分くらい上記の作業を行いましたが、少し過剰だったような気もします。
しかし、前述の通り本試験は範囲が広く、一部のセクションは自分があまり触れてこなかったジャンルでもあったので、弱いセクションの補強という形では一定効果があったのではないかと感じています。
(特にRAID構成やUPSの構成、無線通信の規格などは、この試験対策をしないとしばらく通ることのなかった分野だと思います。)
学習期間
実際の勉強期間は3週間弱でした。
試験結果
試験結果は79/100点での合格となりました。
試験は日本語で受けたのですが、正直和訳が怪しいところが多々ありました。ComptiaやAWSの試験とは異なり、原文を表示する機能がないので選択肢の意図が汲み取れない問題も数点ありました。
かといって英語で受けても自分の英語力だと問題文に不安が出てくるので悩みどころです。
認定資格の有効化
試験が終わって数日経過すると、ASPENからメールが届きます。ASPENとは、EC-Councilが所轄する資格認定のプラットフォームです。登録料として80ドル要求されました。
また、EC-Councilの資格はECEというクレジットを3年以内に120ポイント貯めないと更新できない仕組みになっています。
RISSやCISSPと同じような仕組みと思って置けば問題ないです。
どうでもいいですけど、ここらへんの申請周り、もっと手軽にならないですかね。。。。
感想と今後の展望
CNDの資格は、深い知識を確認するようなものではなく、広く体系だった知識を整理するツールとして非常に効果的でした。
(その分、知っているカテゴリの研修中は集中力を維持するのが大変でしたが。。。)
試験に受かった事自体より、鈍器のような教科書を使って自分の知識を整理していた時間がとても有意義に感じました。
仕事で自社防衛に関わるのならチャレンジして損しない資格だと思います。
次は、CEHやComptia CASP+などの資格に挑戦してみたいと思います。
以上。

