禁止された情報ストリームを作成します。 257スレッド

これは、禁止情報フロー(IP)の作成に関する一連の記事の最初の記事です。 これらのIPを整理するためのアイデアは、私が発明したのではなく、ここで発明されたものではありません。 私がしなければならなかったのは、これらの脆弱性を実証するユーティリティをトレーニング目的で実装することだけでした。



この記事では、別のアプリケーションによる最初の状態の調査に対する、その状態のアプリケーションの1つによる変化に基づいて、情報フローの編成について説明します。 この相互作用モデルでは、単一のトランスミッターに複数のリスナーが存在する場合があります。 以降の記事では、プログラムの対話環境と情報交換アルゴリズムの両方が異なります。



だから、コードに! 最初に、追加の256スレッドの識別子を持つ配列が必要です。 スレッドは作成されませんが、識別子はゼロに等しくなります。



#define MAX_THREADS 256 pthread_t threads[MAX_THREADS];
      
      





次のステップで、現在のスレッド数と必要なスレッド数に関する情報を保存するいくつかの変数を宣言します。



 int todayThreads = 0; int tomorrowThreads = 0;
      
      





ここで、新しく作成されたすべてのスレッドが向けられる関数を見てください。



 void * funcParallel(void * p) { long threadIndex = (long)p; while (true) { usleep(200); if (threadIndex + 1 > tomorrowThreads) { pthread_exit(NULL); return NULL; } } }
      
      





次に、実行中のスレッドの数を指定されたスレッドの数と等しくする関数を作成します。



 void changeNumThreads(int num) { tomorrowThreads = num; if (tomorrowThreads > todayThreads) { // Creating new threads for (int i = todayThreads; i < tomorrowThreads; i++) pthread_create(threads+i, NULL, funcParallel, (void*)i); } else if (tomorrowThreads < todayThreads) { void * status; // Waiting for killing threads pthread_join(threads[tomorrowThreads], &status); } todayThreads = tomorrowThreads; }
      
      





それでは、メイン関数に入りましょう。 パラメーターなしでプログラムを開始するときに、プログラムが送信側になり、プロセス識別子を通知するとします。 また、パラメータを指定して起動すると、送信プログラムのプロセス識別子をパラメータから読み取り、そこからデータを受信しようとします。 つまり、最初にパラメーターなしで実行すると、PIDが表示されます。 表示されたPIDと等しいパラメーターを使用して、プログラムの2番目のコピーを起動します。



 int main(int argc, char * argv[]) { int pid = getpid(); if (argc == 1) { runSender(pid); } else if (argc == 2) { sscanf(argv[1], "%d", &pid); runReceiver(pid); } else { printf("Usage: unichat [PID]\n"); printf("Examples: unichat\n"); printf(" unichat 2790\n"); } }
      
      





次に、 runSender()伝達関数のコードを見てみましょう。 PIDを出力します。その後、標準入力ストリームから一度に1文字ずつ読み取り、スレッド数を読み取り文字のコードに等しい数に変更し、1000マイクロ秒待機して、スレッド数をゼロに等しくしてから再び待機します。



 void runSender(int pid) { printf("Sender PID = %d\n", pid); while (true) { char ch = getchar(); changeNumThreads(ch); usleep(1000); changeNumThreads(0); usleep(1000); } }
      
      





ホストコードを見ることは残っています。 彼はもう少し複雑です。 特定のアプリケーションのスレッド数を監視し、検出された最大数を記憶します。 スレッド数が0(メインスレッドを除く)になるとすぐに、コードが表示されたスレッドの最大値に等しい文字を出力します。 印刷後、保存されているスレッドの最大数がリセットされます。



 void runReceiver(int pid) { printf("Receive from PID = %d\n", pid); char line[1024]; char filename[1024]; snprintf(filename, sizeof(filename), "/proc/%d/status", pid); int maxThreads = 0; int threads = 0; while (true) { usleep(200); FILE * f = fopen(filename, "rt"); if (f == NULL) { printf("Can't open file %s, error: %d!\n", filename, errno); return; } while (!feof(f)) { fscanf(f, "%s", line); if (feof(f)) break; if (memcmp(line, "Threads:", 8) == 0) { fscanf(f, "%d", &threads); threads--; if ((threads == 0) && (maxThreads != 0)) { printf("%c", maxThreads); fflush(stdout); maxThreads = 0; } else { if (threads > maxThreads) maxThreads = threads; } break; } } fclose(f); } }
      
      





そのため、次のことが起こります。

1.パラメーターなしでプログラムを実行する

2.画面に、 1234などの数字が表示されます

3.パラメータ1234でプログラムを実行します

4.最初のプログラムで、「a」ボタンを押します

5.プロセス1234のスレッド数は「a」+ 1 = 98になります

6.ホストプログラムは、スレッド数の増加を観察します(これは、ファイル/ proc / 1234 / statusに書き込まれます)

7.ホストは最大値98をキャプチャします

8.送信プログラムは、メインスレッドを除くすべてのスレッドを強制終了します)

9.ホストプログラムは、スレッド数= 1(メイン)を修正します

10.受信プログラムは、コード98-1 = 97 = 'a'のシンボルを画面に印刷します。



結論:

したがって、データは、機密レベルの高いプロセスから機密レベルの低いプロセスに転送されます。 交換する機能は、あるプロセスが別のプロセスの状態を監視する機能に基づいており、機密レベルに制限はありません。



All Articles