chouett0's note

掃きだめ的なsomething

UNIXとLinuxとBSDと色々

はじめに

この記事の内容はUNIXLinuxBSDとその他色々なOSの違いや成り立ちを忘れないよう、自分なりに理解するためのまとめです。新たな発見も無ければ間違いが多く含まれていると思われます。

UNIX

UNIXとは、言わずと知れた現在にUbuntuRHELなどのLinuxの誕生に影響を与えたOSです。1969年に米国のAT&Tベル研究所で開発が行われ、1971年に初めて公開されました。当時はアセンブラ言語での実装が一般的であったため、初期のUNIXアセンブラ言語で記述されていましたが後にC言語で改めて実装がなされました。オペレーションシステムを高級言語で記述するという試みは、先駆的であり他のプラットフォームへの移植をようにしました。
UNIX高級言語で記述された初めての言語」と言われますが、実は最初はアセンブラ言語で実装されていた、と言うのは初耳でした。さらに、当時では高級言語でOSが記述されるという事自体が一般的ではない(と言うよりもCの実装が今より使える言語ではなかった?)と言うことも意外でした。

UNIXの誕生にはさらに深い歴史があり、1960年代中ごろにマサチューセッツ工科大学ベル研究所、General Electric(GE)がGEのメインフレームコンピュータ用に開発した「Multics」というタイムシェアリングシステム、つまりは複数ユーザで様々な処理を行うことができるシステムを共同開発していました。しかし、革新的かつタイムシェアリングシステムという様々な処理を行うというコンセプトからわかるように、機能が増えていっていくに比例してその複雑さは増す一方となりついにはベル研究所Multics開発から離脱します。そこで、よりシンプルなシステムを開発しようとして生まれたのがUNIXです。つまりは、UNIXMulticsの複雑さを複雑さを解消する目的で開発されたということです。
このことから、UNIXMulticsの影響を受けて開発されたのだろうと解釈しました。また、「UNIX」という名称の由来も初期のUNIX、このころは「Unics」というシステムはMulticsと違いシングルタスクでのみしか動作できなかったのでMultiの逆で単一という意味の「Unit」から生まれたようです。 余談ですが、UNIXAT&Tの様々な事情によりソースコードが公開され、大学や企業に広まったようです。

GNU

初期のUNIXの公開から約10年後の1983年にリチャード・ストールマンによって、「フリーソフトウェアのみで構成されたUNIXの完全互換ソフトウェア」を開発するという目標の元作り出されたGNUは、ライブラリ、コンパイラテキストエディタUnixシェル、Windowシステムなどを備えていたものの、低水準の要素であるデーモンやカーネルデバイスドライバといったものは利用できなかったようです。後にLinuxを世に送り出すリーナス・トーバルズは、GNUカーネルが利用できなかったこともLinuxを開発した要因の一つであると述べています。
この記事を書くまでGNUについて詳しく調べてみたことがなかったのですが、GNUはOSでありLinuxとはまた違ったコンセプトで開発されたということがわかりました。さらに、LinuxUNIXを無料で利用するために誕生したという話を聞いていたので、意外なものが関係しているのだなと思いました。

BSD

1970年代後半から1980年代にかけて、カリフォルニア大学バクレー校のCSRGはUNIXの派生版としてBSDを開発しましたが、UNIXの利用者のライセンスを制限する、つまりは現代でいうところの著作権のようなものの関係がありBSDを公開することができなくなってしまいました。そこで、ライセンスに関わる部分を削り必要な部分を書き換えました。さらに、386で動かすコードを補って1992年にウィリアム・ジョリッツによってリリースされたのが386BSDであり、NetBSDFreeBSDの祖先となるシステムです。当時、現代的なマルチプロセスやメモリ保護などの機能が実装できる安価な32bitパーソナルコンピュータが普及され始めたこともあり、BSDのようなUNIXの移植が行われるようになりLinuxの開発にも影響しました。 BSDの成り立ちが私の中で一番あいまいで、BSDUNIXの関係性がイマイチ理解できていませんでしたが 、BSDLinuxの開発にも影響していたということは知らなかったのでなるほどなと思いました。また、この頃から今のようなPCが徐々に世に出ていくと考えるとなかなか面白くもあり時代が変わっていくのだなと感じます。

Linuxの誕生

上記BSDでもあるように、1990年代には比較的安価で買えるIntel 80386CPUを搭載した32bitPC/AT互換パーソナルコンピュータが普及し始めていました。その当時ヘルシン大学の学生であったリーナスはオペレーティングシステムについて強い好奇心を抱いていました。そこで彼はその安価なコンピュータを使用してUNIX互換の動作をするOSを動作させたいと考えますが、商業UNIXは高価であり、ここでは登場していませんがMINIXという教育用のOSは制限が多かったため、彼の思うようにはいきませんでした。そこで、自作のターミナルエミュレータファイルシステムなどのUNIX互換APIを実装して独自のOSカーネルを開発しました。これが後のLinuxカーネルになっていきます。
Linuxの開発はMINIX上で行われていたため、MINIXで動作するソフトウェアはLinuxでも動作可能でしたが後にLinux上でLinuxの開発が行えるようになると、MINIXコンポーネントGNUのプロダクトによって置き換わっていきました。
当時のLinuxの実装は単純であり他のUNIX互換のシステムと比べても見劣りするもので、機能面でLinuxは劣っていたものの自由なUNIX互換カーネルを利用でき、かつライセンスなどの問題が発生しないシステムは当時Linuxのみであった。
当時の、PCで動作するフリーのUNIX環境を求めるユーザたちの多くはMINIXを利用していたため、リーナスはMINIXメーリングリスト上でLinuxを公開しGPLの下で利用しました。ちょうど32bit PC/AT互換パーソナルコンピュータが普及し始めた時期であったためGPLでの改良が可能であったため、多くの開発者たちへ改良を促しました。その結果として開発者たちはLinuxカーネルをより良いものにしていくと同時に、GNUコンポーネントと統合する作業を行い、今のLinuxの形となりました。 今でこそ多くのOSの素となっているLinuxですが、当初は他のOSとは比較できないほど未熟であったのにも関わらずフリーかつLinuxの開発に影響を与えたGNUよりも早い段階で独自のカーネルを形にしていたというところを武器にして負けず劣らずな戦いを繰り広げていたというのはとても面白いですね。また、やはりOSSとしての利点として多くの開発者たちの手によってより良く改良されていったのも要因の一つなのかもしれませんね。さらに、上記BSDのライセンス問題を解消してリリースされたFreeBSDの公開が1994年11月であるのに対して、Linuxが公開されたのが1990年代前半というタイミングもLinuxの広まった要因の一つのように思えます。ここからは私の想像になってしまいますが、一般的に「Linux」と呼ばれているOSは、ここまで書いてきた「Linuxカーネル」を指すものでありRHELDebianは「Linuxカーネル」に独自のプログラムを追加したものなのではないかなと思います。

MINIX

Linuxでたびたび出てきたMINIXについても少しだけメモしておきたいと思います。
MINIXは、アンドリュー・タネンバウムによって作られたUNIX系のOSです。コンピュータ科学におけるオペレーティングシステムの教育という目的に重点を置いた設計で、企業ライセンスなどが無いように書かれたものでしたが、コンパイラにライセンスの問題がある、教育目的なので教科書として広く配布するために商業出版を必要とした関係もありライセンスには制限がありました。

まとめ

知っていたようで意外に知らないことも多く、特にUNIXが初めはアセンブラで書かれていたことに驚きました。
BSDの歴史やライセンスの問題、MINIXMulticsなどのあまり聞きなれないOSなど深く調べれば調べるほど様々な情報が得られ
よりコンピュータについての興味が生まれてくるので現代の技術も大切ですが歴史についても調べてみるのも良いかもしれないなと感じました。
特に、歴史の関連性などがまだ調べられていないのでいつか調べてみたいと思います。

参考文献

Unixの歴史 - Wikipedia

Linux - Wikipedia

ISUCON7で予選落ちした話

はじめに

先週の土日で行われたISUCON7に「インターネットは爆発しました」と言うチームで出場しました。
今回がISUCON初参加だったので参加しての感想とそのWriteupがメインの記事となります。

やったこと

僕の所属していたチームでは、3人中2人がサーバ担当、残りの1人でコードのチューンを行うと言う分担を行いました。
今回の競技ではメインで実行されていたアプリケーションはPythonのようでしたが、PHPに切り替えてチューンを行うことにしました。 補足として、PHPでのオリジナルコードのベンチマークスコアは「6000」でした。
やったこととして、まず始めに

パフォーマンス1000%UP!PHPでMySQLのDB処理を行うと重いときに行うパフォーマンス施策~基礎編~

この記事を参考にコード内のSQLクエリの命令をバッククォートで囲みました。
具体的には

SELECT UserName, Pass, ScreenName FROM UserList WHERE UserName = "hogehoge"

と言うようなクエリがあった場合

SELECT UserName, Pass, ScreenName FROM UserList WHERE UserName = "hogehoge"

と言ったように、テーブル名や要素名をクォートで囲むことで無駄な処理が減り、今回のように数千単位のデータを扱う場合では有効なようです。 さらに、今回のコードではいくつかの機能別に関数を定義しておきそれを別関数内で読んでいる構造をしているためなのか
DBからデータを取得する際に「*」で全フィールドを取ってきていたので、各関数で必要なフィールドを書き出して必要最低限の
データのみを処理するように変更しました。
ひとまずはこれでSQL部分のチューニングはいいだろうと考え、今度はコード全体を眺めていくと、「str_replace」と言う関数を使っている処理を発見しました。この関数でもまったく問題なく動作するのですが、どうやらこの関数はあまり速度的に速く無いようだったため
「strtr」と言う関数へ変更しました。

たったこれだけのことにかなりの時間をかけてしまいましたが、たったこれだけで最終スコアは20000代に跳ね上がり、約4倍の高速化を行うことができました。
それもサーバサイドのチューニングを一切行なっていなかったのでSQLがかなりのボトルネックになっていたのだろうと感じました。
もしこれでサーバサイド、そして記事内で触れていませんでしたが画像呼び出しがSQL内のバイナリを変換して画像化すると言う処理をしている影響で 見て分かるほど処理が重たくなっていたので画像の実ファイル化を行えていればもしかすると今回のボーダーの40000点も超えられたのかなと感じました。

まとめ

今回は予選敗退という結果に終わりましたが、初参戦ながらもそこそこ良い結果を出せたのかなと思いました。また、今までコードチューンを 行う機会がなかったので初めて聞いたことや初めて知ったことなどが多く久しぶりに真剣に取り組んだなぁと感じました。
最近はやたら周りがCTFで盛り上がっていて萎えr...勢いについていけなくなったのもあってか、ISUCON非常に熱いなと感じたので来年も参加したい。

Goバイナリ解析メモ

はじめに

chouett0note.hatenablog.com

前回の記事ではC, PythonそしてRustで「Hello World!」を表示するだけのプログラムをコンパイル等を行なって実行ファイルへ変換したものの解析を行いましたが、先日の某LTの懇親会にてGo言語で実装したものを解析してみたら面白いのではないかと意見をいただいたため、今回の検証を行いました。なお、今回も最適化を無効化した32bitバイナリを対象としています。

検証メモ

以下は検証を行なった際のメモとなります。

Stirling

f:id:chouett0:20171010231347p:plain
* Cバイナリに比べてやはりサイズが大きくなっている、ヘッダーとヘッダーとボディー感のNULL領域以外は相似していない
* 先頭付近に「Go Build」と言う文字列が存在する f:id:chouett0:20171010231505p:plain
* 途中から可読文字列が現れ始める(expやesiなど)
-> この周辺になんらかの処理が埋まってる?
f:id:chouett0:20171010231528p:plain
* 一部下毒文字列ではない文字列を挟んだ後にintやboolなどの型名らしき文字列が出現
* 後半に進むに従ってGoの関数と思われる名称が多く現れる
f:id:chouett0:20171010231608p:plain
* io.Writer, Sync.PoolなどのGoの要素がいくつか確認できる
-> 内部でGoの関数定義を行なっている?
* 「kernel32.dll」などのDLLファイルの名称が含まれている
-> 内部でバイナリに変換する際に利用?
f:id:chouett0:20171010231742p:plain
* Cで利用される関数名が存在する
-> 独自で関数を持っている?
* Goソース、Goライブラリを列挙した部分がある
-> コンパイル時に必要?
-> 1.5以降のGoではGoとアセンブリで実装されていると言う仕様から、その線が高い
f:id:chouett0:20171010231711p:plain

vxPEViewer

f:id:chouett0:20171010231918p:plain
f:id:chouett0:20171010232009p:plain
* ヘッダーに特に変わった点は無し
* ImportLibraryでは「winmm」「ws2_32」「kernel32」がインポートされている f:id:chouett0:20171010232022p:plain
* Stirlingを用いた解析時に現れたCの関数と同じ関数がインポートされている
* 直接関係のない関数を読み込んでいる点はRustと同じように思える
-> Goソース内でimportしたGoライブラリで利用されている関数で利用されているもの?
* なぜかWriteConsoleWはあるもののWriteConsoleAが読み込まれていない(他の関数ではどちらも読み込まれている)

Ollydbg, x32dbg

f:id:chouett0:20171010232320p:plain
* これまで同様初期化処理と思われるコードからjmpする
* WriteFile, WriteConsoleにBPを仕掛けるもののそのまま通常終了している点から、別の関数を利用 or 独自の処理を行なっている?
* 今までのように特定のDLLの関数を直接呼び出さずに外部関数を呼び出す総合的なcall命令が存在する
-> 実質一つの命令で様々な命令を再現できる
-> 上記の関数にBPを仕掛けても効果がなかったことも頷ける

f:id:chouett0:20171010232711p:plain
このcall命令が文字列を表示する関数を呼び出しているようで、同時にeaxに関数のアドレスを渡すことで様々な関数を呼び出すことのできる命令でもある
f:id:chouett0:20171010232832p:plain
このように、eaxに関数のアドレスを渡すことで呼び出していました。

f:id:chouett0:20171010232918p:plain
f:id:chouett0:20171010232930p:plain
先ほどのcall命令の内部へ入ると上記のようになっており、eaxに与えるアドレスによって呼び出す関数が変わっていることがわかります。
f:id:chouett0:20171010233055p:plain
最後に、このcall命令が最終的な文字列表示を行う処理でありWriteConsoleWを呼び出していることがわかります。
f:id:chouett0:20171010233226p:plain
f:id:chouett0:20171010233239p:plain

まとめ

今回の検証は、今まで行ってきたどのバイナリよりも複雑なものでありWriteConsole関数にBPを仕掛けるだけではうまくいかないと言うこともありかなり苦戦しました。特に、関数名や処理名をデバッガ側でアシストされなかったのが一番の難点だったと思います。
しかし、関数アドレスを渡すことで呼び出しを行う処理の攻略は自バイナリで主要処理を保持していたりパッカーまではいかなくとも難読化を行われているようなバイナリを解析する練習としては非常に良い経験になったと思います。
今回もおそらく本来の仕様とは異なる点が多くあるかと思うでの意見等頂ければ嬉しいです。

Hello World入門したかった

# はじめに タイトル通り、「Hello World」入門をしたかったお話です。
UNIX環境でHello Worldを解析していく本のパクリかよと思われたかもしれませんが、今回の場合はWindows環境で行いました。決してパクリではありません。
更に、今回の検証ではただ単にHello Worldを出力するプログラムを解析するだけでなくCでコンパイルした一般的なバイナリと、Rustでコンパイルしたバイナリ
そしてPy2exeでexe化したバイナリを比較していくことにしました。というよりもこの三つのバイナリを解析したいという思いつきからはじめた検証です。
というのも、同じ処理を行うバイナリならば、コンパイルを行うことで同じバイナリを生成するのではないか、もし異なるモノであるならどこに差があるのかを調べてみたいと思ったため、 Revのリハビリも兼ねて調べてみることにしました。
とあるLTで発表したスライドも参考にして頂ければ良いかなと思います。
Hello world(kari)

環境について

今回の検証では、MBP上にVBoxでWindows7環境を構築して行いました。
ツールに関しては静的解析には「Stirling」,PE Header解析にはvxPEViewer, 動的解析にはOllydbgと少しだけIDA freeを使用しました。

検証メモ

以下のメモが検証を行ったまとめになります。

Hello World Memo

C,rust,pythonにてバイナリを生成時に最適化オプション無効

  • cl -Od hello.c(C)
  • rustc -C opt-level=3 -C debug_assertions=no hello.rs(Rust)
  • optimize : 1(python)

Stirling

* Cを基準にそれぞれのバイナリを比較・素材を収集 *

C-Python

  • C-pythonでは、ヘッダーとヘッダー・ボディ間のnullバイト列の空白以外はほぼ異なるバイナリ
  • バイナリ列中にIsDebuggerPresentやGetLastError等の一般的な関数が列挙されている
    -> Cバイナリにも同じような関数名を列挙した箇所がある
  • pythonバイナリのヘッダー付近に「python27」等の文字列が現れる
    -> python側でエラー処理を行っている?(error 等の文字列が多く現れているため) -> 相似していないのではなく、python側の処理分ズレている可能性あり(サイズが大幅に肥大化しているのもその影響かも)
  • 一部タグらしき形式の文字列あり
  • 最終部辺りで「pyo」等のpython関連と思しき文字列あり
  • そもそも最適化が適応されていない?

C-Rust

  • Python同様ヘッダー以外は異なったバイナリ
    -> 若干python以上に異なる部分が多い
  • stringsを用いると.idataなどの文字列が多く出力される
  • GCCなども多くみられる
  • 前半部はほぼ解読不可なもので、おそらく後半部に重要な処理がある? -> 後半部はrust文らしきものが多くある
  • rust特有の命令(Cではない命令)が含まれている.
  • error処理が大半
  • Python同様、わかる形で「Hello World!」は格納されていない

Rust-Python

  • これまでと同じく特に似通った個所は無し

まとめ

どのバイナリもヘッダー以外は独自の構造をしているため似通った個所は見当たらない。そもそもバイナリのサイズがそれぞれ違うため相似しているとは思えない。...が、強いて最も似通ったバイナリ構造をしているものを挙げるならばC-Python

vxPEView, stud_PE

* Cを基準にそれぞれのバイナリの構造を比較 *

* 同時に関連性のありそうなファイルも解析を行う *

C-Python

  • 些細な違いはあるものの、タイムスタンプ等の違いの出ておかしくない部分が大半
  • Pythonと読み込んでいるライブラリに違いがあり、MSVCR90.dllを読み込んでいる -> MSVCR90.dllはアプリケーションを動作させるためのライブラリ(コンパイラの違いが原因?)
  • .relocセクションがなく.rsrcが存在している
    -> .relocは再配置情報、rsrcはリソース情報 -> これかの違いからヘッダー以下の構造が変わっている?
  • 同じくkernel32.dllを読み込んでいるものの、利用している関数に違いがある
  • msvcr90.dllには_snprintfやexit関数が読み込まれている
    -> Cではコンパイル時に基本的な関数は組み込まれているから?
  • 実行時にpython27.dllを必要とするにも関わらず実際には読み込まれていない
  • .textセクション中のSizeofRawdataの数値に違いがある
    -> その分アセンブリのコード量が多い
    -> 変換処理が含まれている?

C-Rust

  • 明らかに読み込んでいるdllの量がCに比べて多い -> python27.dllと似ている?
  • おそらく呼び出されることはないであろうwinsock2を扱うws2_32.dllの含まれていることから予め大方のライブラリを読み込んでいる?
  • セクション数が以上に多い ->
  • SizeOfRawdataが以上に大きい

* これより下は関連性のありそうなファイルの解析結果 *

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

select.pyd

  • 「.pyd」pythonスクリプトWindows用にコンパイルしたファイルの拡張子
  • Ollydbgで読み込みが行えることからおそらくdllと同じ
  • vxPEViewを用いると、複数のdllを読み込んでいる模様
    -> その一つに「pyhton27.dll」を読み込んでいることから、何らかの関連性がある?
    -> 「kernel32.dll」はほとんどのバイナリで読み込まれるため省略
    -> 「ws2_32.dll」はwinsock2を扱うためのライブラリ
    -> 「select」という名称から、socket関連のdllかも?
    -> python27.dllは主に初期化やエラー処理を行う内容? -> socket関連なら初期化・エラーは必要な処理
  • その他の要素は普通のdllと差はない

unicodedata.pyd, bz2.pyd

  • select.dllと同様、python27.dllは読み込まれているが、ws2_32.dllが読み込まれていない点から、上記の仮説は正しいと思われる。
  • 同じくpython27.dllが読まれててエラー処理が含まれているが、「format」や「string」などの文字列操作系の処理と思われる関数が含まれている
    -> 内部でCやシステムコールラッパ等に変換している?
    -> PyXX_xxxxxx : XX部が処理の内容(ErrやOS等), xx部がその具体的な処理名
    -> snprintfなどのCで用いられる関数も含まれていることから上記の仮説no 辻褄があう

_hashkub.pyd

  • ほとんど上記のpydファイルと差はないが、一部違うdllを読み込んでいる

pyd まとめ

おそらくpythonスクリプトを変換するためのdllであると考えられる。
本来コンパイラがCソースコード構文解析しているものを、pythonスクリプトを議事Cソースコードへ変換してコンパイラに渡す、もしくはpythonスクリプトを直接アセンブリに変換していると思われる。そのためにpython27.dllではC言語もしくはアセンブリへの変換処理が含まれていると思われる。

Python27.dll

  • kernel32.dll, user32.dll, msvcr90.dllなどの一般的によく利用されるdllの他にshell.dllというdllが含まれている。
  • shell32.dll/shellexecute : 外部アプリケーションを操作する関数
    -> 何らかの実行ファイルを実行・終了するために利用する?
  • pythonスクリプトをexeファイルに変換時にスクリプトで利用される関数を抽出して新たな小型のdllを生成している?
    -> pydがそれに該当する?
    -> もしくは各pydから読み込まれて利用される

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

Ollydbg,IDA Free

* ここでは各実行ファイルのみ解析を行い、dllの解析は行わないこととする *

* なお、解析に関しては一度Cの実行ファイルを解析した後に比較を行う *

C

  • 「call 0095154B」を最初に実行しているが、メインルーチンでないため、おそらく初期化などの処理を行なっている?
  • 引数として「Hello World」と1(stdout)を渡してcallしている処理があるものの、実際のメインルーチンではない模様
  • ImageBase範囲外で主な処理を行なっている?
  • メインルーチンと思われる00400000番台のアドレスを経由せず、様々なアドレスへジャンプしながら最終的にwriteconsoleA関数を呼び出すことで画面出力を行なっている
  • アドレス値がImageBaseと異なるのは環境の問題? -> その影響からか、直接printf関数を呼び出さずにwriteconsoleAを呼び出している?
  • WriteFile => WriteCosoleという流れから、UNIX系統で用いられるglibのwrite() => writeシステムコールラッパの構造に似ている?
  • コンソール上に文字列(Hello World!)を表示させる最終的な関数はWriteConsoleAであり、表面上ではWriteFile関数を呼び出すことで表示させている
    -> WriteFileがWriteConsoleのラッパの役割を果たしている?

C-Python

  • 開始時点ではCファイルのようにWriteConsole関数もWriteFile関数もない -> 実行していくとWriteConsoleA関数を呼び出す処理がある
  • _writeという名前で呼び出される
    -> glibでも存在するwriteシステムコールラッパと同等?
  • Cファイルとは違い、ImageBase範囲内でコードが実行されている -> Cファイルで最適化無効が効いてない?
  • PyEval_EvalcodeEx => PyFrame_New => etc...を経由する処理から、表面上はPython27.dll内で処理が行われている?
    -> 内部で様々なpyと付く関数の定義が成されている
    -> そもそもvxpeViewerで読み込まれていなかったはずが、実際にはアクセスしている点から、python27.dllはあらゆる関数をpythonスクリプトから変換する役割を持つという仮説の信ぴょう性が高くなった
  • printf関数をkernel32.dllからimportしている
    -> 変換の際に利用されている?
  • python27.dllで定義されている関数は内部で既存の関数を呼び出している点から標準関数のラッパである可能性が濃厚 -> ループ処理を繰り返すことで変換を行なっている? -> python27.dllを書き換えることで任意の処理に改ざんできる?
  • WriteFileを呼び出して内部でWriteConsoleAを呼び出すルーチンはCと同じ
    -> PyFile_WriteObjectが一番外側 && ラッパの関数

C-Rust

  • CともPythonとも異なる初期コードを持っている
    -> call => jmpという流れは同一
  • C,Pythonと違い、エントリーポイントが正常な位置に存在している? -> いくつかアドレスを経由しているが、これまでのファイルよりも本来の処理に近い形をしている
  • Stirlingでは発見できなかったが、セクション内に「Hello World!」が存在している?
  • WriteConsoleWを使用している -> 最適化の問題?
  • Cと異なり、WriteFIleを経由せずに直接(一応Rustではラッパを作成しているかも)WriteConcsole関数を呼び出している -> 自前で関数ラッパを作成している
    -> vxPEViewerでの仮説が正しい可能性が濃厚
    -> ファイルサイズのわりに実行する処理がさほど多くないのも其のため?

まとめ

僕の検証が必ずしも正しいというわけではなく、あくまでこうなっているのかなという想像のお話なのでもしツッコミや鉞を投げてくださる人がいれば教えていただければと思います。 検証の感想としては、同じ処理を行うとしてもやはりその再現方法は様々でありそこでパッカーや難読かなどの手法にも応用できるものがありそうだと感じました。
また、Rustやpy2exeを用いる場合とCでコンパイルした場合とではファイルのサイズに大幅な差が生じていることからCがベアメタル環境で用いられているのもそのためなのかなと思ったり、初歩的なプログラムながら学ぶことが多く色々な想像ができる検証でした。

LInuxでもDLL Injectionがしたい

はじめに

相当前の記事で書いたWindows環境でDLL Injectionを用いたマルウェアを利用したDNS詐称の続きとして、
環境をWindowsではなくLinux環境で行うことができればLinuxの搭載されたサーバはもちろんルータも対象にできるのではと思いつき
Linux上でDLL Injectionを行うための手法を調べた際のまとめです。

LinuxでのDLL Injection

当然ではありますが、LInuxWindowsではOSが違うためDLLというものは(基本的には)存在しません。
そこで以前ユーザランドでの関数の書き換えを行うことができるという記事を読んだのを思い出し
Shared Objectを任意のプロセスへ注入できれば実現できるのではと考えて調べてみると

github.com

このような記事を発見したのでコードリーディングを行なってみることにしました。
ざっと中身を眺めてみた結果としてわかったことは、一部インライナーアセンブラで実装しなければいけない部分があり
複雑な部分が若干あるもののコード量的には読むだけなら一時間あれば読める程度の内容でした。
まだ詳しくは解読出来ていないので近いうちに読んだ結果から自分なりのツールを実装してみたいと思います。

Tails Linuxを常用OSにしたかった話

はじめに

タイトル通り、Tails Linuxを常用したかった時に知った知見や僕の見解のメモ。
まずそもそもなぜTails Linuxを使いたいと思ったかというと、天から「ハードディスクもSSDも抜いてUSB(3.0)ブートでTails使え」というお言葉を頂いたことがきっかけです。
そんな感じで使ってみようと思い小一時間使ってみての感想等のメモです。

Tails Linux とは

まずそもそもTails Linuxとは何かですが、簡単に言ってしまえば匿名で利用できる秘匿性の高いOSのことです。
torやMAC Spoofingに始まり、純正アプリケーションは匿名性の高いものが採用されており、たとえ内臓ストレージが存在していても一切のアクセスを禁止されるといった徹底ぶりです。
当然homeディレクトリに作成したファイル等もシャットダウン時に削除されてしまいます。(一応保存する方法はあります)

Tails Linuxのインストール方法について

今回は必要なツール等のインストールやインストールディスク作成にレッツノート、インストール用マシンにThinkpad X220を選択しました。
理由は机に落ちてたからです。
Tailsではインストール用ディスクとインストール先のディスクの二つのUSBが必要となるので注意が必要でした。
インストールに関してですが、ISOがあるサイトが一番わかりやすいのでそちらを参考にしてください。

実際に触ってみての感想

USBからブートするliveOSという事もあり、複数機を気分で使い分けてるような人には同じ環境で開発等が行えるため非常に使い勝手が良い…と思って居たのですが、どうやら標準以外のパッケージからインストールしたものも消去されてしまうらしく同じソースコードは合っても環境までは同一には出来そうにありませんでした。(もしかしたらできるかも…)
ただ、torを経由していてもパッケージ管理ができる点や、特に設定もなくいきなりtorを通してブラウジングできる点は非常によく、保存しておきたいファイルは暗号化されているので例えガサ入れでお巡りさんのご厄介になる時もある程度は足止め出来そうなのでメリットもかなり多くありました。
それでもやはり、僕には馬が合わず常用OSにはならないなという結論に至りこの案は無しとなりました。
やっぱりUbuntuが良い

僕はTails Linuxを使いこなせませんでしたが、有名なハッカー・クラッカー・スパイの方々も使っているということと、ブートメニューを開ける権限を与えられていれば端末上に情報を残さずに使用できる点など非常に素晴らしいOSである事は確かなので是非興味を持った方は試していただきたいと思います。

ISTSC8 Writeup

初めに

8/26、27の2日間開催されていたISTSC8にチームIPFactoryとして参加してきました。あまりサーバについての(というかLinuxに関する)知識がないので基本的にネットワーク問題オンリーで参加することになりました。その際に担当した問題のwriteup兼戒めとなります。

伝統の国 第一のトラブル

基準点: 120 / 満点: 200

問題

旅の途中、酒場に訪れた。

ドワーフ「お客さん、見ない顔だね。どこから来たんだい?」

エイト「私は始まりの国のはずれよ。この人たちは私が異世界から呼んできたの」 ドワーフ「ほーう。ここに壊れたスイッチがあって修理する当てを探しているんだが……。まぁおまえらじゃあ解決できないだろうな、ほら帰ってくれ」

そう言い残すとドワーフは、店の奥に消えていった。

エイト「キー! 悔しい。あんたたち絶対直してみせなさい!! 解決して見返してやりましょう」

注意事項

2960B を再起動してはいけない。 達成すべき事項

7 番ポートをリンクアップをさせ、原因を特定する パスワードを broken_port? に変更する

このような形で問題が出題されました。どうやら7番ポートがダウンしているようなのでshow interface FastEthernet 0/7をすると、「err disabled」となっているので、ハードではなくソフト的にダウンさせられたんだろうなと予想がつきます。 ちょうど前日にport-securityの設定をすると強制shutdownされるという知見を得ていたのでそれだろうと考えているとどうやらそもそも設定されていない模様。
そこで(というか初めからやるべきでしたが)show logでエラーログを探ると、

*Mar 2 03:46:29.100: %STORM_CONTROL-3-SHUTDOWN: A packet storm was detected on Fa0/7. The interface has been disabled.

というログがったので調べてみると「storm-control」という機能によるものであるとわかりました。
よって、何らかの要因でパケットが大量に送られてきたことによるトラフィックの上昇をstorm-control機能が検知して7番ポートを落としてしまったと推測できます。 復旧方法は単にポートの再起動で可能でした。また、パスワードに「?」を含めるようにする方法ですが、Ctrl + Vでできるようです。

伝統の国 第二のトラブル

問題文

スイッチの問題を解決した後、ドワーフに話しかけられた。

ドワーフ「いや~まさか本当にトラブルを解決するとはビックリしたぜ。ついでにもう一つ頼まれてくれないか?」

ドワーフ「実は魔法陣の構成を 892j から 1941 に変更して、同じ呪文を書き込んだんだがNAT-PTが動作しないんだ。頼む……この>通りだ」

エイト「コンフィグを使いまわしたってこと? そんなことするから動かないのよ。悪いけど、あんたたちやってあげてくれない?」

アクセスできる機材

cisco 1941

892J時の動作

  • Pv4アドレスにIPv6ネットワークからpingをする際には宛先に2017::(IPv4アドレス)を宛先にするとできていた
  • 例として192.168.140.2にpingをする際は2017::192.168.140.2が宛先となる

達成条件

  • NAT-PTを機能させる
  • 1941のgi0/0ポートにつないだIPV6アドレスのみを持つPCから192.168.140.1にpingが通る

この問題はcisoc 892Jを使っていた時のコンフィグをcisco 1941でそのまま流用したけどなぜか動かないからどうにかしてくれ、という問題です。
普通に考えればファームアップしている機器ならそのまま流用するようなことはしないのかもしれないのですがね。。。
というわけでなぜこれが動かないのかをコンフィグから割り出すと、どうやらIPv6でNAT-PTを行っているようなのですが「ipv6 cef」という設定を無効化しないといけないようでしたので、「no ipv6 cef」というコマンドを実行することで動作するようになりました。
CEFとは、cisco社のExpress Forwarding技術の略称のことで、パケットの転送処理をHWで行うことで高速化を図る技術なのですが、これが曲者でNAT-PTを利用する場合はこれを無効にする必要があるようです。

伝統の国 第三のトラブル

問題

NAT-PTの問題を解決した後、再びドワーフが話しかけてきた。

ドワーフ「2つもトラブルを解決してくれるとは驚いた。俺とあんたたちはもう家族も同然だよな? だから最後にあと1つだけいい>か?」

エイト「え~まだあるの?」

ドワーフ「実は新しく喫茶店の支店作っていてなぁ~。そことIPsecで魔法陣をつなぎたいんだが、うまくつながらないんだ。なん>とかしてくれよ~俺たち家族だろう?」

エイト「もう~調子がいいんだから。何度もごめんね。これだけ手伝ってあげてくれない?」

アクセスできる機材

  • 1841-B
  • 1941

注意事項

  • 892J内のNAPTルータのconfigの変更は一切行ってはいけない

達成すべき事項

  • IKE Phase1成功を確認する。
  • IKE Phase2成功を確認する。
  • IPsecによる通信で1941のLoopBack0から1841-BのLoopBack0への疎通を確認する。

この問題は競技中に回答できなかった問題なのですが、ただ単にIPSecVPNを張るだけ…のはずがうまくいきませんでした。
しかもこの問題を解答できたのが1チームだけのようでその難易度がうかがえます。ネットワーク担当としてとても心残りになる問題でした。

今回で参加は2回目になりますが、前回と違い少しはチームに貢献できたかなという感想でした。しかし、やはりまだ戦力にはならない上にサーバ問題になると途端に手足が出せなくなるのでやはりまだまだなんだなと実感しました。
出来れば 来年以降はNOCとして参加してみたいものですね。