web-dev-qa-db-ja.com

このCTF演習でシェルを実行するにはどうすればよいですか?

私はCTFウォーゲームをプレイしていて、unfortunatleyがこのレベルで立ち往生しているので、「クラウドソーシング」したいと思います。完全な答えは必要ありませんが、ヒントで十分です。

どうやって:

  1. Strcmpを0にする(falseかどうかを評価)
  2. どういうわけかシンガーを抑制?

シェルを実行したい:

execl("/bin/sh", "sh", NULL);

何か案は?

バイナリはsetuidであり、/ levels/level08.passは上位レベルでのみ読み取り可能です。

-r-sr-x---  1 level9  level8   7696 Apr 25  2015 level08
-r--------  1 level8  level8    412 Apr 25  2015 level08.c
-r--------  1 level9  level9     13 Apr 25  2015 level08.pass

Level08.cのプログラムコードは次のとおりです。

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
        char buf[64];
        FILE *fp;
    signal(SIGABRT, SIG_DFL);
    fp = fopen("/levels/level08.pass", "r");
        fgets(buf, 64, fp);
        buf[strcspn(buf, "\n")] = '\0';
        if(strcmp(buf, argv[1]))
                raise(SIGABRT);
        execl("/bin/sh", "sh", NULL);
}
2
dev

strcmp呼び出しとその原因は正しいです。信号をいくらか抑制するための2番目の直感は正しいものです。

signal(SIGABRT, SIG_DFL);
…
raise(SIGABRT);

raiseを呼び出すと、デフォルトのアクションがプログラムの強制終了であるシグナルが発生します。 signalへの以前の呼び出しにより、デフォルトのアクションが確実に実行されます。プロセスがそれ自体をシグナルするとき、これは同期的です:raise関数が戻る前にシグナルが受信されます。

キャッチは何ですか? 無視されることに加えて、シグナルはブロックされることができます。無視されたシグナルが配信されても​​、何も起こりません。ブロックされたシグナルが受信されると、カーネルはそれをメモするだけで配信しません。そのため、プログラムは正常に動作し続けます。信号のブロックが解除されると、信号が配信され、配信時に信号に関連付けられたアクションが実行されます。

ブロックされた信号がexecveの境界を越えています。 POSIXの根拠であるexecve にそれに関する注記があります。シグナルブロッキングを管理する関数は sigprocmask です。

したがって、SIGABRTをブロックしてプログラムを呼び出すと、パスワードチェックがバイパスされます。

Perl -MPOSIX -we 'sigprocmask(SIG_BLOCK, POSIX::SigSet->new(SIGABRT), POSIX::SigSet->new()); exec "level08", ""'
  1. Strcmpを0にする

Strcmpが正しく実装されていると仮定すると、これは、argv[1]level08.passの内容と63バイトまたは最初の改行/ nullバイトまで正確に一致する必要があることを意味します。

ファイルの内容がわからないため、argv[1]を操作して、正しい文字列を含むメモリ内のアドレス(たとえば、buf)をポイントするのが唯一のオプションです。 argcチェックがないため、これについて不思議に思いましたが、argvの処理方法は不可能です。

  1. どういうわけか信号を抑制する

プロセス信号マスクを見てください。

この段落には the docs の重要なポイントがいくつかあります。

現在ブロックされている信号の集まりを信号マスクと呼びます。各プロセスには独自のシグナルマスクがあります。新しいプロセスを作成すると(「プロセスの作成」を参照)、親のマスクを継承します。信号マスクを変更することにより、完全に柔軟に信号をブロックまたはブロック解除できます。

2
grc

/levels/level08.passの最初の行を入力すると、シェルを実行するようです。たぶん、タイミング攻撃を使用してstrcmpの終了場所を確認し、それを使用して一度に1文字を推測することができます。

0
Sjoerd