Atlas
Table of Contents
Introduction/What is this Project?
- This repo is the homepage for the Mythic-C2 Atlas agent.
- Atlas is a .NET 3.5 and .NET 4.0 compatible agent that is designed as an initial payload offering only the bare essentials before loading upa more fully-featured agent.
- The current version of Atlas supports Mythic
<FIXME>
and will be kept up-to-date as necessary to ensure clean operation with the latest stable release of Mythic-C2. - It is not compatible with Mythic
<FIXME>
and below.
How to install Atlas into Mythic
- Installing from Mythic C2 Host
- You can use the
mythic-cli
binary to install Atlas in one of three ways:sudo ./mythic-cli install github https://github.com/user/repo
to install the main branchsudo ./mythic-cli install github https://github.com/user/repo branchname
to install a specific branch of that reposudo ./mythic-cli install folder /path/to/local/folder/cloned/from/github
to install from an already cloned down version of an agent repo
- You can use the
- You have three(3) options as to when you can install Atlas as an agent into Mythic-C2:
- Mythic is already up and going, then you can run the install script and just direct that agent's containers to start (i.e.
sudo ./mythic-cli payload start agentName
and if that agent has its own special C2 containers, you'll need to start them too viasudo ./mythic-cli c2 start c2profileName
). - Mythic is already up and going, but you want to minimize your steps, you can just install the agent and run
sudo ./mythic-cli mythic start
. That script will first stop all of your containers, then start everything back up again. This will also bring in the new agent you just installed. - Mythic isn't running, you can install the script and just run
sudo ./mythic-cli mythic start
.
- Mythic is already up and going, then you can run the install script and just direct that agent's containers to start (i.e.
Understanding How Atlas Works
- Code Architecture
- Execution Flow
- Execution Starts in
Main()
inProgram.cs
- One function is immediately called,
Utils.GetServers();
- This function's execution chain ends with a list of servers being added to the
Config.Servers
list
- This function's execution chain ends with a list of servers being added to the
- The next step is a compile-time flag seeing whether to validate the TLS certificate on callback.
- Next up is a while loop, that checks for if the
HTTP.CheckIn
function returns false, and if so, generates an int and sleeps for that amount of time.while (!Http.CheckIn())
- Evals whetherHttp.CheckIn()
returns true.
- After the
HTTP.CheckIn
is eval'd, aJobList
object is created, fromMessages.JobList
. This sets the internal varjob_count
to 0, andjobs{}
as an array.JobList
definition:Messages.JobList JobList = new Messages.JobList
- This creates the List object
jobs
public List<Job> jobs { get; set; }
- This object also contains a function called
JobList()
- This function creates a new variable
jobs
with the value ofnew List<Job>()
- This function creates a new variable
- Finally, we have a while loop
while (true)
, which performs 3 tasks:Dispatch.Loop(JobList);
- This function, as the name implies, first performs an
if/else
check regarding the current date, and should that be satisfied, continues on to:- Retrieve tasking using
Http.GetTasking(JobList);
- Perform said tasking using:
StartDispatch(JobList);
- Returns the results of task execution to the Mythic server:
Http.PostResponse(JobList);
- Retrieve tasking using
- This function, as the name implies, first performs an
int Dwell = Utils.GetDwellTime();
GetDwellTime()
- Creates a high and low number using
Config.Sleep + (Config.Sleep * (Config.Jitter * 0.01))
andRandom()
to pick a 'random' number for each one.int Dwell = random.Next(Convert.ToInt32(Low), Convert.ToInt32(High));
- Then multiplies the result by
1000
, and returns that as the value forDwell
System.Threading.Thread.Sleep(Dwell);
- Self-explanatory, process 'sleeps' for the
Dwell
time value established above.
- Self-explanatory, process 'sleeps' for the
- Execution Starts in
- Understanding Tasking of Atlas
- Tasking occurs During Step 6 above, specifically with the
Dispatch.Loop(JobList);
function.- This function first performs a date check, to ensure it is not being ran outside allowed parameters.
- Next,
Http.GetTasking(JobList)
is called, with the argument passed being theJobList
object from before.- The function definition can be seen at the below URL.
- The first two lines establish the string field
action
and int fieldtasking_size
as get/set-ters * See: https://stackoverflow.com/questions/5096926/what-is-the-get-set-syntax-in-c - After those two lines, the next line & function defines a string format to use to format strings from tasking messages.
public string JsonFormat = @"{{""action"":""{0}"",""tasking_size"":{1}}}";
- Then the function
ToJson()
is defined.- This function by default takes two arguments, as seen in its definition:
GetTasking
&get_tasking
- We can next see that it returns three(3) objects as string values.
get_tasking.JsonFormat
<Unsure>
This line converts theget_tasking
object to JSON formatting.
JavaScriptStringEncode(get_tasking.action)
- This line encodes the string stored in
get_tasking.action
. - https://docs.microsoft.com/en-us/dotnet/api/system.web.httputility.javascriptstringencode?view=net-6.0
- This line encodes the string stored in
JavaScriptStringEncode(get_tasking.tasking_size.ToString())
- This line also encodes a string, however, first, the value stored in
get_tasking.tasking_size
is converted to a string object, so that it can be properly encoded as a string.
- This line also encodes a string, however, first, the value stored in
- This function by default takes two arguments, as seen in its definition:
- The function definition can be seen at the below URL.
- Then
StartDispatch(JobList)
, which has the definition line ofpublic static bool StartDispatch (Messages.JobList JobList)
- This function iterates through the
JobList
object, checking to see if any entries match any of the available commands.- If so, the matching code is ran, and the matching
Job
fromJobList
(JobList.jobs
) is modified to reflect the status of the task.
- If so, the matching code is ran, and the matching
- Finally,
Http.PostResponse(JobList);
atlas/Payload_Type/atlas/agent_code/Http.cs
Line 230 in 037349c
- This function is a bit bigger than the others, with the definition line being:
public static bool PostResponse(Messages.JobList JobList)
- It first opens a try/catch block, and tries the following:
Messages.PostResponse PostResponse = new Messages.PostResponse
PostResponse
definition:
- Next, it proceeds to iterate over each
job
item in theJobList.jobs
foreach (Messages.Job Job in JobList.jobs)
JobList
Object definition:Job
object definition:
- This continues in a loop, until the entire list of jobs initially passed in the
JobList
object has been iterated through.
- Tasking occurs During Step 6 above, specifically with the
Extending Atlas's Features & Functionality
- The agent has
mythic_payloadtype_container==0.0.44
PyPi package installed and reports to Mythic as version "8".
- 101
- F