bytecode77 / r77-rootkit

Fileless ring 3 rootkit with installer and persistence that hides processes, files, network connections, etc.
https://bytecode77.com/r77-rootkit
BSD 2-Clause "Simplified" License
1.59k stars 389 forks source link

bug report: hidden file.exe faild to load #11

Closed GV13057911485 closed 3 years ago

GV13057911485 commented 3 years ago

Hi,

just found a new bug: hidden files.exe failed to load to process. I tried to hide the process with the config system, and in the meantime, the files /directory were hidden, but found failed to load to process. Remove the file hidden, then it can be loaded to process normally, and also the process can be hidden.

Windows 10 Home version 20H2, OS build 19042.928

hope my report helps. thanks!

bytecode77 commented 3 years ago

What do you mean by "failed to load to process" and "but found failed to load to process"?

GV13057911485 commented 3 years ago

one of the processes named a.exe (file instance: a.exe). I can load the a.exe without problem if I only configure $77config/process_names\ "a"="a.exe", this process a is stealthy. then I tried to do more with file hiding, so I configure further with $77config/paths\ "a"="c:\windows\system32\a.exe", then the file a.exe was hidden, but this a.exe can not start properly.

bytecode77 commented 3 years ago

Now I understand what you're trying to do: You want to hide a process by name and its file by path, but the executable won't start. I have managed to reproduce this.

The executable (a.exe) and/or the process that started the a.exe process cannot find the file and it therefore doesn't start. It seems like your file is hidden from itself, thus leading to undefined behavior. Unfortunately, there are some troublesome edge cases, like the one you described.

Problems like these are the reason why r77 hides entities only from enumerations, but allows directly accessing them. For example, you could open a hidden file, if you know the exact full path. r77 does not obfuscate this by hooking NtCreateFile and returning ERROR_FILE_NOT_FOUND, because this would lead to "hiding loops", where files would become permanently inaccessible.

I would suggest to create:

That way, the file itself is not hidden, but inside a hidden directory. I have tested this, and the process starts. You could also use the $77-prefix for the directory, if you want.

GV13057911485 commented 3 years ago

thank you for your detailed explanation and yes, your understanding is 100% correct. I will try your suggestion, if any problem arising, I will report futher.

GV13057911485 commented 3 years ago

Now I understand what you're trying to do: You want to hide a process by name and its file by path, but the executable won't start. I have managed to reproduce this.

The executable (a.exe) and/or the process that started the a.exe process cannot find the file and it therefore doesn't start. It seems like your file is hidden from itself, thus leading to undefined behavior. Unfortunately, there are some troublesome edge cases, like the one you described.

Problems like these are the reason why r77 hides entities only from enumerations, but allows directly accessing them. For example, you could open a hidden file, if you know the exact full path. r77 does not obfuscate this by hooking NtCreateFile and returning ERROR_FILE_NOT_FOUND, because this would lead to "hiding loops", where files would become permanently inaccessible.

I would suggest to create:

  • A hidden path: C:\Windows\myhiddenapp
  • A hidden process name: a.exe
  • And write the file to C:\Windows\myhiddenapp\a.exe

That way, the file itself is not hidden, but inside a hidden directory. I have tested this, and the process starts. You could also use the $77-prefix for the directory, if you want.

I tried your suggestion, and failed to startup. I removed the directory hidden from config system, then it normally loaded.

bytecode77 commented 3 years ago

I tried again and it seems like it depends how the process is created.

For example, I typed C:\_testdir\a.exe into cmd.exe and it works. But when I type the same string in the explorer.exe search bar, the process doesn't start. Apparently, explorer is looking for every part of the path and aborts, because the directory is hidden. Also, pressing Win+R (run) and typing the filename there doesn' work, too.

How exactly are you creating the process of a.exe? I would like to try exactly this and see what happens.

GV13057911485 commented 3 years ago

The process a.exe loaded by service b.exe which is fail loaded as well, a.exe, and b.exe all hidden in the file system. I removed files hidden for a.exe and b.exe, both of them loaded normally. later, I will try to hide this two file.exe one only to see what will happen.

and in the win7, they load fine even files.exe are hidden.

bytecode77 commented 3 years ago

Like I said, whether or not the programs can successfully start depends on the process that starts them. If the executables are hidden and you use CreateProcess/ShellExecuteEx/etc. this could cause undefined behaviour.

It's much mure reliable to hide the directory where the files are in, instead of the files themselves. That way, creating the process will work. And because the parent directory is hidden, there is no way to see the files, unless the name of the parent directly is known.

GV13057911485 commented 3 years ago

Like I said, whether or not the programs can successfully start depends on the process that starts them. If the executables are hidden and you use CreateProcess/ShellExecuteEx/etc. this could cause undefined behaviour.

It's much mure reliable to hide the directory where the files are in, instead of the files themselves. That way, creating the process will work. And because the parent directory is hidden, there is no way to see the files, unless the name of the parent directly is known.

I tested again, failed again when the directory was hidden. but the process can be loaded successfully if the parrent directory prefix with $77 instead of hides from the config system.

bytecode77 commented 3 years ago

It can be hard to reproduce a bug without knowing exactly what the directory structure looks like, as well as how the invoking process creates the child process.

Can you provide a minimal program that reproduces the issue? Something with source code that I can compile in Visual Studio, and what operating system & version you used to test it, along with instructions: what files to put where to run your minimal program. Then I could run it on a VM to reproduce the bug.

GV13057911485 commented 3 years ago

It can be hard to reproduce a bug without knowing exactly what the directory structure looks like, as well as how the invoking process creates the child process.

Can you provide a minimal program that reproduces the issue? Something with source code that I can compile in Visual Studio, and what operating system & version you used to test it, along with instructions: what files to put where to run your minimal program. Then I could run it on a VM to reproduce the bug.

yes, I can provide you the program as long as I can contact you privately.

bytecode77 commented 3 years ago

Please send an encrypted archive (zip or rar) to mail@martinfischer.it and I will have a look at it this week.

bytecode77 commented 3 years ago

Maybe issue #13 could help you? If you include the helper signature at compile time as mentioned there, your file will not be injected with r77 so it can start the hidden file. Could you try that?

bytecode77 commented 3 years ago

Version 1.2.2 is available.

This issue was addressed in the new version that is now available for download.

Section 2.8 of the documentation:

The issue: If you set up a hidden file for startup, for example using the HKCU...\Run key, Windows cannot not find the file (because it is hidden) and therefore it does not start.

The solution: r77 is in charge of starting hidden files. This comes with several advantages:

  1. Your file will start under the SYSTEM account with system integrity.
  2. Your file will start before the first user is logged on.
  3. You can add files to startup with non-elevated privileges and they will start up with system integrity.

If you want your process to be run under a specific user account, you have to perform impersonation. This is required in case you need access to the user’s desktop.

Note: Just by adding the file to $77config\startup, it is not implicitly hidden. The same rules apply: The file has to have the prefix, or it has to be hidden by the configuration system. If you want the file to not be injected by r77, then writing the helper signature to the executable file will avoid injection (see section 4.1).