New modules, functionalities and improvements
2021-02-23 * Wintrmvte
After a short break from any dev work, I proceeded with final testing of my flagship C2 product tailored for security auditors. I am really excited to announce that Oyabun v.2.0 has been finally released earlier this morning, with new functionalities that have been actively worked on for the past few months:
At the end of this post, I have also included a short Q&A section to clarify any doubts regarding this tool.
Currently, there are 9 different, optional methods that can reliably discover presence of virtualization mechanisms, and accordingly shut down the implant. Their source is dynamically added to the implant's template, so if no sandbox detection method is specified, no additional code is embedded (say hello to partial polymorphism :> ). You can use all of the detectors at once (--sandbox-all
) or just a few, based on what kind of environment you are testing.
Default values for each method (when --sandbox-all
is used) can be lowered with --sandbox-less
- this option helps you avoid false positives when implants are launched on machines with older hardware.
Two new modules for Linux and over 20 multi-platform modules (Linux+Windows, possibly OSX too) were added to the implant in this release:
:extract
(platform: multi, no elevated privileges required)
Parses a .docx
, .pdf
or .txt
file and extracts vital data, such as e-mail addresses, IP and MAC addresses, credit card numbers, phone numbers, domains, timedates, passwords and addresses of crypto wallets.
:unshadow
(platform: Linux, elevated privileges required)
Automatically downloads contents of /etc/shadow
and /etc/passwd
and uses unshadow tool locally to obtain password hashes.
:reverse
(platform: multi, no elevated privileges required)
Spawns a reverse shell.
:bind
(platform: multi, no elevated privileges required)
Spawns a bind shell.
:proc
(platform: multi, no elevated privileges required)
Lists all running processes and prints them in a beautiful table. You can specify a pattern to show only the processes that are interesting to you.
:pkill
(platform: multi, no elevated privileges required)
Kills a process or a list of processes either by their PIDs or by canonical names. For example, running:
$ oyabun (3) - :pkill -p apac -p 1234
will send a kill signal to all "apache" processes (and possibly others that have "apac" in their name) and also to a process with PID = 1234.
:elevate
(platform: multi, no elevated privileges required)
Attempts to re-execute the implant binary in superuser context. If it suceeds, the binary is deleted from target host, and the previous non-elevated process is terminated. If it doesn't, an error message is sent back to the server and printed to terminal.
:klog
(platform: Linux, elevated privileges required)
Grabs keystrokes from automatically detected input device. User can additionally specify the time keylogger should run for, maximum number of keystrokes that are sent in a single response and a specific keyboard to capture from.
:remove
(platform: multi, no elevated privileges required)
Simply removes the implant binary from the directory it was executed in.
:wifi
(platform: multi, no elevated privileges required)
List BSSIDs and passwords of access points that the host previously used.
:sec
(platform: multi, no elevated privileges required)
Performs attempts to disable currently active security measures - UAC, Powershell Execution Policy and Defender (for Windows) + SELinux and AppArmor (for Linux).
:sploit
(platform: multi, no elevated privileges required)
This module downloads raw source of a local privilege exploit in C from exploit-db, compiles it (using default platform-specific compiler and flags) then immediately executes it. Requires a single argument (--id
) that specifies the identificator of exploit to use (as seen on exploit-db.com.
:vm
(platform: multi, no elevated privileges required)
Checks if implant was launched inside a virtual machine.
:clog
(platform: multi, no elevated privileges required)
Clears system logs.
:cpu
(platform: multi, no elevated privileges required)
Launches a forkbomb exclusively on CPU for a given time. You can specify percentage of maximum load and number of cores to exhaust.
:geo
(platform: multi, no elevated privileges required)
Obtains geolocation data about controlled host.
:lock
(platform: multi, no elevated privileges required)
Locks a screen.
:notify
(platform: multi, no elevated privileges required)
Spawns desktop notifications. User can specify number of messages, their text and title + delay between showing each of them.
:stamp
(platform: multi, elevated privileges required)
Changes access and modification times of single or multiple files.
:disks
(platform: multi, no elevated privileges required)
Lists information about logical drives.
:dos
(platform: multi, no elevated privileges required)
Performs multiple, simultaneous HTTP requests against given target.
:logout
(platform: multi, elevated privileges required)
Logs out all users from their sessions (except for the current one)
This functionality is nothing more than a tip of the hat to the Vim users. Besides, typing :<module_name>
is way faster than mod_<module_name>
. From now on, each post-exp module is invoked by prepending it's name with single :
character. To show a help dialog for selected module, execute :<module_name> -h
. Any entered string that isn't a module invocation (nor a global command) is sent to the implants as a system command to be executed.
This novel group of options can be further divided into active (launched when implant is executed) and passive (used in pre-compilation phase) antivirus evasion methods.
The main objective of active ones is to employ non-default behavioral patterns that partly or fully inhibit the ability of automatic scanners to analyze implant's binary.
Passive methods focus solely on code obfuscation, and make it harder to denote what is actually happening under the hood. My favorite one is --long
option, thanks to which all functions' and most variables' names simply won't fit inside your IDA Pro dialog without folding :> .
By default, a tunneling server in a random region is chosen. This can be tweaked with --region <region_name>
option. List of available regions can be found here.
Thanks to complete rewrite of how Oyabun's TLS server listens for reverse connections, you can now execute commands and post-exploitation modules on more than one host simultanously.
Every time an implant is activated and connects back, a status message is outputted to the screen, and a structure that contains basic information about this connection is added to the pool.
Then you can choose implants you wish to communicate with using interact
command and print information about all implants with list
. Using -v
switch with the latter command will show all connected implants in vertical arrangement.
I suppose that the STATUS
keyword requires some explanation - it does not indicate whether implant is connected or not, but rather if it belongs to the active pool that will execute entered commands. For example, running oyabun (3) - interact 2 0
will make sure that only implants with IDs 2
and 0
will receive subsequent instructions. Instead of exclusive selection, you can add implants to the active list (without clearing it first) with -a
flag.
When controlling a large pool of hosts, specifying each ID by hand isn't effective at all. You can select specific subgroups to interact with (linux
, windows
, x86
, x64
, root
) or choose to interact with every connected implant by specifying a single asterisk (*
) instead of a list of IDs.
In scenarios where you can perform Remote Code Execution rather than Remote Command Execution, you might want to embedd your command stager (that downloads and executes the implant) inside a particular one-liner that runs the command you. Following stagers are currently available: ruby
, python
, javascript
, php
, perl
and lua
. There are also two additional stagers: they can be used for targeting specific services rather than within RCE (mysql
and redis
). Name of the selected stager should be specified with --stager-lang
command-line flag.
From now on, when --tunnel
command-line option is specified, each newly executed implant communicates with the C2 server using a separate Ngrok connection. This implementation of stream multiplexing allows you to control up to 40 different hosts (or unlimited number, based on the Ngrok plan of your choice) from any place in the world, thanks to NAT traversion mechanism that this service provides. No external server needed, so you can forget about renting an AWS for your asessment ;> Due to the fact that Ngrok can work from behind most firewalls, data flow usually remains uninterrupted, yet might be a bit slower due to latency.
It is also worth noting that when tunneling is enabled and --stager
option is present, a local HTTP server that hosts the implant binary for download is also forwarded, but using a different solution (Localtunnel). Because of this, instead of pointing to a resource on a LAN, command stager contains URL of the tunnel.
You probably know this sad and fairly unexpected moment when your reverse connection goes dead out of the blue. It is often unavoidable, but using check
command, you can see which implants are still connected to the server, and optionally remove those that are no longer responsive (with -r
flag).
This specific post-exploitation module is quite unstable and doesn't work all the time, but offers some interesting capabilities and is probably my favourite. It proves useful especially in conjunction with a social engineering vector - user will have a fairly hard time figuring out what is going on right after he clicked the binary, as most of his input and output devices would be dead.
The Ngrok's authtoken is initialized only when --token <value>
flag is used. Setting <value>
to random
will cause a selection of random token from ngrok_tokens.txt
file.
Current command prompt looks like this: oyabun (X) -
(where X
indicates the number of implants you interact with at the specific moment).
Same as in previous version, keypairs are embedded inside the implant's template right before compilation. What changed is the way they are created: instead of running external Bash script, you can use --keygen
option to prepare fresh, self-signed authentication assets using OpenSSL.
If your campaign targets more that one type of OS/platform, you might want to prepare a separate implant for each different host. This is where --compile-all
option can be used. Whenever something goes wrong during compilation for a specific target, a verbose error message is printed to terminal.
Definitely not a ground-breaking feature, but I concluded that it would be good to know when exactly a piece of information is received and printed to terminal. Time is presented in format HH:mm
.
Sometimes, due to slow network or a problem of unknown origin, your implant will not connect back to you in a single strike. With --reconnect <X>:<Y>
flag, you can specify number of reconnection tries (X
) and number of seconds to sleep between each of them (Y
).
Due to a really dumb yet tricky error, when C2 server received anything unexpected on the socket, the whole connection used to go down and sometimes a race condition appeared. To prevent that, the server no longer parses any data that is malformated / does not meet specific criteria.
Using --av-concurrent
flag, all selected AV evasion methods can be launched simultaneously, in separate threads. When multiple evasion methods are used, this functionality greatly reduces amount of time needed for the implant to establish connection with the server, and adds some level of runtime complexity. The same mechanism is also available for invocation of post-exploitation modules (--mod-concurrent
).
Previous command-line switches (--shrink-dwarf
and --shrink-debug
) were consolidated into a single --shrink
option that has exactly the same effect as those two combined - implant becomes a few MBs smaller. A novelty is the --increase
argument - it adds empty imports to the binary right before compilation. It fairly enlarges it's size and makes the analysis a little bit harder for common AVs.
You can place imports you wish to use in your implants inside empty_imports.txt
file, one per line (without quotation marks). Option --increase
loads all imports from the file, but you can instruct Oyabun to select <n>
random imports from this file with help of --imports-num <n>
.
Output logging was already available in ver. 1, but it lacked intuitiveness. Now you can specify/inspect all configuration variables with a single command.
As I recently discovered, previous banner was HoRriBly kErnEd and not custom enough, so I hit my custom cellphone and had a quick call with a custom ASCII artist (for shame). Here are the results:
--root
The implant won't run if it wasn't executed with elevated privileges.
--out-friendly
Implant is saved under a random, "friendly" name, such as witcher_3_launcher.exe
, gimp
, etc.
--global-ip
Implant uses global IP of the host it was compiled on (useful if you decided to run this tool on external server without --tunnel
flag).
--cmd <file>
Specify a file containing commands to be launched by the implant after initial execution.
--[windows|linux]-shell <shell>
Select a non-default shell for platform-specific execution of commands.
--port-blend <port>
C2 server is launched on a random, low level port (21, 80, 443 etc.) to evade some basic firewall rules based on "block all" policy.
--stager-clip
Command stager used for downloading and executing the implant is copied to system clipboard.
--cores <num>
Set maximum number of cores that the implant can use for co-processing.
--server <port>
Oyabun only starts C2 server; phase of creating a new implant is skipped.
A: It probably is (thus I didn't upload it to VirusTotal, so I can't be 100% sure ;>). I deployed it on several machines with Kaspersky and Malwarebytes enabled, and it wasn't detected, so I hope for the best. I suppose that behavioural analysis/EDR would be able to succesfully and easily pin it down, but if you are aware about what modules and functionalities you are using (and know their potential IOCs), chances are quite low.
A: Oyabun is a single binary that has an implant's template (and other cool code chunks) embedded inside itself. After the program is launched, the implant's source is transformed (based on command-line arguments that were specified) and later dynamically compiled to a binary form. After this part is completed, Oyabun goes into C2 server mode, waiting for previously compiled implant to be executed on target hosts.
A: Both C2 server ( ~6k LOC ) and the implant ( ~2k LOC) are pure Golang.
A: I already have plenty of tools in OS formula + I try to regularly grant researchers with free, useful resources. And I actually make sure that the internet becomes a safer place - by providing this tool to professionals that emulate malicious advisories, so that security posture of tested environments can be efficiently enhanced.
A: This is paid software, so if you encounter any unexpected behaviour, your issue will be fixed right away (or at least as fast as I can) and won't simply hang in Github's section of open issues for two months.
A: Oyabun doesn't use any external servers (except for Ngrok tunnels, optionally) for communication between implants and server. But you don't have to trust my pledge here - simply run a Wireshark on the same host that C2 server and/or implant was launched on, and find out by yourself.
A: You can buy our tool here
I hope that you will have as much fun using this tool as I had writing it. In case of any questions, or if something remains unclear, please hit me up using 'Contact' form from the above menu.