-
Notifications
You must be signed in to change notification settings - Fork 13
Using boko As A Class
boko stores all data in a dictionary for parsing. I wanted to keep all information usable in case someone wanted to hook into it for their own purposes.
To utilize this dictionary the boko class first needs to be imported, initialized, and run.
When initializing boko, you need to give it a Boolean value for verbosity and sipdisabled.
verbosity will affect how it outputs to the standard output of your terminal.
-
Truewill output everything boko discovers to standard out. -
Falsewill only output Definite certainty vulnerabilities.
sipdisabled can be used if you would like to scan all files on the system including directories that are read-only because of SIP by default. This should only be used if SIP is disabled on the system.
-
Truewill scan all files on the system and ignore Read-Only default directories. The scanner will still check whether or not the user context has read or write permissions to a file or hijackable path. -
Falsewill ignore Read-Only default directories and system binaries when performing any of the scan options. Additionally, this will take the fact that a file is in a Read-Only directory to calculate certainty that the current user can exploit the vulnerability.
Below is an example of initializing the class:
import boko
verbosity = True
sipdisabled = False
bokoscanner = ExecutableScanner(verbosity, sipdisabled)Next, you can choose the type of scan you want to perform. The base information discovered here is stored within a dictionary. This information consists of the filepath as the dictionary key, whether or not the file is writable under the current user context, the filename, the filetypeh if it is an interesting file, whether or not it will parse the file, and set the mode key as "Passive" for the time being.
- The
loadedBinariesfunction will scan all currently running binaries. Ifsipdisabledis set toTruethis will scan all binaries running (not recommended), otherwise this function will scan everything running except for system binaries.
bokoscanner.loadedBinaries()- The
installedBinariesfunction will scan a given directory for any executable and interesting files. Typically, it will take a specific path as a string argument to declare a path. If the path is omitted, it scans all files on the system starting at/.
# example to scan a specific directory
path = "/Applications/Numbers.app"
bokoscanner.installedBinaries(path)
# example to scan all files on the file-system starting at /
bokoscanner.installedBinaries()Once one or all of the scan types are selected, boko needs to parse the files discovered for executables, scripts, and dylibs with the parseExecutables function. This function will only read files to view file headers and does not perform any execution. This will store additional dictionary items under the main filepath key. If the file is an executable boko will store load command information under the load key, including LC_RPATHs as a list, LC_LOAD_WEAK_DYLIBs as a list, and LC_LOAD_DYLIBs as a list; boko will also create a vulnerable placeholder key for scripts and binaries; and finally store the filetype if it is a binary and the human readable file type as filetypeh under the main filepath key.
bokoscanner.parseExecutables()After the files discovered are parsed as executables, scripts, and other interesting files. You'll want to process the data. Here there are a few methods: processBinariesPassive, processBinariesActive, ProcessScriptBackdoors, and ProcessInterestingFiles. This is where boko will store vulnerability information on the files it processes. Under the vulnerable key these functions will store a list of dictionaries within the WeakDylib, DylibHijack, and BackdoorableScript keys. The dictionaries in these lists will store the Certainty of the vulnerability, the hijackPath path to use to exploit the vulnerability, the WriteAccess of the hijackable path, the LoadOrder of the rpath that is expanded, and whether or not the hijack path is within a SIP ReadOnlyPartition.
- The
processBinariesPassivefunction will only process the executable and dylib information that was discovered through parsing based on the file type header.
bokoscanner.processBinariesPassive()- The
processBinariesActivefunction will parse the discovered files for anything that has the 'MH_EXECUTE' indicator in the file header. Once the binary is deemed a main executable, this function will the execute the binary for 3 seconds to scrape the rpaths that fail to expand. This only gives "Definite" certainty results, but may cause issues on the system if more than one program directory is chosen with theinstalledBinaries, even more so if a directory is omitted, because it will execute every executable file on the system (not recommended). One added feature here is that an additional dictionary keyexecutionwill be added to the mainfilepathkey, which contains any standard and error output from executing the binaries. IfverboseisTruethis will also get output to the command line.
bokoscanner.processBinariesActive()- The
ProcessScriptBackdoorsfunction will just do additional processing of the scripts and populate potential vulnerability information to theBackdoorableScriptkey.
bokoscanner.ProcessScriptBackdoors()- The
ProcessInterestingFilesfunctions only use is to output interesting files to standard output, since all the data is already stored in the dictionary.
bokoscanner.ProcessInterestingFiles()Finally, once all the processing is complete you may access the dictionary with the GetResults function. You could technically use this function any time after the scanner is initialized, but it will be missing pieces of information.
results = bokoscanner.GetResults()filepath: { # Full file path of file that was parsed
'writeable': Bool, # indicates whether or not the current user that ran the tool has write permissions on the file
'execution': { # dictionary for execution output, only applicable if the --active or --both flag is used
'standardoutput': [], # standard output from executing the binary
'erroroutput' [] # standard error output from executing the binary, this will include the debug rpath information
},
'load': { # if a file is deemed an executable type this is created
'LC_RPATHs': [], # a list of all load command rpaths
'LC_LOAD_WEAK_DYLIBs': [], # a list of all load command weak dylibs
'LC_LOAD_DYLIBs': [] # a list of all loaded dylibs
},
'filetypeh': 'String', # indicates the file type as a string : Executable, Dylib, Bundle, KextBundle, Script, Misc (based on file extension)
'filetype': mach_header filetype, # only stored for executable file types
'parse': 'String', # indicates if the file was an executable and was parsed for weaknesses
'filename': 'String', # File name without full path
'vulnerable': {
'WeakDylib': [ # list of weak dylibs, each weak dylib has its own dictionary
{
'Certainty': 'String', # indicates how certain the vulnerability exists based on load path ordering and file type : Definite, High, Potential, Low
'hijackPath': 'String', # full path a malicious dylib can be placed to hijack the load order of the base file
'WriteAccess': Bool, # indicates whether or not the current user that ran the tool can write to the hijackPath
'LoadOrder': int, # indicates the order in which the main binary Filename loads the dylib relative path, starts at 0
'ReadOnlyPartition': Bool # indicates whether or not the directory is in a SIP-protected partition
}
],
'DylibHijack': [ # list of hijackable dylibs, each dylib has its own dictionary
{
'Certainty': 'String', # indicates how certain the vulnerability exists based on load path ordering and file type : Definite, High, Potential, Low
'hijackPath': 'String', # full path a malicious dylib can be placed to hijack the load order of the base file
'WriteAccess': Bool, # indicates whether or not the current user that ran the tool can write to the hijackPath
'LoadOrder': int, # indicates the order in which the main binary Filename loads the dylib relative path, starts at 0
'ReadOnlyPartition': Bool # indicates whether or not the directory is in a SIP-protected partition
}
],
'BackdoorableScript': [ # list of potentially backdoorable scripts, each script has its own dictionary
{
'Certainty': 'String', # indicates how certain the vulnerability exists based on load path ordering and file type : Definite, High, Potential, Low
'hijackPath': 'String', # full path a malicious dylib can be placed to hijack the load order of the base file
'WriteAccess': Bool, # indicates whether or not the current user that ran the tool can write to the hijackPath
'LoadOrder': int, # indicates the order in which the main binary Filename loads the dylib relative path, starts at 0
'ReadOnlyPartition': Bool # indicates whether or not the directory is in a SIP-protected partition
}
]
}
}