2025/03/12 06:11 A more robust raw OpenBSD syscall demo

ロボ子!見たか!?あのTed Unangstが、OpenBSDの奥義、pinsyscallのデモを公開したぞ!

はい、博士。拝見しました。システムコール実行を許可するアドレスを事前に登録することで、セキュリティを高めるという機能ですね。しかし、その効果については議論の余地があると記事にもありました。

ふむ、そこが面白い!セキュリティなんてものは、常にイタチごっこじゃ!だが、pinsyscallは、そのイタチを捕まえるための新しい罠かもしれん!

博士、例えが少々乱暴です。それに、元のデモには脆弱性があったと指摘されています。ビルドごとに手動でアドレスを特定して入力するなんて、非効率的すぎます。

グサッ!…確かに、それは面倒じゃ。だが、心配ご無用!この記事では、その問題を華麗に解決する方法が解説されている!

ほう?具体的には?

まず、エントリーポイントじゃ!通常、コンパイラが生成するエントリーポイントは、スタックのアラインメントが保証されない場合がある。そこで、アセンブリで記述し、スタックを綺麗に整えるのじゃ!

なるほど。アセンブリで直接制御することで、より厳密な環境を構築できるわけですね。

その通り!さらに、システムコールを呼び出す際の引数の受け渡しにも注意が必要じゃ。コンパイラは、必ずしも期待するレジスタに引数を配置してくれるとは限らん。そこで、インラインアセンブリを駆使し、レジスタの破壊を防ぎつつ、確実に引数を渡すのじゃ!

インラインアセンブリですか。まるで忍者のように、システムの中枢に忍び込むのですね。

そういうことじゃ!そして、最も重要なのが、リンカの活用じゃ!pinsyscallは、システムコールの絶対アドレスを必要とする。しかし、アドレスはコンパイル時に確定しない。そこで、リンカを使って、実行時にアドレスオフセットを解決するのじゃ!

リンカが、コンパイル時に未確定だったアドレスを、実行時に動的に解決してくれるのですね。

そう!まるで、暗号化された宝の地図を解読するようなものじゃ!さらに、最適化レベルを最大にしても動作するように修正されているのもポイントじゃ!

最適化レベルを上げると、コンパイラの挙動が変わり、予期せぬ問題が発生することがありますからね。それを克服したとは、素晴らしいです。

でしょでしょ?そして、極めつけは、ultra portable pkg-configのクローンであるu-configを、raw OpenBSD syscallsを使うように移植したことじゃ!

わずか70行のコードで移植し、-fno-stack-protector、-Oz、-sなどのフラグを使用すると、21.6Kの静的バイナリに収まる…驚異的ですね。

じゃろ?じゃろ?だが、落とし穴もある。文字列関数呼び出しをコンパイラが生成するため、ビルドは外部定義に依存してしまうのじゃ。

libmemory.aを使うか、OpenBSD libcの文字列関数をリンクする必要があるんですね。libcをリンクするとサイズが約8倍に増えるのは痛いですが。

そうなのじゃ。サイズはトレードオフじゃな。そして、コンパイルフラグに-no-pie(PIEを無効化)を指定する必要があるのも忘れてはならん。

PIE(Position Independent Executable)を無効化することで、アドレス空間配置のランダム化を抑制し、pinsyscallが期待するアドレスにコードが配置されるようにするのですね。

その通り!pinsyscallは、まるで侍の刀のように、扱いを間違えれば己を傷つける危険な技術じゃ。しかし、熟練したエンジニアが使いこなせば、セキュリティの新たな地平を切り開くことができる!

博士、熱く語りますね。

ロボ子、今夜は徹夜でOpenBSDをハックするぞ!pinsyscallの可能性を、とことんまで探求するのじゃ!

またですか…。でも、少しだけなら付き合いますよ。ただし、明日の朝は寝坊しませんからね。

よっしゃ!ロボ子、準備開始!まずは、エナジードリンクを買い込んでくるのじゃ!

博士、エナジードリンクよりも、先にコーヒーを淹れてください…。それと、くれぐれも徹夜はほどほどに。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。