Розробники проекту Grsecurity
Патчі HKSP були опубліковані співробітником компанії Huawei, включають згадку Huawei у профілі GitHub і використовують слово Huawei у розшифровці назви проекту (HKSP – Huawei Kernel Self Protection). При цьому представники Huawei спростували зв'язок проекту HKSP з компанією та заявили, що код розроблений з особистої ініціативи працівника, не є офіційним проектом Huawei і не використовується у продуктах цієї компанії. на
HKSP включає такі зміни, як рандомізація зсувів у структурі cred, захист від атак на простір імен ідентифікаторів користувачів (pid namespace), відділення стеку процесів від області mmap, виявлення подвійного виклику функції kfree, блокування витоків через псевдо-ФС /proc (/proc/ {modules, keys, key-users}, /proc/sys/kernel/* і /proc/sys/vm/mmap_min_addr, /proc/kallsyms), покращення рандомізації адрес у просторі користувача, додатковий захист Ptrace, посилення захисту smap та smep , можливість заборони відправлення даних через raw-сокети, блокування некоректних адрес в UDP-сокетах і перевірка цілісності процесів, що запускаються. До складу також входить модуль ядра Ksguard, орієнтований визначення спроб застосування типових руткітів.
патчі
Вивчення патчу розробниками Grsecurity виявило безліч помилок та слабких місць у коді, а також показало відсутність моделі загроз, що дозволяє адекватно судити про можливості проекту. Для наочної демонстрації того, що код написаний без застосування методів безпечного програмування, наведено приклад тривіальної вразливості в обробнику
файлу /proc/ksguard/state, що створюється з правами 0777, які мають на увазі відкриття доступу всім на запис. У функції ksg_state_write, що використовується для розбору команд, що записуються в /proc/ksguard/state, створюється буфер tmp[32], який дані записуються виходячи з розміру переданого операнда, без урахування розміру цільового буфера і без перевірки параметра з розміром рядка. Тобто. Для перезапису частини стека ядра атакуючому достатньо записати спеціально оформлений рядок /proc/ksguard/state.
static ssize_t ksg_state_write(struct file *file, const char __user *buf,
size_t len, loff_t *offset)
{
u64 value;
char tmp [32];
size_t n = 0;
if (copy_from_user(tmp, buf, len))
return -1;
value = simple_strtoul(tmp, '\0', 10);
...
Прототип експлоїту:
char buf[4096] = {};
int fd = open("/proc/ksguard/state", O_WRONLY);
if (fd >= 0) {
write(fd, buf, sizeof(buf));
close(fd);
}
Джерело: opennet.ru