追加読書

追加読書
$ k=v p &
[1] 3028

言及されていないp内容を変更する方法はありますか?/proc/3028/environk=v しかし、 pまだ走っていますか?

ベストアンサー1

Linuxでは、スタックの環境文字列値をオーバーライドできます。

したがって、この項目をゼロまたは他の項目で上書きして非表示にすることができます。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[], char* envp[]) {
  char cmd[100];

  while (*envp) {
    if (strncmp(*envp, "k=", 2) == 0)
      memset(*envp, 0, strlen(*envp));

    envp++;
  }

  sprintf(cmd, "cat /proc/%u/environ", getpid());

  system(cmd);
  return 0;
}

次に実行:

$ env -i a=foo k=v b=bar ./wipe-env | hd
00000000  61 3d 66 6f 6f 00 00 00  00 00 62 3d 62 61 72 00  |a=foo.....b=bar.|
00000010

k=v上書きしました\0\0\0

この場合、新しい文字列が割り当てられるため、値をオーバーライドしてsetenv("k", "", 1)も効果はありません。"k="

環境変数を有効または変更しない場合は、次のk操作を実行してスタックの文字列アドレスを取得することもできます(その1つ)。setenv()putenv()k=v

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(int argc, char* argv[]) {
  char cmd[100];
  char *e = getenv("k");

  if (e) {
    e -= strlen("k=");
    memset(e, 0, strlen(e));
  }

  sprintf(cmd, "cat /proc/%u/environ", getpid());

  system(cmd);
  return 0;
}

ただし、削除のみ可能であることに注意してください。一つk=v環境で受信された項目の数。通常、1つだけですが、渡された環境のリストから誰もk=v1(または2回)の両方を渡すのを防ぐことはできません。k=v2これが過去にセキュリティ違反が発生した理由です。k=vexecve()CVE-2016-2381bash実際、シェルショックの前に変数と関数を同じ名前でエクスポートしたときに、これが発生する可能性がありました。

それにもかかわらず、env var文字列を上書きしない小さなウィンドウが常にあるため、それを渡す別の方法を見つける必要があります。秘密/proc/pid/environ必要に応じて、公開されたコマンド(パイプなど)を使用して情報を検討してください。

逆に、同じeuidまたはルート(またはプロセスのeuidとruidが異なると思われる場合にのみルート)を持つプロセスからのみアクセスできます/proc/pid/cmdline/proc/pid/environment

から値を非表示にすることができますが、/proc/pid/environデバッガを接続するなど、メモリ内の文字列の他のコピーを取得することができます。

バラよりhttps://www.kernel.org/doc/Documentation/security/Yama.txt少なくとも、root以外のユーザーがこれを行うのを防ぐ方法を学びます。

おすすめ記事