1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-18 07:11:12 +02:00

Use RtlGetVersion to detect version

This means we can actually correctly detect the version of Windows in
use past 8.1 (ie including 10 and later).
This commit is contained in:
OJ 2015-09-24 15:42:37 +10:00
parent 5d41b05765
commit f76b51e265

@ -3,6 +3,9 @@
#ifdef _WIN32 #ifdef _WIN32
#include <Sddl.h> #include <Sddl.h>
#include <Lm.h> #include <Lm.h>
typedef NTSTATUS(WINAPI *PRtlGetVersion)(LPOSVERSIONINFOEXW);
#else #else
#include <sys/utsname.h> #include <sys/utsname.h>
#endif #endif
@ -437,6 +440,135 @@ DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
return dwResult; return dwResult;
} }
#ifdef _WIN32
DWORD add_windows_os_version(Packet** packet)
{
DWORD dwResult = ERROR_SUCCESS;
CHAR buffer[512] = { 0 };
do
{
HMODULE hNtdll = GetModuleHandleA("ntdll");
if (hNtdll == NULL)
{
BREAK_ON_ERROR("[SYSINFO] Failed to load ntoskrnl");
}
PRtlGetVersion pRtlGetVersion = (PRtlGetVersion)GetProcAddress(hNtdll, "RtlGetVersion");
if (pRtlGetVersion == NULL)
{
BREAK_ON_ERROR("[SYSINFO] Couldn't find RtlGetVersion in ntoskrnl");
}
OSVERSIONINFOEXW v = { 0 };
v.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
if (0 != pRtlGetVersion(&v))
{
dwResult = ERROR_INVALID_DLL;
dprintf("[SYSINFO] Unable to get OS version with RtlGetVersion");
break;
}
dprintf("[VERSION] Major : %u", v.dwMajorVersion);
dprintf("[VERSION] Minor : %u", v.dwMinorVersion);
dprintf("[VERSION] Build : %u", v.dwBuildNumber);
dprintf("[VERSION] Maint : %S", v.szCSDVersion);
dprintf("[VERSION] Platform: %u", v.dwPlatformId);
dprintf("[VERSION] Type : %hu", v.wProductType);
dprintf("[VERSION] SP Major: %hu", v.wServicePackMajor);
dprintf("[VERSION] SP Minor: %hu", v.wServicePackMinor);
dprintf("[VERSION] Suite : %hu", v.wSuiteMask);
CHAR* osName = NULL;
if (v.dwMajorVersion == 3)
{
osName = "Windows NT 3.51";
}
else if (v.dwMajorVersion == 4)
{
if (v.dwMinorVersion == 0 && v.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
osName = "Windows 95";
}
else if (v.dwMinorVersion == 10)
{
osName = "Windows 98";
}
else if (v.dwMinorVersion == 90)
{
osName = "Windows ME";
}
else if (v.dwMinorVersion == 0 && v.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
osName = "Windows NT 4.0";
}
}
else if (v.dwMajorVersion == 5)
{
if (v.dwMinorVersion == 0)
{
osName = "Windows 2000";
}
else if (v.dwMinorVersion == 1)
{
osName = "Windows XP";
}
else if (v.dwMinorVersion == 2)
{
osName = "Windows .NET Server";
}
}
else if (v.dwMajorVersion == 6)
{
if (v.dwMinorVersion == 0)
{
osName = v.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows 2008";
}
else if (v.dwMinorVersion == 1)
{
osName = v.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows 2008 R2";
}
else if (v.dwMinorVersion == 2)
{
osName = v.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows 2012";
}
else if (v.dwMinorVersion == 3)
{
osName = v.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows 2012 R2";
}
}
else if (v.dwMajorVersion == 10)
{
if (v.dwMinorVersion == 0)
{
osName = v.wProductType == VER_NT_WORKSTATION ? "Windows 10" : "Windows 2016 Tech Preview";
}
}
if (!osName)
{
osName = "Unknown";
}
if (wcslen(v.szCSDVersion) > 0)
{
_snprintf(buffer, sizeof(buffer)-1, "%s (Build %lu, %S).", osName, v.dwBuildNumber, v.szCSDVersion);
}
else
{
_snprintf(buffer, sizeof(buffer)-1, "%s (Build %lu).", osName, v.dwBuildNumber);
}
dprintf("[VERSION] Version set to: %s", buffer);
packet_add_tlv_string(*packet, TLV_TYPE_OS_NAME, buffer);
} while (0);
return dwResult;
}
#endif
/* /*
* sys_sysinfo * sys_sysinfo
* ---------- * ----------
@ -447,18 +579,14 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
{ {
Packet *response = packet_create_response(packet); Packet *response = packet_create_response(packet);
#ifdef _WIN32 #ifdef _WIN32
CHAR computer[512], buf[512], *osName = NULL, * osArch = NULL, * osWow = NULL; CHAR computer[512], buf[512], * osArch = NULL, * osWow = NULL;
DWORD res = ERROR_SUCCESS; DWORD res = ERROR_SUCCESS;
DWORD size = sizeof(computer); DWORD size = sizeof(computer);
OSVERSIONINFOEX v;
HMODULE hKernel32; HMODULE hKernel32;
memset(&v, 0, sizeof(v));
memset(computer, 0, sizeof(computer)); memset(computer, 0, sizeof(computer));
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
v.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
do do
{ {
// Get the computer name // Get the computer name
@ -469,113 +597,33 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
} }
packet_add_tlv_string(response, TLV_TYPE_COMPUTER_NAME, computer); packet_add_tlv_string(response, TLV_TYPE_COMPUTER_NAME, computer);
add_windows_os_version(&response);
// Get the operating system version information
if (!GetVersionEx((LPOSVERSIONINFO)&v))
{
res = GetLastError();
break;
}
if (v.dwMajorVersion == 3)
osName = "Windows NT 3.51";
else if (v.dwMajorVersion == 4)
{
if (v.dwMinorVersion == 0 && v.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
osName = "Windows 95";
else if (v.dwMinorVersion == 10)
osName = "Windows 98";
else if (v.dwMinorVersion == 90)
osName = "Windows ME";
else if (v.dwMinorVersion == 0 && v.dwPlatformId == VER_PLATFORM_WIN32_NT)
osName = "Windows NT 4.0";
}
else if (v.dwMajorVersion == 5)
{
if (v.dwMinorVersion == 0)
osName = "Windows 2000";
else if (v.dwMinorVersion == 1)
osName = "Windows XP";
else if (v.dwMinorVersion == 2)
osName = "Windows .NET Server";
}
else if (v.dwMajorVersion == 6)
{
if (v.dwMinorVersion == 0)
{
if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows Vista";
else
osName = "Windows 2008";
}
else if (v.dwMinorVersion == 1)
{
if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 7";
else
osName = "Windows 2008 R2";
}
else if (v.dwMinorVersion == 2)
{
if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 8";
else
osName = "Windows 2012";
}
else if (v.dwMinorVersion == 3)
{
if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 8.1";
else
osName = "Windows 2012 R2";
}
}
else if (v.dwMajorVersion == 10)
{
if (v.dwMinorVersion == 0)
{
if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 10";
else
osName = "Windows Server Technical Preview";
}
}
if (!osName)
osName = "Unknown";
if (strlen(v.szCSDVersion) > 0)
_snprintf(buf, sizeof(buf) - 1, "%s (Build %lu, %s).", osName, v.dwBuildNumber, v.szCSDVersion);
else
_snprintf(buf, sizeof(buf) - 1, "%s (Build %lu).", osName, v.dwBuildNumber);
packet_add_tlv_string(response, TLV_TYPE_OS_NAME, buf);
// sf: we dynamically retrieve GetNativeSystemInfo & IsWow64Process as NT and 2000 dont support it. // sf: we dynamically retrieve GetNativeSystemInfo & IsWow64Process as NT and 2000 dont support it.
hKernel32 = LoadLibraryA("kernel32.dll"); hKernel32 = LoadLibraryA("kernel32.dll");
if (hKernel32) if (hKernel32)
{ {
typedef void (WINAPI * GETNATIVESYSTEMINFO)(LPSYSTEM_INFO lpSystemInfo); typedef void (WINAPI * GETNATIVESYSTEMINFO)(LPSYSTEM_INFO lpSystemInfo);
typedef BOOL (WINAPI * ISWOW64PROCESS)(HANDLE, PBOOL); typedef BOOL(WINAPI * ISWOW64PROCESS)(HANDLE, PBOOL);
GETNATIVESYSTEMINFO pGetNativeSystemInfo = (GETNATIVESYSTEMINFO)GetProcAddress(hKernel32, "GetNativeSystemInfo"); GETNATIVESYSTEMINFO pGetNativeSystemInfo = (GETNATIVESYSTEMINFO)GetProcAddress(hKernel32, "GetNativeSystemInfo");
ISWOW64PROCESS pIsWow64Process = (ISWOW64PROCESS)GetProcAddress(hKernel32, "IsWow64Process"); ISWOW64PROCESS pIsWow64Process = (ISWOW64PROCESS)GetProcAddress(hKernel32, "IsWow64Process");
if (pGetNativeSystemInfo) if (pGetNativeSystemInfo)
{ {
SYSTEM_INFO SystemInfo; SYSTEM_INFO SystemInfo;
pGetNativeSystemInfo(&SystemInfo); pGetNativeSystemInfo(&SystemInfo);
switch(SystemInfo.wProcessorArchitecture) switch (SystemInfo.wProcessorArchitecture)
{ {
case PROCESSOR_ARCHITECTURE_AMD64: case PROCESSOR_ARCHITECTURE_AMD64:
osArch = "x64"; osArch = "x64";
break; break;
case PROCESSOR_ARCHITECTURE_IA64: case PROCESSOR_ARCHITECTURE_IA64:
osArch = "IA64"; osArch = "IA64";
break; break;
case PROCESSOR_ARCHITECTURE_INTEL: case PROCESSOR_ARCHITECTURE_INTEL:
osArch = "x86"; osArch = "x86";
break; break;
default: default:
break; break;
} }
} }
if (pIsWow64Process) if (pIsWow64Process)
@ -583,23 +631,30 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
BOOL bIsWow64 = FALSE; BOOL bIsWow64 = FALSE;
pIsWow64Process(GetCurrentProcess(), &bIsWow64); pIsWow64Process(GetCurrentProcess(), &bIsWow64);
if (bIsWow64) if (bIsWow64)
{
osWow = " (Current Process is WOW64)"; osWow = " (Current Process is WOW64)";
}
} }
} }
// if we havnt set the arch it is probably because we are on NT/2000 which is x86 // if we havnt set the arch it is probably because we are on NT/2000 which is x86
if (!osArch) if (!osArch)
{
osArch = "x86"; osArch = "x86";
}
if (!osWow) if (!osWow)
{
osWow = ""; osWow = "";
}
_snprintf(buf, sizeof(buf) - 1, "%s%s", osArch, osWow); _snprintf(buf, sizeof(buf) - 1, "%s%s", osArch, osWow);
dprintf("[SYSINFO] Arch set to: %s", buf);
packet_add_tlv_string(response, TLV_TYPE_ARCHITECTURE, buf); packet_add_tlv_string(response, TLV_TYPE_ARCHITECTURE, buf);
if (hKernel32) if (hKernel32)
{ {
char * ctryname = NULL, * langname = NULL; char * ctryname = NULL, *langname = NULL;
typedef LANGID (WINAPI * GETSYSTEMDEFAULTLANGID)(VOID); typedef LANGID(WINAPI * GETSYSTEMDEFAULTLANGID)(VOID);
GETSYSTEMDEFAULTLANGID pGetSystemDefaultLangID = (GETSYSTEMDEFAULTLANGID)GetProcAddress(hKernel32, "GetSystemDefaultLangID"); GETSYSTEMDEFAULTLANGID pGetSystemDefaultLangID = (GETSYSTEMDEFAULTLANGID)GetProcAddress(hKernel32, "GetSystemDefaultLangID");
if (pGetSystemDefaultLangID) if (pGetSystemDefaultLangID)
{ {
@ -621,22 +676,31 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
} }
if (!ctryname || !langname) if (!ctryname || !langname)
_snprintf(buf, sizeof(buf) - 1, "Unknown"); {
_snprintf(buf, sizeof(buf)-1, "Unknown");
}
else else
_snprintf(buf, sizeof(buf) - 1, "%s_%s", langname, ctryname); {
_snprintf(buf, sizeof(buf)-1, "%s_%s", langname, ctryname);
}
packet_add_tlv_string(response, TLV_TYPE_LANG_SYSTEM, buf); packet_add_tlv_string(response, TLV_TYPE_LANG_SYSTEM, buf);
if (ctryname) if (ctryname)
{
free(ctryname); free(ctryname);
}
if (langname) if (langname)
{
free(langname); free(langname);
}
} }
LPWKSTA_INFO_102 localSysinfo = NULL; LPWKSTA_INFO_102 localSysinfo = NULL;
if (NetWkstaGetInfo(NULL, 102, (LPBYTE *)&localSysinfo) == NERR_Success) { if (NetWkstaGetInfo(NULL, 102, (LPBYTE *)&localSysinfo) == NERR_Success)
{
char *domainName = wchar_to_utf8(localSysinfo->wki102_langroup); char *domainName = wchar_to_utf8(localSysinfo->wki102_langroup);
packet_add_tlv_string(response, TLV_TYPE_DOMAIN, (LPCSTR)domainName); packet_add_tlv_string(response, TLV_TYPE_DOMAIN, (LPCSTR)domainName);
packet_add_tlv_uint(response, TLV_TYPE_LOGGED_ON_USER_COUNT, localSysinfo->wki102_logged_on_users); packet_add_tlv_uint(response, TLV_TYPE_LOGGED_ON_USER_COUNT, localSysinfo->wki102_logged_on_users);