idor – TechKranti https://techkranti.com CyberSecurity Revolution Wed, 26 Aug 2020 17:22:03 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 169658937 Delete IDOR on a Fashion eCommerce Website https://techkranti.com/delete-idor-on-a-fashion-ecommerce-website/ Wed, 26 Aug 2020 17:21:37 +0000 http://techkranti.com/?p=223 Yes, another IDOR. I find a lot of IDORs. It’s my favourite class of bugs. This is a story of an IDOR I reported on an Asian fashion eCommerce website’s private program. Let’s get on with the story:

The Feature:

Like most eCommerce websites, this website provided a feature to store addresses in the customer’s account. The Account section had an option to manage addresses. The address management API calls looked like these:

Note: Requests have been URL decoded for better readability

Create An Address:
POST /customer/address/create/?ajax=true&address_id= HTTP/1.1

AddressForm[first_name]=Amey&AddressForm[last_name]=Test&AddressForm[cell_phone]=2418174&phone_prefix=8,9&phone_len=7&AddressForm[phone]=&AddressForm[address1]=2418174&AddressForm[address2]=&AddressForm[postcode]=241817&AddressForm[fk_customer_address_region]=&AddressForm[city]=Singapore&AddressForm[fk_country]=198&AddressForm[id_customer_address]=
Edit An Address:
POST /customer/address/edit/?ajax=true&address_id=2417909 HTTP/1.1

AddressForm[first_name]=Name&AddressForm[last_name]=Two&AddressForm[cell_phone]=98989898&phone_prefix=8,9&phone_len=7&AddressForm[phone]=&AddressForm[address1]=Lkb 122, asdsaasd sad Rd&AddressForm[address2]=12-321&AddressForm[postcode]=423122&AddressForm[fk_customer_address_region]=&AddressForm[city]=Singapore&AddressForm[fk_country]=198&AddressForm[id_customer_address]=2417909
Delete An Address:
GET /customer/address/delete/?address_id=2418179&YII_CSRF_TOKEN=token HTTP/1.1

Note that there are two injection points for triggering an IDOR in the above requests, except for delete. One in the URL query parameter and another in the POST body parameter. I tried all possible ways to impact an address that I did not own by changing the id’s being passed in the request. I tried things like Parameter Pollution, Passing multiple IDs in a array, varying values in the query parameter and body parameter. But none of them seemed to work.

While hunting further on the application, I noticed that it provided an option to add an address in the checkout flow as well. The thing that caught my attention was that the endpoint called to create an address from the checkout flow was different than the one we saw above. The create address request from checkout flow looked like this:

POST /checkout/shipment/saveaddress/ HTTP/1.1

AddressForm[first_name]=Amey&AddressForm[last_name]=Test&AddressForm[cell_phone]=2418174&phone_prefix=8,9&phone_len=7&AddressForm[phone]=&AddressForm[address1]=2418174&AddressForm[address2]=&AddressForm[postcode]=241817&AddressForm[id_customer_address]=

I immediately tried manipulating the value of the “AddressForm[id_customer_address]” parameter and set it to an address ID belonging to another test account I had created. I checked the ID of the newly created address and the ID returned from the server matched the ID I had entered when creating the request. Feeling elated, I headed over to the other test account to check if the address was deleted from there. I refreshed the page, but somehow the address with the same ID was present there as well and the information contained in the address was unaffected. The manipulated request had caused no visible impact to the victim account’s address.

While I was still logged into the victim’s account, I attempted to edit the target address in the victim’s account. To my surprise, as soon as I tried to edit it, the address disappeared from the list of address in the victim’s account. I realized that something has happened because of my malformed request.

I used the same technique again to delete another address from victim’s account. This time to verify the change, I logged out and logged in again to the victim’s account. This time when I visited the Address Management page, the target address was no longer present in the victim’s account. This proved that I was able to delete addresses from other users’ accounts by manipulating the “AddressForm[id_customer_address]” parameter.

I came to the conclusion that a logout was required to see the change because the request was probably being served by a cache server and hence the address was still visible in the victim’s account after deletion. This is true for a lot of websites. Any unintended changes to a user’s information are reflected when a new session is created.

If you have any feedback or would like to ask any questions related to hacking, hit me up on twitter @ameyanekar. My DMs are open.

]]>
223
IDOR through MongoDB Object IDs Prediction https://techkranti.com/idor-through-mongodb-object-ids-prediction/ Tue, 25 Aug 2020 18:42:43 +0000 http://techkranti.com/?p=206 This post assumes that you have a fair understanding of what an IDOR is. If you are not familiar with IDORs, I would recommend reading the below articles before moving ahead:

Whenever I start application testing, IDORs is the first category of bugs I look for. Two reasons behind it:

  1. Easy to test
  2. Straightforward to conclude whether vulnerable or not

Historically, system developers have been assigning auto-incrementing integer identifiers to database rows. This made it trivial to exploit IDORs. Just one vulnerability could allow exfiltration of all objects belonging to any user in the application. Same goes for delete or edit IDORs.

With the introduction of MongoDB, developers started depending on Mongo Object IDs as identifiers. Mongo Object IDs provided some degree of randomness to the identifiers. However, these object IDs are not truly random. Infact, they are barely random. It is still trivial to predict Mongo Object IDs based just one know valid Object ID from the application.

Structure of a Mongo Object ID:

Mongo Object IDs are 12-byte hexadecimal strings. Calling it a string is not technically correct, but for the sake of this post, it is OK to consider them as strings. From a character length perspective, they are made of 24 hexadecimal numbers. These 12 bytes or 24 characters are not entirely random. MongoDB Object IDs follow the following pattern:

For example, here’s how we can dissect an actual Object ID returned by an application: 5f2459ac9fa6dc2500314019

  1. 5f2459ac: 1596217772 in decimal = Friday, 31 July 2020 17:49:32
  2. 9fa6dc: Machine Identifier
  3. 2500: Process ID
  4. 314019: An incremental counter

Of the above elements, machine identifier will remain the same for as long as the database is running the same physical/virtual machine. Process ID will only change if the MongoDB process is restarted. Timestamp will be updated every second.

The only challenge in guessing Object IDs by simply incrementing the counter and timestamp values, is the fact that Mongo DB generates Object IDs and assigns Object IDs at a system level. Object IDs are not incremented at a collection (Mongo equivalent for relational database tables) level. Say, for example, if you are testing an extremely busy application, and two users register on the application within a difference of 1 second. If there were no other Object IDs being generated on the system apart from these users, the last part of the Object ID would just be incremented by 1 and the timestamp would be incremented by 1 second. But on a really busy system, MongoDB can generate thousand of Object IDs per second. So, although these users were created just 1 second apart, their counters can be thousand places away from each other.

Although not trivial, it is still fairly predictable. You do not need to predict Object IDs for testing an IDOR. For testing, you can just create two accounts like usual and try accessing other user’s information using the identifier. Once, you have established that an endpoint is vulnerable to IDOR, you can then go ahead to predict Object IDs to increase severity of the vulnerability.

Tool: mongo-objectid-predict

I found this really useful tool written by andresriancho: https://github.com/andresriancho/mongo-objectid-predict

With the default setting, given a seed Object ID, it sends back about 1000 probable Object IDs that could have possibly been assigned to your victim’s resource. Here’s what the output looks like:

Once, you have the list of valid Object IDs, you can import these values in Burp intruder or run them on a custom script to test if they are valid.

If you have any feedback or would like to ask any questions related to hacking, hit me up on twitter @ameyanekar. My DMs are open.

]]>
206