novitoll_ch
806 subscribers
68 photos
30 videos
15 files
139 links
By @novitoll

Diverse interests in science and IT to share and to memo for personal historical reasons.

All information provided on this channel is for educational, informational purposes only.
Download Telegram
немного продолженние темы по Stack overflow: Stack clashing vs jumping vs smashing.
В Кернеле есть фича для автоматического расширения стэка (рассматриваем stack grows down варианты x86_64, arm etc.):
1. если stack pointer (esp, rsp) доходит вниз до начала стэк фрейма и внизу уже незамапленная область, то происходит Page fault.
2. Кернел обрабатывает PF, экспандит стэк путем уменьшение адреса начала стэка
3. Соответственно, если внизу замапленна область другого процесса, то это приводит к stack clash.

В 2010-м году, Линус каммитает фикс с защитой в один PAGE_SIZE (1 << 12 = 4096 B, PAGE_SHIFT = 12 [x86_64, arm, misp etc.]), чтобы при попытке экспандии стэка, была проверка на "попадет ли esp/rsp в stack_guard_page" (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=320b2b8de12698082609ebbc1a17165727f4c893).

В 2017-м году (v4.12) один кернел разраб увеличивает эту область до 1 MB (256UL << PAGE_SHIFT) (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1be7107fbe18eed3e319a6c3e83c78254b693acb)

Эта текущий гэп, через который надо "перепрыгнуть" для того, кто пишит эксплоиты, чтобы сделать stack clashing.

Ну и Stack smashing - это когда мы перезатираем stack другой области памяти или даже при execstack вызываем шеллкод, как пример, в стэке.
#linux_mm
Немного про Stack clashing, smashing, jumping.
-- stack clashing: в архитектуре (amd64, i386/x86_64), где стэк растет вниз, области памяти стэка и кучи/замапленной памяти могут встретится ("clash"). Линукс кернел позволяет динамично расширять user-process стэк до предела RLIMIT_STACK если %rsp достиг до конца фрейма (до %rbp получается), CPU вызывает PAGE FAULT, OS хендлит это и вызывает функцию expand_downwards(), где есть проверка на Stack Guard Pages. (Писал про это выше)
-- stack jumping -- как раз таки перепрыгивание через stack guard page. Интересно, считается ли NOP slide stack jumping? 😒
-- stack smashing -- перезаписывание стэка произвольным значением, например, адреса возврата программы в случае крэша ret можно захэндлить и перезатереть еще одной %rip, чтобы он прыгнул в твой шеллкод посреди NOP.

Мораль: не используйте alloca() и бережно аллоцируйте в стэк :)
#linux_mm #systemd
*ret2libc. Part 1.*
_"..exploiting buffer overflows should be an art."_ @ Solar Designer

Продолжаем тематику моего изучения buffer overflow. В этой части, расскажу, что перед тем как сразу идти на эксплоиты как какой-то scriptkiddie 🙂 я бы хотел понять "почему и для чего?". На этот раз, мы сталкиваемся с реальным миром, где у нас не выключено `gcc -execstack`, где есть защита со стороны хардвара (CPU -> NX bit). Вот начал копаться в ret2libc с видео туториала LiveOverflow YT канала. За 10:37 минут, Фабиан рассказал по быстрому как вместо того, чтобы загружать пэйлоад с `/bin/sh` CPU инструкциями, который не будет работать в реальном мире, обойти защиту NX bit [1]. Перед тем как дойти до части NX, давайте почитаем сообщение об открытии *ret2libc* в 1997-м году от автора Solar Designer [2] (Alexander Peslyak). Это привело меня в чувство ностальгии, которой мне наиву не встретить из-за того, что в 1997 solar было 20 лет.
https://insecure.org/sploits/linux.libc.return.lpr.sploit.html

В туториале от LiveOverflow упоминается про ROP (return oriented programming), я про него слышал, как возможность обхода ASLR путем `jmp|call *some instr with pointer`, но пока закончим с ROP. Дальше в *ret2libc part 2* продолжим на тему stack buffer overflow + адрес нужной нам функции в libc.so. На выходных, думаю, продолжить. Stay tuned.
*********************

[1] *W^X* - Write XOR Execute фича, первая появившаяся в OpenBSD (2003 г), где страницы помечены флагом с ИЛИ Writeable, ИЛИ Executable, совокупные привелегии запрещены. Это как раз таки является защитой для нашего shellcode execution в стэке в прошлом посте. Не знал про это. В терминологии Windows упоминается как *DEP* (Data Execution Prevention), у Линукса - это идет вместе с патчем *PaX* (анонимные контрибьюторы, которые также являются автором ASLR 👽)

Имплементация для этого фичей является *NX bit*. Intel - XD bit (eXecute Disable), AMD - EVP bit (Execution Virus Protection), ARM - XN bit (eXecute Never).

В Вики упоминается: _" a feature normally only found in Harvard architecture processors. However, the NX bit is being increasingly used in conventional von Neumann architecture processors, for security reasons."_.

Тут я задался вопросом: "а что такое это von Neuman arch?" [3]. Нашел в мануал Intel, что NX bit - это 63-й бит (most significant bit) в адресе, который задает флаг включен ли W^X или нет. Кстати, в Линуксе эту фичу можно управлять сисколлом `mprotect`. Интересно, что можно изменять RWX правила даже на существующих адрес маппинге процесса. Хмм.. Также LiverOverflow упоминает, что во многих IoT девайсах нету PaX, то есть отсутствует защита ASLR, NX. Надо бы проверить :)

[2] - Solar Designer также являтся автором *john the ripper* (тулзой для крэкинга пароля), openwall, 1st heap-buffer-overflow exploit, ret2libc. Мне понравился его креативный доклад с философвской/политической/рациональной точки зрения на ИБ.
https://www.youtube.com/watch?v=4Y91dJ--1NM.

[3] von Neuman arch vs Harvard arch. --- TL;DR: Насколько понял, это две концептуальные модели микроархитектур, которые являются основой существующих ARM, AMD, x86 etc. Насколько понял разница в том, что если в von Neuman для процесса нужно сделать 2 cycles для загрузки CPU инструкции и данных, так как физический используется 1 шина (bus), где для Harvard arch. используется 2 шины и загрузка инструкции и данных выполняется за 1 cycle. Intel считается "pure von Neuman arch". Также существует Advanced Harvard arch. Но не углублялся в детали. Узнал, что у von Neuman есть инструкции и это напоминает текущие Intel инстр.:

```
--------------------------------------
von Neuman | Intel (32-bt)
--------------------------------------
MAR (Memory Addr Reg)|%esp?
MDR (Memory Data Reg)| %edx
AC (Accumulator)| %eax
PC (Program Counter) | %ecx
CIR (Current Instr Reg)%eip
```


#linux_mm #ret2libc
_Linux OOM killer, Part 1._

Надо разобраться как работает Out-of-memory killer в ядре. Так как, это Linux Memory Management (является самой сложной частью ядра[2]), то надо также пройтись по механизмам работы и траблшутинга ядра с памятью.

`read()` сисколл считывает до 2-х GB памяти в x86, x86_64 арх.

Допустим 3 кейса, если запустить Питон скрипт с `open("/dev/urandom", "rb").read(X)` в системе без swap:
1) и с RAM >= X, то по сисколлам будет следующее `mmap(XGB) = 0xdeadbeef; => read() = 2GB; read() = 2GB; ... => munmap(0xdeadbeef);`. Т.е. мы замаплим файл и будем возвращать в юзерспейс по 2 гига пока не считаем весь файл < X.
2) и с RAM < X, то мы получим ENOMEM при `mmap`. Еще надо учитывать, что у нас стоит дефолтное значение `vm.overcommit_memory = 0` [3]
3) и с RAM >= X, но тут мы форкаем процесс в N раз, да так, что N * X > RAM.
В начале, address space child процессов помечены как COW (copy-on-write) - шарят один и тот же address space, что и парент, до тех пор пока мы не начали использовать эту память. Ну или аналогичный юзкейз можно сделать и без форков, а когда другие процессы мапят память безвозвратно `munmap / free`. В итоге, получается, что ядро отдает `mmap` область памяти для процессов, которые по 2 Гига продолжают считывать в память и когда истекает физическая память с Page Fault, то выходит на охоту OOM killer, чтобы убить жирные процессы, ceteris paribus. Но и получается такие моменты, когда в системе происходит момент, когда OOM killer в своем рекурсивном `goto retry` не может убить процесс[6] (через SIGKILL), и система "зависает", что технический говоря, входит в livelock[7].

Если прогуглить "Linux OOM killer", то прочитывая статьи по ссылкам lwn.net etc., то выстраивается некая хронология по которой можно понять траекторию развития этой важной фичи ядра. В *mm/oom_kill.c* учитывается архитектура MMU - NUMA vs SMP[4], есть ли cpusets[5], в каком cgroups находится процесс, какие эвристические метрики у процесса `/proc/xxx/oom_score` etc. Вот, в этих критериях и развитии OOM killer-а надо разобраться. Stay tuned.

[1] https://lwn.net/Articles/317814/
[2] "Understanding Linux Kernel, 3-edition, 29p”
[3] https://www.kernel.org/doc/Documentation/vm/overcommit-accounting
[4] NUMA (non-uniform memory access) - изоляция на уровне железа микропроцессоров с DRAM по локальным шинам, тем самым увеличивая КПД за счет эффективных cache hit-miss в L1, L2 и зашаренных L3 уровней.
[5] cpuset - изоляция на уровне софта путем `mbind(), set_mempolicy()` для микропроцессеров и memory node. Эффективна в NUMA архитекутре.
[6] https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L862-L913
[7] Livelock - разновидность deadlock, только здесь процесс меняет свое состоение (если `read` -> uninterr. sleep (D), sleep (S), running (R) etc.), но при этом блочится из-за нехватки ресурсов. Интересное узнал, что одним из классических решении deadlock-а является *Banker's algorithm* (E. Dijkstra, 1962-1963) по схеме работы банка: "Приходит клиент в банк, просит денег, банкир проверяет хватит ли банку отдать сумму клиенту, и при этом оставить в запасе еще у себя денег". Но данный алгоритм в ядре не используется из-за динамичности памяти. Используется методы синхронизации RCU (read-copy-update), описанных в "linux/kernel/rcu".
#linux_mm
exploit.c
8.2 KB
SecCon_2020 CTF, kstack: #rop SMEP bypass (SMAP disabled), #userfaultfd #kUAF #doublefree #setxattr #uaf #linux

P.S.: After getting shell, exploit crashes due to misaligned RSP. So proper mmap for fake stack is required. Only this part. Exploitation is correct. Note that SMAP is disabled in this task

Exploit was written per "smallkirby" writeup
https://lwn.net/Articles/925371/

EEVDF replaced, in v6.6 update, Linux kernel scheduler CFS, which had been since v2.6.23.

AFAIU, it computes the process taken "fair" time by new metric "lag" that's calculated with factors like process priority, "virtual deadline" with process allocated time consideration.

Interesting, how much "old" stuff can be optimized with other algorithms' alternatives?
EEVDF algo was est. in 1995

#linux
I wrote my 1st blog post on my website and started with:

Mutt setup with Gmail labels for Linux kernel emails

https://novitoll.com/posts/2024-4-09/mutt.html

This is my 1st experience with mutt, so configs are not advanced per se.

#linux
The Psychology of TikTok Duets: Analyzing Collaborative Content