diff --git a/external/source/meterpreter/source/extensions/stdapi/server/stdapi.c b/external/source/meterpreter/source/extensions/stdapi/server/stdapi.c index 22393d7f3c..324c63408e 100755 --- a/external/source/meterpreter/source/extensions/stdapi/server/stdapi.c +++ b/external/source/meterpreter/source/extensions/stdapi/server/stdapi.c @@ -243,6 +243,37 @@ Command customCommands[] = { EMPTY_DISPATCH_HANDLER }, }, + // Event Log + { "stdapi_sys_eventlog_open", + { request_sys_eventlog_open, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "stdapi_sys_eventlog_numrecords", + { request_sys_eventlog_numrecords, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "stdapi_sys_eventlog_read", + { request_sys_eventlog_read, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "stdapi_sys_eventlog_oldest", + { request_sys_eventlog_oldest, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "stdapi_sys_eventlog_clear", + { request_sys_eventlog_clear, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + { "stdapi_sys_eventlog_close", + { request_sys_eventlog_close, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + { "stdapi_sys_power_exitwindows", + { request_sys_power_exitwindows, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + // Terminator { NULL, { EMPTY_DISPATCH_HANDLER }, diff --git a/external/source/meterpreter/source/extensions/stdapi/server/sys/eventlog/eventlog.c b/external/source/meterpreter/source/extensions/stdapi/server/sys/eventlog/eventlog.c new file mode 100755 index 0000000000..fabc1d21a5 --- /dev/null +++ b/external/source/meterpreter/source/extensions/stdapi/server/sys/eventlog/eventlog.c @@ -0,0 +1,221 @@ +#include "precomp.h" + +/* + * Opens a event log and returns the associated HANDLE to the caller if the + * operation succeeds. + * + * I should add support for the UNCServerName someday... + * + * TLVs: + * + * req: TLV_TYPE_EVENT_SOURCENAME - The event log name + */ +DWORD request_sys_eventlog_open(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + LPCTSTR sourceName = NULL; + DWORD result = ERROR_SUCCESS; + HANDLE hEvent; + + sourceName = packet_get_tlv_value_string(packet, TLV_TYPE_EVENT_SOURCENAME); + + if(!sourceName) { + result = ERROR_INVALID_PARAMETER; + } + else { + hEvent = OpenEventLog(NULL, sourceName); + if(!hEvent) { + result = GetLastError(); + } + else { + packet_add_tlv_uint(response, TLV_TYPE_EVENT_HANDLE, (DWORD)hEvent); + } + } + + packet_transmit_response(result, remote, response); + + return ERROR_SUCCESS; +} + +/* + * Returns the number of event records in an event log + * + * TLVs: + * + * req: TLV_TYPE_EVENT_HANDLE - The event log handle + */ +DWORD request_sys_eventlog_numrecords(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + HANDLE hEvent = NULL; + DWORD numRecords; + DWORD result = ERROR_SUCCESS; + + hEvent = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_HANDLE); + + if(!hEvent) { + result = ERROR_INVALID_PARAMETER; + } + else { + if(GetNumberOfEventLogRecords(hEvent, &numRecords) == 0) { + result = GetLastError(); + } + else { + packet_add_tlv_uint(response, TLV_TYPE_EVENT_NUMRECORDS, numRecords); + } + } + + packet_transmit_response(result, remote, response); + + return ERROR_SUCCESS; +} + +/* + * Reads one record from an event log + * + * TLVs: + * + * req: TLV_TYPE_EVENT_HANDLE - The event log handle + * req: TLV_TYPE_EVENT_READFLAGS - The flags for the read operation + * opt: TLV_TYPE_EVENT_RECORDOFFSET - The record offset for SEEK operations + */ +DWORD request_sys_eventlog_read(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + HANDLE hEvent = NULL; + DWORD readFlags = 0, recordOffset = 0, bytesRead, bytesNeeded; + DWORD result = ERROR_SUCCESS; + EVENTLOGRECORD * buf = NULL; + BYTE * str = NULL; + + hEvent = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_HANDLE); + readFlags = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_READFLAGS); + recordOffset = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_RECORDOFFSET); + + do { + if(!hEvent || !readFlags) { + result = ERROR_INVALID_PARAMETER; + break; + } + + /* get the length of the next record, ghettoly */ + if(ReadEventLog(hEvent, readFlags, recordOffset, + &bytesRead, 0, &bytesRead, &bytesNeeded + ) != 0 || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + result = GetLastError(); + // packet_add_raw(response, TLV_TYPE_EVENT_BYTESNEEDED) + break; + } + + if((buf = malloc(bytesNeeded)) == NULL) { + result = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + if(ReadEventLog(hEvent, readFlags, recordOffset, + buf, bytesNeeded, &bytesRead, &bytesNeeded + ) == 0) { + result = GetLastError(); + // packet_add_raw(response, TLV_TYPE_EVENT_BYTESNEEDED) + break; + } + + packet_add_tlv_uint(response, TLV_TYPE_EVENT_RECORDNUMBER, buf->RecordNumber); + packet_add_tlv_uint(response, TLV_TYPE_EVENT_TIMEGENERATED, buf->TimeGenerated); + packet_add_tlv_uint(response, TLV_TYPE_EVENT_TIMEWRITTEN, buf->TimeWritten); + packet_add_tlv_uint(response, TLV_TYPE_EVENT_ID, buf->EventID); + packet_add_tlv_uint(response, TLV_TYPE_EVENT_TYPE, buf->EventType); + packet_add_tlv_uint(response, TLV_TYPE_EVENT_CATEGORY, buf->EventCategory); + + packet_add_tlv_raw(response, TLV_TYPE_EVENT_DATA, (BYTE *)buf + buf->DataOffset, buf->DataLength); + + str = (BYTE *)buf + buf->StringOffset; + while(buf->NumStrings > 0) { + packet_add_tlv_string(response, TLV_TYPE_EVENT_STRING, str); + /* forward pass the null terminator */ + while(*str++ != 0); + buf->NumStrings--; + } + + } while(0); + + packet_transmit_response(result, remote, response); + + if(buf) + free(buf); + + return ERROR_SUCCESS; +} + + +/* + * Returns the record number of the oldest record (not necessarily 1). + * + * TLVs: + * + * req: TLV_TYPE_EVENT_HANDLE - The event log handle + */ +DWORD request_sys_eventlog_oldest(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + DWORD result = ERROR_SUCCESS; + HANDLE hEvent = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_HANDLE); + DWORD oldest; + + if(GetOldestEventLogRecord(hEvent, &oldest) == 0) { + result = GetLastError(); + } + else { + packet_add_tlv_uint(response, TLV_TYPE_EVENT_RECORDNUMBER, oldest); + } + + packet_transmit_response(result, remote, response); + + return ERROR_SUCCESS; +} + +/* + * Returns the record number of the oldest record (not necessarily 1). + * + * Should sometime support the BackupFile, but not right now.. + * + * TLVs: + * + * req: TLV_TYPE_EVENT_HANDLE - The event log handle + */ +DWORD request_sys_eventlog_clear(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + DWORD result = ERROR_SUCCESS; + HANDLE hEvent = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_HANDLE); + + if(ClearEventLog(hEvent, NULL) == 0) { + result = GetLastError(); + } + + packet_transmit_response(result, remote, response); + + return ERROR_SUCCESS; +} + +/* + * Closes the specified event log. + * + * TLVs: + * + * req: TLV_TYPE_EVENT_HANDLE - The event log handle + */ +DWORD request_sys_eventlog_close(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + DWORD result = ERROR_SUCCESS; + HANDLE hEvent = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_HANDLE); + + if(CloseEventLog(hEvent) == 0) { + result = GetLastError(); + } + + packet_transmit_response(result, remote, response); + + return ERROR_SUCCESS; +} \ No newline at end of file diff --git a/external/source/meterpreter/source/extensions/stdapi/server/sys/eventlog/eventlog.h b/external/source/meterpreter/source/extensions/stdapi/server/sys/eventlog/eventlog.h new file mode 100755 index 0000000000..f2b691aabb --- /dev/null +++ b/external/source/meterpreter/source/extensions/stdapi/server/sys/eventlog/eventlog.h @@ -0,0 +1,14 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_STDAPI_STDAPI_SERVER_SYS_EVENTLOG_EVENTLOG_H +#define _METERPRETER_SOURCE_EXTENSION_STDAPI_STDAPI_SERVER_SYS_EVENTLOG_EVENTLOG_H + +/* + * Event log interaction packet handlers + */ +DWORD request_sys_eventlog_open(Remote *remote, Packet *packet); +DWORD request_sys_eventlog_numrecords(Remote *remote, Packet *packet); +DWORD request_sys_eventlog_read(Remote *remote, Packet *packet); +DWORD request_sys_eventlog_oldest(Remote *remote, Packet *packet); +DWORD request_sys_eventlog_clear(Remote *remote, Packet *packet); +DWORD request_sys_eventlog_close(Remote *remote, Packet *packet); + +#endif diff --git a/external/source/meterpreter/source/extensions/stdapi/server/sys/power/power.c b/external/source/meterpreter/source/extensions/stdapi/server/sys/power/power.c new file mode 100755 index 0000000000..fb7582884b --- /dev/null +++ b/external/source/meterpreter/source/extensions/stdapi/server/sys/power/power.c @@ -0,0 +1,55 @@ +#include "precomp.h" + +/* + * Shutdowns, restarts, etc the remote machine. Calls ExitWindowsEx + * + * TLVs: + * + * req: TLV_TYPE_POWER_FLAGS - Flags to ExitWindowsEx + * req: TLV_TYPE_POWER_REASON - Shutdown reason + */ +DWORD request_sys_power_exitwindows(Remote * remote, Packet * packet) +{ + Packet * response = packet_create_response(packet); + + HANDLE token = NULL; + TOKEN_PRIVILEGES tkp; + + DWORD result = ERROR_SUCCESS; + DWORD flags = packet_get_tlv_value_uint(packet, TLV_TYPE_POWER_FLAGS); + DWORD reason = packet_get_tlv_value_uint(packet, TLV_TYPE_POWER_REASON); + +// result = ERROR_INVALID_PARAMETER; + + do { + if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) == 0) { + result = GetLastError(); + break; + } + + if(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid) == 0) { + result = GetLastError(); + break; + } + + tkp.PrivilegeCount = 1; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if(AdjustTokenPrivileges(token, FALSE, &tkp, 0, NULL, NULL) == 0) { + result = GetLastError(); + break; + } + + if(ExitWindowsEx(flags, reason) == 0) { + result = GetLastError(); + break; + } + } while(0); + + packet_transmit_response(result, remote, response); + + if(token) + CloseHandle(token); + + return ERROR_SUCCESS; +} \ No newline at end of file diff --git a/external/source/meterpreter/source/extensions/stdapi/server/sys/power/power.h b/external/source/meterpreter/source/extensions/stdapi/server/sys/power/power.h new file mode 100755 index 0000000000..0de35aea52 --- /dev/null +++ b/external/source/meterpreter/source/extensions/stdapi/server/sys/power/power.h @@ -0,0 +1,9 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_STDAPI_STDAPI_SERVER_SYS_POWER_POWER_H +#define _METERPRETER_SOURCE_EXTENSION_STDAPI_STDAPI_SERVER_SYS_POWER_POWER_H + +/* + * Power interaction packet handlers + */ +DWORD request_sys_power_exitwindows(Remote *remote, Packet *packet); + +#endif diff --git a/external/source/meterpreter/source/extensions/stdapi/server/sys/sys.h b/external/source/meterpreter/source/extensions/stdapi/server/sys/sys.h index 65a24bab1b..0edabd4b53 100755 --- a/external/source/meterpreter/source/extensions/stdapi/server/sys/sys.h +++ b/external/source/meterpreter/source/extensions/stdapi/server/sys/sys.h @@ -3,5 +3,7 @@ #include "process/process.h" #include "registry/registry.h" +#include "eventlog/eventlog.h" +#include "power/power.h" #endif diff --git a/external/source/meterpreter/source/extensions/stdapi/stdapi.h b/external/source/meterpreter/source/extensions/stdapi/stdapi.h index 1fbdb9b670..2772d14c72 100755 --- a/external/source/meterpreter/source/extensions/stdapi/stdapi.h +++ b/external/source/meterpreter/source/extensions/stdapi/stdapi.h @@ -380,4 +380,86 @@ TLV_TYPE_EXTENSION_STDAPI, \ 3000) +// Event Log +#define TLV_TYPE_EVENT_SOURCENAME \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4000) +#define TLV_TYPE_EVENT_HANDLE \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4001) +#define TLV_TYPE_EVENT_NUMRECORDS \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4002) +#define TLV_TYPE_EVENT_READFLAGS \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4003) +#define TLV_TYPE_EVENT_RECORDOFFSET \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4004) + +#define TLV_TYPE_EVENT_RECORDNUMBER \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4006) +#define TLV_TYPE_EVENT_TIMEGENERATED \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4007) +#define TLV_TYPE_EVENT_TIMEWRITTEN \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4008) +#define TLV_TYPE_EVENT_ID \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4009) +/* only a word, but will just put it in a dword */ +#define TLV_TYPE_EVENT_TYPE \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4010) +/* only a word, but will just put it in a dword */ +#define TLV_TYPE_EVENT_CATEGORY \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4011) +#define TLV_TYPE_EVENT_STRING \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4012) +#define TLV_TYPE_EVENT_DATA \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_RAW, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4013) + +/* power */ +#define TLV_TYPE_POWER_FLAGS \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4100) +#define TLV_TYPE_POWER_REASON \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_STDAPI, \ + 4101) + #endif