-
Notifications
You must be signed in to change notification settings - Fork 421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HookNtSetContextThread race condition and detection vector #44
Comments
I found another issue with the current HookNtSetContextThread: Here's a proof of concept code that erases all hardware breakpoints from another process, even with TitanHide enabled: DWORD pidToStealFrom = /* put some pid here */;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snapshot != INVALID_HANDLE_VALUE)
{
THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(snapshot, &te))
{
do
{
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
sizeof(te.th32OwnerProcessID) && te.th32OwnerProcessID == pidToStealFrom)
{
HANDLE threadHandle = OpenThread(THREAD_ALL_ACCESS, false, te.th32ThreadID);
if(threadHandle == NULL)
continue;
printf("Stealing hw bp's from Process 0x%04x Thread 0x%04x\n", te.th32OwnerProcessID, te.th32ThreadID);
SuspendThread(threadHandle); // probably not needed
CONTEXT threadContext = {};
threadContext.ContextFlags = 0x10;
SetThreadContext(threadHandle, &threadContext);
ResumeThread(threadHandle); // probably not needed
}
te.dwSize = sizeof(te);
}
while (Thread32Next(snapshot, &te));
}
CloseHandle(snapshot);
} The tricky thing here is that if you patch this issue, maybe debuggers such as x64dbg won't work either? |
Heya,
Generally TitanHide is fitting my needs, but I’ll be happy to review any
PRs you might have. As you can probably tell by the code this was the first
driver I ever wrote and it’s just a bunch of rootkits and other crap put
together so don’t worry about the quality of the code ^^
…On Thu, 27 Feb 2020 at 19:54, dauthleikr ***@***.***> wrote:
I found another issue with the current HookNtSetContextThread:
It does not check if the target of the SetThreadContext call is hidden,
instead it checks if the process that called the function is hidden. This
usually the same process, but it's possible that another process protects
the debugged process by constantly removing it's hardware breakpoints.
Here's a proof of concept code that erases all hardware breakpoints from
another process, even if with TitanHide enabled:
DWORD pidToStealFrom = /* put some pid here */;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);if (snapshot != INVALID_HANDLE_VALUE)
{
THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(snapshot, &te))
{
do
{
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
sizeof(te.th32OwnerProcessID) && te.th32OwnerProcessID == pidToStealFrom)
{
HANDLE threadHandle = OpenThread(THREAD_ALL_ACCESS, false, te.th32ThreadID);
if(threadHandle == NULL)
continue;
printf("Stealing hw bp's from Process 0x%04x Thread 0x%04x\n", te.th32OwnerProcessID, te.th32ThreadID);
SuspendThread(threadHandle); // probably not needed
CONTEXT threadContext = {};
threadContext.ContextFlags = 0x10;
SetThreadContext(threadHandle, &threadContext);
ResumeThread(threadHandle); // probably not needed
}
te.dwSize = sizeof(te);
}
while (Thread32Next(snapshot, &te));
}
CloseHandle(snapshot);
}
If you guys want I can submit a PR for all these issues, but I have no
experience writing drivers so I might produce bugs/vulnerabilities ...
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#44?email_source=notifications&email_token=AASYFGNMO76BN4LWM3L322DRFAD65A5CNFSM4K4N3TW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENFQQQQ#issuecomment-592119874>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASYFGLY57LWOCR7CU2RWFLRFAD65ANCNFSM4K4N3TWQ>
.
|
…g registers, fix race condition for stripping ContextFlags
Closing this for now, a proper implementation is not trivial, and I doubt anybody really abuses this specific vector |
I think the vector is still there so I'll keep the issue open :) |
I am aware that detection vectors and race conditions have low priority due to nobody abusing them, but this one may be in actual use (not 100% sure yet, as understanding obfuscated code without breakpoints is not fun).
Race condition
TitanHide strips the
ContextFlags
inHookNtSetContextThread
so that the debug registers will not be overwritten:However TitanHide assumes that the
ContextFlags
cannot be set after the strip, and just passes theContext
pointer to the actual function:This gives the caller plenty of time to try to un-strip the
ContextFlags
- consider the following proof of concept code:Detection vector
An additional detection vector that I believe is being used in my target program is that
GetThreadContext
does not return a previously set hardware breakpoint when running under TitanHide. Proof of concept:Possible fix
I understand that you guys are not trying to be super stealthy, but at least copying the
Context
before checking it and passing it on, to avoid the race condition, would be nice :)The text was updated successfully, but these errors were encountered: