Предотвращение чтения файлов из памяти в ядре xnu - PullRequest
0 голосов
/ 03 июля 2018

У меня есть файл dylib, для которого я запрещаю доступ на уровне ядра. Я использую драйвер, который прослушивает область действия kauth vnode с обратным вызовом, который предотвращает любой доступ к этому файлу.

Однако я заметил, что инфраструктура coreSymbolication может обойти этот поток авторизации после 4 попыток доступа к файлу и получить прямой доступ к файловой памяти, как это может быть показано в следующей обратной трассировке:

frame #2: 0xffffff7f87ac4784 IOStorageFamily`dkreadwrite(dkr=0xffffff8062fca3e0, dkrtype=<unavailable>) at IOMediaBSDClient.cpp:2975 [opt]
frame #3: 0xffffff80072d8734 kernel`spec_strategy(ap=<unavailable>) at spec_vnops.c:2409 [opt]
frame #4: 0xffffff8007282212 kernel`buf_strategy(devvp=<unavailable>, ap=<unavailable>) at vfs_bio.c:1379 [opt]
frame #5: 0xffffff800728ad42 kernel`cluster_io [inlined] VNOP_STRATEGY(bp=0xffffff8062fca3e0) at kpi_vfs.c:5696 [opt]
frame #6: 0xffffff800728ad0b kernel`cluster_io(vp=0xffffff80145a8c18, upl=0xffffff80107f7700, upl_offset=0x0000000000004000, f_offset=40960, non_rounded_size=0, flags=141, real_bp=<unavailable>, iostate=<unavailable>, callback=<unavailable>, callback_arg=<unavailable>) at vfs_cluster.c:1801 [opt]
frame #7: 0xffffff800728b8f5 kernel`cluster_pagein_ext(vp=0xffffff80145a8c18, upl=0xffffff80107f7700, upl_offset=<unavailable>, f_offset=24576, size=<unavailable>, filesize=-549414335464, flags=<unavailable>, callback=<unavailable>, callback_arg=<unavailable>) at vfs_cluster.c:2171 [opt]
frame #8: 0xffffff800728b7e5 kernel`cluster_pagein(vp=<unavailable>, upl=<unavailable>, upl_offset=<unavailable>, f_offset=<unavailable>, size=<unavailable>, filesize=<unavailable>, flags=0) at vfs_cluster.c:2116 [opt]
frame #9: 0xffffff7f893d60be
frame #10: 0xffffff80075a811a kernel`vnode_pagein [inlined] VNOP_PAGEIN(size=24576, flags=341478424, ctx=<unavailable>) at kpi_vfs.c:5273 [opt]
frame #11: 0xffffff80075a80d3 kernel`vnode_pagein(vp=0xffffff80145a8c18, upl=<unavailable>, upl_offset=<unavailable>, f_offset=24576, size=<unavailable>, flags=341478424, errorp=<unavailable>) at vnode_pager.c:593 [opt]
frame #12: 0xffffff80070dc119 kernel`vnode_pager_cluster_read(vnode_object=0xffffff80145a48e8, base_offset=24576, offset=<unavailable>, io_streaming=<unavailable>, cnt=0x0000000000004000) at bsd_vm.c:851 [opt]
frame #13: 0xffffff80070dbe93 kernel`vnode_pager_data_request(mem_obj=0xffffff80145a48e8, offset=24576, length=<unavailable>, desired_access=<unavailable>, fault_info=<unavailable>) at bsd_vm.c:639 [opt]
frame #14: 0xffffff80070eb011 kernel`vm_fault_page [inlined] memory_object_data_request(memory_object=<unavailable>, offset=<unavailable>, length=4096, desired_access=1, fault_info=<unavailable>) at memory_object.c:2134 [opt]
frame #15: 0xffffff80070eaffb kernel`vm_fault_page(first_object=0xffffff8011d64a00, first_offset=4096, fault_type=1, must_be_resident=0, caller_lookup=0, protection=0xffffff806717be90, result_page=<unavailable>, top_page=<unavailable>, type_of_fault=<unavailable>, error_code=<unavailable>, no_zero_fill=<unavailable>, data_supply=0, fault_info=<unavailable>) at vm_fault.c:1770 [opt]
frame #16: 0xffffff80070ef82a kernel`vm_fault_internal(map=<unavailable>, vaddr=<unavailable>, caller_prot=1, change_wiring=<unavailable>, wire_tag=0, interruptible=2, caller_pmap=<unavailable>, caller_pmap_addr=<unavailable>, physpage_p=<unavailable>) at vm_fault.c:4610 [opt]
frame #17: 0xffffff8007188f92 kernel`user_trap [inlined] vm_fault(map=<unavailable>, fault_type=<unavailable>, change_wiring=0, wire_tag=0, interruptible=2, caller_pmap_addr=0) at vm_fault.c:3416 [opt]
frame #18: 0xffffff8007188f6f kernel`user_trap(saved_state=0xffffff800f07b7a0) at trap.c:1083 [opt]

У меня вопрос, как можно получить ошибку памяти в файловой памяти, не открывая ее сначала (kauth предотвращает открытый системный вызов). Какой системный вызов на самом деле может инициализировать поток ядра, обратная трассировка которого указана выше?

спасибо

1 Ответ

0 голосов
/ 13 июля 2018

Предположительно, файл открывается и отображается во время загрузки исполняемого файла хоста, в котором он указан как зависимость прямо или косвенно через другую зависимость. Я не знаю специфики в мучительных деталях, но, предположительно, код для загрузки динамических библиотек в dyld, но ядро ​​может в какой-то степени сотрудничать. Я знаю, что dyld выполняет некоторое кеширование, поэтому возможно, что файл не загружается напрямую, но вместо этого в процесс отображается уже сохраненная в памяти кэшированная версия. Если это правда, это, вероятно, будет трудно предотвратить. Я бы проверил исходный код dyld и выяснил, как загружаются динамические библиотечные зависимости исполняемого файла, и посмотрел, где, если угодно, вы можете его перехватить.

...