#
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\0511
for tasking info%programfiles%\Windows NT\2028
for task output%programfiles%\Windows NT\Nlts
for 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\Parameters
under theServiceDll
value - The service name (
WinResSvc
) is written to registry keyHKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost
under theWinSysRestoreGroup
value
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.h
orDropper/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 NT
To check if the service is created and running, open up task manager, go to the
services
tab, and then look for theWinResSvc
service.- If the service does not exist or is not running, you may need to check privileges or cleanup and try again.
If the
WinResSvc
is 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.jpg
andC:\Program Files\Windows NT\bootinfo.dat
, respectively.- These log files can be decrypted on a Windows machine using the
Resources/Carbon/Orchestrator/bin/castDecrypt.exe
utility. - The
bootinfo.dat
error 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.dat
communications library log file.- This log file can be decrypted on a Linux machine using the
Resources/Carbon/CommLib/decrypt_logs.py
utility:
- 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,
msys2
was installed and used to install mingw64.choco install msys2
- Add
C:\tools\msys64
to your PATH enviromment variable to runmsys2
. Reopen console windows to register the new env variable. - Run
msys2
and within the new prompt, run the following:pacman -Syu
pacman -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\bin
or equivalent CMakebin
folderC:\tools\msys64\mingw64\bin
or equivalent Mingw-w64bin
folder- Paths to folders containing
gcc
andg++
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.
Dropper
orLoader
):
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 (
Dropper
orLoader
) - 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