Skip to content

Network Profiles

Kris edited this page Feb 4, 2020 · 2 revisions

Introduced in 0.5.3 Network Profiles are self-contained module profiles which define the communication between an implant and their corresponding C2 server.

Overview

Network profiles have 2 distinct tasks, which are directly linked. The first task is the creation of new listeners, which allow implants to communicate home, and secondly the code in which the implant uses to communicate home.

In this page we will cover the common interfaces between the C2 server, the listener, and the implant communication to allow the reader to create your own network profile for FudgeC2.

Profiles typically contain 3 files, which are:-

  • Network Profile - this defines statics values which handed to different parts of the server, such the name of the profile, its' Powershell code, or webforms.
  • Profile interface - The interface is the class responsible for controlling the network profiles listener. This contains common interfaces allowing Fudge to start, stop and query the listener component of the network profile
  • Listener - The code which contains the listener. This could be broken into multiple files if the netwrok profile authors requires.

Importing Network Profiles

FudgeC2 has a list of all imported network profiles which can be found in "NetworkListenerProfile.py" file. When an author wishes to import their completed profile they will need to import the profile, and add an instansated object to the profiles list, for example adding the "GithubNetworkProfile" would make the code look like so:

from NetworkProfiles.Profiles.BasicHttpProfile.BasicHttpProfile import BasicHttpProfile
from NetworkProfiles.Profiles.GithubProfile import GithubNetworkProfile

class NetworkProfileManager:
    profiles = [
        BasicHttpProfile()
        GithubNetworkProfile()
        ]

Network profiles should be stored in their own folder, which is then place in the below directory:

{installation directory}/FudgeC2/NetworkProfiles/Profiles/

Creating a new Network Profile

In this section we modify the core 'BasicHttpProfile' which is contained in FudgeC2, We

Network Profile

Below are all of the public methods which will be required for the network profile to correctly function. For reference you can use the 'BasicHttpProfile'.

name

This is the common name of the implant i.e. "Basic Http Profile"

description

A description of the Network profile, such as caveats and limitations, as well as additional requirements

profile_tag

This is a unique value which is used to distinguish the network profile from others.

get_powershell_code()

This returns the raw Powershell code as a string. This will then be run through the generation engine using Jinja2 templating. The user will have access to common Jinja parameters

get_powershell_obf_strings()

This returns 2 dictionary's which are used in the Jinja templating for every unqiue Jinja tag you create in the get_powershell_code() method, you will need a corresponding keypair. The second dict is the port reference to be used by Jinja2.

get_powershell_implant_stager(implant_data=None)

Takes a dictionary containing all information from an implant template, which can be used to generate a stager. Stagers should be able to communicate with the listener in order to trigger a payload generation.

get_docm_implant_stager(implant_data=None)

Takes a dictionary containing all information from an implant template, which can be used to generate a docm string. Stagers should be able to communicate with the listener in order to trigger a payload generation.

get_webform()

Returns a HTML bootstrap form snippet which will then be rendered on the create implant template page.

validate_web_form(key, value)

Takes 2 string values which will be used to identify and validate the response from the form provided by get_webform(). This allows us to known which port to call back to and which listener profile should call back to that port. Returns dicts which has the profile_tag as the key, and the port as the value.

get_listener_profile_form()

Returns the data needed to create an option in the 'New Listener' modal. a = {"name": self.name, "profile_tag": self.profile_tag, "port": "Port"} return a

get_listener_interface()

Returns an instantiated object of the network profiles interface. I.e.

import NetworkProfiles.Profiles.BasicHttpProfile.BasicHttpInterface as interface
interface = interface.ListenerInterface()
return interface

get_listener_object()

Returns a the network listener class. N.b this should NOT be instantiated. I.e:

import NetworkProfiles.Profiles.BasicHttpProfile.HttpListener as listener
return listener