はじめに
この記事は、2025年夏に開催された セキュリティキャンプ全国大会 の参加記録です。
参加のきっかけから応募コース選定、当日の活動、そして得られた学びを振り返ります。
セキュリティキャンプに参加した目的は以下の2点でした:
- セキュリティエンジニアになるために、今の自分にどんな知識やスキルがあり、何が不足しているかを見極めること
- 自分の研究分野に関して、より深い知見を得ること
このイベントの存在を知ったのは 外部大学院入試の準備 をしていたときです。
志望していた研究室のメンバーの経歴を調べる中で、「セキュリティキャンプ全国大会に参加している人が多い」と気づき、なんだその大会はと思いつつ、調べていく中で、自分も挑戦してみたいと思いました。院試勉強と並行しながら応募課題に取り組み、無事に突破して参加できました。
(参考:院試合格体験記)
応募コース選定
参加コースを決める際には、いくつかの候補で迷いました。特に関心を持ったのは以下の3つです:
- 専門C(脅威解析クラス)
- 開発Z2(オフェンシブセキュリティツール徹底解析ゼミ)
- 開発Z3(セキュリティ用AI Agent開発ゼミ)
どれも自分の興味分野と近く、魅力的でしたが、最も惹かれたのは Z3クラス でした。
「専門コースと開発コースの併願は不可」というルールもあったため、最終的に Z3とZ2の2つ に応募しました。
※応募課題は自分の研究内容を大きく絡めて書いたため、公開予定はありません。
1日目:共通講義と交流
初日は全体の共通講義がありました。印象に残ったのは、
「情報セキュリティは単体で極めるだけでなく、他分野と掛け合わせることで新しい価値が生まれる」
という考え方でした。
実際の例として紹介されたのは、「セキュリティ × アニメ × 鉄道」 という、一見するとセキュリティとは直接関係なさそうな組み合わせ。
しかしこうした異分野を掛け合わせることで独自の強みが生まれ、社会に役立つ取り組みに発展するという話でした。
私はこの話を聞きながら、「サッカー × セキュリティ」 のように、自分が興味を持っている分野と組み合わせられないかと考えました。
スポーツの世界でもデータの正確性、不正防止、公平性の担保など、セキュリティが力を発揮できる領域は多いと感じます。
この「セキュリティ × ○○」という発想は、自分の関心分野にからめて考えるのも有効だと気づき、キャリアや研究を考えるうえで大きな視点の広がりを与えてくれました。
また、この日は名刺交換を通じて同じ28卒・修士進学予定の仲間が多くでき、とても刺激になりました。
2日目:Z3クラス開始
いよいよZ3クラスの活動が始まりました。
まずは参加者全員で事前課題(LLMを用いたアプリ)を紹介し合いました。私は以下のアプリを開発していました:
その後、チームで「どんなAIエージェントを開発するか」を話し合う中で、凌さんから NIST サイバーセキュリティフレームワーク を参考に、どの分野のオペレーションに取り組むかを考えてみようと提案をいただきました。
参考にしたのは以下の資料です:
議論の結果、識別(IDENTIFY)の分野 にフォーカスすることが良いのではないかという結論になり、そこから 「非管理デバイスに存在する既知の脆弱性の発見」 をテーマに開発を進めることになりました。
チームで取り組んだテーマ
テーマは 「非管理デバイスに存在する既知の脆弱性の発見」 です。
タスクは以下の通りに分担しました:
- 組織名から関連組織を列挙
- 組織名からドメインを列挙
- ドメインからFQDNを列挙
- FQDNからIPを解決
- (S3などクラウドストレージの探索)
- IP上で動作しているソフトウェア/ハードウェアを特定
- バージョン特定と脆弱性照合(NVDなどを利用)
私は ドメイン→FQDN列挙 と FQDN→IP解決 を担当しました。
今回の取り組みは、公開情報を活用して調査する OSINT(Open Source Intelligence) 的なアプローチでもあり、実務でも使われる要素を体験できました。
技術的ハイライト
ドメイン → FQDN → IP 解決フロー(2〜3日目)
設計方針
全サブドメインを盲目的に探索すると冗長になるため、
Shodanで候補列挙 → NSレコードを持つものだけ再帰 という枝刈り方式を採用。
最終的に得られたFQDNを A/AAAAでDNS解決してIPを取得しました。
ポイント
Shodanで広く候補を収集
NSを持つものだけ再帰(効率化)
A/AAAA両対応・例外処理で堅牢化
スニペット(再帰の本体)
from typing import List
def enumerate_subdomains(domain: str) -> List[str]:
subs = get_subdomains_from_shodan(domain)
result = []
for sub in subs:
result.append(sub)
if has_ns_record(sub):
result.extend(enumerate_subdomains(sub)) # NSを持つものだけ再帰
return list(set(result))
スニペット(FQDN → IP解決)
def resolve_fqdn_to_ip(fqdn: str) -> List[str]:
resolver = Resolver()
resolver.nameservers = ["1.1.1.1"]
ips: List[str] = []
for rtype in ("A", "AAAA"):
try:
answers = resolver.resolve(fqdn, rtype)
for rr in answers:
ips.append(rr.to_text())
except DNSException:
pass
return ips
VirusTotal を用いたサブドメイン補完(3〜4日目)
設計方針
Shodanだけでは拾えないFQDNを補完するため、VirusTotalのGUIページをスクレイピングして Relations 情報を抽出しました。
APIキー不要で導入しやすく、結果を 重複排除・正規化 して統合しています。
ポイント
GUIから必要箇所だけを軽量スクレイピング
Shodan結果とマージ+去重
DOM変化や失敗を考慮した例外処理
スニペット(抽出の骨子)
def get_subdomains_from_virustotal(domain: str) -> List[str]:
url = f"https://www.virustotal.com/gui/domain/{domain}/relations"
page = fetch_page(url) # UA/リトライ等を考慮して取得
subs = parse_subdomains(page) # DOMからサブドメインを抽出
return subs
まとめ(この実装の価値)
探索効率:NSレコードで再帰を絞り込み、無駄な探索を削減
網羅性:ShodanとVTの二段構えで取りこぼしを補完
堅牢性:A/AAAA両対応・例外処理・正規化で実運用を意識した実装
👉フル実装はこちら
3日目:実装と交流
この日はチームで結合テストを行い、各自が実装した機能を組み合わせて動作確認をしました。作業が一段落した後は、他のコースを見学して雰囲気を感じたり、夜には BoF(自由に集まって意見交換する場) に参加しました。
特にBoFでは、参加者同士の会話のレベルが非常に高く、自分の知識不足や伸ばすべき方向を痛感しました。同時に「もっと成長しなければ」と強く刺激を受けたのを覚えています。
4日目:拡張実装と成果
最終日には VirusTotal連携の実装を完成させ、最終成果に組み込みました。
また、講師陣から自分の研究に関するフィードバックをいただくことができ、とても有意義な学びになりました。
まとめ
今回のセキュリティキャンプ全国大会では、技術的な学びや新しい知識の習得に加え、他大学や社会人の参加者との交流を通じて、研究やキャリアについての視野が大きく広がりました。
特に大きな収穫は、自分の視座が大きく高まったことです。
これまで技術習得にばかり目が向いていましたが、「その先にどうつなげるか」を考える視点を持てたことは、今後に大きく影響すると思います。
実装面での挑戦や議論を通じて、自分に不足しているスキルや今後伸ばすべき方向も明確になりました。さらに今回の経験は、公開情報をもとに調査を進める OSINT の実践例でもあり、学んだ技術を今後の研究や実務にどう応用できるかを考える良い機会にもなりました。
余談ですが、宿泊環境や食事も快適で、集中して学びに取り組むには最高の環境でした。こうしたサポートのおかげで、安心して全力を尽くすことができました。
おわりに
セキュリティキャンプは、参加するだけで得られるものが非常に大きいイベントです。
これから参加を検討している方には、ぜひ挑戦してみてほしいと思います。
もし質問やフィードバックがあれば、ぜひコメントで教えてください!