Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
/* https://fstarlang.github.io/lowstar/html/Introduction.html#the-essence-of-low
Consider the following very simple program:
module Intro
module P = LowStar.Printf
module C = LowStar.Comment
module B = LowStar.Buffer
open FStar.HyperStack.ST
open LowStar.BufferOps
let main (): St Int32.t =
push_frame ();
let b: B.buffer UInt32.t = B.alloca 0ul 8ul in
b.(0ul) <- 255ul;
C.comment "Calls to printf are desugared via meta-programming";
let s = "from Low*!" in
P.(printf "Hello from %s\nbuffer contents: %xul\n"
s 8ul b done);
pop_frame ();
0l
....
Once compiled by the KreMLin compiler, we obtain the following C code:
*/
int32_t main()
{
uint32_t b[8U] = { 0U };
b[0U] = (uint32_t)255U;
/* Calls to printf are desugared via meta-programming */
Prims_string s = "from Low*!";
LowStar_Printf_print_string("Hello from ");
LowStar_Printf_print_string(s);
LowStar_Printf_print_string("\nbuffer contents: ");
LowStar_Printf_print_lmbuffer_u32((uint32_t)8U, (uint32_t *)b);
LowStar_Printf_print_string("\n");
return (int32_t)0;
}
Какая-то компилируемая в сишку хренотень с завтипами, разрабатываемая в Microsoft Research
Нахрен кстати им генерить какую-то там сишку, пусть бы сразу в какое-нибудь middle-end представление компилятора набрасывали (в Clang это LLVM-байткод, в GCC это байткод GIMPLE). Заодно пусть все оптимизации и трансформации докажут формально.
Теперь понял. Это кэш одного из возможных состояний (наиболее вероятного). Если нужно перейти к другому (к эвалам всяким), придётся переключаться обратно к честной интерпретации.
Кстати, а как реализована библиотека «Phobos» для языка «D»? Ну там всякие «std.functional», где код передаётся строками? Она в рантайме вызывает модуль для компиляции кода и инжектит сгенерированный код?
В "D", если я не туплю, в рантайме ничего не генерится, это труъ конпелятор. Просто он умеет выполнять какое-то ограниченное подмножество "D" в компайлтайме и отдавать строки из mixin своему же парсеру.
Джитня реализуема через переключения mprotect()-ом из "rw-" в "r-x". Можно и такое переключение запретить, но тогда надо и mmap с PROT_EXECUTE запретить, и dlopen запретить, и еще /proc/self/mem запретить, и execve запретить (ведь можно насрать байтиками в файл с нужными разрешениями и тупо запустить его)
Ну тут достаточно запретить грузить файлы, которые не помечены как исполняемые. А дальше можно на уровне файлухи вырубить "x", а на файлухе с исполняемыми файлами отобрать у юзера "w" и хрен ты насрёшь байтиков в исполняемый файл.
Ну тут можно пойти дальше и через selinux запретить привилегированным процессам шариться по юзерским каталогам. Вообще. Всем. Ну кроме какой-нибудь бекапилки (но у неё можно отобрать write на систему) и тулов для управления юзерами (им достаточно delete и create, без чтения и записи обойдутся).
В интеловских процах сейчас тоже такая фишка есть, кстати (SMAP и SMEP).
https://rdot.org/forum/showthread.php?p=39356
>SMEP
>Не позволяет процессору, будучи в ring0, выполнять код со страниц, помеченных флагом User.
>Таким образом, столь привычные способы эксплуатации, когда есть возможность перезаписать указатель в какой-нибудь структуре в ядре адресом в юзер-моде, заммапить этот адрес и ждать, что ядро прыгнет на него исполнять наш шелл-код, перестают работать.
>SMAP
>Не позволяет процессору, будучи в ring0, обращаться (например, читать) к страницам, помеченным флагом User.
>Поскольку ядру это необходимо в работе, были введены 2 новые инструкции, которые должны использоваться перед и после обращением к страницам памяти с флагом User: CLAC/STAC.
>Использование SMAP незначительно увеличивает размер ядра и уменьшает скорость работы.
Это вообще не об этом. Запретить что-то читать и писать на жесткий диск этим не выйдет
Ну я про аналогию, что супер-юзер не может лезть к данным обычного юзера и исполнять его код. Суть уязвимостей ведь абсолютно такая же -- кривой привелигированный код без причины взял что-то у юзера и неаккуратно поюзал.
Open: повёрнутость на безопасности, отсутствие свистелок и пирделок (минимализм), много фишек для сети (CARP, качественный файрвол pf), очень хорошая документация в man.
Net: максимальная переносимость, RUMP kernel.
Free: максимально производительный сервер на x86, драйверов очень много, большое коммунити, хороший handbook.
DragonFly: максимальная многопоточность (раньше всех убрали локи в ядре чтобы использовать все ядра), своя файловая система похожая на ZFS
На сервере приложений логично иметь free, на роутере или бастионе Open. Остальное скорее академический интерес
> Новые то я и в крестах могу высрать при желании.
Ты и в крестах можешь mprotect-нуть сегмент с исполняемым кодом и переписать байтики опкодов в какой-то там функции и потом эту патченную хуйню исполнять.
Загрузка/генерация новых классов не ломает AOT. Старый скомпилированный код либо их вообще не увидит либо будет к ним обращаться через какие-то уже известные ему интерфейсы.
- Хранить в метаинфе для рефлексии ссылку на нативный метод. Тогда линкер его не удалит даже если все точки вызова заинлайнились и нам всегда будет что вызвать.
- Хранить в метаинфе оригинальный IL метода. Тогда его всегда можно воссоздать на лету и проинтерпретировать/заджитить.
Still in the original paper, one may access a buffer index, then select a number of fields.
let uint128_high (x: B.buffer uint128): Stack UInt64.t
(requires fun h -> B.live h x /\ B.length x = 1)
(ensures fun h0 _ h1 -> B.live h1 x)
=
(x.(0ul)).high
Тогда еще надо чтоб бесконечное адресное пространство, чтоб указатели были бигинтами
Только зачем тогда что-то выделять в бесконечном адресном пространстве, если всю хуйню можно в бигинте хранить?
j123123 # 0
JloJle4Ka # 0 ⇈
ASD_77 # 0 ⇈
bormand # 0 ⇈
Да, это не труъ AOT. Но приложухи после него вполне шустро работают.
PayToiletsGovno # 0 ⇈
bormand # 0 ⇈
guest # 0 ⇈
bormand # 0 ⇈
Ну вот... т.е. это скорее стартовый снепшот для JIT'а, чем нативный образ.
PayToiletsGovno # 0 ⇈
Кстати, а как реализована библиотека «Phobos» для языка «D»? Ну там всякие «std.functional», где код передаётся строками? Она в рантайме вызывает модуль для компиляции кода и инжектит сгенерированный код?
https://dlang.org/phobos/std_functional.html
bormand # 0 ⇈
PayToiletsGovno # 0 ⇈
PayToiletsGovno # 0 ⇈
Дизасм:
И ещё куча питушни для реализации writeln. Фактически writeln — это крестошаблон.
PayToiletsGovno # 0 ⇈
bormand # 0 ⇈
Да он и сейчас вполне норма... JIT'ы ведь работают.
PayToiletsGovno # 0 ⇈
guest # 0 ⇈
точнее создать можно, загрузить нельзя
bormand # 0 ⇈
MAKAKA # 0 ⇈
В base system таких файлов нет
bormand # 0 ⇈
В винде такое только в ядре решились сделать.
guest # 0 ⇈
j123123 # 0 ⇈
guest # 0 ⇈
да, так тоже можно)
bormand # 0 ⇈
Ну тут достаточно запретить грузить файлы, которые не помечены как исполняемые. А дальше можно на уровне файлухи вырубить "x", а на файлухе с исполняемыми файлами отобрать у юзера "w" и хрен ты насрёшь байтиков в исполняемый файл.
PolinaAksenova # 0 ⇈
j123123 # 0 ⇈
Надо еще убедиться в том, что нет таких готовых исполняемых файлов, которые можно было бы перезаписать.
> дальше можно на уровне файлухи вырубить "x", а на файлухе с исполняемыми файлами отобрать у юзера "w"
Их может допустим перезаписать какой-нибудь кривой говноскрипт, у которого будут такие права
bormand # 0 ⇈
Ну тут можно пойти дальше и через selinux запретить привилегированным процессам шариться по юзерским каталогам. Вообще. Всем. Ну кроме какой-нибудь бекапилки (но у неё можно отобрать write на систему) и тулов для управления юзерами (им достаточно delete и create, без чтения и записи обойдутся).
В интеловских процах сейчас тоже такая фишка есть, кстати (SMAP и SMEP).
j123123 # 0 ⇈
>SMEP
>Не позволяет процессору, будучи в ring0, выполнять код со страниц, помеченных флагом User.
>Таким образом, столь привычные способы эксплуатации, когда есть возможность перезаписать указатель в какой-нибудь структуре в ядре адресом в юзер-моде, заммапить этот адрес и ждать, что ядро прыгнет на него исполнять наш шелл-код, перестают работать.
>SMAP
>Не позволяет процессору, будучи в ring0, обращаться (например, читать) к страницам, помеченным флагом User.
>Поскольку ядру это необходимо в работе, были введены 2 новые инструкции, которые должны использоваться перед и после обращением к страницам памяти с флагом User: CLAC/STAC.
>Использование SMAP незначительно увеличивает размер ядра и уменьшает скорость работы.
Это вообще не об этом. Запретить что-то читать и писать на жесткий диск этим не выйдет
Тут надо делать поеботину примерно как в KasperskyOS https://youtu.be/zUyllpPYpXY?t=746
bormand # 0 ⇈
Ну я про аналогию, что супер-юзер не может лезть к данным обычного юзера и исполнять его код. Суть уязвимостей ведь абсолютно такая же -- кривой привелигированный код без причины взял что-то у юзера и неаккуратно поюзал.
Hacpy # 0 ⇈
> как создать безопасный промышленный шлюз
На авито за 1000 рублей купить
j123123 # 0 ⇈
На помойке найти
guest # 0 ⇈
Чтобы mmapнуть регион с W&X нужно иметь ключ в заголовке ELF
Но с обычной FS такой бинарь не загрузится: нужно прикрутить FS со спец ключом
Base system и home без такого ключа, так что там физически не может быть W&X
А usr/local с таким ключом, так что в сёрд парти софте можно срать, но на продакшен сервере такого софта лучше не иметь
Потому для SMTP, WWW, Perl, FTP и X11 у них свои сборки без W&X
HEu3BECTHblu_nemyx # 0 ⇈
guest # 0 ⇈
Net: максимальная переносимость, RUMP kernel.
Free: максимально производительный сервер на x86, драйверов очень много, большое коммунити, хороший handbook.
DragonFly: максимальная многопоточность (раньше всех убрали локи в ядре чтобы использовать все ядра), своя файловая система похожая на ZFS
На сервере приложений логично иметь free, на роутере или бастионе Open. Остальное скорее академический интерес
bormand # 0 ⇈
j123123 # 0 ⇈
А хотя какая разница, в любом случае дотнет говно, как впрочем и жаба.
bormand # 0 ⇈
j123123 # 0 ⇈
Ну CLR (он же MSIL) там модифицировать можно
https://www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time
И вот еще https://stackoverflow.com/questions/7299097/dynamically-replace-the-contents-of-a-c-sharp-method
> Новые то я и в крестах могу высрать при желании.
Ты и в крестах можешь mprotect-нуть сегмент с исполняемым кодом и переписать байтики опкодов в какой-то там функции и потом эту патченную хуйню исполнять.
bormand # 0 ⇈
Хуй там... Откуда я знаю, куда ещё конпелятор заинлайнил и заанроллил код, который я хочу запатчить?
А новый класс будет через VMT взаимодействовать, там всё чисто.
j123123 # 0 ⇈
Для этого просто нужен особый компилятор, который будет предсказуемым образом что-то инлайнить и анроллить по какой-то строгой спецификации.
bormand # 0 ⇈
bormand # 0 ⇈
Ну такое...
В одном варианте какие-то кишки рантайма/джита пинают чтобы переджитить заново, в другом варианте нативный jmp (sic!) патчат в джит-переходнике.
Может быть я невнимательно читала, но выглядит как ёбаные хаки.
Desktop # 0 ⇈
guest # 0 ⇈
j123123 # 0 ⇈
guest # 0 ⇈
https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.assemblybuilder?view=net-5.0
bormand # 0 ⇈
Загрузка/генерация новых классов не ломает AOT. Старый скомпилированный код либо их вообще не увидит либо будет к ним обращаться через какие-то уже известные ему интерфейсы.
guest # 0 ⇈
А новый класс потрогает. Да и старый может потрогать через рефлексию, и в этом случае оно разAOTится обратно кмк
bormand # 0 ⇈
Чтобы рефлексия работала я вижу джва варианта:
- Хранить в метаинфе для рефлексии ссылку на нативный метод. Тогда линкер его не удалит даже если все точки вызова заинлайнились и нам всегда будет что вызвать.
- Хранить в метаинфе оригинальный IL метода. Тогда его всегда можно воссоздать на лету и проинтерпретировать/заджитить.
guest # 0 ⇈
j123123 # 0 ⇈
guest # 0 ⇈
j123123 # 0
Struct types
Flat records are part of the original paper formalization, and are translated as regular C structs.
In the original paper, structs may be allocated within buffers.
Still in the original paper, one may access a buffer index, then select a number of fields.
j123123 # 0 ⇈
https://github.com/FStarLang/kremlin/blob/6e60e33aac1551c1ae20e4e02cb66a188935990b/include/kremlin/internal/target.h#L38
Проверка на NULL после malloc()? Не, не слышали
PolinaAksenova # 0 ⇈
j123123 # 0 ⇈
Только зачем тогда что-то выделять в бесконечном адресном пространстве, если всю хуйню можно в бигинте хранить?
guest # 0 ⇈
JloJle4Ka # 0
j123123 # 0 ⇈
JloJle4Ka # 0 ⇈
j123123 # 0 ⇈
JloJle4Ka # 0
[email protected] # 0 ⇈
https://ru.wikipedia.org/wiki/Путивльский_кремль
j123123 # 0 ⇈
gologub # 0 ⇈
gologub # 0 ⇈
JloJle4Ka # 0
Какой понятный синтаксис )))