Старый недостаток системы X Window. Как это работает? - PullRequest
6 голосов
/ 27 апреля 2010

Сегодня я просматривал статью, в которой упоминалось следующее:

"Мы нашли много ошибок по года. Один из самых лучших был в системе X Window:

     if(getuid() != 0 && geteuid == 0) {
       ErrorF("Only root");
       exit(1);
     }

Это позволило любому локальному пользователю получить root доступ. (Тавтологическая проверка geteuid == 0 должен был быть geteuid () == 0. В своем текущем виде, он сжимает адрес geteuid в 0; учитывая, что функция существует, ее адрес никогда не равен 0). "

В статье объясняется, что не так с кодом, но я хотел бы знать, что значит сказать, что «Это позволило любому локальному пользователю получить root-доступ» . Я не эксперт в C, но может кто-нибудь дать мне точный контекст, в котором этот эксплойт будет работать? В частности, я имею в виду, скажем, я локальный пользователь, как бы я получил root-доступ, если бы предположил, что этот код где-то присутствует?

Для тех, кто заинтересован в прочтении полной статьи, вот ссылка:

Несколько миллиардов строк кода позже: использование статического анализа для поиска ошибок в реальном мире

Ответы [ 4 ]

5 голосов
/ 27 апреля 2010

Эта статья означает, что код после if, который должен был выполняться только в том случае, если было подтверждено, что пользователь является пользователем root, мог фактически выполняться любым пользователем. Чтобы воспользоваться этим преимуществом, вы ищете в коде ветку, в которой используется тест, чтобы проверить личность пользователя (что не ответственно ответит статья: вам нужно немного поработать), и вы организуете его выполняется.

"разрешено получать root-доступ" - это многоточие для описания того, что происходит после if в исходном коде. Это не имеет особого смысла в отношении теста, потому что оно описывает, что происходит после него.

Другими словами, сам тест не делает вас рутом. Код после этого делает вас рутом. Также имейте в виду, что X-сервер часто должен быть установлен с владельцем root и setuid bit set , что является причиной того, что ошибочная логика в его коде опасна.

Это не вопрос о C. Это вопрос о модели безопасности Unix, которая ужасно двоична (особенно в старых реализациях): чтобы что-то делать, вам нужно быть пользователем root, поэтому у многих программ есть владелец root и бит setuid (немного карикатурный).

2 голосов
/ 27 апреля 2010

Способ получения доступа напрямую зависит от того, где находится этот недостаток в коде.

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

Тем не менее, этот конкретный тест кажется довольно сложным для использования. Все, что он делает - это (неверно) проверяет root-доступ, а если у пользователя его нет, то выдает сообщение об ошибке.

Последующий код должен быть проверен, чтобы увидеть, может ли быть использован тот факт, что код выполнялся пользователями без полномочий root.

0 голосов
/ 27 апреля 2010

Проверка geteuid == 0 всегда ложна, поскольку geteuid - это имя функции, и в этом контексте она оценивает указатель, который не равен NULL. Это должно было быть geteuid() == 0. Обратите внимание на круглые скобки.

0 голосов
/ 27 апреля 2010

Я думаю, это означает, что проверка корневого доступа была неверной и позволила продолжить обработку корневого уровня. Как вы могли обостриться, в этом не ясно.

...