asu_paraの日常

日々感じたことをまとめて投稿するときに使います

1桁加減算カリキュレータの作成 

何かしらのシステムを作ってそれを早く動かしたい!!という野望を持った時、どういう発想があるだろうって気になっていた時がありました。私はシステムの基盤そのものを早くしたいと思いますね。もちろんデータ構造やそれに伴って勉強しなければならないアルゴリズムの観点というのは非常に重要です。それはソフトウェアとしての対策。めちゃくちゃ重要です。ではハードウェアからのアプローチってなんだろうと思って作ったものがこれです。脆弱性についてもより低いところではソフトウェアレベルでもハードウェアレベルでも対策をしないといけない(*1)のでそのアプローチの視点を増やすためにこういったことを勉強の一環で開発していました。 

------------------------------------------------------------------------------------------------

実機で実際に動いたのを確認済みです。最後に最終結果として写真貼っておきます。 

 

作成の手順 (Github)より 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator  

 

全体としてどういうシステムを作りたいのかについて共有します。 

 

 

SEG_1_OUTとSEG_SEL_1はSEG_A~SEG_Dを、SEG_2_OUTとSEG_SEL_2はSEG_E~SEG_Hをそれぞれ制御できるように配置する。LEDの割り当て配置と表示の例(3) 

 

  • さらに7セグの表示器と制御論についてもう少し補足 

7セグメントLEDはダイナミック方式で制御される。出力データをセレクタで切り替えて表示する。出力データはSEG_1_OUT、セレクタ信号はSEG_SEL_1OK 

 

 

上のハード設計を踏まえて 

SEG_SEL_1 = 1110 (E) -> SEG_1_OUTはSEG_Aで表示 

SEG_SEL_1 = 1101 (D) -> SEG_1_OUTはSEG_Bで表示 

SEG_SEL_1 = 1011 (B) -> SEG_1_OUTはSEG_Cで表示 

SEG_SEL_1 = 0111 (7) -> SEG_1_OUTはSEG_Dで表示 

SEG_SEL_2 = 1110 (E) -> SEG_2_OUTはSEG_Eで表示 

SEG_SEL_2 = 1101 (D) ->SEG_2_OUTはSEG_Fで表示 

SEG_SEL_2 = 1011 (B) ->SEG_2_OUTはSEG_Gで表示 

SEG_SEL_2 = 0111 (7) ->SEG_2_OUTはSEG_Hで表示 

の、ような表示を高速切り替えできるようにし全てのLEDに対して割り当てを行う。 

 

  1. Halfadder

1ビット(A,B) の加算を行い,和(Y) と上位への桁上げ信号キャリー(CO) を出力する回路を書いてやる極めてシンプルな加算回路のコンポーネント 

 

Github 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/halfadder.v  

なぜかわからないけどCoqとして読まれている。実機上では正しく動作が確認できたので問題なし。証拠写真 

 

 

テストベンチ::Github 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/test_halfadder.v  

transcript上での動作確認が取れた 

 

雑に感じたこととしては1step == 1psに相当すると予想。そして$finishというタスクが実行されプログラムが終了。$monitorでは書式と変数を指定しておりこれはC++の出力ストリームと非常に似ていると感じた。しかしこの1行によって何度も文字が出力されていることから、$monitorは変数の変化を検出するたびに実行でうまく動かしているのではないかということだ。 

 

  1. 2. Fulladder

bitの被加数A, 加数B, 下位桁からのキャリーCINの加算を行い,和(SUM) と上位への桁上げ信号キャリー(COUT) を出力。フルアダーは2個のハーフアダーと,1個のORゲートで構成。⏬構成図と対応表 

 

みたままの割り当てをしてやれば良い Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/full-adder.v  

 

テスト 

テストベンチ::Github 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/test_fulladder.v  

transcript 桁上げ対応がちゃんとできていることがわかる。 

ただしい挙動を得ることができた 

 

ソースコードについて A,B,SUM は4ビット指定している。それを出力するコードをモジュール内に書いた。テストベンチについてテスト入出力の信号を4ビット幅でとって タイムステップを50でとることによってタイムステップごとに a, b の値を変化させてシュミレーションすることによってテストを行うことができた。 

 

 

  1. 3. four (4) bit ripple carry adder

3個のフルアダー(FA1FA3) と1個のハーフアダー(HA0) を図のように接続すると4ビット2進加算器(ripple4adder)ができる。これはいわゆる構造記述の一環で今までに書いてきたものを部品としてみることによって部品として扱うことができるのでそれらを定義通りに組み合わせるにはどうすれば良いのかを考える。 

 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/ripple4adder.v  

 

テストについてもここで提示する。Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/test_ripple4adder.v  

 

テスト結果 

加算結果が16を超えない範囲では出力SUMが正しい数値を表示していることが分かる。これらの組み合わせではcarry0を出力していた。6+14, 13+9など合計が16を超えるとcarry信号が1となりsumに何かしらの信号が確認できるのでO K 

 

 

  1. BCD adder & BCD hosei6 module

これには前提としてBCD符号についての理解が必要。10-16にはA-Fが割り当てられることになるがS0110 = 610 を加えて補正するとこれが1の桁になる)つまり下記の表のように補正する必要性がある。 

 

では全体としてどのような概略図になるのだろうか。以下である。 

 

dummyはハーフアダーの桁上げ信号と接続されていることから桁あふれを表す信号線。3ビットの出力を設けてやりさらにdummyを設けることによって補正結果の調整に使うことを想定している。ここでは前に書いたhalf adderとfull adderを接続することによって計算している。 

 

大きくテーマに分けると「桁上げ検出」「6補正」を先ほど作ったモジュールに噛み合わせれば作成できそうな目算がたった。では順番に処理の過程を見ていくことにする。 

 

「桁上げ検出」 

and演算とor演算をしているところが桁上げ検出である。それがcarry detect。加算されて出てきた結果を入力側に渡してk1とk2のand演算k3とk4のand演算を割り当てる。そして一番重要なのがdetect= (an1 || an2) || k5の部分だがそこでは論理条件を考えることによって桁上げの検出をしている。 

 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/carrydetect.v  

 

「6補正」 

16進数で表現されてしまうため補正を行う必要があってこの補正方法として表現数の差である6を加算結果にもう一度加算することで強制的に桁をあふれさせ0~9の表現のみを使用できる仕組みをうまく利用することによって桁の処理をする。2進数の加算をして得た結果と桁上げ判定後の結果を入力信号として受け渡すことでつなげている。 

 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/hosei6.v  

 

ここまでできたら次はそれら3つのコンポーネントを繋いで本格的にシステムを組み上げていく作業。新しいモジュールを立ててそこに書き込むことで接続した。 

 

それがBCDTOP 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/BCDTOP.v  

無事、f0-f4ワイヤ線を結合することができました。 

 

それではテストプログラムを書いて挙動の確認をしてみる。 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/test_BCDTOP.v  

 

結果的にこうなりました。 



補正検出回路では4bitの加算で桁あふれが発生した場合と結果のbitから10以上であることを検出した場合に信号が1になっている。つまり桁上げとして正しくないところに1を出すことができているのでその他正常に動作しているものと合わせ、うまく動作できた。 

 

  1. 5. six (6) bit add-subtract circuit

したの図の部分を主に作成する。4までで全体制御は書くことができたのでここからは実際に入力された信号に対する過減算装置を記述する。以下の手順で作成して実機に反映させるまでのステップを踏んだ。 

 

 

(1) 減算モジュールの設計 

4bitの入力A,Bの減算結果を6bitのSUB_DATAへ出力する回路を設計する。減算は入力Bの2の補数を生成しその数とAを足し合わせることによって実現する。 

イメージ図はこんな感じ 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/sub.v  

 

 

(2) 加算モジュールの設計 

4bit加算器を実装するFPGAの仕様に合わせて改良したものを使用する。 

イメージ図はこんな感じ 



Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/add.v  

 

 

(3) 1桁加減算トップモジュールの設計 

設計した計算モジュールとあらかじめ用意されたコントロールモジュールを組み合わせてトップモジュールを設計する。 

イメージ図はこんな感じ 

 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/calc_one_top.v  

 

LEDへの出力の受け渡しと配線->controllerで制御部分の実装。インスタンス部分では.CLK(CLK)などの部分が続くがこれはテンキーへの制御受け渡しをしている部分で非常に核となる重要な実装箇所 

 

(4) トップモジュールのテストベンチの設計 

モジュールの動作確認するためのテストベンチを設計する。検証する計算は1+2, 5-9, 9+8, 6-6でやった。 

3で作ったものに対するテストベンチを作成する。以下の様な実装をした。 

Github:: 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/test_calc_one.v  

 

クロック信号、リセット信号、Key dataの呼び出しをすることにSEG_1_OUTはSEG_Cで表示、SEG_SEL_1 = 0111 (7) のときSEG_1_OUTはSEG_Dで表示する必要があるのでこれに従った実装をすることである。出力はLED に渡してやる。次にトップのモジュールを呼び出す。これは動作指定したものをテストで呼び出す作用を測っている。次にalways文でシグナル生成をしてタイムステップを踏む。ここでのポイントは7セグメントLEDはダイナミック方式での制御であるため出力データをセレクタで切り替えて出力しないといけない点である。つまり例を示すとSEG_SEL_1 = 1110 (E) のときSEG_1_OUTはSEG_Aで表示、SEG_SEL_1 = 1101 (D) のときSEG_1_OUTはSEG_Bで表示、SEG_SEL_1 = 1011 (B) のときといった感じである。その際のテンキーの受け渡しのルールはFPGAの仕様に基ついて以下のルールを守って行う。 

 

テンキーの割り当てについて 

  1. キーデータ,ボタンデータは押していない状態では"1"が出力されている。押すと"0"が出力される。キー,ボタンについては”0” が有効データ 
  1. リセットボタンを押すとRST_X信号が"0" になる。離すと"1" になる。
  2. テンキーデータは,14ビットの信号PSW[13:0] にセットされる。
  3. あるキーを押したとき,対応するPSW [X]の値が"0" になる

 

(5) シミュレーションで波形が正しいことを確認したらQuartus を起動しVerilogコンパイル、ピンのアサインを行ってFPGAにプログラムを書き込む。実機での動作確認 

 

その結果 

完成しました。 

 

コラム      (追加の実装          -もっと高速でより速いFPGA実装への探求- ) 

先ほど示したsubの改良論理回路設計に伴う変更コードを作成した。改良点としては最下位bitの加算にFulladderを用いているところである。これによってセレクタ信号が1の時に「A_DATA + B_DATA + 1」のような演算ができることによって少し機能性の上がった回路設計になったのではないか?とおもう。ソースコード、およびテストのソースコードについて載せておく 

 

ソースコード 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/andandsub.v  

テストのソースコード 

https://github.com/ultrasupara-jump/One-digit-add_subtract-calculator/blob/main/work/src/test_andandsub.v  

技育博2022に参加した

渋谷で学生IT団体が集まるらしいっすよ。そう聞いた自分は交通費も出るらしいし顔出してみるかくらいの感覚で応募フォームを書いたの思い出しました。

 

じっさい参加してみるとTwitterなどのSNSで見たことのある人がたくさんいておーってなりました。新規の方も含め、あってくださった方本当にありがとうございました。

 

また企業と会えるというのが魅力的でした。自分たちはコロナ時代の学生なので学科内でのつながりが希薄なのはもちろん、企業なんてかなり遠い存在にすら感じていました。しかし実際は就職活動は迫ってくるものだしそういった意味で企業のことを知ることは非常に重要です。学生が企業のことが遠い存在になったならその逆もまたありそうで企業も学生のことを知る機会が減ったのではないでしょうか。企業にとっても新卒採用など、かなり重要な部分でこういったマッチングがあると企業側も意欲的な学生と会えるのでお互いにWinWinですね。

 

RiSTのブースにはたくさんの企業、学生団体の方がお越しくださいました。今一度厚く御礼申し上げます。お話しできた企業さんや団体の方へ今後団体のほうからご連絡させていただく場合がありますのでその際はよろしくお願いします。また、逆にLT会のようなライトなものから勉強会、CTF主催などの件でのDMは大歓迎です。ぜひうちの団体のTwitterまでご連絡お待ちしています。(@realRiST)

 

今回このような素晴らしいイベントを開催してくださった運営の皆さんには感謝でいっぱいです。今後ともよろしくお願いします。短いですが参加記です。

 

 

pwnやる過程で読んできた記事の検索履歴掘り起こし

pwnの初心者です。こんにちは @ultrasuparaです。

- pwn / pwnable / Binary Exploitation
  - サーバーで動いているバイナリを攻撃するジャンル
  - 要はメモリ破壊  RTAのバグ技がイメージしやすい
  - Buffer Over Flow / Format String Attack / Heap Exploit / etc

 

book.mynavi.jp

これの1章と2章を徹底的にやる。これで十分やろ。

あとは常設やたまに開催されているCTFに参加すとかで。

 

**補助教材**

pwnの前にリバーシングを抑えといたほうがいいんじゃないですか?という突っ込みを受けましたので全体的に抑えられる記事を投下

 

yukituna.com


これを導入教材とした記憶。

pwnjump.hatenadiary.jp

 

0から始めるpwn
基本的なことができる人が何をしているか、どう手を動かして解析しているか見た。

www.youtube.com

docs.google.com

 

qiita.com

楽しいPwn入門 · GitHub

 

wiki.mma.club.uec.ac.jp

raintrees.net

sig.tsg.ne.jp

これの後半部分はpwnの内要に合致する。

www.ipa.go.jp

qiita.com

hama.hatenadiary.jp

pwnの有名な脆弱性とその攻撃手法のまとめについては以下のブログのリンクを1つ1つ参考にした。

kataware.hatenablog.jp

rkx1209.hatenablog.com

FSB

ptr-yudai.hatenablog.com

kataware.hatenablog.jp

rkx1209.hatenablog.com

HEAP

kataware.hatenablog.jp

kataware.hatenablog.jp

kataware.hatenablog.jp

kataware.hatenablog.jp

kataware.hatenablog.jp

追記ここにもだいたいまとまってた Learning ARM Exploit Development

www.alicemacs.com

ROP

ywkw1717.hatenablog.com

 

以下の3つを重宝した。

inaz2.hatenablog.com

smallkirby.hatenablog.com

ptr-yudai.hatenablog.com

 

ここからしたはおまけ

 

www.slideshare.net

www.slideshare.net

www.wivern.com

www.elastic.co

だいぶ古い資料だけどこれいい。

https://www.nic.ad.jp/ja/materials/security-seminar/20041004/3-koga.pdf

harekaze.com

nanuyokakinu.hatenablog.jp

h-noson.hatenablog.jp

www.ninjastars-net.com

 

攻撃者が悪用できるlinuxコマンド一覧

gtfobins.github.io

 

web.archive.org

 

pwnと直接関係がある記事ではないが抑えといたほうが良いことが書かれている

低レイヤを知りたい人のためのCコンパイラ作成入門の「はじめに」と「機械語アセンブラ」まで

www.sigbus.info

 

応用

 

kam1tsur3.hatenablog.com

 

 

-seccamp全国大会2021まとめ-

B2が終わろうとしています。asuparaです。

 

オンライン開催でしたがやはり対面でやりたかった人も多かったみたいで........まあ、たしかに.....自分もです。今回のブログですがたくさん優秀な学生が体験記を書いてくれているようでしてその部分はその人たちに任せます。グループワークで内容の濃いことをしたのでそのことについて多めに触れつつどのようなことを自分たちでやったのかについて多く特筆していこうと思います。

 

はじめに ーセキュリティキャンプの紹介ー

この業界にとってはseccampは夏の季語だそうで。セキュリティの業界のみならず業界全般への登竜門としてu-22の学生を対象にプロが集中講義を展開する人気のイベントです。セキュリティキャンプに興味をもってくださった学生の皆さん!ぜひ公式のサイトをご覧になっていろいろ見てみることを勧めます。メインの選択コース、集中コースに加えジュニアやネクストなど幅広い年齢層の方が参加できるようになっています。また、全国大会のみならず地方大会も開催されています。個人的には、参加するしないにかかわらず興味があることに自分の手を動かして考えてみることができるのかということが技術者としては大事なのかなと思ってます。もしかするとそういう姿勢が応募のときに生きてくるかもしれないです.......皆さんの参加を

 

 

ー謝辞ー

応募して参加することができたこと、これは非常にスタートとしてかけがえのないいい体験となりました。全国大会2021の参加者の皆さん、講師チューターの皆さん、協賛企業の皆さんに厚く感謝します。

 

--全体のセッションやグループワークについて--

f:id:karasuparan:20210817064436p:plain

初日は偉い人とかの講演をきいたりグループワークしたりって感じでした。

早速やらかしたのですが......

 ということでしょうがないのでスマホで開会式に入ることに........

 参加者にいじられるなど

 

まあ、そんな茶番は置いておいてですね.........普段どおり勉強しているだけでは聞くことのできない法律の話であったりとかイベント開催の裏側の話などいろいろきけたのでよかったと思います。そういった人を呼ぶのはかなり難易度が高いことを聞かされ認識を改めました。キャンプはすごい人がごろごろいるので感覚がおかしくなります。

 

LT大会は何を言っているのかよくわからない人もいたような.....( ´∀` )面白いものもたくさんありました。

 

--グループワークでやったこと--

グループワークのメンバー 

@sitositositoo   @iwashiira  @ultrasupara 他 

現在グループワークとしての取り組みは一旦終了しています。今後はグループワークとしてやったことを実践の場で生かしていきたいと考えています。具体的には個人やたまにはここでやったメンバーを募ってCTFに参加してみるということです。しかしこの場でやった内容はコンピュータサイエンス的なバックグラウンドをもったものであったのでこれらをもとに今後、個人が研究などの学術的な活動や既知の脆弱性調査などにも生かしていけものにも応用できると考えました。

 

--iwashiira先生によるpwn講義--

2回にわたるセッション7時間 でpwnの演習(iwashiira ctf)をしていただきました。すべての内容は一般に公開できるものではありませんが演習の概略を書き記しておきます。詳解セキュリティコンテストという最近出た本のpwnをいちから読み進めていくための補助的な役割にもなり得るものだと先生はおっしゃっていました。これを読むとどの手順で勉強すればいいのかの大まかな流れが示されるので参考になることもあるかもしれないです。

www.amazon.co.jp

 

流れ

1.PCの物理的な構成

この章ではコンピュータをつかさどる構成としてCPU、Memory、補助記憶装置、マザーボード、電源といったものが電気的につながっておりそれらがどのようにデータの読み書きを伝え保存しているのかということを学びました。通常の自作PCの構成やノートPCや物理サーバーの構成を見ながらどう有機的につながっているのかについてみていきました。(例えば記憶に関する項目では記憶回路を半導体レベルで見るということまではしていませんが自分が勉強していることとかなり密接につながっており今後もこの分野の理論は理解を煮詰めていきたいところなのでいろいろとまとまったらこれらに追記してまとめたブログをあげたいと考えています) pwnで物理的なデバイスの話からする人に初めてであったというのか感想ですが実際はこれが本当の形かなと思いました。もしハードをやっている人に低レベルなソフトウェアに興味をもたせるときにこのような導入をしたら興味をもってもらいやすいんだろうなという感想を抱きました。

 

 

2.コンピュータアーキテクチャ

コンピュータにおける基本設計や設計思想として命令セットアーキテクチャがあることを大きく取り上げx86-64命令セットアーキテクチャの特質するべきもの(レジスタの形式ごとにどの数値を入れることができるのか、プログラムカウンタ、RAX,RCX...といったものがアドレスでありどのような役割を持つか)についての思考の整理をしました。それとともにx86-64命令セットアーキテクチャ機械語と1-1対応するアセンブリについて学ぶとその仕組みがわかることについて理解しました。コンピュータアーキテクチャに関しては情報科ではどこでも開講されるような科目ですがここではpwnを理解するためのものとして最小単位の必要理解をコンパクトにまとめられておりかなり良かったと感じました。余談にはなりますがうちの教授激推しの教科書、パターソン&ヘネシーの紹介を添えておきます。

www.amazon.co.jp

 

 

3.アセンブリを見る

簡易なプログラムのwatch.s(仮)を見ながら実際の機械語がどのように動くのかについてみた。実行して生じたelfファイルをobjdump、hexdumpで観察した。radare2を使ってみた。(ここは好みでgdb-pedaを使ってもいいがというか自分はそうだが先生はradareを好んでいるようです。やったことをめちゃくちゃ薄く書きます。

 

gcc watch.s -o watch -no-pie  でファイル生成 

watchが生成された!

objdump -S -M intel watch

main以外にもたくさんコードがあって機械語と命令コードやオペランドとの対応が1-1であることについてみた。

hexdump -C watch 

べタなバイナリの観察。ファイルの中身(16進数)とそれに対応するASCII コードの見方について学んだ

 

radareでの操作

r2 -dA watch

s main でメイン関数部分を見る。pdfで表示

db <main address>ブレークポイントを張る。

dc でhit breakpointさせて実行をいかせる。

v! RIP(プログラムカウンタ)をだしてそれをもとにメモリアクセスをしにいって機械語を呼び出す一連のながれを観察した。

x86_64のアーキテクチャは可変長のものであり1byteの命令もあればMAXで15byteの命令もあることについて視覚的に確認できた。

 

特に面白かったのは命令ごとの違いでのbyte数の違いで大きなプログラムを設計するときにこのような微妙な数の違いがソフトウェア全体に与えうる影響について考察したことですかね。例えばcmpとtestは同じような指示を与える命令だが4byteと3byteといった違いがあることについてみたりした。

 

 

4.スタックというメモリ構造

スタックを理解することはpwnにおいてもかなり重要な問題であるのでかなり重点的に扱ったと思います。データ構造やアルゴリズムの内容ですね。スタックは個人的にも実装したことがあるのでやってみると一番よくわかると思います。実装例↓

github.com

 

pwnにおいて大事なのはRSPとRBPレジスタを使っていることでありPOPとPUSHというRSPを扱う専用の命令があることである。CALLやRETが関数に関連がある命令でありスタックに影響を与えること。アドレスは大きい->小さいのほうにメモリの構造が動いているということなどを整理した。

 

 

5. C言語の関数などの機能がどのように機械語で実現されているのか

stackのプログラムは

f:id:karasuparan:20211214031957p:plain

であるとして gcc -o stack stack.c -no-pie -fno-stack-protector でstackの実行ファイルを作成する。

f:id:karasuparan:20211214025919p:plain

上図を基に考察すると、ローカル変数の上にsumの引き数ぶんの領域をとる。call命令によってメイン関数に戻った際にのちに実行したいRIPの値をスタックに格納する。メイン関数からsumへのサブルーチンへの実行が移るわけだがただ実行するだけだとRIPの値が書き換わるだけであるのでサブルーチンを実現するときに元のルーチンに戻ってくるような所作ができるようにするためである。次にRBPの値もスタックに格納する。(push RBP )スタックポインタの指している値を8小さくすることによってスタックの領域を増やすことによってこれを実現する。さらに小さくしてsum用のローカル変数の値をスタックに追加する。(func1)このようにスタックを組むことでleave,retして元に戻せる過程の追跡を行った。

 

 

6.OSの機能を呼び出すシステムコール

システムコールカーネルの機能をユーザーモードから使うために発行するものである。Cの共有ライブラリの関数はその中でシステムコールを呼んでいる。例えばprintfではWriteシステムコマンドを呼んでいる。今回はHello World! を表示するようなsyscall.sの読解をした。(r8とrbxに特定の値を入れてpushしてsyscall。exit 0 で終了してsyscallしたもの)生のデータをradare2にかけてやるとその動きがより詳細にわかった。また、straceコマンドを実行してやるとどのようなシステムコールを呼んでやったのかが一目で分かるように表示してくれるのでそれで改めて呼び出しの観点からプログラムを見るということをやった。

 

 

7.ELFファイルとその構造、それにまつわるソフトウェア群

.c(ソースコード)->.s(アセンブリのコード)->.o(オブジェクトファイル)->実行ファイルの流れで変換できるがその際、コンパイラ(cc1)、アセンブラ(as)、リンカというソフトウェアがその操作を与える。すべてgccによって操作を与えることができ #includeなどを指定すればコンパイルの前にプリプロセッサによるプリプロセスが走る。cc1をとりあげ広義の意味のコンパイル、狭義の意味のコンパイルについて学習した。オブジェクトファイル(ELF形式)まではファイルの中で完結しておりリンカによってリンクすることによって1つの実行ファイルにまとめることができることについて学習した。ELF自体はその実態は0と1のバイナリでありプログラムによって解釈されるファイルでありファイルのどの部分に何の情報が入っているかがわかるように決まったフォーマットをとっている。ELFは様々な情報を含んでいるのでその内容を理解するにはコンピュータの動く仕組みも理解する必要がある。

 

ELFの構造は以下のとおりであることを学んだ。

• ELFヘッダという全体の情報を管理する領域がある。
• プログラムヘッダの配列としてプログラムヘッダテーブルが存在し、プログラムヘッダはセグメントというものの情報を保持している。
• セグメントはローダによってロードされる際の単位であり、ローダ用の区分である。
• セクションヘッダの配列としてセクションヘッダテーブルが存在し、セクションヘッダはセクションというものの情報を保持している。
• セクションはリンカによってリンクされる際の単位であり、リンカ用の区分である。
• 普通、プログラムヘッダテーブルは存在していればELFヘッダの直後に存在し、セクションヘッダテーブルは存在していればファイルの末端に存在する。 

 

もっと詳しいやつ↓

smallkirby.hatenablog.com

 

方法1  readelfコマンドで実際に見てみた

readelf -h filename          readelf -S filename        readelf -l filename などで確認した

 

方法2  Ghidraから眺めてみた。

GhidraについてはC3講義Zero to Malware Analystで使い方のレクチャーがあったがそれを実際にpwnを考えるときにも使ってみた。

 

8.pwnの中身  (ツール、攻撃の種類、CTF問題演習)

Stack based Buffer OverflowReturn Oriented ProgrammingFormat String BugといったpwnableのCTF問題で頻出の問題の攻撃手法について勉強した。それぞれの攻撃や脅威がどのようなものなのかについては、ほかの人もたくさんブログを書いていると思うのでそちらのほうを参考にしてください。これらの頻出問題のCTFを解くことによって実際の手の動かし方を学習しました。またCanaryやRelocation Read-Onlyなどのセキュリティ機構について学習しました。pwnではいちいちradare2で解析したものを手打ちして解くこともできるけど問題がより複雑になると打ち間違いなどの思わぬミスを招いてしまう可能性もあるのでpwntoolsというpythonのライブラリを用いたコードの書き方をライブコーディングしました。かなりためになる勉強会でした!

 

かなりためになった資料

qiita.com

ここに上で示した攻撃の色々はまとまっています

furutsuki.hatenablog.com

ptr-yudai.hatenablog.com

 

これでグループワークでやったことの紹介は終わりますがこれは概略を示しただけですのでもっと詳しく書き記したものを別のブログにて更新していきたいと考えています。pwn初心者もいた中でよくやったほうなのではないでしょうか!!!!!!!!pwn分野に関する学習の継続の過程が作っていければと思います。

-------------------------------------------------------------------------------------------

 

自分が受講したもの

f:id:karasuparan:20210817071003p:plain

 

f:id:karasuparan:20210817070450p:plain

A2 任意USBデバイス開発実験

かなりの低レイヤーに関する実験でした。生の通信をするコードを見るという体験はなかなか斬新なものだったと思います。Wiresharkは高レイヤー、Arduinoを使ったら負けということで自分の手をうごかして開発ボードの上でどう動くのかを見る。動かすソースファイルはCだったですけれどもそれがだす信号は回路的にはどうなっているのかについてみるということをしました。動かした内容も多岐にわたるものでしてLチカから始まり4*4のキーから制御を送った信号を見たりマウスを制御したりと楽しいものが多かったです。自分でオリジナルの制御を与えることができるとよりその面白さがわかる実験だったと思いますね。

 

f:id:karasuparan:20210817071806p:plain

C3 Zero to Malware Analyst Part1/Part2

 これは大人含めいろんな人が聞きたい講義なのではないでしょうかね.......自分はGhidraのような実践的なリバースエンジニアリングツールを使った実践的なマルウェア解析はやったことがなかったのでその基本から聞くことができたのは激アツな経験でした。ざっと昨今のマルウェア関連の脅威についての説明があった後に「マルウェア」の分類やタイプに関する知識の整理をしました。XORなどのエンコーディングRC4などの暗号アルゴリズムマルウェアと深いかかわりがあることについて知りました。まとめると一般的によく使う手法について学習しました。どのように解析するのかについて表層解析、動的解析、静的解析をあげてケースバイケースでどのようなときにこの手法(ツール)を使うと有利・不利かなどについて学習しました。それで今回は静的解析を主に取り上げGhidraを用いての解析方法やテクニックについてすすめました。静的解析は幅広い技術的知識が必要ということで事前課題ではx86_64アーキテクチャやCやアセンブリに関して、Windows OSの内部情報の基本事項やツールの使い方などについてを講義で取り扱いました。それを使ってサンプルでのGhidraを使った実践をグループに分かれてやったりしました。自分の将来的な目標的にはCTFのpwn問題を解いていくときにradare2を使いつつGhirdaをきちんと使って解析ができることですかね。講師のかたが著者の本「Ghirda実践ガイド」をいただいています。途中までしか読んでいないので春休みにあったら残りの部分を読んでみて自分が挙動に興味があるプログラムや与えられたサンプルでもCTFでも自分が納得がいくまで動かしてやってみようと思います。

 

f:id:karasuparan:20210817072225p:plain

A6 チップレベルでカスタマイズができることで見える世界の体験

これに関しては筆者が学校でやっている内容とのかぶりがありましたね。ソフトウェア的な側面としてコンピュータを見るときOSやコンパイラなどのソフトウェア主体で見ていくと思うがハードウェア主体で眺めてみると集積デバイスのことになります。ムーアの法則の話がありましたけれどもここで例を挙げるとiPhoneXののTr数が43億個でプロセスは10nm、iPhoneXsのときのTr数が69億個、iPhone11のTr数が85億個、この時のプロセスは7nmという感じでこれらはムーアの法則の線形性に従います。面白かった話としてはソフトとハードの乖離ができつつあるという話でそこには越えられない壁があるのかという話でした。プログラムがただしく動くには動かすためのソフトウェアのみならずトランジスタレベルでのハードウェア設計が確実なものでありたいのでやはりソフトとハードはつながっています。しかし、両者の専門性はかけ離れており...といった興味深い話でした。コンピュータの複雑化やブラックボックス化に伴う脆弱性としての側面がintel のCPUにもでてきていたーといった話しがありました。

hardware.srad.jp

ではその気持ちがわかるためにはどうするのかという話でCPU自作の話があった。HDLで論理回路を書いて高位合成して回路を作るといったやり方の全体像を示された。私はFPGAにRTL記述したことがあるがその時と同じようなもので、論理設計とシュミレーションしたものを論理合成して配置配線することによって作ることができるということをシミュレーションしてみた。

 

f:id:karasuparan:20211213155239p:plain

C7 オフェンシブ・セキュリティを「研究」する

本講義では学術寄りにサイバーセキュリティの研究をするということはどういうことかの基本から文献の検索方法など聞きたい話をたくさんパック詰めにしたものを提供していただいた。オフェンシブセキュリティのホットなキーワードとして「サイドチャネル攻撃」がある。もともとサイドチャネル攻撃は電磁波解析などハードよりのものだが近年はそのレイヤがソフトウェアのさらにWebのレイヤにも浸潤し始めているということでBugBountyの対象になることも多いという。このセッションでは実際にサンプルのサイトを用いて認証に関するクイズ?を実施して解析方法を考察してみたりした。Webにおけるサイドチャネル攻撃に関してどういうものか知らなかったが実際に手を動かしてみたらすんなりと腑に落ちる内容だったので面白かった。CTFなどでは攻撃手法というものがあってそれを勉強して実際に解き方があって問題をとくがあるが研究では「攻撃があってそれはどのような事例に活かせるものか・解決するには」ということを考えないといけないのが難しいところだと思った。この順番での発想は研究をしたことがない学部二年生の私には難しいものであり実際にこのような研究でいかされましたという研究紹介を受けたり論文を見てみて研究者のすごさがわかった。しかしすべての研究には基本的な技術に基ついた着想があるはずだというのも響いた。今回は「研究」の世界の全体外観が少し分かったし自分が思っていなかった大事なことがたくさん出てきてよかった。

 

D1-1 1-2 1-3   AIシステム・ハッキング入門

Long (8/10-8/22-9/19)で3回にわたって横断的に実施

トラックホームルームでセキュリティキャンプに参加した理由といった話しがあったと思うが「CTFなどでからは学習できない部分の実践的な技術に触れることができる」というものがあったと思う。それを一番実感できたのがAIシステムハッキングに関する横断的な話だった。

 

1日目ではAIを利用した攻撃として事前学習モデルの汚染(Attack)をしました。そのための機械学習フレイムワークがありDeeplearningに特化したTensorflowについて基本機能をGoogle Colabを用いた演習を行うことによって習得した。任意の計算や関数を分類器の層としてあつかうことができるLambdaレイヤに任意のコードを埋め込んで攻撃するデモの実験をした。また、Tensorflowはおおくの充実したAPIを提供しておりそのファイル操作のAPIを悪用した攻撃のデモを実践した。

 

2日目ではまず入力データに微細な摂動を加えることによってご認識を誘発する敵対的サンプルについてその理論を学習した。簡単にいいかえると「AIをだます」とはどういうことなのだろうかということである。敵対的サンプルを作るのに必要なニューラルネットワークや誤差が小さいとはどういうことか・大きいとはどういうことかを理解した。Black Box Attackを実現させるための必要条件とその手法としてのJacobian-based data augmentationについて学習した。ここまで難しい言葉が並んだが要は「AIに誤認識させるための工夫」の過程を一つ一つ見ていったということができる。敵対的サンプルを作った結果の侵入例として顔認証システムを攻略した。ではこの脅威に対してどのように対策していこうか、それは「多層防御」による観点である。多層防御とは下の文献によると

""Defense in depth is the concept mof protecting a computer network with a series of defensive mechanisms such that if one mechanism fails, another will already be  in place to thwhat an attack.""

 

と述べられており、その要件はメカニズムが1つkillしてもほかの要素で脅威の対策を補完できるような構成を組むことである。対策の例としてAdversarial Trainingやフィルタ処理の観点を学習した。ほかの観点についてもキーワードを提示していただいていたので自分なりに調べた。結果的にわかったことはこの要因は状況ごとに変わってくるので難しいということである。

  1.  

3日目はDeepfakeについて本格的に学習しFake動画を作ってコンテストを開催した。e-KYCシステムというオンラインの本人確認システムについてbypass実験をした。また、コンテストでの結果をもとにDeepfakeへの対策について考えた。しかしこれについて自分は個体差による違いがあることが難しい問題だと感じた。システム自体の脆弱さは生体情報と連携するなどソフトウェアとしての機能追加や向上をはかれば改善されるケースもあるがそれだけでは解決しない問題を感じた。総じてAIシステムのセキュリティはまだまだ課題が多くその解決を図るのに難しい部分もあるがこれから時代が進歩して技術が一般に普及してサンプル数が増えていくことによって解決することができることもあるだろうという推測を立てた。

 

多層防御について↓

www.sans.org

 

講義の理論部分の内容のほとんどは講師が執筆したこちらのブログに記載されている

jpsec.ai

 

おわりに

勉強したことがたくさんありました。高度な技術にガンガン触れたし普段生きてて出会えない人たちに会うことができた。しかし、技術的な側面だけでなく精神面でも学んだことが多かったので書き出しておきます。

 

1.脅威解析をやろうという人でも実装力はとても重要

2.いろんな暗号アルゴリズムを知ること、そのためには数学からも逃げない

3.主体的にやっていく人はやっぱり強い、分野の継続と深堀りを

4.同じ興味や関心を持っている仲間は大切

5.謙虚な姿勢で取り組むことが大切

 

結果的にたくさんの技術に触れて・知って感じることが多かったので参加してよかったと感じています。これで興味をもった人は応募してみてください。

 

修了証書をゲット

 

 

 

 

RSAを手計算する課題とてもかったるかったので実装した。[python]


このブログは提出したものの改良版です。個人情報や講義に支障がない範囲での公開としていますので至らない部分もあるかもしれないです。軽量版でお送りします。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

問題文 

RSA暗号の数値例を作成しなさい。 
2つの素数は、いずれも10進数2桁とする。なお、10進数2桁の素数には、11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 がある。 
これらから自由に選択しなさい。選んだ素数に対して、暗号化と復号化に必要なパラメータの導出過程を示しなさい。平文M=127を暗号化する過程を示しなさい。 
上記で得られた暗号文を復号する過程を示し、元の平文が得られることを確認しなさい。計算には、電卓やPCを利用すればよいが、計算の過程が分かるように、適宜、途中の計算結果を示すこと。なお、PCを利用する場合、通常の整数演算を利用し、多倍長整数演算は使わないこと。

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

解答 

とてもとても手計算などではやってられないと感じましたので一般化する意味も込めて当該内容のスクリプトを記述しました。pythonで書きました。プログラムで書くとレポートは数学の手計算をする手間がゼロになってコードの解説を添えることで完成になるという斬新な感じに仕上がりました。

 

import math
from math import gcd

""" ここでは引数に与えた最小公倍数を求める """
def lcm(p,q):
    return (p * q) // gcd(p, q)

"""ここでは与えられた2つの素数p.qから秘密鍵と公開鍵を生成する"""
def generate_keys(pq):
    N = p * q
    P = lcm(p-1, q-1)

    for i in range(2, P):
        if gcd(i, P) == 1:
            E = i
            break

    for i in range(2, P):
        if (E * i) % P == 1:
            D = i
            break

    return *1

""" 公開鍵=public_keyを使って平文=plain_textを暗号化する """
def encrypt(plain_textpublic_key):
    E, N = public_key
    plain_integers = [ord(char) for char in plain_text]
    encrypted_integers = [pow(i, E, N) for i in plain_integers]
    encrypted_text = ''.join(chr(i) for i in encrypted_integers)

    return encrypted_text

""" 秘密鍵=private_keyを使って暗号文=encrypted_textを復号する """
def decrypt (encrypted_textprivate_key):
    D, N = private_key
    encrypted_integers = [ord(char) for char in encrypted_text]
    decrypted_intergers = [pow(i, D, N) for i in encrypted_integers]
    decrypted_text = ''.join(chr(i) for i in decrypted_intergers)

    return decrypted_text

""" ユニコードエラーが起こらないように文字コードutf-8にそろえておく """
def unitetext(encrypted_text):
    return encrypted_text.encode('utf-8''replace').decode('utf-8')

""" ここから下がmain関数 """
if __name__ == '__main__':
    public_key, private_key = generate_keys(1729)

    plain_text = '127'
    encrypted_text = encrypt(plain_text, public_key)
    decrypted_text = decrypt(encrypted_text, private_key)

    print(f"""
秘密鍵{public_key}
公開鍵: {private_key}
平文:【{plain_text}
暗号文:【{unitetext(encrypted_text)}
復号後の平文:【{decrypted_text}
"""[1:-1])

 

計算をするのでmathモジュールをインポートしてきました。gcdに関してはmathの中に提供されていたのですがlcmに関しては見つからなかったので自ら関数定義してやって作りました。p*q=gcd(p,q)*lcm(p,q)が自明に成り立つことから式変形したやったものを条件式に入れてやることでできますね。整数をリターンしてやるだけできわめて簡単に実装できました。//は切り捨て剰余演算子で除算結果にmath.floor(x)つまり x 以下の最大の整数(Integral値)を返します。

 

docs.python.org

docs.python.org


次のブロックでは2つの素数から公開鍵と秘密鍵を生成する関数を示しています。レジュメのアルゴリズムを素直に実装しています。返り値は公開鍵と秘密鍵のタプル型で、それぞれの鍵は 2 つの整数のタプル型で表現しました。

 

encrypt 

公開鍵を用いて平文を暗号化しています。文字列plain_textを整数値であるE,Nを使って計算したいので文字列をリスト変換してやります。その部分がord(char)の部分です。1 文字の Unicode 文字を表す文字列に対し、その文字の Unicode コードポイントを表す整数を返します。pow(base,exp,mod)では base の exp 乗に対する mod の剰余を返します。 powはそういう組み込み関数です。これは暗号化に際しては必ず必要な部分です。plain_text^E mod N の適用を意味しています。最後にchr()関数でUnicodeのコードポイントが整数である文字を表す文字列を返してやります。変換したものを連結して文字列生成をしています。 

 

decrypt 

秘密鍵を使って暗号文を復号して平文に戻しています。基本的には暗号化したときと同じ作用を与えてやるだけです。 

 

docs.python.org

 

qiita.com

 

docs.python.org

 

ここからはおまけです。すべての場合において暗号化したものの文字がどのような形式になるのかの予測がつかないことからprint()での予期せぬエラーの回避を目的にunitetextという関数を作っています。つまり”書式の強制的な統合化”を意味しています。 

 

今回、問題文の中に与えられていた2つの素数は17と29を選びましたのでmainのgenerate_keys(p,q)のp,qにその二つを与えてやりました。plain_textすなわち問題文の平文M=127を設置しました。暗号文は平文を公開鍵で暗号化してやったものです。復号文は暗号文を秘密鍵で復号化してやったものです。最後はそれぞれ関数定義してやったものを一気にprintf引き出してやりました。 

f:id:karasuparan:20210603024959p:plain

できていることが確認されました。平文を暗号化して復号することもきちんとできいます。 授業に参加している皆さんは自分が選んだ数値の部分を変えて遊んでみると提出した課題があっているのかどうかの確認ができます。なので遊んでみると楽しいかもしれないです。

 

注、このブログでの回答は最終版ではなく簡易版なので今後追加していく可能性があります。

 

*1:E, N),(D, N

2021/6/7 RiST/LT pwn入門以前の事前課題

RiSTのみなさん!こんにちわ!そうでない人も!!ただいまーーあすぱらだよ!

 

6月7日にLTやるよー。ということで内容はpwnについて扱おうと思っておりますがもしかしたら一年生にとってはハードルが高いかもしれないと思ったので事前課題を準備します。これは絶対的なわけではないですがだしてくれるとうれしいです。二年生も復習になるでしょう。

 

PDFでもテキストでもdiscordのDMにでも送ってくれたらみんなの分見ます。LTでは提出してくれた人の解答を説明に採用したり比較したりします。みんなのちからで新しいLT形式の実現を願いたいところです。

 

C言語には脆弱性があります。もともと堅牢なシステムソフトウェアをつくるためにできた言語ではありません。C言語は直接メモリを扱うことができます。なので勉強になります。学校でも採用されているのはそういう理由なのかもしれません。しかし、その扱いの制御に対する手段はRustみたいに静的な挙動も、Javaのように動的な挙動もないというのが火種になっています。そんな根本部分にある古典的なセキュリティホールについて当日は探検していきましょう。

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

問1 スタックバッファのオーバーランが悪用するメカニズムについて説明してください。一つ攻撃例をあげてそれについて説明しても構いません。その際、例としてあげるならreturn-to-libc攻撃について説明してください。分量はどのくらいでもいいです。ひとことでもわかったところまででも....でもこれはメモリ割り当ての図を使って説明したほうがよさそうです。図やCのソースコード、文章を織り交ぜるとよりよいでしょう。

 

問2 Cにはたくさんのprintfがあります。printfはどのようなときに使うと安全ではないのでしょうか?説明できるだけやってみてください。ん?わかんない?しょうがないなあ....脆弱性のあるコードを一つ示してみるからそれを参考に考えてみるっていうのはどうよ.....???

>||

#include <stdio.h>

int main() {
    char buffer[1024];
    gets(buffer);
    printf(buffer);
    printf("\n");
    return 0;
}

||<

 char gets %s %x %n について調べてみましょう。それがヒントです。

 

問3 Canaryとはなんでしょうか?言葉だけでも図を使ってもいいです。簡潔に説明してみてください。

 

問4(追加問題)Canaryはバッファーオーバーフローしたときにプログラムがクラッシュするのを防ぎますか?

 

 

たくさん待ってます!!!!忙しいとは思いますが。。。あすぱらはいつでもいいのでとにかく待ってます。

 

 

 

 

2021/4/17 京都

旅ブログを書くとかいう新しい視点を得ました。

 

なんだかんだ記事を書くとか行っておきながら全然かかない人になっていました。そもそもあんまり文章を書くのは好きではありませんがこれから旅ブログの方もガンガンやってかいていきたいと思います。

 

この日は土曜日でして朝から空いていましたが朝はあいにくの雨.....ということで夕方からのおでかけになったのであまり回れませんでしたがそれでもよるおそくまで京都市内を堪能することができました。

 

 

 はい、16時ごろに京都駅に降臨しました。

 

 

京都駅の烏丸中央口から奈良線が走る方面に歩いていきますと京都駅の次の駅である東寺駅が見えてきます。そこからちょっと奥にむかっていくと東寺があります。五重塔がきれいでした。

 

 

こんな感じで......そして9条のあたりまでちょっと下ってお散歩した後に4条のほうのとある飯屋で腹を満たそうではないかと思ってちょっと遠いんですけど歩いていくことにしました。そしてついた先は.........

 

 

 京都の四条にぼ!!!!!!!

 

にぼに関しては滋賀県草津市にもあるのですが京都の店にしか味曽のにぼがないのです。それを食べに来たのです!!!食券を買ってと.........

 

 

野菜マシマシにしてしましました!!!。この迫力!!!!

ちょっとたべきれなかったのでのこしてしまいました。残念10代のころは食えたのかもなーなどと思ったり...........

 

 

四条から下のほうに下って行ったんですけど河原町あたりでぶらぶらしたいなーって思ってこの辺を歩いていました。めちゃくちゃ人が多かった.........

 

 

鈍器の前を通るなど........

 

 

この辺を通り.......

 

 

犬も歩けば国宝に当たるーということで八坂神社の前を通り......

 

 

清水のほうに向かっていきました。一回この坂を上るのがしんどかったです

 

 

坂を上った先に美しい景色が待ってくれていました。ちょいばずりしてますね......

 

 このへんは嫌というほど国宝の神社があります。ここから京都駅方面に逆戻りです。

 

 

さてはて、京都市内を17キロもあるきました。めちゃめちゃ大変だったけどいろんな寺社や美しい景色が見れてとても楽しい一人旅でした。雨も上がってくれて運がめちゃめちゃよかった........