PetrSec Notes
94 subscribers
8 photos
9 files
12 links
Привет!

Меня зовут Пётр, я Application Security Engineer в Айдеко - занимаюсь фаззингом, статическим анализом, уязвимостями.
Тут пишу о всём, что мне интересно.

Мой GitHub - https://github.com/petrvaganoff
Личка - @petrsec
Download Telegram
Deref of Null в интерпретаторе CPython 3.11+ 💥

Примерно полтора месяца назад я нашёл интересный баг в модуле sqlite3 стандартной библиотеки CPython. После сборки под статическим анализатором Svace и запуска анализа, Svacer подсветил маркер DEREF_OF_NULL.RET.LIB (CWE-476) в Modules/_sqlite/connection.c - возможное разыменование нулевого указателя cls. NULL может вернуть функция sqlite3_aggregate_context() несколькими строками выше. Причем после неё и так уже стоит
assert(cls != NULL);

Но, как известно assert() работает только в отладочных сборках, но не в релизе. Значит в релизе оно вполне может выстрелить, потому что по коду других причин почему это не может случиться я не нашел)

Далее я попытался понять каким образом могу вызвать выполнение этой строки, причем, чтобы пришел именно NULL после sqlite3_aggregate_context(). И, через некоторое время у меня был готов минимальный репродюсер:
import sqlite3

class A:
def value(self):
return 1

con = sqlite3.connect(":memory:")
con.create_window_function("f", 1, A)

con.execute("CREATE TABLE t(x)")
con.execute("INSERT INTO t VALUES (1)")

con.execute("""
SELECT f(x)
OVER (ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
FROM t
""").fetchall()

Этот код, запущенный через REPL, роняет интерпретатор с SIGSEGV, у меня падает вот так:
zsh: segmentation fault (core dumped)  python3


Оценить критичность находки в тот момент было для меня затруднительно, но было понятно одно - данный баг может привести к DoS только в случае когда:
1. В скрипте регистрируется custom window function при работе с SQLite.
2. Скрипт позволяет внешнему пользователю управлять содержимым SQL запроса. То есть этот баг может использоваться только в цепочке эксплойтов. К примеру SQL-injection + этот DoS.

Поскольку, я не до конца понимал насколько вообще распространён код подобного вида в продакшене, на всякий случай решил этот баг отправить через приватный Security Advisories на GitHub. В результате переписки с мэйнтейнерами выяснилось что это обычный баг, он недостижиим извне - поэтому следующим шагом я создал публичный issue - в нем подробнее описаны технические детали. Даже хотел в ближайшее время заняться и исправить этот баг, но меня немного опередили)) Нашелся доброволец, который вроде как починил это через Claude Code😀, фикс пока на стадии ревью и вроде выглядит +- норм.

В результате всего мне удалось много узнать о том, как вообще выстроен процесс репортинга уязвимостей и багов в CPython.

А ещё, мне кажется, находить подобные баги можно так же методом фаззинга самого интерпретатора CPython через кастомные мутаторы AFL++ на основе формальной грамматики python3, как нибудь попробую эту тему изучить.

#bug #python #svace #opensource
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7