Sweet Potato

SweetPotato – Local Service to SYSTEM

SweetPotato – Service to SYSTEM

I have had a keen interest in the original RottenPotato and JuicyPotato exploits that utilize DCOM and NTLM reflection to perform privilege escalation to SYSTEM from service accounts. The applications behave by leveraging the SeImpersontePrivilege and MITM to perform privilege escalation when a high privilege process connects to a MITM server running on the same machine.

I wont dive into too much detail since the method has been covered extensively by Fox Glove Security and Decoder’s Potatoes and tokens blog.

In the interest expanding my knowledge on the subject I decided to rewrite JuicyPotato in C#. In addition to the original JuicyPotato functionality I also added an additional PrivEsc that decoder and a few others had found with the BITS service. When instantiating a BITS COM object, if the service is not running, COM will start the service on behalf of the user requesting the COM object. On startup, the BITS service attempts to connect to the local WinRM service on port 5985. If WinRM is not active, we can setup a server to listen on port 5985 and force the BITS service running as SYSTEM to preform local NTLM authentication and impersonate. Further details about the the discovery can be found on decoder’s blog here

SweetPotato

The tool was designed to be used with Cobalt Strike’s execute-assembly command, so it carries no baggage in the form of dependencies. A release build is circa ~70KB in size and works for both 32bit and 64bit processes. Since the original DCOM vulnerability that Rotten/JuicyPotato exploits is fixed in Windows 10 1809+ and Windows Server 2019 the tool should automatically switch to the BITS/WinRM exploit described above. So to recap:

  • Works on Windows 7 up to the latest version of Windows 10 and Server 2019
  • Compatible with execute-assembly from Cobalt Strike an other C2 projects that support in memory execution of .NET executables
  • Works on 32 bit and 64 bit operating systems.
  • Can be compiled for for .NET 2 and 4 depending on target OS.
  • Automatically attempts the correct exploit to execute.

If you are interested in trying it out, head over to the GitHub project here

Caveats

The tool should work an all flavors of Windows but will only work when executed from a process with impersonate privileges. This is typically given to services, but can be a low privilege Network Service or similar. Additionally for the exploit to work on the latest Windows 10 or Windows Server 2019, WinRM cannot be enabled. This is the default for Windows 10, but not for Windows Server 2019.

Acknowledgements

Huge shout out to @decoder_it and @Giutro for JuicyPotato which SweetPotato is heavily based upon and of course @foxglovesec for the original RottenPotato code.

Weaponizing your favorite Go program for Cobalt Strike

Introduction

There are a myriad of ways currently to weaponize various offsec tools for use within Cobalt Strike. Many of these methods remain undetectable by modern day AV and EDR engines. Anything from in-memory PowerShell execution to using the execute-assembly command to run your latest SharpXXX .NET binary completely from memory.

Recently I have noticed an increase in the use of Golang for writing many offsec tools. Why? Well personally I put it down to the ease of compiling on both Windows, Linux and dare I say MacOS. In addition to ease of compiling, Golang can produce monolithic binaries that have no dependencies what so ever, other than the DLL’s or shared objects that are distributed as part of the operating system. The drawback of this of course is fairly large binaries. A simple helloworld program with Go 1.7+ comes in at around 1MB after stripping debug symbols. Once you start throwing in imports to 3rd party libraries this can easily reach 8MB+ and beyond.

So with the single monolithic binary in mind, I started looking at how a Go program can be weaponized for offsec purposes within Cobalt Strike. Cobalt Strike and metasploit have the capability of reflectively loading a DLL and executing it directly from memory. I won’t cover reflective loading here, since there are plenty of write-ups already on the subject, but if you are interested, head over to Stephen Fewer’s ReflectiveDLLInjection project which is one of the originals that many are based on today.

Goreflect

I have released a template project on GitHub than can be used to convert your favorite Go tool and compile it as a reflective DLL. The template is based on gobuster, but the project can be adapted for any Go tool. Currently the project is built using CMake, GCC and of course the Golang compiler. It utilizes the CGO interface within Go, which allows your Go entry point to be called from the reflective DllMain

The top level project file, CMakeLists.txt, is the glue for building our reflective DLL. The project adds gobuster as a dependency to our goreflect program, which in turn is linked to our reflective DLL, libgoreflect.

project (goreflect)
#Dependency to add simple Go support to CMake
include(${CMAKE_SOURCE_DIR}/cmake/GolangSimple.cmake)
#Your favorite go tool definition
GO_GET(gobuster github.com/OJ/gobuster)
#Dependency for goreflect to allow parsing of a command line string
GO_GET(gsq github.com/kballard/go-shellquote)
#Our Go static library, result is linkable using GCC
ADD_GO_INSTALLABLE_PROGRAM(goreflect_prog
                           goreflect.go  # our lightweigth wrapper around gobuster
                           gobuster gsq) # everything else is a dependency
#Standard C shared library using metasploits version of the reflective loader code
add_library(goreflect SHARED "ReflectiveDll.c" "ReflectiveLoader.c" "ReflectiveLoader.h" "ReflectiveDLLInjection.h")
target_include_directories(goreflect PUBLIC ${CMAKE_BINARY_DIR})
target_compile_definitions(goreflect PUBLIC GF_EXPORTS REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN)
#Linking all our dependencies as static, including our go program.  Results in no dependancies
target_link_libraries(goreflect ${CMAKE_BINARY_DIR}/libgoreflect_prog.lib -static-libgcc -static-libstdc++ -static -lpthread )

Our goreflect program a is a simple wrapper that exports our CGO function to the C world under the name start, allowing it to be called from our reflective DLL. The arg parameter is then parsed into individual arguments that can be used to call our go program. Now since go does not allow multiple main packages to be declared within a single program, we cannot import or call gobusters main directly. But luckily most go programs are designed in such a way that the main function is a proxy for the real main inside a separate package, in this case github.com/OJ/gobuster/cli/cmd. If you find that this is not the case, you may need to replicate some of the main code inside the startfunction within goreflect.go

package main
import "C"
import (
	 "os"
	 "fmt"	
	 "github.com/OJ/gobuster/cli/cmd"
	 
	 gsq "github.com/kballard/go-shellquote"
)
func main(){
	//not used
}
//export start
func start(arg string) {
	//parse our monolithinc argument string into individual args
	args, err := gsq.Split(arg)
	//our first argument is usally the program name, to just fake it
	args = append([]string{"goreflect"}, args...)
	if err == nil {
		//replace os.Args ready for calling our go program
		os.Args = args
		//run our go program
		cmd.Execute()
	} else {
		//parsing arguments failed, so bail.  Possibly unterminated string quote, etc...
		fmt.Printf("Failed to parse start arguments, %v\n", err)
	}
}

Our final piece of logic sits inside the ReflectiveDll.c file. This file holds the entry point to our reflective DLL and will call our start function exported from our go program. The DllMain function again is a fairly lightweight.

//===============================================================================================//
// This is a stub for the actuall functionality of the DLL.
//===============================================================================================//
#include "ReflectiveLoader.h"
#include <libgoreflect_prog.h&gt;
// Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
// defined in the project properties (Properties-&gt;C++-&gt;Preprocessor) so as we can specify our own 
// DllMain and use the LoadRemoteLibraryR() API to inject this DLL.
// You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c)
extern HINSTANCE hAppInstance;
//===============================================================================================//
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;
            GoString goArgs;
            goArgs.p = (char*)lpReserved;
            goArgs.n = strlen(lpReserved);
            start(goArgs);
			
			break;
        }
		case DLL_PROCESS_DETACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
            break;
    }
	return bReturnValue;
}

Inside the DLL_PROCESS_ATTACH case statement, we convert the lpReserved argument to a GoString object, as this is what the start function is expecting as it’s prototype. The lpReserved parameter is what Cobalt Strike and metasploit use to pass arguments to the reflective DLL.

I have made a quick video below showing goreflect in action. Utilizing the inject program from the ReflectiveDLL project, it demonstrates injecting the libgoreflect.dll into itself along with the arguments to send to our in-memory gobuster.

The code for goreflect can be found on GitHub.

That’s it for now. In part two I’ll cover how we can work around the 1MB limit within Cobalt Strike for reflective loading of our goreflect DLL.

Acknowledgements