GithubHelp home page GithubHelp logo

idov31 / nidhogg Goto Github PK

View Code? Open in Web Editor NEW
1.6K 32.0 255.0 1010 KB

Nidhogg is an all-in-one simple to use rootkit.

Home Page: https://idov31.github.io/2022/07/14/lord-of-the-ring0-p1.html

License: GNU General Public License v3.0

C++ 98.42% C 0.89% YARA 0.38% Python 0.31%
cpp cybersecurity infosec kernel red-team redteam rootkit windows windows-rootkits cyber-security

nidhogg's Introduction

Hi there! 👋

👨🏻‍💻 About me:

I am a security researcher, who has worked in various cybersecurity roles over the past 5 years. My main interests are OS internals, reverse engineering, kernel development and exploit development. In my free time, I am working on projects in the areas of evasion, persistence and injection methods for both kernel mode and user mode and based on these projects I am publishing educational papers.

📧 Feel free to contact me via Twitter, Telegram or mail regarding any of my projects or publications.


💭 Currently working on:

  • New projects
  • New papers

📙 Currently learning:

  • UEFI Development

🌐 My blog posts:


🗣️ Talks:


⚒️ Programming Languages ⚒️

                               


📊 My stats 📊


Ido's GitHub Stats

Ido's Trophies

nidhogg's People

Contributors

idov31 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nidhogg's Issues

[FEATURE] Get signature level offset dynamically

More of a QoL change than anything but instead of hardcoding offsets and choosing them from the windows version you can get it dynamically by getting the base addr of PsGetProcessSignatureLevel and looking at these bytes
ida64_7SOYoSGz6J

[BUG] I can't implement shellcode

Describe the bug
After trying to enter the shell code, i will receive the message "[ - ] Operation failed: 1784". I tried different versions of the shellcode and more than one did not work, it gives the same error. When using the standard DLL implementation, everything works.

To Reproduce
Steps to reproduce the behavior:

  1. Running function - InjectShellcodeAPC/InjectShellcodeThread/InjectDllThread/InjectDllAPC
  2. Caused...

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions

  • Windows 10 & 22H2
  • 1.0
  • InjectShellcodeAPC/InjectShellcodeThread & 1784

Additional context
Probably the problem is that it is not possible to allocate memory for shellcode, I encountered this problem in my own driver.

A few bugs to fix.

General notes

  • Pretty much every single IOCTL handler has incorrect input buffer checking.
    • size % sizeof(X) == 0 is true when size == 0, so passing an empty buffer to pretty much any of them will crash you.
    • None of the user supplied pointers in the buffers are are probed for length/alignment/actually being an UM pointer.
    • Data inside user supplied pointers is not copied and creates TOCTOU vulnerabilities.
  • For none of the things you end up signature scanning, do you validate whether the dereferenced offsets make any sense or are even inside the image.
  • Use mutexes consistently. Some of your APIs expect the caller to acquire the mutex, some of them acquire it themselves. There are no comments that indicate this and FAST_MUTEX is not recursive. IIRC there were places that the data wasn't protected by a mutex at all.
  • What is the point of copying over every single signature to its own paged pool, instead of just using it directly (or at least to a stack buffer since size is known at compile time).
  • You already use AutoLock. Same thing can be done for 90% of the allocations to avoid the goto Cleanup spam.
  • There are no SAL annotations for anything.

Bugs list

  • Incorrect iteration / removal from sparse array.

    • If you're iterating an array and decrementing its size while doing that, you'll miss/leak half of the entries.
    • If the array is sparse and you remove not from the end, decrementing the size will make you miss/leak last entry.
      for (ULONG i = 0; i < this->DisabledCallbacksCount; i++) {
      if (this->DisabledCallbacks[i].CallbackAddress == Callback->CallbackAddress) {
      DisabledCallback->CallbackAddress = this->DisabledCallbacks[i].CallbackAddress;
      DisabledCallback->Entry = this->DisabledCallbacks[i].Entry;
      DisabledCallback->Type = this->DisabledCallbacks[i].Type;
      this->DisabledCallbacksCount--;
      status = STATUS_SUCCESS;
      break;
      }
      }

      for (ULONG i = 0; i < this->Files.FilesCount; i++) {
      ExFreePoolWithTag(this->Files.FilesPath[i], DRIVER_TAG);
      this->Files.FilesPath[i] = nullptr;
      this->Files.FilesCount--;
      }

      for (ULONG i = 0; i < this->Files.FilesCount; i++)
      if (_wcsicmp(this->Files.FilesPath[i], path) == 0) {
      ExFreePoolWithTag(this->Files.FilesPath[i], DRIVER_TAG);
      this->Files.FilesPath[i] = nullptr;
      this->Files.FilesCount--;
      return true;
      }

      for (ULONG i = 0; i < this->hiddenDrivers.Count; i++) {
      RemoveHiddenDriver(i);
      }

      for (ULONG i = 0; i < this->hiddenDrivers.Count; i++) {
      if (this->hiddenDrivers.Items[i].DriverName != nullptr)
      if (_wcsicmp(this->hiddenDrivers.Items[i].DriverName, item.DriverName) == 0) {
      ExFreePoolWithTag(this->hiddenDrivers.Items[i].DriverName, DRIVER_TAG);
      this->hiddenDrivers.Items[i].DriverName = NULL;
      this->hiddenDrivers.Items[i].originalEntry = NULL;
      this->hiddenDrivers.Count--;
      return true;
      }
      }

      for (ULONG i = 0; i < this->HiddenProcesses.PidsCount; i++) {
      if (this->HiddenProcesses.Processes[i].Pid == pid) {
      entry = this->HiddenProcesses.Processes[i].ListEntry;
      this->HiddenProcesses.Processes[i].Pid = 0;
      this->HiddenProcesses.PidsCount--;
      break;
      }
      }

      for (ULONG i = 0; i < this->ProtectedThreads.TidsCount; i++)
      if (this->ProtectedThreads.Threads[i] == tid) {
      this->ProtectedThreads.Threads[i] = 0;
      this->ProtectedThreads.TidsCount--;
      return true;
      }
  • Comparing thread ID with thread object.

    if (info->Threads[i].ClientId.UniqueThread == PsGetCurrentThread())

  • Missing buffer size check and assumption that an UNICODE_STRING will be null terminated. MAX_PATH Buffers and assumption of C disk isn't something you'd expect from a driver either.

    WCHAR fullPath[MAX_PATH + 1] = DEFAULT_DRIVE_LETTER;
    auto stack = IoGetCurrentIrpStackLocation(Irp);
    if (!stack || !stack->FileObject)
    return ((tNtfsIrpFunction)NidhoggFileUtils->GetNtfsCallback(0).Address)(DeviceObject, Irp);
    if (stack->FileObject->FileName.Length == 0)
    return ((tNtfsIrpFunction)NidhoggFileUtils->GetNtfsCallback(0).Address)(DeviceObject, Irp);
    wcscat(fullPath, stack->FileObject->FileName.Buffer);

  • Dereferencing object you have not acquired if PsLookupThreadByThreadId is unsuccessful.

    status = PsLookupThreadByThreadId(info->Threads[i].ClientId.UniqueThread, Thread);
    if (!NT_SUCCESS(status) || PsIsThreadTerminating(*Thread)) {
    ObDereferenceObject(*Thread);
    *Thread = NULL;
    continue;
    }

  • Incorrect size for terminating character.

    WCHAR* buffer = (WCHAR*)ExAllocatePoolWithTag(PagedPool, wcslen(item.DriverName) * sizeof(WCHAR) + 1, DRIVER_TAG);

  • Missing removal of hooks on driver unload.

    AntiAnalysis::~AntiAnalysis() {

  • Object is not dereferenced anywhere.

    status = FindAlertableThread(pid, &TargetThread);

    status = PsLookupProcessByProcessId(ULongToHandle(ModuleInformation->Pid), &targetProcess);

  • Missing output buffer length validation for the callbacks array that is populated from an unbounded list.

    for (ULONG i = 0; i < callbacksListCount; i++) {
    if (ReplacedFunction && ReplacerFunction) {
    if (currentCallback->Function == ReplacedFunction)
    currentCallback->Function = ReplacerFunction;
    }
    else {
    Callbacks->Callbacks[i].CallbackAddress = (ULONG64)currentCallback->Function;
    Callbacks->Callbacks[i].Context = currentCallback->Context;
    if (NT_SUCCESS(MatchCallback((PVOID)Callbacks->Callbacks[i].CallbackAddress, driverName)))
    strcpy_s(Callbacks->Callbacks[i].DriverName, driverName);
    }
    currentCallback = (PCM_CALLBACK)currentCallback->List.Flink;
    }

    for (SIZE_T i = 0; i < routinesCount; i++) {
    currentRoutine = *(PULONG64)(routinesList + (i * 8));
    currentRoutine &= ~(1ULL << 3) + 1;
    if (ReplacedFunction && ReplacerFunction) {
    if (*(PULONG64)(currentRoutine) == ReplacedFunction)
    *(PULONG64)(currentRoutine) = ReplacerFunction;
    }
    else {
    Callbacks->Routines[i].CallbackAddress = *(PULONG64)(currentRoutine);
    if (NT_SUCCESS(MatchCallback((PVOID)Callbacks->Routines[i].CallbackAddress, driverName)))
    strcpy_s(Callbacks->Routines[i].DriverName, driverName);
    }
    }

  • Missing null checks.

    Nidhogg/Nidhogg/Nidhogg.cpp

    Lines 210 to 214 in d8697ca

    NidhoggProccessUtils = new ProcessUtils();
    NidhoggFileUtils = new FileUtils();
    NidhoggMemoryUtils = new MemoryUtils();
    NidhoggAntiAnalysis = new AntiAnalysis();
    NidhoggRegistryUtils = new RegistryUtils();

  • Missing lock for iteration of PsLoadedModuleList.

    for (PLIST_ENTRY pListEntry = PsLoadedModuleList->InLoadOrderLinks.Flink;

    PLIST_ENTRY pListEntry = PsLoadedModuleList->InLoadOrderLinks.Flink;

  • Missing address space / VAD locks.

    NTSTATUS MemoryUtils::VadHideObject(PEPROCESS Process, ULONG_PTR TargetAddress) {

  • Trusting usermode PEB pointers to be valid or for the address space to be intact at all.

    for (PLIST_ENTRY pListEntry = targetPeb->LoaderData->InLoadOrderModuleList.Flink;

    for (PLIST_ENTRY pListEntry = targetPeb->LoaderData->InLoadOrderModuleList.Flink;

  • Trusting any RVA to be correct while parsing PE headers or for the pointer to be valid at all.

    PVOID MemoryUtils::GetFunctionAddress(PVOID moduleBase, CHAR* functionName) {

  • All allocated features are leaked in case of failure in driver entry.

    InitializeFeatures();

  • MmHighestUserAddress, MmUserProbeAddress, MmSystemRangeStart are a better choice. Not that this really does any useful validation.

    Nidhogg/Nidhogg/pch.h

    Lines 9 to 11 in d8697ca

    #define VALID_USERMODE_MEMORY(MemAddress)(MemAddress > 0 && MemAddress < 0x7FFFFFFFFFFFFFFF)
    #define VALID_KERNELMODE_MEMORY(MemAddress)(MemAddress > 0x8000000000000000 && MemAddress < 0xFFFFFFFFFFFFFFFF)
    #define VALID_ADDRESS(MemAddress)(VALID_USERMODE_MEMORY(MemAddress) || VALID_KERNELMODE_MEMORY(MemAddress))

  • Operator new is not allowed to return null, consider using std::nothrow version instead. The opposite is true for operator delete where it allows being passed in a null pointer, but ExFreePoolWithTag doesn't.

    void* operator new(size_t size) {
    return ExAllocatePoolWithTag(NonPagedPool, size, DRIVER_TAG);
    }

  • Missing NTSTATUS check.

    MmCopyVirtualMemory(PsGetCurrentProcess(), &this->PrevEtwTiValue, PsGetCurrentProcess(), &enableProviderInfo->IsEnabled, sizeof(ULONG), KernelMode, &bytesWritten);

BSOD

by Patchguard

Compiling Error

On Win 11 VM with VS2022 I'm trying to compile but I'm getting

Severity	Code	Description	Project	File	Line	Suppression State
Error		The BaseOutputPath/OutputPath property is not set for project 'Nidhogg.vcxproj'.  Please check to make sure that you have specified a valid combination of Configuration and Platform for this project.  Configuration='Release'  Platform='x64'.  This error may also appear if some other project is trying to follow a project-to-project reference to this project, this project has been unloaded or is not included in the solution, and the referencing project does not build using the same or an equivalent Configuration or Platform.	C:\Users\User\Desktop\Nidhogg-master\Nidhogg\Nidhogg.vcxproj	C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets	823	

What can be the reason?

Thanks

[FEATURE]

I was thinking maybe a way to communicate with the rootkit from another PC (your main pc) maybe with host and port, or something similar and execute commands.

[FEATURE] -- Initial operations on startup

Hello, I would like to know how I can make it so that when the driver loads automatically, it does things for me without needing the usermode interface? for example: I create a service and configure the driver to start automatically when the driver starts it finds the file C:\Windows\System32\test.dll and inject it into the explorer.exe process?

[BUG] Windows 11 compiling issues

i compiled the driver and tested it on windows 7 pro x64 and windows 11 enterprise x64 and when i start the driver i got a blue screen with the error "SYSTEM THREAD EXCEPTION NOT HANDLED" both machines were with the test mode activated so I can load the driver, do you know how I solve this error?

[BUG] BSOD bug in the file protect(I have use EfiGuard closed PatchGuard )

Describe the bug
BSOD bug in the file protect(I have use EfiGuard closed PatchGuard )

To Reproduce
Steps to reproduce the behavior:

  1. Running function...
  2. Caused...

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions

  • OS & Build windows 10 LTSC 21h2
  • Nidhogg's Version 1.0
  • Function that you attempted to run & error code

Additional context
Add any other context about the problem here.

PatchGuard causes BSOD

我想我已修复它,如果您仍然遇到 BSOD,请重新打开此问题 :)。

WIN10 Microsoft Windows [version 10.0.18363.418]

When I use PChunter to detect its stealth effect,The system immediately blue screen

image

Originally posted by @scareing in #3 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.