#
Carbon DLL Installer
#
Usage
To run the installer, simply run the dropper.exe executable (release builds located in bin/) as an administrator.
#
Component Breakdown
#
Dropper
The Carbon DLL dropper will create the following subdirectories in the Carbon working directory:
%programfiles%\Windows NT\0511for tasking info%programfiles%\Windows NT\2028for task output%programfiles%\Windows NT\Nltsfor task config files
The Carbon DLL dropper will drop the following files to disk1,3:
- Configuration file to
%programfiles%\Windows NT\setuplst.xml - Loader DLL to
%systemroot%\System32\mressvc.dll - Orchestrator DLL to
%programfiles%\Windows NT\MSSVCCFG.dll - Communications library DLL to
%programfiles%\Windows NT\MSXHLP.dll
After successful file writes, the dropper will create a service to execute the loader DLL.3
The service details are as follows:
- Service Name:
WinResSvc - Display name:
WinSys Restore Service - Bin path:
C:\Windows\System32\svchost.exe -k WinSysRestoreGroup(svchost is used since we are running a DLL as a service).
Turla has used the same display name in the past, though we changed the service name to avoid using the exact same naming convention.
The dropper then performs two registry writes to make sure that the service can find the loader DLL and that the service will run under svchost:
- The loader DLL path (
%systemroot%\system32\mressvc.dll) is written to registry keyHKLM:\SYSTEM\CurrentControlSet\services\WinResSvc\Parametersunder theServiceDllvalue - The service name (
WinResSvc) is written to registry keyHKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchostunder theWinSysRestoreGroupvalue
Once the service is set up, the dropper will start it before terminating its own execution.
#
Dropper Build Instructions
Since the Carbon DLL dropper contains the various implant components (config file and DLLs), you will need to add those components in as resources at compile-time.
Use the add_resources.py script to auto-generate the src/components.cpp file that contains each of the latest resource components. Supply the appropriate file paths
to the latest version of each resource that you want to include.
Note that PyCryptoDome is required. You can installed it with the following command:
pip install pycryptodome
To generate the src/components.cpp file:
# Run from the Dropper directory
python3 add_resources.py --config-path path/to/config/file --loader-path path/to/loader/dll --orchestrator-path path/to/orchestrator/dll --commslib-path path/to/commslib/dll -o src/components.cpp -k [key hex string] -l DEBUG
The encryption key used for adding resources is f2d4560891bd948692c28d2a9391e7d9, which was generated by using PBKDF2 with 5 iterations of SHA1, passphrase of checkmatepepper and salt of salty, resulting in a 128-bit key. Example using CyberChef)
Now that you have all of the resources in src/components.cpp, you can build the dropper executable.
The dropper executable was built on Kali Linux using the following build command from the Dropper directory:
x86_64-w64-mingw32-g++ -I include/ -static -std=c++20 -lstdc++fs -Wall -Wextra -Werror -o bin/dropper.exe src/*.cpp
To remove symbols, you can use the strip command:
strip -s bin/dropper.exe
To verify, you can run strings or objdump --syms bin/dropper.exe - you should see an empty symbols table.
#
Loader DLL
The loader DLL is one of the components dropped by the Carbon DLL dropper. The dropper will then create a service to run the loader DLL under svchost, which requires some registry key creation
and modification. The loader DLL exports a ServiceMain function in order to be run as a service.
When running as a service, the loader DLL will execute the orchestrator DLL by calling its exported CompCreate function.3
#
Loader DLL Build Instructions
The loader DLL executable was built on Kali Linux using the following build command from the Loader directory:
x86_64-w64-mingw32-g++ -I include/ -static -shared -std=c++20 -Wall -Wextra -Werror -o bin/loader.dll src/*.cpp
To remove symbols, you can use the strip command:
strip -s bin/loader.dll
To verify, you can run strings or objdump --syms bin/loader.dll - you should see an empty symbols table.
#
Cleanup
To remove artifacts, run the Resources/cleanup/Carbon/carbon_cleanup.ps1 Powershell Script as an administrator on the target host(s).
You can do so from a domain controller using the following powershell command (from a directory containing the script):
Set-ExecutionPolicy bypass -force
$targethosts = "host1","host2","host3"
foreach ($targethost in $targethosts) {
Write-Host "[+] Performing Carbon cleanup on $targethost"
Invoke-Command -ComputerName $targethost -FilePath .\carbon_cleanup.ps1
}
#
Troubleshooting
If the installer returns an error in its output, the error code will either be a Windows system error code or a custom error code defined in
Dropper/include/file_handler.horDropper/include/service_handler.h.To check if files were dropped, you can open up file explorer on the target host and look in
C:\Program Files\Windows NTTo check if the service is created and running, open up task manager, go to the
servicestab, and then look for theWinResSvcservice.- If the service does not exist or is not running, you may need to check privileges or cleanup and try again.
If the
WinResSvcis stopped, or if it's running and you still don't have a Carbon beacon even with Edge open, you can check for the Carbon Orchestrator log and error files atC:\Program Files\Windows NT\history.jpgandC:\Program Files\Windows NT\bootinfo.dat, respectively.- These log files can be decrypted on a Windows machine using the
Resources/Carbon/Orchestrator/bin/castDecrypt.exeutility. - The
bootinfo.daterror file will likely explain why injection into Edge failed, or if the orchestrator failed in an earlier spot. - If neither file exists, it's likely the service was unable to start, and you will likely need to perform cleanup and try executing the installer again.
- These log files can be decrypted on a Windows machine using the
If you're still having issues obtaining an initial beacon, or if you obtained a beacon and then lost communication from the Carbon implant, look for the
C:\Program Files\Windows NT\2028\dsntport.datcommunications library log file.- This log file can be decrypted on a Linux machine using the
Resources/Carbon/CommLib/decrypt_logs.pyutility:
- This log file can be decrypted on a Linux machine using the
python3 decrypt_logs.py -p /path/to/commslib/log -o /plaintext/output/log/path
- If this file does not exist, then that means the communications library was either not injected or was not even able to start up.
- Once decrypted, you can look through the log for indicators of problems, such as pipe communication issues for peer-to-peer.
#
Installer Build Commands for the Scenario
Optional: rebuild the Loader DLL (run from the Loader directory:
x86_64-w64-mingw32-g++ -I include/ -static -shared -std=c++20 -Wall -Wextra -Werror -o bin/loader.dll src/*.cpp;
strip -s bin/loader.dll
To compile the installer, run the following from a Linux machine from the Dropper directory:
rm src/components.cpp
python3 add_resources.py --config-path resources/carbon_w1_config --loader-path ../Loader/bin/loader.dll --orchestrator-path ../../Orchestrator/bin/MSSVCCFG.dll --commslib-path ../../CommLib/bin/commlib.dll -o src/components.cpp -k f2d4560891bd948692c28d2a9391e7d9 -l DEBUG
x86_64-w64-mingw32-g++ -I include/ -static -std=c++20 -lstdc++fs -Wall -Wextra -Werror -o bin/dropper_w1.exe src/*.cpp && strip -s bin/dropper_w1.exe && objdump --syms bin/dropper_w1.exe && cp bin/dropper_w1.exe ../../../payloads/epic/dropper.exe
rm src/components.cpp
python3 add_resources.py --config-path resources/carbon_w2_config --loader-path ../Loader/bin/loader.dll --orchestrator-path ../../Orchestrator/bin/MSSVCCFG.dll --commslib-path ../../CommLib/bin/commlib.dll -o src/components.cpp -k f2d4560891bd948692c28d2a9391e7d9 -l DEBUG
x86_64-w64-mingw32-g++ -I include/ -static -std=c++20 -lstdc++fs -Wall -Wextra -Werror -o bin/dropper_w2.exe src/*.cpp && strip -s bin/dropper_w2.exe && objdump --syms bin/dropper_w2.exe && cp bin/dropper_w2.exe ../../../payloads/carbon/carbon_installer_3.exe
rm src/components.cpp
python3 add_resources.py --config-path resources/carbon_dc_config --loader-path ../Loader/bin/loader.dll --orchestrator-path ../../Orchestrator/bin/MSSVCCFG.dll --commslib-path ../../CommLib/bin/commlib.dll -o src/components.cpp -k f2d4560891bd948692c28d2a9391e7d9 -l DEBUG
x86_64-w64-mingw32-g++ -I include/ -static -std=c++20 -lstdc++fs -Wall -Wextra -Werror -o bin/dropper_dc.exe src/*.cpp && strip -s bin/dropper_dc.exe && objdump --syms bin/dropper_dc.exe && cp bin/dropper_dc.exe ../../../payloads/carbon/carbon_installer_2.exe
#
Unit Tests
Unit tests were run on a Windows machine using CMake. Each component subfolder has its own unit test setup.
- Make sure CMake is installed on your machine
choco install cmake --installargs '"ADD_CMAKE_TO_PATH=System"'- You will need to restart the shell to use cmake.
- If cmake was already installed but is not in your path, add it to your path manually (e.g.
C:\Program Files\CMake\bin)
- Make sure mingw64 is installed on your machine. In this particular example,
msys2was installed and used to install mingw64.choco install msys2- Add
C:\tools\msys64to your PATH enviromment variable to runmsys2. Reopen console windows to register the new env variable. - Run
msys2and within the new prompt, run the following:pacman -Syupacman -S --needed base-devel mingw-w64-x86_64-toolchain
- Ensure the following paths are set in the SYSTEM environment PATH variable (note that these may differ in your environment depending on how you installed CMake and mingw64).
C:\Program Files\CMake\binor equivalent CMakebinfolderC:\tools\msys64\mingw64\binor equivalent Mingw-w64binfolder- Paths to folders containing
gccandg++compilers if not already included in the above Mingw-w64 path folder. - Reopen console windows to register the new env variables.
- Set up and run tests via Powershell from the directory of the component to check (e.g.
DropperorLoader):
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_C_COMPILER:FILEPATH=gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=g++.exe -S . -B build -G "MinGW Makefiles"
cmake --build build --config Release --target all -j 4 --
cd build
ctest
(OPTIONAL) If running CMake via Visual Studio Code:
- Make sure you have the following VS Code extensions:
- CMake
- CMake Tools
- C/C++
- Configure CMake settings in VS Code:
- CMake: CMake Path
- Set to wherever the cmake executable is located
- CMake: Generator
- Set to "MinGW Makefiles" (no quotes)
- CMake: CMake Path
- Open the corresponding project folder in VS Code (
DropperorLoader) - In Command Palette, run
CMake: Run Tests
#
CTI References
- https://www.welivesecurity.com/2017/03/30/carbon-paper-peering-turlas-second-stage-backdoor/
- https://www.ncsc.admin.ch/ncsc/en/home/dokumentation/berichte/fachberichte/technical-report_apt_case_ruag.html
- https://www.gdata.pt/blog/2015/01/23926-analysis-of-project-cobra