#windows #kernel #windbg
Вопрос:
Я пытаюсь изучить маркер и дескриптор безопасности при проверке доступа. В учебных целях я написал следующую программу, которую я мог бы использовать для тестирования:
#include <iostream>
#include <windows.h>
int wmain( int argc, wchar_t *argv[], wchar_t *envp[] )
{
if (argc < 3)
{
std::cerr << "Usage: OpenWithAccess <file> <read/write> [ -d ]" << std::endl;
return ERROR_INVALID_PARAMETER;
}
if (argc == 4 amp;amp; !_wcsicmp(argv[3], L"-d"))
{
__debugbreak();
}
HANDLE hFile = ::CreateFile(argv[1], !_wcsicmp(argv[2], L"write") ? FILE_ALL_ACCESS : GENERIC_READ, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile != INVALID_HANDLE_VALUE)
{
std::wcout << L"Successfully opened " << argv[1] << L" with " << argv[2] << L" access" << std::endl;
}
else
{
std::wcout << L"Failed to open " << argv[1] << L" with " << argv[2] << L" access, error = " << ::GetLastError() << std::endl;
}
return ERROR_SUCCESS;
}
Когда я запускаю эту программу OpenWithAccess.exe c:Windowssystem32driversetchosts write -d
как обычный пользователь, я знаю, что вызов проходит через проверку Ntaccess (которая завершается ошибкой с отказом в доступе).
В отладчике ядра я могу установить точку останова в nt!NtCreateFile выглядит так:
bp /p <myprocessaddress> nt!NtCreateFile
Это прекрасно ломается. Однако:
bp /p <myprocessaddress> nt!NtAccessCheck
Не ломается. Однако, если я ворвусь, nt!NtCreateFile
а затем просто продолжу работать t
, чтобы отслеживать через API, в котором я в конечном итоге окажусь nt!NtAccessCheck
. Так почему же одна точка останова работает, а другая нет?
Я должен отметить, что если я запущу это без моего текущего процесса, как:
bp nt!NtAccessCheck
Он действительно ломается, но не в моем текущем потоке, который пропускается, хотя я знаю, что он запущен, и перехватывается какая-то другая проверка доступа. Того, кого я ожидаю, никогда не поймают. Чего мне не хватает?
Комментарии:
1. Что произойдет, если вы это сделаете
bu nt!NtAccessCheck ".if (@$proc != <yourproc>) { gc; }"
? Не обращайте внимания на производительность для целей этого упражнения.
Ответ №1:
попробуйте установить точку останова на nt!Проверьте и проверьте, предоставляет ли он вам достаточно информации
я просто скомпилировал код и прокрутил его, он попал в nt!Проверка наличия
0: kd> !process @$proc 3f
PROCESS ffffd10fc1503080
SessionId: 1 Cid: 17b8 Peb: 55e8cf000 ParentCid: 0bd4
DirBase: 0ef40002 ObjectTable: ffffaa883bdb1240 HandleCount: 32.
Image: fufu.exe
нажмите bp3
0: kd> bp /p ffffd10fc1503080 nt!NtCreateFile
0: kd> bp /p ffffd10fc1503080 nt!IopCreateFile
0: kd> bp /p ffffd10fc1503080 nt!NtAccessCheck
0: kd> bp /p ffffd10fc1503080 nt!SeAccessCheck
0: kd> g
Breakpoint 0 hit
nt!NtCreateFile:
fffff802`4c8974e0 4881ec88000000 sub rsp,88h
1: kd> g
Breakpoint 1 hit
nt!IopCreateFile:
fffff802`4c897570 4c894c2420 mov qword ptr [rsp 20h],r9
1: kd> g
Breakpoint 3 hit
nt!SeAccessCheck:
fffff802`4c3bd730 48895c2410 mov qword ptr [rsp 10h],rbx
1: kd> kb
# RetAddr Call Site
00 fffff802`4c942c28 nt!SeAccessCheck
01 fffff802`4c9417bf nt!ObpLookupObjectName 0x188
02 fffff802`4c897974 nt!ObOpenObjectByNameEx 0x1df
03 fffff802`4c897559 nt!IopCreateFile 0x404
04 fffff802`4c46d785 nt!NtCreateFile 0x79
05 00007fff`2c6e0114 nt!KiSystemServiceCopyEnd 0x25
06 00007fff`295ee5d6 ntdll!NtCreateFile 0x14
07 00007fff`295ee2c6 KERNELBASE!CreateFileInternal 0x2f6
08 00007ff7`afaa12ed KERNELBASE!CreateFileW 0x66
09 ffffffff`fffffffe fufu!wmain 0xed [c:usersxxxdesktopfufufufu.cpp @ 17]
0a 00007ff7`00000002 0xffffffff`fffffffe
0b 00007ff7`afb39358 0x00007ff7`00000002
0c 00007ff7`afaa1032 fufu!std::classic_locale$initializer$
0d 00007ff7`00000004 fufu!`dynamic initializer for 'std::numpunct<wchar_t>::id'' 0x12
0e 00000000`00000080 0x00007ff7`00000004
0f 00000000`00000000 0x80
1: kd> dt nt!_SECURITY_DESCRIPTOR @rcx
0x000 Revision : 0x1 ''
0x001 Sbz1 : 0 ''
0x002 Control : 0x10
0x008 Owner : 0xffffd10f`bb148fb0 Void
0x010 Group : 0xffffd10f`bb148fb0 Void
0x018 Sacl : 0xffffaa88`36e05c10 _ACL
0x020 Dacl : (null)
Комментарии:
1. Могу я спросить, что это за ОС? Я пытался прерваться
nt!SeAccessCheck
изначально, так как это то, чего я ожидал, но это не сработало. Я только что разобралnt!ObpLookupObjectName
свой Win10 , и он на самом деле не звонитSeAccessCheck
, а скорее звонитSeAccessCheckWithHint
, что кажется недокументированным вариантом. К счастью, я могу сломаться на этом, и, похоже, у него очень похожие параметры, которые дают мне SD и токен. Спасибо, что подкрутили это, хотя очень интересно, что в вашей системе все по-другому.2. это было на устаревшей виртуальной машине с ознакомительной версией w10 для предприятий. неудивительно, что все эти API безопасности меняются каждый третий день или, может быть, даже каждый день, если ваша машина сказала, пожалуйста, не выключайте, это означает, что была реализована некоторая безопасность с помощью somescurity