<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by SPARTaN on Medium]]></title>
        <description><![CDATA[Stories by SPARTaN on Medium]]></description>
        <link>https://medium.com/@001SPARTaN?source=rss-2d7dacfa9fd------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*u63b_jOGtKbuHHHe.jpg</url>
            <title>Stories by SPARTaN on Medium</title>
            <link>https://medium.com/@001SPARTaN?source=rss-2d7dacfa9fd------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 04:18:08 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@001SPARTaN/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Cobalt Strike Visualizations]]></title>
            <link>https://medium.com/@001SPARTaN/cobalt-strike-visualizations-e6a6e841e16b?source=rss-2d7dacfa9fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/e6a6e841e16b</guid>
            <category><![CDATA[red-team]]></category>
            <category><![CDATA[pentesting]]></category>
            <category><![CDATA[cobalt-strike]]></category>
            <category><![CDATA[aggressor]]></category>
            <dc:creator><![CDATA[SPARTaN]]></dc:creator>
            <pubDate>Mon, 23 Apr 2018 06:30:54 GMT</pubDate>
            <atom:updated>2018-04-23T06:30:54.832Z</atom:updated>
            <content:encoded><![CDATA[<p><em>NOTE: This post is not entry-level. This will be a deep dive into complex Aggressor scripting, and undocumented functionality. Fair warning — even I don’t understand visualizations fully, and there’s a lot more to explore. This is just scratching the surface.</em></p><p>If you saw my blog post a couple weeks ago, you know that <a href="https://medium.com/@001SPARTaN/aggressor-101-unleashing-cobalt-strike-for-fun-and-profit-879bf22cea31">I like writing Aggressor scripts for Cobalt Strike</a>. Aggressor allows you to add functionality to the framework, and make it even more useful for your purposes. This can be done in many different ways, but one thing that has caught my interest recently is the possibility offered by Cobalt Strike <strong>visualizations</strong>.</p><h3>What are Visualizations?</h3><p>Visualizations are the different views that Cobalt Strike offers to an operator, found in the <strong>View</strong> menu. The default visualizations are what you’re used to seeing in the top pane of Cobalt Strike: Sessions view, Targets view, and the Pivot Graph. Basically, they’re there to give you information about the engagement, and the current state of Cobalt Strike. But what if we could display more information to operators? What information is kept within the framework that isn’t as easy to see? More importantly, how can we display that to operators to allow them to use that information?</p><h3>Visualizing Success</h3><p>A few months ago, I was playing around with some Aggressor, and while browsing the official reference, I stumbled across a function I had never really paid attention to: <a href="https://www.cobaltstrike.com/aggressor-script/functions.html#addVisualization"><strong>addVisualization</strong></a>. My interest was piqued, because the Aggressor function reference only gives this:</p><blockquote>Register a visualization with Cobalt Strike.</blockquote><blockquote>Arguments</blockquote><blockquote>$1 - the name of the visualization<br>$2 - a javax.swing.JComponent object</blockquote><blockquote>Example</blockquote><blockquote>$label = [new javax.swing.JLabel: &quot;Hello World!&quot;];<br>addVisualization(&quot;Hello World&quot;, $label);</blockquote><p>Not much to go on. I wanted to find out more. What else could I do with addVisualization? Could I create anything useful? There was one problem… There weren’t any other examples of visualizations in Cobalt Strike. None. I looked exhaustively. There were Aggressor scripts that dealt with GUI elements — notably from <a href="https://bluescreenofjeff.com/2016-09-07-adding-easy-guis-to-aggressor-scripts/">@bluescreenofjeff</a> and <a href="https://github.com/HarmJ0y/cortana/blob/master/veil_evasion/veil_evasion.cna">@harmj0y</a>, both of which were <em>extremely</em> helpful for certain parts — but there were no scripts that I could find that actually created visualizations. Without other code to reference, I was in uncharted territory. Rather than give up, I fired up Cobalt Strike and started tinkering.</p><h3>Hello, world!</h3><p>The first step was to create a very simple visualization. I just wanted to make sure that I could add a visualization to the framework and display it. From there, I could build on that to make a visualization that actually displays useful data.</p><p>The code for this was fairly simple, and most of it is in the little snippet in the docs. First, you have to create a JComponent object. The example in the docs (posted above) uses a JLabel, so that’s what I started with. Here’s my first working visualization:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5e39cf6c295de2fc27488bb6622a63ff/href">https://medium.com/media/5e39cf6c295de2fc27488bb6622a63ff/href</a></iframe><p>And here’s what that looks like when you load the script into Cobalt Strike:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/827/1*hBgCZ2pZrVQVsf0tqAXtPQ.png" /><figcaption>My very first visualization!</figcaption></figure><h4>Aggressor and Java</h4><p>Before we go through this simple script, we need to talk a little bit about Java inside of Aggressor. If you haven’t dealt with Java in Aggressor before, Aggressor scripts can import any Java packages or libraries you want, and you can access them from within Aggressor with a slightly different syntax compared to what you might do in Java.</p><p>For example, to make a new JLabel in Java, we would use this syntax:</p><p>vis = new JLabel(“Hello, world!”);</p><p>To do this in Aggressor, we use the following syntax, as seen in line 6 of the helloworld.cna script:</p><p>$vis = [new JLabel: “Hello, world!”];</p><p>Converting Java constructors to Aggressor is fairly straightforward. Instead of new Object(arg1, arg2), you can use [new Object: arg1, arg2]. You use a similar syntax when calling methods on Java objects. I’ll show an example of that here, because we’ll use that later. Consider a Java object that we’ve created in Aggressor like this:</p><p>$obj = [new someObject];</p><p>Let’s say the someObject class has a doStuff(“argument”) method that will return a string. To get this string in Java, we’d do something like:</p><p>String str = obj.doStuff(“argument”);</p><p>To do the same thing in Aggressor, it looks like this:</p><p>$str = [obj doStuff: &quot;argument&quot;];</p><p>This syntax will let us convert Java to Aggressor, and thus create more advanced visualizations. Back to our simple visualization.</p><h4>Creating and Displaying Visualizations</h4><p>As seen in the docs for addVisualization, once we’ve created a visualization, we use addVisualization to register the visualization within Cobalt Strike. This still doesn’t display it to the user, though! The syntax for addVisualization that our script uses is this, on line 7:</p><p>addVisualization(&quot;hello&quot;, $vis);</p><p>In this case, “hello” is a label that we can use to reference our visualization now, and we use this label to display the visualization with showVisualization:</p><p>showVisualization(&quot;hello&quot;);</p><p>Pretty simple, right? …Right?</p><h3>Making Useful Visualizations</h3><p>While creating my first test visualization was pretty easy, the rest wasn’t so easy. Working without a good reference, I turned to the <a href="https://github.com/rsmudge/armitage">source code for Armitage</a>, Raphael Mudge’s precursor to Cobalt Strike. Many parts of Cobalt Strike are based on Armitage, and luckily still utilize many similar components. By looking through the various Cortana scripts (the precursor to Aggressor), I managed to cobble together a basic visualization that allowed me to display a table of Beacons alongside a simple console display, <a href="https://github.com/001SPARTaN/aggressor_scripts/blob/master/visualizations/vis.cna">vis.cna</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tzDn5w6Aa7u0xdlEJQFWpw.png" /><figcaption>Vis.cna in all its glory.</figcaption></figure><p>As you can see, it was fairly minimal, but it provided a good way to test out various things within Cobalt Strike visualizations. This visualization pulls information from the Cobalt Strike data model to populate the table of Beacons on the left, and displays web log hits and new Beacon events in the console on the right. There was one major issue with this visualization, but first let’s go through how it’s constructed.</p><h4>Vis.cna Deconstructed</h4><p>I started my work on a custom visualization by attempting to build a simple table, and to pull Beacon data into that table. To create a table, it first requires a GenericTableModel, which is what will populate our table with data. GenericTableModel is provided by the table package, built in to Cobalt Strike. To create a GenericTableModel, you provide an array of column names, a column to use as the lead column, and an expected size for the table.</p><p>$model = [new GenericTableModel: @(“user”, “host”, “bid”), “bid”, 16];</p><p>The next question is: How do we pass data into our GenericTableModel? In vis.cna the function that does that is updateTable(). This function is fairly straightforward. First, we clear the model. Next, we have to iterate through the Beacons that Cobalt Strike has information about, and create a hash with the appropriate user, host, and ID for each one.Then, we use the addEntry method of GenericTableModel to add the entry to the model. We’re not quite done yet, because we have to tell the ATable we’re populating with this GenericTableModel that the model has changed. That’s where fireListeners comes in.</p><p>Now that we’ve created our GenericTableModel to populate it with data, let’s create our ATable. First, we create a new ATable, with the GenericTableModel as an argument.</p><p>Next, we have to tell the ATable how to sort the data in the GenericTableModel, so that you can click the column headers to sort based on the data in those columns. First, we need to create a TableRowSorter to control how the data is sorted. Next, we need to use the setComparator method of this TableRowSorter to tell it <em>how</em> to sort each column. We have three columns: username, hostname, and Beacon ID. Usernames and hostnames are sorted alphabetically, but we need to sort Beacon IDs numerically. To sort the first column alphabetically, we need this snippet:</p><p>[$sorter setComparator: 0, { return $1 cmp $2; }];</p><p>To sort the Beacon ID numerically, we use this snippet:</p><p>[$sorter setComparator: 2, { return $1 &lt;=&gt; $2; }];</p><p>With that, we’ll be able to change the sort order of the table by clicking the column headers. After making sure we can sort the table, let’s add a secondary component to display certain events in the Cobalt Strike console. I chose a Display from the built-in console package in Cobalt Strike, because it will give us nice formatting options for the text, and it matches with the way information is displayed in the rest of the framework. Creating this is pretty simple:</p><p>$console = [new console.Display];</p><p>After we’ve created our ATable and Display, we need to create something to house both of these, because addVisualization takes a single object. For this, I chose a JSplitPane, which will allow us to have both components side by side, with a divider that we can drag to resize the size of either component. Here’s how we do that:</p><p>$content = [new JSplitPane: [JSplitPane HORIZONTAL_SPLIT], [new JScrollPane: $table], $console];</p><p>You might have noticed that we didn’t put $table directly into the JSplitPane. Instead, we first put it into a JScrollPane, to allow the table to be scrolled if there are more items than fit in the pane. We also specified the direction of the split as the first argument, using [JSplitPane HORIZONTAL_SPLIT]. In Java, this would be JSplitPane.HORIZONTAL_SPLIT, but we need to use Sleep’s Java syntax in this case. To make things look a little nicer, I chose to set the default divider location to have a bit of an offset with this line:</p><p>[$content setDividerLocation: 450];</p><p>The last thing we need to do before adding our new visualization is call our updateHosts function to populate data into the GenericTableModel. Then, we can finally add our visualization to Cobalt Strike with addVisualization(“Custom”, $content). Note that this doesn’t do anything with the visualization, it just registers it with the framework.</p><p>To actually view our new visualization, we can use showVisualization, like this:</p><p>showVisualization(“Custom”);</p><p>Visualizations are referenced by their title in Cobalt Strike, so we choose the title that we used in addVisualization as the argument in showVisualization. At the bottom of vis.cna, I have a short snippet to add the visualization to the View menu in the Cobalt Strike interface, which will allow us to quickly access the new visualization.</p><h3>Wrapping Up</h3><p>Hopefully this post has been useful if you’re interested in Cobalt Strike visualizations! This is just scratching the surface of what is possible, and I’m working on exploring these possibilities, but I wanted to share what I’ve learned so far in the hopes that others will see this post and decide to experiment as well. At the most basic, visualizations are just JComponent objects, and they can allow you to customize how information is displayed to operators in Cobalt Strike. I haven’t seen other public examples of Cobalt Strike visualizations, but check out my <a href="https://github.com/001SPARTaN/aggressor_scripts/blob/master/visualizations/logvis.cna">logvis.cna</a> script for another example, and please let me know if you make anything with visualizations!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e6a6e841e16b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Aggressor 101: Unleashing Cobalt Strike for Fun and Profit]]></title>
            <link>https://medium.com/@001SPARTaN/aggressor-101-unleashing-cobalt-strike-for-fun-and-profit-879bf22cea31?source=rss-2d7dacfa9fd------2</link>
            <guid isPermaLink="false">https://medium.com/p/879bf22cea31</guid>
            <category><![CDATA[cobalt-strike]]></category>
            <category><![CDATA[aggressor]]></category>
            <category><![CDATA[pentesting]]></category>
            <category><![CDATA[red-team]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[SPARTaN]]></dc:creator>
            <pubDate>Tue, 13 Mar 2018 13:18:59 GMT</pubDate>
            <atom:updated>2018-03-13T13:18:59.637Z</atom:updated>
            <content:encoded><![CDATA[<p>I use Cobalt Strike a lot. It’s my team’s go-to tool for compromising Windows environments, and that’s what I find myself doing more often than not during red team engagements. One of the reasons I enjoy it so much is that it abstracts a lot of the common things that we need to do on engagements, giving us more flexibility to focus on our objectives, and how best to accomplish them.</p><p>Even so, I’m obsessed with making our workflow even more efficient, and giving us the power to accomplish objectives even faster. One of the best ways to do this is with Aggressor Script, Cobalt Strike’s native scripting language. I should also add a caveat to this post: I am not a software developer. I do not have a formal background in developing, nor do I focus on efficiency or speed when I’m writing Aggressor.</p><p>Recently, I was able to attend the (excellent) SpecterOps Adversary Tactics: Red Team Operations course, which gave me the opportunity to talk to various red teamers, getting their perspectives on preferred tools, and how they use them. One of the things that surprised me somewhat was how few people make use of the power that Aggressor Script can provide. A sentiment that I heard a lot was that even red teams already paying for Cobalt Strike haven’t implemented much Aggressor Script into their workflows. I’d like to change that.</p><h4><strong>An Introduction to Aggressor</strong></h4><p><a href="https://www.cobaltstrike.com/aggressor-script/index.html"><strong>Aggressor Script</strong></a> is based on <a href="http://sleep.dashnine.org/manual/"><strong>Sleep</strong></a>, a language created by Raphael Mudge (also the author of Cobalt Strike). Sleep is basically a Perl-like language which runs on the JVM. Before you start complaining, I believe that the power that Aggressor Script gives you in Cobalt Strike far outweighs any issues some might have with writing Perl, or dealing with Java.</p><p>This post will assume that you’re comfortable using Cobalt Strike, and that you know the various concepts behind operating with it. This will not be an introduction to Cobalt Strike.</p><p>With that out of the way, what does Aggressor Script actually look like? I find the syntax to be pretty simple, especially if you’re used to writing Perl, though many concepts will be perfectly understandable if you’ve written code before. Here’s a simple “Hello, world!” script, written in Aggressor:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/406f5adcd27ceb1d8a225c7516545823/href">https://medium.com/media/406f5adcd27ceb1d8a225c7516545823/href</a></iframe><p>Pretty easy. We create a new function named “hello” with sub hello {...} , and print text to the console with println(&quot;Hello, world!&quot;) . Statements in Aggressor must end with a semicolon, and functions must be defined <em>before </em>they’re called. Because the function doesn’t take any arguments, calling it with hello() will run the code.</p><p>Now that we have our first script, how do we actually use it? First, open up Cobalt Strike, and connect to your teamserver. Once your client is connected, go to <strong>View-&gt;Script Console</strong>, and type load /path/to/helloworld.cna (the full path is required). With that, you should see something like the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*6ojoWcVgmOHM8ArQFahmIA.png" /><figcaption>Hello, world!</figcaption></figure><p>The cool thing about the script console is that it lets you test stuff out without having to write a full script, too. We can create the same function using the e command in the script console to evaluate Aggressor snippets. To do this, we can take the same code, and instead put it on a single line. In the script console, type e sub hello {println(&quot;Hello, world!&quot;);} , and hit enter. This won’t return anything, but we can then run our hello() function by running e hello() in the script console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/1*3aarAmOkBt8eyIXK4lR-2A.png" /></figure><p>Just like that, we can test out bits of Aggressor. When I’m writing Aggressor scripts, I constantly use the script console to prototype small bits of code, and make sure they’re working before I pull them into a larger script. It’s a very useful tool to debug scripts, or to quickly run snippets that don’t necessarily constitute a full scripts.</p><p>Now that we’ve gone over how to run Aggressor scripts, let’s explore how to construct more useful scripts.</p><h4>The Building Blocks</h4><p>In order to build useful Aggressor scripts, we’ll need a bit more to go on than just printing stuff to the console. To do that, we need to learn about the various datatypes in Sleep, and how to work with them. The main datatypes in Sleep are <strong>strings</strong>, <strong>arrays</strong>, and <strong>hashes</strong>. <strong>Strings</strong> are denoted with $ , <strong>arrays</strong> with @ , and <strong>hashes</strong> with %.</p><p>If you’ve written code in another language, these datatypes should be familiar. Strings contain characters or strings of characters; arrays can hold multiple strings, arrays, or hashes (you <strong>can</strong> mix types in an array); and hashes contain multiple key-value pairs. What do these look like in practice?</p><p>This is a string with a few words:</p><p>$string = &quot;This is a string.&quot;;</p><p>This is an array with three elements; a <strong>string</strong>, a <strong>number</strong>, and the $string <strong>variable</strong> that we defined before:</p><p>@array = @(&quot;The first element.&quot;, 2, $string);</p><p>This is a hash with three elements; key1 has a value of &quot;value1&quot;, the value for key2 is the array we defined as @array, and key3 contains our $string variable.</p><p>%hash = %(key1 =&gt; &quot;value1&quot;, key2 =&gt; @array, key3 =&gt; $string);</p><p>Using the x command in the script console, we can examine what these variables contain:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7ttSAfaA7uEv1cvUFkLSxg.png" /><figcaption>Strings, arrays, and hashes; the primary datatypes in Sleep</figcaption></figure><p>As you can see, Sleep has no issues combining datatypes, or dealing with nested arrays or hashes. In fact, it’s often very useful to nest arrays and hashes to create structures for storing things.</p><p>Before we start writing useful Aggressor scripts, I’ll go through how to access data stored in arrays and hashes. These two datatypes behave like they do in other languages. First, data contained in arrays can be accessed by its <strong>index</strong>, or its position in the array. Let’s define an array:</p><p>@array = @(&quot;First&quot;, &quot;Second&quot;, &quot;Third&quot;);</p><p>The index of the first element in an array is 0. To view this value, we can use @array[0] :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/758/1*9DgsAO1jU73R7ZfzkpO50Q.png" /></figure><p>To access the other elements in the array, we can use their indices in the same way:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*21oaAn9ZPJ90whrKC9-uxQ.png" /><figcaption>Fun with arrays!</figcaption></figure><p>We can also use these in println statements to directly print the values. The dot operator will concatenate two values as a string:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*P-Uqi7dAcx01sdqt8xW-hQ.png" /></figure><p>Hashes work in a similar way, though instead of using the index of an item, you’ll use the key that the value is stored under. Here’s what that looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tfNH3kiDXcxWkMaVNgkIrQ.png" /><figcaption>Fun with hashes!</figcaption></figure><p>The key values can be named whatever you’d like, and the value can be any type of data you want. Now that we’ve learned about the datatypes in Aggressor, how do we use this information to do useful things inside of Cobalt Strike?</p><h4>Scripting Cobalt Strike</h4><p>At the core of Cobalt Strike is the Cobalt Strike data model. This is where all of the information accessible to operators is stored, and it gives us a large amount of data to use for automating things in Cobalt Strike. The data collected in the data model includes information about the current beacons, credentials gathered from compromised systems, screenshots, downloaded files, and many other things.</p><p>For an example of how to use this data, let’s say we have a single beacon on a system. We can get an array of all the currently connected beacons by using the beacons() function, a built-in function in Aggressor. We can view this information with x beacons() in the script console.</p><p>If you try this, you’ll get a lot of information about each beacon. Beacons are arranged in an array, and each beacon is stored as a hash in this array. This is what that looks like with a single beacon in the data model:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v5n0ORCwx1rJ9Z5Q26Xlqw.png" /><figcaption>Beacon data returned with the beacons() function</figcaption></figure><p>So what can we do with the information in the data model? Let’s start with a fairly simple task that you might want to do: run a command on all of the beacons that you have connected to a teamserver.</p><h4>Your First Aggressor Script</h4><p>Let’s build this script out a piece at a time. First, we’ll start with creating a script to run a command on a single beacon. To do this, we’re going to use the <a href="https://www.cobaltstrike.com/aggressor-script/functions.html#bshell">bshell</a><strong> </strong>function, a built-in function of Cobalt Strike. Here’s the definition from the official Aggressor Script documentation:</p><blockquote>bshell — Ask Beacon to run a command with cmd.exe</blockquote><blockquote>Arguments</blockquote><blockquote>$1 - the id for the beacon. This may be an array or a single ID.<br>$2 - the command and arguments to run</blockquote><p>So how do we write a script to utilize this? We’re going to create an <strong>alias</strong>, or a command that you can type into any beacon console to execute custom Aggressor code. Here’s what that looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/799a7d970a7f1a736df3d6bd72e8bbb2/href">https://medium.com/media/799a7d970a7f1a736df3d6bd72e8bbb2/href</a></iframe><p>If you haven’t written Aggressor before, you might be curious about the $1 and $2 variables we’re using in bshell. Whenever a function takes arguments in Aggressor, those arguments are passed to the function as numbered variables, named in the order in which they’re passed. For aliases, the first argument is the beacon ID that the alias is being used on, and any arguments after that are things you type after the alias when you run it from a beacon console. In this case, if you type shellcmd whoami into a beacon console, $2 will be &quot;whoami&quot;. If you want to rename these variables to something that is easier to keep track of, you can assign them to other variables that you create. For more information on the functions available for use in Aggressor, and the arguments they take, <a href="https://www.cobaltstrike.com/aggressor-script/functions.html"><strong>check out this page</strong></a>.</p><p>To test this new alias out, save the script, and load it into Cobalt Strike (through the script console or through the script manager). You should now be able to type shellcmd &lt;COMMAND&gt; into a beacon console, and it will run the command for you! Note that you will also be able to tab-complete this alias.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*C6QdccRWnWb73I17mZy30A.png" /><figcaption>Using our custom alias to run whoami</figcaption></figure><p>Right now, this isn’t a very impressive script. It does the same thing as the built-in shell command, but you have to type more to use it. How can we make our script run a command on <em>all </em>beacons, not just a single beacon? First, let’s write a bit of Aggressor to run a set command on multiple beacons, and then we’ll modify it until we can run whatever command we want on multiple beacons.</p><p>To do this, we’ll first need to iterate through all the beacons connected to the teamserver. Cobalt Strike makes this pretty easy. Remember that beacons() function from earlier? We can use that to iterate through all beacons with a simple foreach loop. Here’s what that looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55e8c8baa8ff0bf27414e459bf206c2c/href">https://medium.com/media/55e8c8baa8ff0bf27414e459bf206c2c/href</a></iframe><p>Here, we’re using a foreach loop to iterate through every beacon returned by the beacons() function. Remember, beacon information returned by this function is stored as a <strong>hash </strong>for each beacon. From the hash, we’re selecting the <strong>id </strong>key with %beacon[&#39;id&#39;], and printing this ID.</p><p>How can we modify this script to instead run a command on every beacon returned by beacons()? Let’s start by rewriting it to run whoami on every beacon.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/52a0f3cf6b019670fbb3a2906793d104/href">https://medium.com/media/52a0f3cf6b019670fbb3a2906793d104/href</a></iframe><p>Again, this is a pretty simple script, but we need to make it a little more useful. Instead of just running whoami on every beacon, let’s create a beacon alias that will run whatever command we want on every beacon. There are a couple ways to do this, but here’s a good start:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/942663a9f0e7c6148e10d63ea706bd6f/href">https://medium.com/media/942663a9f0e7c6148e10d63ea706bd6f/href</a></iframe><p>To run this script, type runall into a beacon console, followed by a command. Due to the way alias works in Aggressor, if you want to run a command with spaces in it, you’ll need to wrap it in double quotes. There are ways to get around this, but I wanted to keep this post as a basic introduction to Aggressor.</p><p>Hopefully this post has given you a better idea of how to write basic Aggressor scripts! This is just scratching the surface of what’s possible with Cobalt Strike. You can use <a href="https://www.cobaltstrike.com/aggressor-script/events.html"><strong>events</strong></a> to automatically trigger actions. You can alter the Cobalt Strike GUI with additional menu items or even custom visualizations. Aggressor doesn’t have functionality you want? You can even use inline Java object expressions to incorporate functionality from any Java library!</p><p>It might not be the prettiest language, but Aggressor gives you a tremendous amount of power, and allows you to expand Cobalt Strike however you want to. If you’re a Cobalt Strike user and you’re not writing Aggressor, you’re missing out on one of the most powerful tools available to you. In future posts, I’ll go through more of what makes Aggressor so useful. Until then, I hope this has been a useful introduction.</p><p>Questions? Comments? Hit me up on <a href="https://twitter.com/001SPARTaN"><strong>Twitter</strong></a>, or come hang out in the <a href="https://bloodhoundgang.herokuapp.com/"><strong>BloodHound Slack</strong></a>, especially the #aggressor channel.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=879bf22cea31" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>