Monday, March 28, 2011

Converting any file to ASCII for Transfer

Problem Overview
I was sitting around trying to figure out a good way to transfer files using nothing but ASCII text.  There are two reasons for this:
  1. If you have a shell to a computer, how do you transfer a file withut FTP, HTTP, etc... and just "type it"
  2. For some of my initial Teensy research, I want to transfer a file from the Teensy to the computer using nothing but keyboard keystrokes
Solution Overview
In order to do this, I searched high and low.  I wanted to be able to do this using nothing but VBScripting.  This would allow me to deliver the file and decode it without the need for debug privileges or another executable being present. After searching on hacking forums and Google, I finally came across this blog post: VBScript read/write binary, encode/decode Base64.

From this research I learned two things:
  1. VBScript has the ability to do byte arrays and read a binary file into memory
  2. Base64 encoding will take a byte array and translate it into ASCII readable text.
*For more information on Base64 encoding I recommend reading the Wikipedia page on the topic.

Now after finding that blog post, I modified it a bit to fit my needs. The next sections will walk you through the steps that are needed to accomplish the initial goals.
  1. Identify a executable that you wish to transfer
  2. Create the VBScript to encode the executable
  3. Transfer the ASCII text output to your victim computer
  4. Create a VBScript on the victim computer to decode the ASCII  text
  5. Run the Executable
For this blog post I am going to skip step three since any transfer mechanism (Remote Shell, Teensy, file transfer, etc...) can be used.

Step 1: Identify/Create an executable
This first step is a very simple one.  You must first identify the file (most likely executable) that you want to transfer.  For the sake of this post, I am going to use the file named "helloworld.exe" throughout this example.  It is going to be located in the "C:\Base64Example\" directory.


Step 2: Encoding a File
I created "Base64encode.vbs" within the "C:\Base64Example\" directory.  It contained the following code:
------------------------------------------------------- 
Option Explicit
' common consts
Const TypeBinary = 1
Const ForReading = 1, ForWriting = 2, ForAppending = 8


' getting file from args (no checks!)
Dim arguments, inFile, outFile


Set arguments = WScript.Arguments
inFile = arguments(0)
outFile = arguments(1)


Dim inByteArray, base64Encoded, base64Decoded, outByteArray
inByteArray = readBytes(inFile)
base64Encoded = encodeBase64(inByteArray)
Dim myFSO, WriteStuff
Set myFSO = CreateObject("Scripting.FileSystemObject")
Set WriteStuff = myFSO.OpenTextFile(outFile, ForAppending, True)
WriteStuff.WriteLine(base64Encoded)
WriteStuff.Close


private function readBytes(file)
  dim inStream
  ' ADODB stream object used
  set inStream = WScript.CreateObject("ADODB.Stream")
  ' open with no arguments makes the stream an empty container
  inStream.Open
  inStream.type= TypeBinary
  inStream.LoadFromFile(file)
  readBytes = inStream.Read()
end function


private function encodeBase64(bytes)
  dim DM, EL
  Set DM = CreateObject("Microsoft.XMLDOM")
  ' Create temporary node with Base64 data type
  Set EL = DM.createElement("tmp")
  EL.DataType = "bin.base64"
  ' Set bytes, get encoded String
  EL.NodeTypedValue = bytes
  encodeBase64 = EL.Text
end function
------------------------------------------------------- 

Once the the file has been created, run it using CScript while passing it input and output files as arguments.  For my example I am going to output the encoded text to "helloworldencoded.txt"
To do this:
  1. Start a command prompt (Start > Run > cmd.exe)
  2. Navigate to the directory containing the encode script and the executable.  In my example that would be the "C:\Base64Examples\" directory
  3. Run the following command: cscript Base64encode.vbs helloworld.exe helloworldencoded.txt
    1. Where helloworld.exe is your input file and helloworldencoded.txt is our output text.
After all of this has completed there will be a text file with Base64 encoded ASCII of the file you chose.  If you run into errors let me know.

Step 4: Decoding a File
After you have copied the text file over to a victim computer of your choosing, it is time to decode the text.  To do this the decode VBScript must first be created on the computer.  In the same directory as your "helloworldencoded.txt" file on the victim computer create a file with the code below.  For this example I named my "decodebase64.vbs".
------------------------------------------------------- 
Option Explicit
' common consts
Const TypeBinary = 1
Const ForReading = 1, ForWriting = 2, ForAppending = 8


' getting file from args (no checks!)
Dim arguments, inFile, outFile


Set arguments = WScript.Arguments
inFile = arguments(0)
outFile = arguments(1)


Dim base64Encoded, base64Decoded, outByteArray
dim objFS
dim objTS
set objFS = CreateObject("Scripting.FileSystemObject")
set objTS = objFS.OpenTextFile(inFile, ForReading)
base64Encoded = objTS.ReadAll
base64Decoded = decodeBase64(base64Encoded)
writeBytes outFile, base64Decoded


private function decodeBase64(base64)
  dim DM, EL
  Set DM = CreateObject("Microsoft.XMLDOM")
  ' Create temporary node with Base64 data type
  Set EL = DM.createElement("tmp")
  EL.DataType = "bin.base64"
  ' Set encoded String, get bytes
  EL.Text = base64
  decodeBase64 = EL.NodeTypedValue
end function


private Sub writeBytes(file, bytes)
  Dim binaryStream
  Set binaryStream = CreateObject("ADODB.Stream")
  binaryStream.Type = TypeBinary
  'Open the stream and write binary data
  binaryStream.Open
  binaryStream.Write bytes
  'Save binary data to disk
  binaryStream.SaveToFile file, ForWriting
End Sub

------------------------------------------------------- 
After the file has been created, decode the copied text by running the following command where helloworldencoded.txt is the base64 encoded text file and newhelloworld.exe is the decoded executable. 
  • cscript decodebase64.vbs helloworldencoded.txt newhelloworld.exe

Step 5: Run the Executable
The final step is to run the executable.  You can do this one of two ways, you can do it manually or script it.  I will include more details on my implementation with my follow-up posts showing off this process in action.  In the mean time, here is a screenshot of the decoded executable running.


Next Steps
So what is next on this topic?  My goal is to post some examples with screen captures and transfer statistics in future follow-up posts.  I hope to show this running through a remote shell session and demonstrate it with the Teensy.  Additionally, I will provide some discussions on transfer rates and any pitfalls that I run into. (UPDATE: I have a follow-on post which leverages this tutorial to copy an executable to a computer via Teensy: http://dabermania.blogspot.com/2011/04/copying-executable-from-teensy-using.html)