Cannon — Post Exploitation Framework

Kavishka Gihan
11 min readJul 9, 2021

--

Cannon is a post exploitation framework fully developed using python3. This tool automates your work once you have access to the system. You will be able to download and upload files, run pre-defined modules, harvest reverse shells, and many more. Most of the utilities that this framework carries are based on attacking UNIX-based systems. But some of the functions will still work in Windows as well.

If you are a CTF player just like myself, you must know how disappointing it is when you want to share files between your machine and the target machine. When you accidentally press Ctrl+c and kill your reverse shell, that is the worst nightmare ever. But not anymore !!! Cannon will help to do all this stuff very easily.

Installation

You can get this from my GitHub

git clone https://github.com/kavishkagihan/Cannon.git

After installing this, you should see three files as cannon, client, and requirements.txt in the cannon directory. You have to change the permissions of the cannon file first.

cd Cannon && chmod +x cannon

Then, you have to install the required python libraries with pip.

pip3 install -r requirements.txt

How does this work?

As I mentioned earlier, this framework is built on python3. It uses python socket library to create socket connections. The basic concept of this framework is the server-client concept. You will spin up a control center almost like a server and, the clients will connect back to you.

New features will be often added to this framework in order get the best performances. You can check the New features section to see what and when these new features were added

This framework is intended to run in UNIX systems where you can have better control of the environment. Despite that, your target system can be either UNIX or Windows.

In both cases, core features of this tool like downloading and uploading files, getting shell access will work. But additional features like running modules and harvesting reverse shells will be available only for UNIX systems.

You can run the framework just like any python file with python3 or as an executable.

./cannon

If you don’t specify an IP address and a port, it will start the listener on the loopback interface with the default port of port 4444.

If you want to specify an IP and a port you can use them as arguments.

./cannon 192.168.1.6 9001

Creating the payload

Once you have launched the framework, you have to create a payload file (like a reverse shell). You can do this with the create command.

This is mentioned in the help menu as well.

help

This command takes only one argument which is the port that you are listening.

create <port>

Now if you look at the cannon directory, you will see that there is a file called cannon.shell. This is the created payload file. You can also change the name of the payload file name. (discussed in the configure section)

Working with hosts

Once you execute the payload file, you can see if you got a connection back to your listener with the list command.

list

As you can see, this will list all the hosts connected.

Now you can interact with that host the connect command. This takes an argument which is the number of the host.

connect <host_no>

This will drop you to a meterpreter instance. (discussed in the meterpreters section). If you want to go back to the cannon instance you can use the back command.

If you want to disconnect a host you can use the same arguments with the disconnect command.

disconnect <host_no>

Working with listeners

Let’s say that you pen-testing network where you have more than one machine. You can connect all these machines to one listener. But it is kind of messy right?

So to say organized, you can start new listeners and connect different hosts to different listeners. The bind command is used to start (bind) a new listener. This also takes only one argument which is the port you want to start the listener on.

bind <port>

You can see the active listeners with the status command. This will also show some other statistics such as the Internet status, number of hosts connected.

status

So what if you want to kill an active listener. You can use the kill command with the port number of the listener. This will automatically disconnect all the hosts connected to that listener.

kill <port>

One of the many things that annoys me the most is when you are using some tool and you want to know your IP address or run some other commands. You will have to start another terminal and run it and then again come to this terminal. But with this you can run shell commands as well.

shell

When you are done using the shell you can exit with the exit command.

Working with meterpreters

When you connect to a host, you can run different commands. You can always use the help command if you get lost.

Ever happened ? You upload an enumeration script like linpeas and it gets automatically deleted by a cronjob or something, so you have to upload it again.

With cannon you can easily upload files with just one-click using the upload command. This takes two arguments. The first one is the source file to upload and the destination file path for the file to be saved.

upload <source_file> <destination_file>

Just like this you can download files as well. Arguments are also the same.

download <source_file> <destination_file>

You may be thinking, “Well, we can do this all quickly. No problem with that. But can’t we execute commands”. Yes, you can. Using the channel command you can enter to a remote shell of the machine.

channel

But remember, this is not a tty shell. So you won’t be able to run any interactive commands like sudo . If you do, it might kill the connection. (don’t worry… Cannon got you !!)

Wait a minute…! So if we can’t get a tty shell, what is the worth of using this? That’s where the revshell command comes in. With this command you can easily get a reverse shell without having to bother about anything. You only have to specify the port that you are listening on.

revshell <port>

Then check your listener…!

You can get as many shells as you want.

So, one of the first things I do when I get into a box is checking the system information. Checking if the kernel is an old one that is vulnerable to any kernel exploits. The info command will give you some basic information about the system.

You can use different flags as arguments. -s is for system information, -m is for memory information and -a is for both of these.

info <flag>

Working with modules

Modules are pre-defined functions that will run when they are called. First, you have to load a module (basically upload) before running it.

You can define your own modules to fit your preference. (discussed in the configure section) To work with modules you can use the module command. Use help as an argument to get the help menu.

module help

You can use the list command to list the defined modules.

module list

By default, you will see these 3 modules. The first word you see is the module name and the path you see after the “:” is the module path.

When you want to load a module you can just use the load command followed by the module name.

module load <module_name>

If you look at the place where you have your payload file, you will see that the file you have specified (in this case linpeas.sh) is uploaded.

After loading the module, you can run it. So by default, it will run the file and log the output of that file to another file.

But what if you don’t want to log it and just want to run it. You can configure that as well.

module run <module_name>

If you have more than 10 modules, how can you know which modules have been already loaded? You can do that with the show command. This will show all the loaded modules.

module show

You can also search for modules. Whether if you want to know the path of the module file or to know if a certain module exists or not, you can use the search command

module search <module_name>

Also, you can check modules whether they are loaded or not by their name using the check command.

module check <module_name>

Configuration

Cannon is a very flexible framework that allows you to configure it the way you need. If you open up the cannon file in a text editor, you will see that there is a Configuration area where you can configure stuff.

Here you can change the default port that cannon starts its initial listener (DEFAULT_PORT), the name of the payload file (SHELL_FILE) ,the path to the template payload file (CLIENT_SCRIPT_PATH), whether you want to enable or disable key event detection (DETECT_KEYEVENTS), and the keyboard shortcut to exit (EXIT_KEY).

You can try out different ones and change to what works for you best. The main thing that I am going to talk about is the module configuration. So as I said in the modules section, you can define modules and methods.

A module is going to contain two values. The first one is the module name and the second one is the path to the file.

So let’s say that I wanted to add a module called foo and the file that I want to add to this module is /tmp/foo_bar.py

In this case, I will simply add an entry to the MODULE_LIST list.

‘<module_name>’ : ‘<path_to_the_file>’

Make sure you add a comma to the end of the previous line.

Now you can run cannon and do the module list command to view the newly added module.

After adding a module, you have to add a method to that module. This defines the way how the module is run after the module run command is called.

Here you can see the content of the /tmp/foo_bar.py file.

As you see it just echoes “I Love Python” to a file called foo_bar.log. So this runs in python right? And the command is “python3 /tmp/foo_bar.py > foo_bar.log”.

To add a method to do this in a module, I will add an entry like this

“<module_name>” : “<method>”

You may be wondering, “Okay, I get what you did adding the method, but what is that MODULE_METHOD_IDENTIFIER thing?”.

What that does is that it searches for the MODULE_METHOD_IDENTIFIER value (by default it’s ‘MDL’) in the method you specify and replaces it with the name of your script. So when the module runs, the command would look something like this.

python3 foo_bar.py > foo_bar.log

This will run the script (foo_bar.py) and log the output to the log file (foo_bar.log). If you don’t need to log the output to a file and just want to run it, you can do that too. But remember you won’t see the output of the commands you run as modules.

New features added

I will be updating this section every time a new feature is added so that you can keep track of the functionalities.

  1. Downloading binary files (07/07/2021)
  2. Download files to a specific [OUTPUT_DIR] directory (12/07/2021)

Error handling

Depending on the way and the environment you use this tool, may throw you some errors. Don’t worry it won’t affect the performance of this tool.

  1. Invalid syntax error

This occurs when you don’t specify the correct syntax with the commands. You can check the syntax with the help if it doesn’t automatically give you the correct syntax.

2. Ignoring key detection error

This error is raised when the script has problems importing the pynpupt module. The reason is that pynput module uses GUI interfaces utilities to detect key events. So, if you don’t have the correct environmental set up for that, this module will be ignored. This usually happens when you SSH into a box or use command-line only environments.

As a result, you won’t be able to use the EXIT_KEY to exit.You will have to use the exit command. You can read about this issue from this article.

Author’s thoughts

I have to admit that I am not a good programmer. I just wanted to put up something that will make your way easier when you do CTF competitions and stuff like that. This is not going to get the“BEST” standard but I think it will get a “HELPFUL” standard at least.

If you have any issues with this tool, make sure to leave a comment or put an issue on the GitHub repo. And also, if you have any suggestions on adding new features, please let me know.

Contact me

Email — iamkavigihan@gmail.com
Instagram — @_kavi.gihan

--

--

Kavishka Gihan
Kavishka Gihan

Written by Kavishka Gihan

Cyber Security Student | Machine author @hackthebox | find me on instagram @_kavi.gihan

Responses (1)