ペネトレーションしのべくん

さようなら、すべてのセキュリティエンジニア

私はこうやってセキュリティエンジニアになりましたという話

はじめに

セキュリティ、言わずもがな数多の領域がありますが、そのひとつとして、自分自身が悩まされてきた「セキュリティ人材の創出・再現性の向上」とか、「セキュリティ組織の組成」という切り口で何か貢献できないかなーと漠然と思う今日この頃です。

とりあえずその取り掛かりとして、セキュリティ人材の端くれとしての私のキャリアを、思うままに振り返ってみます。 2015年〜現在までのことですし、「同じキャリアを歩めば君もセキュリティエンジニアになれる!」みたいなことではありませんが、誰かしらの何かしらの役に立つことを願っています。

お前は誰

shinobe(しのべ)といいます。20代前半に異業種からIT業界に転職してきて、

  • SES(2.5年): ネットワークエンジニア
  • SIer(0.5年): ネットワークエンジニア
  • 事業会社(10年): ネットワークエンジニア(5年) -> セキュリティエンジニア(5年)
  • 事業会社(1ヶ月、現職) : セキュリティエンジニア

というキャリアです。前職の事業会社ではセキュリティチームの立ち上げと、マネジメントをしていました。今は別の事業会社で、セキュリティチームの一員として働いています。

ITの仕事を始める前

文系の大学を1年で中退して、2年ぐらいフリーターや営業の仕事をしていました。IT業界へ移ったきっかけは、「手に職をつけよう」→「PC使えるとかっこいいからエンジニアになろう」というごく単純なもので、その頃はIT業界の領域も分かっていなかったけど、やっていたのが光回線押し売りする仕事だったので、「るーたー」とか「わいふぁい」といった聞き覚えのある用語から着想を得て(?)ネットワークエンジニアを選びました。

インフラエンジニア(=ネットワークやサーバーをやる人)には私みたいに、社会的にはレールを外れてしまったとされる人が多い気がします。これは1社目のように、未経験者にネットワークやサーバー(これでも雑な括りですけど)という限られた領域の知識だけ詰め込んでなんとか現場に送り込む、という会社がたくさんある?あった?からです。

セキュリティの仕事を始めるきっかけ

原点も原点で言うと、IT業界へ転職する段階でセキュリティは意識していました。はじめての派遣先監督者との"顔合わせ"(不穏)のときに、「将来はセキュリティの仕事をしたいです」って言ったことを鮮明に覚えています。

それからしばらくはルーターやスイッチをいじる、L1〜L4に幽閉された日々でしたが、事業会社(1社目)に転職してはじめてファイアウォールを運用し、WAFの導入プロジェクトを手を挙げてやらせてもらいました。セキュリティ領域への足がかりはそれだったと思います。XSSやSQLiのシグネチャがあって、それぞれどんな攻撃なんだっけ、というのを調べながらやっていました。

その後セキュリティチームを立ち上げることになり、私財を投じて本格的にセキュリティの勉強をし始めた、という感じです。

よかったなと思うこと

未経験歓迎の会社に入れたこと

こういう会社はいろんな側面で歓迎されないこともありますが、ことレールを外れてしまった人の救済という視点ではよいと思うし、純粋に感謝しています。

もちろん入るだけではダメで、自主的に学習したりキャリアアップを考えないと、派遣先や営業にいいように使われて疲弊して終わります。仕事内容はピンキリなので、ピンでもキリでも、内容について意味や改善を能動的に考える姿勢が必要です。幸いこの手の会社は給料が安いので、特に一人暮らしの場合なんかはモチベーション以前にまともに生活できないという、差し迫った状況を作ってくれる会社が多くはあります。

セキュリティ以外の領域から参入したこと

私のハードスキルの根幹はネットワークです。最初に入ったSESが、未経験者にCCNAを取得させて現場に送り込む系の会社でした。侵入はネットワーク到達性がないことには難しいので、TCP/IPを最初に押さえられたのはすごくよかったです。

開発から入るのもまたよいと思います。要するに守るものがどんな仕組みで動いているのかを分かってないと、攻撃も防御もできないという当たり前の話です。

一方、キャリアの最初にセキュリティから入っている人の中には、一見アドバンテージがあるようで、実際はアプリやネットワークのことを全然分かっていない、というのもよく見てきました。多重下請け構造の下位で診断業務やSOC業務をしている人に多い印象です。前述した通り、手順書レベルの作業について、意味や改善点を能動的に考える姿勢が必要です。これはどの領域から入る場合でも同様です。

一定以上のビジネスコミュニケーション能力があること

私は営業職を挫折した人間なので、人の考えを変えてお金を出させるようなコミュニケーション能力はありません(本当、営業職の人ってすごいと思う)。ただ10年近く社会人をやって思うのは、組織から浮いちゃったり、周囲からの見られ方に無頓着だったり、何言ってるかよく分からない人がたくさんいるということです。

正しい文章を、分かりやすく相手への配慮も交えて話す。会話だけじゃなくて、身だしなみもコミュニケーションです。これらは営業職やSESで学びました。お話に関しては、できない人がなぜできないのか、正直よく分からない。本とか漫画を読んでいたのがよかったのかなあ。苦手そうな方には入門 考える技術・書く技術をおすすめしています。

趣味がなかったこと

序盤、かなり不安定なキャリアを経験していることもあって、勉強以外のことをしていると「勉強しなきゃ」という気持ちになって手につかないということがよくありました。「趣味: セキュリティ」みたいな状態なので、学習への投資を大きめにできたのがよかったです。……みたいな人は多くないので、こんな私でもマクロな視点では外れ値側に入ってしまう自覚があります。趣味や家族サービスを優先したい人たちでも、不足なくセキュリティの仕事ができる社会であるべき。

セキュリティの勉強をしたこと

当たり前なので、分野毎に使ったコンテンツを紹介します。

ハッキング技術の基礎

  • Virtual Hacking Labs
    • X(当時Twitter)で「OSCPの前哨戦におすすめ」というポスト(当時ツイート)を見て挑戦しました。
    • 実際に手を動かして学ぶコンテンツとしては、今はHackTheBoxとかTryHackMeでもいいんですけど、VHLがよかったのはテキストが1つの大きなPDFだったことです。当時は『ハッキング・ラボ』やのみぞう本みたいな書籍がなく、基礎的な考え方やテクニックを網羅的に学ぶ手段がありませんでした。

ウェブセキュリティ

  • 徳丸本
    • 言わずもがな。徳丸基礎試験も受けました。
  • Web Security Academy
    • これが無料とは信じられないぐらいのクオリティ。

資格

資格は色々持ってるんですけど、その中で取得の過程で学びがあったものは以下。 ※これら以外は学びがなかったわけじゃないけど、力試しの意味合いが強いので

  • CCNA
    • ネットワークの初歩としてはこれ以上ない資格だと思います。
  • AWS認定各種
    • クラウドの基礎は押さえておくとO。
    • 業務に応じてGoogle CloudでもAzureでもOK。
  • eJPT
    • eLearnSecurityのペネトレーションテスター入門者向け資格。

勉強会やコミュニティに参加したこと

有名な人たちがmondとかで「どれに参加したらいいか分からない」という相談を受けているのをたまに見ますが、ピンときたやつに参加すればいいんじゃないと思いますね(その人たちもそう回答している)。これまで、とって食われるようなことはなかったので。

これがあったらな、と思うこと

自分よりセキュリティに詳しい上司・同僚

私がセキュリティチームのマネージャーで、CISOみたいな人もいなかったので、この領域について社内で何かを教わる、導いてもらうということがほぼありませんでした。強いて言えば、インフラやアプリのチームのマネージャーから、各領域に特化したセキュリティの示唆を与えていただくことがあった位。事業会社だと、会社によってはこれすらないかもしれません。

ベンダーと事業会社、入り口はどっちがいいのか?

私はセキュリティに限って言えばベンダーで働いたことはないんですけど、多分どっちでもよくて、守るものが何か、どう守るのかを考えているのかが重要だと思います。ベンダーだと特定製品に張り付けられちゃったり、デリバリーで終わってしまうことが多く、その先を実践するために事業会社へ転職する方をよく見かけます。一方事業会社でも、ベンダーの言いなりでソリューションを導入する「セキュリティ係」で終わってしまうとよくない。

おわりに

とりあえず思うままに書きました。

英語弱者がChatGPTの力を借りて『Do Secure-By-Design Pledges Come With Stickers? - Ivanti Connect Secure RCE (CVE-2025-0282)』を読む

個人的によう分からんと思ったところだけ押さえる。

labs.watchtowr.com

参考(Mandiantのレポート):

cloud.google.com

※この記事はCosense(旧Scrapbox)で下書きしています。

scrapbox.io

最初の画像

入力を待つようなプロンプトのあとに414141…と続いている。バッファオーバーフローの余地があることを示している。

"Same drill" から始まる段落

Ivantiは脆弱性の技術的な詳細を公開していない。すでに悪用しているアクターが、再現できないようにするためってこと? スピルバーグのくだりはよく分からない。茶番だよねってこと?

"Our previously-documented //bin/bash bypass no longer works" のくだり

昨年のIvantiの脆弱性が公開されたときに見つけた、アプライアンスのシェルアクセスを得る手段がもう動かないことを示している。当時の様子はかなりひどい。

https://labs.watchtowr.com/welcome-to-2024-the-sslvpn-chaos-continues-ivanti-cve-2023-46805-cve-2024-21887/

What’s this we see?

 __int64 __fastcall sub_FFFFFFFF826CC601(unsigned __int8 *a1)
 {
   __int64 i;
   if ( strcmp(a1, "/bin/sh") )
     qword_FFFFFFFF827E2030 = a1;
   for ( i = 0LL; i != 31; ++i )
     qword_FFFFFFFF82212168[i] = 0LL;
   return 1LL;
 }

 is… is that a blacklist on the term /bin/sh?! Really?!
What a bizarre check. It’s easily bypassed, of course, by specifying a slightly different (but equivalent) argument (such as //bin//sh).

root\home\bin\webというファイルが、パッチ適用前後で4KB大きくなっていた模様。

stringsコマンドによる可読文字の差分比較では、値のサイズ制限に関するエラーメッセージが追加されていることが分かった。-> バッファオーバーフローに関係ある?

"Too late for IFT_PREAUTH_INIT" とは?

(おそらく)diaphoraというツールによるバイナリの差分比較によって、ソースコード中に追加されたことが分かったコメント。 IFTはVPNに関するプロトコルみたい。Mandiantのレポートでも痕跡除去の手順内に「ifttls」というワードが出てくる。 https://trustedcomputinggroup.org/wp-content/uploads/IFT-TLS-FAQ-Final-May-8-09.pdf

このへんからちょっとよく分かんない。 Openconnectのドキュメント中に「昔のPulse Secureサーバーはクライアント証明書を要求してくるが本来は必要ない。そういうときは古いクライアントを使うといい」みたいな一文がある。Watchtowrはこれに「the worst ‘code smell’」を感じるとのこと。

www.infradead.org

ようやく直接の原因

  • pulse.c というファイル中のIF-Tのリクエスト受信処理にバッファオーバーフロー脆弱性がある
  • clientCapabilities という属性値を受け取る処理にミスコーディングが原因
  • 以下は例のようだが、バッファの長さが256であるところ、strncpy()での入力許容値(第3引数)がclientCapabilitieslength、つまり(おそらく)入力値そのものの長さになってしまっている
 char dest[256];
 ...
 strncpy(dest, connInfo->clientCapabilities, clientCapabilitiesLength);

悪用を難しくする要因

  • ASLRやPIEによる、リターンアドレスのランダム化
  • 以降の処理が破綻してsegmentation faultしないようなスタッキングが必要

表現

  • pledge: 誓い
  • we spotted [ a smoking gun]: 私たちは[ 決定的な証拠]を見つけた
    • smoking gun:銃口から煙が立ち上っている銃、つまり発砲したことが明白であるということ
  • Groundhog Day: 同じことが繰り返される状況、変化のない日常

この記事で使用されている「Groundhog Day」という表現は、1993年の映画『Groundhog Day(邦題:恋はデジャ・ブ)』に由来しています。この映画では、主人公が同じ一日を何度も繰り返すというストーリーが展開されます。そのため、「Groundhog Day」は「同じことが繰り返される状況」や「変化のない日常」を指す比喩として使われるようになりました。

この記事では、2024年と2025年に同様の脆弱性がIvanti製品で発見され、同じような対応が繰り返されている状況を皮肉を込めて「Groundhog Day」と表現しています。具体的には、「As an industry, we are on GroundHog day - but let’s call it GroundHog Year, and pretend this isn’t just incredibly depressing.」と述べられており、業界全体が同じ問題を繰り返していることを嘆いています。

  • 2l8: = Too late

Learning ES|QLを一読してまとめた

Scrapboxを使うようになってから、はてブロに書くことがなくなってしまいました。Scrapbox、カジュアルなテキストの置き場でありながら、情報整理の仕組みも確立していて、非常にいいです。

はてブロのいいところは拡散の仕組みがあるところだと思うので、Scrapboxである程度まとまった記事が書けたら、こっちで流すようにしようと思います。

というわけで、この土日でElasticsearchに新たに実装されたクエリ言語「ES|QL」の入門コンテンツを読んで、以下の記事にまとめました。

scrapbox.io

8.12時点でまだpreviewですが、これまでよりもかなり柔軟にデータ抽出・加工ができるので期待しています。

私はセキュリティ用途、いわゆるSIEMとしてElasticsearchを使っています。この領域のリーダーはSplunk、次いでQrader、Graynoiseあたりかなと思いますが、いち利用者の立場から情報を発信して、ElasticをSIEMとして採用する仲間が増えたらうれしいです。

ParrotOSのPluma(エディタ)のビープ音がうるさいので無効にした話

タイトルの通りです。OSのサウンドとかをいじってもダメだったのでなんじゃこりゃと思ってググっていたら、以下の記事が見つかりました。要するにPulseAudioがゴミだからだそうです。

ubuntu-mate.community

/etc/pulse/default.paというファイルの load-module module-suspend-on-idleコメントアウトして、 pulseaudio -k && pulseaudio --start を実行したら無事鳴らなくなりました。めでたしめでたし。

www.exceedsystem.net

トラックボールの右クリックが効かなくなったのでxinputで解決した話

ごぶさたしております。仕事が忙しくてインプットもままならず、2023年も折り返しに入ったというのに今年2記事目です。

・・・

愛用しているトラックボールの右クリックが効かなくなりました。接点復活剤をかけたが効果が持続しなかったため、ボタンのマッピング変更で対応しました。めでたしめでたし。

※後日追記※

そうは問屋が降ろさない。仕事用PCも同じトラックボールを使うのですが、こちらではマッピングをいじれないので、結局裏側のラバーを剥がしてカバーを開けて直しましたとさ。

接点復活剤を使う

KUREの接点復活スプレーを買って吹きかけたら、「カチッ」というクリック感と引き換えに右クリックが復活……と思いきや、翌日また効かなくなりました。

ボタンのマッピングを変更する

幸い(?)余っているボタンがあったので、別のボタンに右クリックをマッピングすることにしました。以下の記事を参考にしました。

nekoroll.hatenablog.com

記事同様、私の環境も3に右クリックがマッピングされているようで、これを8のボタンと置き換えました。

最後に示されているbashスクリプトが私の環境ではうまく動かなかったので、以下のように修正しました。sedって難しくないですか?

DEVICE_ID=$(xinput list | grep "Kensington" | sed -E 's/.*id=([0-9]+).*/\1/g')
xinput set-button-map ${DEVICE_ID} 1 2 8 4 5 6 7 3

やられサイト対戦記録(vs WackoPicko)

今年はWebに本腰入れて取り組もうかと思います。能書き垂れるぐらいはできるんですが、要領よく脆弱性を見つけるという作業に慣れていないので、とりあえずOVWAD(OWASP Vulnerable Web Applications Directory)で紹介されているやられサイトを、レガシーなものからモダンなものまで、片っ端からやっていこうと思います。せっかくなので挑戦の様子を記事にします。

owasp.org

記念すべき第1戦目はWackoPickoです。

github.com

一応「対戦」と銘打っていますが、手を付けた時点で優勢、成長があったら勝ち、やり切ったら圧勝ということにしようと思います。

対戦記録

Googleスプレッドシートにまとめています。一応簡易レポートの体にしていますが、あくまで備忘目的なので本職の方とか怒らないでほしいです。

docs.google.com

Keep

Problem

  • OSコマンドインジェクション、ちゃんと刺せなかった
  • nameのSQLi見つけられなかった
  • adminのセッションが単なるインクリメントになってるの指摘しそびれた
    • どう考えたって危ない
  • サンプルページのuserid変えられるの、指摘しなかったがparameter manipulationという類のものだっ
    • 少なくとも、このアプリに関してはそんなに致命的じゃない気もする
  • クーポンコードとロジック不備見つけられなかった
    • クーポンコードどうやって見つけんだよ
      • リポ見たら、calender.phpをひたすら1日ずつちゃんと見ていけば出会えた(出会ってた)みたい
  • FlashフォームにXSSがあったっぽい 平成
  • 診断リストのフォーマットがどうもしっくりこない

Try

  • 事前分析をTBHM AppSecの6つの質問に沿ってやってみる
  • 診断リスト、改造する(脆弱性の列は参考ぐらいに思っててもいいかも)
  • 今のうちから自動化を真面目に考えたほうがよさそう
    • ブラックボックスな自動化はあんまりしたくない
      • Burpのactive scanとか(パケット見れば一律同じものを投げているのかもしれないが)
        • 文明の利器は使うべき?
        • 診断屋さんはどうしているんだろうか?
    • Nucleiをいい感じに自動診断させる術はないか(レポート出してくれるから)

……

対戦ありがとうございました。

docker-composeしようとしたら「ERROR [internal] load metadata」というエラーが発生する

docker-composeRubyコンテナを使ってビルドしようとしたら、以下のようなエラーで失敗しました。

$ docker-compose run web rails new . --force 
--no-deps --database=postgresql --skip-bundle
[+] Running 1/0
 ⠿ Container ugiene-db-1  Created                                                       0.0s 
[+] Running 1/1
 ⠿ Container ugiene-db-1  Started                                                       1.1s
[+] Building 0.8s (3/3) FINISHED
 => [internal] load build definition from Dockerfile                                    0.1s 
 => => transferring dockerfile: 32B                                                     0.1s 
 => [internal] load .dockerignore                                                       0.1s 
 => => transferring context: 2B                                                         0.0s 
 => ERROR [internal] load metadata for docker.io/library/ruby:3.1.3                     0.6s 
------
 > [internal] load metadata for docker.io/library/ruby:3.1.3:
------
failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: rpc error: code = Unknown desc = error getting credentials - err: exit status 1, out: ``

以下を順番に実施した結果、解決しました。もしかしたら最後だけでもよかったのかも。

  • (WSLでなく)Windowsdocker login し直す
  • Docker Desktopの設定ファイルから {"features": {"buildkit": true}} を削除する
  • Docker Desktopをリスタートする
  • docker pull ruby:3.1.3 する
  • docker-compose run する