The project involves working with the System Management Mode (SMM) in UEFI firmware, which is a specialized mode in Intel processors used for low-level hardware control. In this project, the aim is to develop and implement an SMM rootkit. The project demonstrates how an SMM rootkit can be designed and implemented in UEFI, showcasing the security implications of such a rootkit by operating at a level higher than the operating system, making it difficult to detect or remove. The outcome includes implementing these features in a proof-of-concept rootkit and demonstrating the results.
In this section, you should mention the hardware or simulators utilized in your project.
- Qemu
- libvirt
- virt-manager
- docker (change your docker registery to arvan cloud: link
the implementation details of this project are given to you in the following steps:
You can skip this part, if you use the firmware already built by cloning our repo and accessing the firmware through SMM-Rootkit/edk2/Build/OvmfX64/RELEASE_GCC5/FV
.
first we need to compile our SMM with the rootkit on it. We can use docker for this matter. Docker would give us an OS-level virtualization. since SMM support is depricated in the newer versions of EDK II, keep in mind to use version vUDK2018
of EDK II. Please note that you may need sudo permissions for running some of the following commands.
git clone [email protected]:jussihi/SMM-Rootkit.git
cd SMM-Rootkit
git clone [email protected]:tianocore/edk2.git
cd edk2
git checkout vUDK2018
cd ..
For using docker environment, you can start by entering the Docker environment:
./run_docker.sh
Once inside the Docker environment, navigate to the edk2
directory and build the base tools necessary for compiling the firmware:
cd edk2
make -C BaseTools
source ./edksetup.sh
exit
After setting up the base tools, you need to copy the rootkit files into the EDK II project directory:
cp -r ../SMM-Rootkit/* edk2/
Since writing directly to driver C is not possible for regular users, we need to change saving directory of smm.txt
to something else. We changed the directory to C:/smm/smm.txt
. keep in mind to create folder smm in drive C after creating the virtual machine.
Remove the part for restoring IAT hook as indicated in the following link
Re-enter the Docker environment and proceed with the final compilation:
./run_docker.sh
cd edk2
source ./edksetup.sh
build -DSMM_REQUIRE
After the build process completes, the firmware files will be located in the following directory:
edk2/Build/OvmfX64/RELEASE_GCC5/FV
Look for files starting with OVMF
, which will include the compiled firmware that now contains the rootkit.
In the next step, we need to create a virtual macine with the infected firmware we built in our previous step.
Move the firmware files (OVMF_CODE.fd
, OVMF_VARS.fd
) to a directory accessible by QEMU or libvirt. /usr/share/OVMF/rootkit/
is used as an example.
Create a firmware descriptor file to map the firmware files. Create file /usr/share/qemu/firmware/60-ovmf-rootkit-x86_64.json
with the following content:
{
"description": "UEFI SMM rootkit OVMF firmware for x86_64",
"interface-types": [
"uefi"
],
"mapping": {
"device": "flash",
"executable": {
"filename": "/usr/share/OVMF/rootkit/OVMF_CODE.fd",
"format": "raw"
},
"nvram-template": {
"filename": "/usr/share/OVMF/rootkit/OVMF_VARS.fd",
"format": "raw"
}
},
"targets": [
{
"architecture": "x86_64",
"machines": [
"pc-i440fx-*",
"pc-q35-*"
]
}
],
"features": [
"acpi-s3",
"amd-sev",
"verbose-dynamic"
],
"tags": [
]
}
- Launch virt-manager
sudo virt-manager
- Start the creation of a new virtual machine and select "Local install media" for the installation method.
- Choose the installation media. for this project we used Windows 10 22H2 Build 19045 version 64-bit Interprise edition. You can download the iso from this link. keep in mind that downloading any other version or edition of windows would cause problem in the following steps.
- Allocate the necessary CPU and memory resources
- check "customize configuration before install"
- Set the chipset to Q35
- Select Firmware to
OVMF_CODE_4M.fd
(this is not the infected firmware. we first need to install windows before changing our firmware to infected firmware)
- We select
Begin Installation
at the top left corner. - Now you must start Installing windows.
- After Installing windows, turn of your virtual machine and navigate to
edit->prefernces' in
virt-managerand select
enable XML editing` in the general section. - after applying your changes, navigate to details of your virual machine and view its XML version.
- change the loader from the default OVMF to your infected firmware
<os>
<type arch="x86_64" machine="pc-q35-6.2">hvm</type>
<loader readonly="yes" type="pflash">/usr/share/OVMF/rootkit2/OVMF_CODE.fd</loader>
<nvram>/var/lib/libvirt/qemu/nvram/win10-3_VARS.fd</nvram>
<boot dev="hd"/>
</os>
Now your Virtual Machine would be ready for testing.
- The sample program provided is a simple C++ application designed to interact with the rootkit you have integrated into the firmware. The program repeatedly calls the
GetCurrentProcessId
function in a loop and outputs the result.
- Below is the sample C++ code provided in the document:
#include <iostream> #include <string> #include <Windows.h> int main() { std::string a; while (std::cin >> a) { std::cout << "Process id is: " << GetCurrentProcessId() << std::endl; } }
since we don't have visual studio already installed on our virtual machine. we need to use another machine for the following steps, or we can install visual studio on the machine.
- You will need to use Visual Studio to compile this sample program. Ensure that the Desktop Development with C++ workload is installed.
- Open the project file
windows_x64_umd_iat.sln
in Visual Studio. - Configure the project to use the Multi-threaded Debug runtime library:
- Right-click on the project in Visual Studio and select
Properties
. - Navigate to
C/C++ -> Code Generation
. - Set the
Runtime Library
option to Multi-threaded Debug (/MTd).
- Right-click on the project in Visual Studio and select
- Build the solution by selecting
Build Solution
from theBuild
menu in Visual Studio. - The compiled executable will be generated in the output directory specified in the project settings.
- Transfer the compiled executable (
.exe
) to the virtual machine running the infected firmware. You can use any file transfer method, such as using a simple HTTP file server. - Rename the executable to
smm_rootkit.exe
to ensure it matches the name expected by the rootkit. - Execute the program on the VM to interact with the rootkit.
After following the steps described above, you now have a virtual machine with the infected firmware on it.
Once you have placed the smm_target.exe
file on your virtual machine, the next steps involve running the program, monitoring its interaction with the rootkit, and verifying that the rootkit is functioning as intended. Here’s how you can proceed:
- Start your virtual machine (VM) with the infected firmware using your virtualization software (e.g., QEMU, Virt-Manager).
- Ensure that the VM is configured to use the modified firmware that contains the rootkit.
- If you haven't already done so, transfer the
smm_target.exe
file to the VM. This can be done using various methods like an HTTP file server, SCP, or a shared folder, depending on your setup.
- On the VM, navigate to the directory where
smm_target.exe
is located and run the executable: - The program will start executing and repeatedly call the
GetCurrentProcessId
function, which should be intercepted by the rootkit.
- The rootkit is designed to log its activity or provide output through a serial console. To observe this output, connect to the VM's serial console:
virsh console win10
- Watch for any messages or logs to indicate the rootkit status.
- the rootkit would create a log file
smm.txt
in aC:/smm/smm.txt
. - Navigate to the directory in your VM’s file explorer or use the command line to check if the log file is present.
- Review the contents of the log file to confirm that the rootkit has successfully intercepted the function calls made by
smm_target.exe
.
As you can see in the screenshots provided, in the serial we can see that after IAT hooking is done, the file smm.txt
is created in the path provided to our rootkit.
Some links related to your project come here.
Authors and their github link come here.
Special Thanks to Hirbod Behnam