Code Injection and SQLi In Wp All Export Pro

Code Injection

Code Injection is the general term for attack types which consist of injecting code that is then interpreted/executed by the application. This type of attack exploits poor handling of untrusted data. These types of attacks are usually made possible due to a lack of proper input/output data validation, for example:

  • allowed characters (standard regular expressions classes or custom)
  • data format
  • amount of expected data

SQL Injection

A SQL Injection attack consists of insertion or “injection” of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system.

This blog contains details on how I was able to find “Code Injection and SQLi in WP All Export Pro” by manually reviewing the source code.

Plugin Description

WP All Export features a three-step export process and an intuitive drag & drop interface that makes complicated export tasks simple and fast.

With WP All Export you can:

  • Export data for easy editing,
  • Migrate content from WordPress to another site

You can find more details here:

https://wordpress.org/plugins/wp-all-export/

The CVEs for these issues are:

Environment Setup

Environment Setup

Details of the vulnerability

I setup the plugin and started interacting with the plugin.

When the user clicks on the export, user has the option to select Specific Post Type available in the dropdown.

1. Specific Post Types

After selecting the Post, on the next page user can specify the data to export based on the selected post type

2. Export Type

I started looking into the implementation of the above functionality, the switch case statement is responsible for different FieldType.

3. Code Snippet

One interesting FieldType was “sql”, Below is the code snippet of the same

4. Code Snippet

5. Code Snippet

Here, the user-controlled value fields ($fieldSql and $fieldCode)(Source) are directly getting passed into the $wpdb->prepare and eval(Sinks) function.

There is another feature of the plugin in which user can export the selected Posts as CSV, simple XML, and custom XML.

6. Custom XML Editor

The XML feature looked interesting to me, so I started looking into the implementation of it.

Here are a few snippets on how the XML is being parsed and the user-controlled xml(source) is entering the eval function(sink) which could lead to Code Injection.

  1. In the preprocess_xml function, user provided XML(Source) is being passed

    7. Code Snippet

  2. There are different filters that are being applied to the input data, such as trimming different characters, checking whether the given functions exist or not, and the result is getting used in the eval function (Sink) where the passed function is being executed.

    8. Code Snippet

Payload: [system(‘id’)]

Easy Multiple Code Injection and SQLi, right?

The vulnerability was reported to the WP All Export Team and they replied by saying that these are intentional functionalities that the plugin supports and shared the documentation as well for the same.

Documentation: https://www.wpallimport.com/documentation/code-snippets/

Lesson learned: Always look for the documentation of the application, if it’s available on different functionalities, and why the developer has put the code in the first place.

So that’s all? Definitely not!!!

I started looking into the documentation and I noticed this

9. Client Mode Doc

I did not have the pro version as the client mode is supported in the pro version of the plugin, but from the documentation, we can see that the client will have the access to the allowed exports, and they can just click on the “Run Export” to export the specific export.

10. Client Mode Doc

Documentation: https://www.wpallimport.com/documentation/how-to-let-clients-run-wordpress-exports/

This UI in the doc for the client looked like the “Manage Exports” in free version of the plugin

11. Client Mode Doc

After clicking on the “Run Export” in the free version, users get redirected to the “confirm and run page” with the options of some advanced settings.

12. Confirm and Run Page

Let’s investigate the code on the implementation part in the free edition. In the free edition, in wp-all-export.php, adminDispatcher function is responsible for calling the different controllers based on the page and action parameters.

13. Code Snippet

I intercepted the request for the “Confirm and Run Export” in burpsuite to see the form details.

14. Intercepted Request

According to the action parameter, update method of the class “PMXE_Admin_Manage”(page param) will get called. Below are the code snippets of the update method.

15. Code Snippet

16. Code Snippet

Spotted the vulnerability?

Remember the cc_php, cc_code, cc_sql fields?

All the default options are being imported and if any of them are present in the post request, that value will be taken by the respective fields i.e., we can control fields like cc_php, cc_code, cc_sql for executing any PHP function, SQL queries as these fields are getting directly getting used in the eval, $wpdb->prepare directly.

I reported the vulnerability to the team and mentioned that if the code flow is same in PRO version as well, the client will be able to execute any PHP code and SQL queries.

The team replied and gave me access to the PRO version, I was able to reproduce the Code Injection and SQLi in the PRO as the code flow was same.

Steps to reproduce (Code Injection)

  1. Intercept the “Confirm & Run Export” page request

    17. Intercepted Request

  2. Add the below fields and turn the intercept off

    ------WebKitFormBoundaryebX838kmAzPMht5c
    Content-Disposition: form-data; name="cc_type[]"
    sql
    ------WebKitFormBoundaryebX838kmAzPMht5c
    Content-Disposition: form-data; name="cc_code[]"
    system('id')
    ------WebKitFormBoundaryebX838kmAzPMht5c
    Content-Disposition: form-data; name="cc_php[]"
    test
    ------WebKitFormBoundaryebX838kmAzPMht5c
    Content-Disposition: form-data; name="cc_sql[]"
    test
    

    18. Modified Intercepted Request

  3. Export is completed. Now click on the “DownloadCSV” to see the content.

    19. Export Completed

  4. Observe that payload(system(‘id’)) got executed and the output in the CSV which was inserted in step 2

    20. Payload Executed

Steps to reproduce (SQLi)

  1. Intercept the “Confirm & Run Export page request

    21. Intercepted Request

  2. Add the below fields and turn the intercept off

    -----WebKitFormBoundaryiJPFIleVAGMODGts
    Content-Disposition: form-data; name="cc_type[]"
    sql
    ------WebKitFormBoundaryiJPFIleVAGMODGts
    Content-Disposition: form-data; name="cc_code[]"
    test
    ------WebKitFormBoundaryiJPFIleVAGMODGts
    Content-Disposition: form-data; name="cc_php[]"
    test
    ------WebKitFormBoundaryiJPFIleVAGMODGts
    Content-Disposition: form-data; name="cc_sql[]"
    insert into wp_users (user_login, user_pass,user_nicename,user_email,user_url,user_activation_key,display_name)values('qwerty_test','password','nicename','user_email','user_url','user_activation_key','display_name')
    

    22. Modified Intercepted Request

  3. Export is completed

    23. Export completed

  4. Observe that one new entry in the wp_users table cause of the insert payload in the step 2.

    24. Payload Executed

Patch Applied

The team fixed the vulnerability by restricting the client to modify only a few of the options.

Timelines

Vulnerabilities reported and acknowledged: 18-08-2022

Vulnerabilities Fixed and a new version released: 30-08-2022

Reward: $500

Conclusion

This was an interesting case of how vulnerabilities like this can be found manually by reviewing the source code which would be hard to find with the automated tools.

Thanks to the WP ALL Export team for the quick responses and reward.

Originally Published at: https://payatu.com/blog/p3n7a90n/wp-all-export-pro

Load Comments?