Я проходил статью сегодня, когда она упомянула следующее:
"Мы нашли много ошибок за эти годы. Один из лучшего абсолюта был следующим в X-оконной системе:
if(getuid() != 0 && geteuid == 0) { ErrorF("Only root"); exit(1); }
Это позволило любому локальному пользователю получать корневой доступ. (Тавтологическая проверка geteuid == 0 была предназначена, чтобы быть geteuid () == 0. В его текущей форме это сжимает адрес geteuid к 0; учитывая, что функция существует, ее адрес никогда не 0)."
Статья объяснила, что было неправильным с кодом, но я хотел бы знать то, что это означает говорить, что "Это позволило любому локальному пользователю получать корневой доступ". Я не эксперт в C, но кто-то может дать мне точный контекст, в котором работало бы это использование? А именно, что я имею в виду, позволяет, говорят, что я - локальный пользователь, как я получил бы корневой доступ, если мы предполагаем, что этот код присутствует где-нибудь?
Для любого заинтересованного чтением полного текста статьи, вот ссылка:
В статье говорится, что код после if
, который должен был выполняться, только если было подтверждено, что пользователь был root , на самом деле может быть выполнен кем угодно. Чтобы воспользоваться этим, вы ищите ветку в коде, в которой тест используется для проверки личности пользователя (что статья ответственно не предоставляет: вам нужно немного поработать), и вы делаете так, чтобы это было выполнен.
«разрешено получить root-доступ» - это многоточие для описания того, что происходит после if
в исходном коде. Это не имеет особого смысла в отношении теста, потому что описывает, что происходит после него.
Другими словами, тест сам по себе не дает root-права. Код после него делает вас root. Также имейте в виду, что X-сервер часто должен быть установлен с корневым владельцем и установленным битом setuid , что является причиной того, что ошибочная логика в его коде опасна.
Это не вопрос о C. Это вопрос о модели безопасности Unix, которая ужасно двоична (особенно в более старых реализациях): вы должны быть root, чтобы делать что-либо, поэтому у некоторого количества программ есть root-владелец и setuid bit (немного карикатурно).
Проверка geteuid == 0
всегда ложна, поскольку geteuid
- это имя функции, и в этом контекст он оценивает указатель, который не равен NULL. Это должно было быть geteuid () == 0
. Обратите внимание на круглую скобку.
То, как вы получите доступ, напрямую связано с тем, где находится эта ошибка в коде.
Если бы вы точно знали, где находится этот код, вы могли бы изучить пути кода, которые могли бы привести вас к этой строке кода, а затем, изучив последствия этого кода, сделать что-нибудь, чтобы воспользоваться ошибочной проверкой уровня безопасности.
Однако; этот конкретный тест кажется довольно сложным для использования. Все, что он делает, это (неправильно) проверяет наличие root-доступа, и, если у пользователя его нет, выдает залог с условием ошибки.
Последующий код должен быть подвергнут аудиту, чтобы увидеть, можно ли использовать тот факт, что код выполняли некорневые пользователи.
Я думаю, это означает, что проверка корневого доступа была неправильной и позволила продолжить обработку корневого уровня. Каким образом вас могли поднять, здесь не ясно.