The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

Описание проблем безопасности при написании suid программ (suid security)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: suid, security,  (найти похожие документы)
Date: Sun, 16 Jun 2002 07:09:07 +0000 (UTC) From: Valentin Nechayev <netch@segfault.kiev.ua> Newsgroups: fido7.ru.unix.prog Subject: Описание проблем безопасности при написании suid программ >> А почему-бы не одну суидную? Потом она fork'ается и одна из них делается >> setuid(geteuid()), а вторая остаётся root. DG> setuid(getuid()). Это во-первых. DG> Во-вторых: DG> А вдруг она до setuid(getuid()) зачитает данные, которые ей по должности DG> (которая == getuid) не положены? А уронят ее? И из корки лишнего DG> прочтут? Вообще-то, во всех нормальных юниксах давно уже есть контроль того, что процесс с момента exec'а делал изменение uid или gid - и в этом случае ставится флаг P_SUGID или сбрасывается флаг dumpable или еще как-то помечается факт "грязности" памяти процесса - и после этого корку она не спечет, и сделать к ней attach не получится, если ты не root. Признак "грязности" хранится все время жизни процесса через все fork'и, пока не сделан exec - тогда предыдущий сбрасывается, но может возникнуть новый, если exec был на suid/sgid бинарник и при этом возникло ruid!=euid или rgid!=egid именно по причине этих флагов бинарника, а не в наследство. (Это чуть упрощенное описание, но показывающее направление действия.) Вот из freebsd (4.5-stable): === cut ptrace() === /* not owned by you, has done setuid (unless you're root) */ if ((p->p_cred->p_ruid != curp->p_cred->p_ruid) || (p->p_flag & P_SUGID)) { if ((error = suser(curp)) != 0) return error; } === end cut === === cut coredump() === if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0) return (EFAULT); === end cut === Вот из linux (2.4.18): === cut ptrace_attach() === if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE)) goto bad; === end cut === === cut do_coredump() === if (!current->mm->dumpable) goto fail; === end cut === На чем можно получить проблемы: - На том, что где-то старая система, которая этого не умеет. - На простейшем эксплойте к коду, которому права пофиг. - На явно включенном sysctl kern.sugid_coredump в BSD системах (хотя такие корки, AFAIR, доступны только руту) (это по умолчанию выключено и его можно включать только для отладки в тяжелых ситуациях) - На явном сбросе флага dumpable самим процессом в Linux - На еще каком-то действии, прорвавшемся через такой контроль из-за неполноты представления кодописателей о происходящем. Например, методом, аналогичным взлому через ptrace в 2.2.16 и близких к тому линуксах - атомарность проверки не выполняется из-за того, что по дороге производится sleep(). - На передаче от исходного процесса в процесс, получивший suid или sgid, какого-то элемента окружения, который влияет на функционирование процесса и вышел за пределы контроля кода. Например, переменные окружения, rlimits... DG> С суидностью надо осторожно. А если можно без нее, то лучше таки без нее. Действительно, сейчас стараются максимально избавиться от всего описанного спектра граблей путем сокращения прав, даваемых программам, и сокращения цепочек выполнения, начатых из такого untrusted источника, как пользовательский процесс. Например, запустив sendmail -bm -v, можно увидеть весь ход доставки и получить цепочку user's process -> injecter -> background runner -> local mailer; для postfix цепочка ограничится укладкой в очередь, причем sgid, а не suid, процессом, и сообщением qmgr'у про новое письмо. /netch

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>



Ваш комментарий
Имя:         
E-Mail:      
Заголовок:
Текст:





  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor