Request a Demo Contact Us

Easy Ways to Narrow Your Focus on Logical Bugs with Eslam

Easy Ways to Narrow Your Focus on Logical Bugs


Have you ever asked yourself why web application scanners don’t find all of the security issues on a given target, and why human testing or human interaction is still needed? Have you wondered what type of bugs the security scanners can’t understand or don’t discover? Today we’ll look to cover some of these questions and more regarding “Logical Bugs”.  

We’ll cover:

  • Logical bugs as a definition 
  • What are the differences between logical and regular bugs? 
  • Practical examples for both

Logical Bugs Defined

Logical bugs are vulnerabilities that allow the attacker to perform a malicious action that takes advantage of flaws in a given application’s logic, as opposed to exploiting misconfigurations that may apply to a variety of applications – whereas logic vulnerabilities are usually unique to the specific application/context in which they’re found. That means we don’t have a fixed schema or standardized exploitation payload like one may have for XSS, SQLi, or other injection-type vulnerabilities, and one won’t find them if they don’t understand the business logic of the application first. To understand the business logic an app, ask yourself these important questions first, so as to gather the necessary pieces of information to help you: 

  • What’s the business / function of the application?
  • What are the different user roles across the application, and how are they used? 
  • What levels of access or abilities does each user level have?  
  • In thinking about the different parts of the application, how could they each potentially be abused? For instance, if dealing with a checkout functionality, some common opportunities for abuse include trying to change the price of an item, getting an item for free, and so on. What else could be abused in a similar manner across the app?
  • And more…

By answering these questions, you’ll gather some of the necessary pieces of information and know where to start testing for logical bugs.  

What’s the difference between logical and regular bugs?

The difference between logical and regular bugs is the method in which one looks for them. Take XSS, for example. To search for XSS you probably follow a method similar to below:

  1. Start searching for a parameter that reflects its value in the page source or stored on the database or reflected in the admin panel. 
  2. Test for the bad characters allowed like < or > 
  3. Inject custom payload for POC like “><script>alert()</script> 

The above steps are a fixed methodology to find and exploit XSS. This is the same with XXE, SQLi, LFI, and other injection-based bugs. But for logical bugs you need a different methodology  because every website’s logic is different. To find a logical bug, it’s then necessary to first understand the logic, learn the website, and to answer the questions above. By doing the above, one can build a threat model for the application based on the logical flows, and begin to try to look for ways to exploit the manner in which the application operates.

For example, say we have an online store that allows users to buy and sell products. One of the most popular variants of logical bugs is to change or tamper with the total cost of a custom product. As an example, by manipulating a poorly validated checkout functionality, one could potentially be able to adjust the price of a product to $10 instead of $10,000. Or one could even tamper with the price to increase their balance; allowing them to make money from the store itself, etc. 

Performing attacks of these natures is usually done via modifying parameter values in the query string (e.g. GET requests) or in the POST body (or PUT, etc, if one is dealing with APIs), though sometimes logic vulnerabilities can even be exploited directly via the user interface.

Practical Examples

Here is a real example of the above, to make it easier to understand. In this example, there’s an online store where one can buy various goods and pay in multiple ways, including cash or by installment plan. 

To answer the questions we outlined above: 

  • What’s the business of the website? Customers buy products and pay. 
  • What are the most critical functions? Payment or checkout functions maybe! 
  • How many user roles are there? The customer only, but in different cases you may have a panel for the seller. 
  • What’s the worst action you can take to break the website’s rules? Buying some items at a lower cost than the original price, or escalating the privileges to the seller. 

First, we try to add items and scan the checkout and payment method using the installment plan. If we choose to pay $20 for 30 months, the total cost will be $600. But what if we could intercept the checkout or payment requests and change the number of months from 30 to 10 months? If effective, the total cost of the product could then end up being $200 instead of the initial $600. And conversely, we would also want to see what happens if we changed the monthly payment price from $20 to something less, like $10. Based on how the application responds, we may have found a significant vulnerability.

This type of attack is called “Cost Manipulation”, and anytime you see the application sending anything relating to prices in the checkout function, you’ll want to investigate if the values can be exploited in a manner that the design didn’t take into account.

In your discovery, if you find that the website sends the total cost of their items in the requests’ parameter as a numerical value, you can try to manipulate it and confirm that there is no backend validation.  

{“product”: “aykalam”, “price”: “600”, “currency”: “USD”} 

You can manipulate multiple functions in a variety of ways: 

  1. You can change the price from 600 to 200.
  2. You can change the price from 600 to -600 if it accepts “-”. Doing so, would increase your wallet balance. 
  3. You can change the currency from USD to EGP, paying less money.
  4. And so on – this isn’t an exhaustive list of ways to manipulate these types of functionalities, but is a good place to start – as we discussed earlier, every application will look and act a little differently, and that’s where human creativity and ingenuity comes into play!

If, instead of specific amounts, you find the below format, these sorts of implementations often can’t be manipulated because the price is imported from the database:

{“product”: “aykalam”, “id”: “45785”} 

Which is one of the potential mitigations that organizations will often apply; that said, even if there is a dollar value in the post body, many applications will also perform validation on the price, rendering this vector unusable – but it’s always worth testing, regardless. 

As another example, we’ll focus on a vulnerable login function and custom login flow. Here, the “logical” issue is in manually tampering with the API version number, which fundamentally comes back to the points of:

  1. Focus on every function logic
  2. Check every request and think about how one could abuse the normal behaviour expected by the application 

For the vulnerable function in this case, there are two steps: 

  1. The first stage takes your username
  2. And after validation, the next stage will redirect you to enter your password. 

For requests sent from the first stage, the app validates the username or the email address, in my case I have the following endpoint: https://sub.target.com/blablala/blablabla/tenetId/userID/option/<API-version> 

Now, to answer our earlier question of “how can we break this logic?”, we can try a few different things:

  1. Try to change the current api version to older versions. If they have version 1.1 or 2 that means they have an old version with issues, updates or parameters that may be vulnerable. Also, you can change to a higher value. You may find published endpoints that are not fully protected yet. 
  2. Try to change the user ID. You may dump data related to another user. 
  3. Try to enumerate the directories, you may find an unprotected endpoint containing sensitive information. 

The default value for an API version is 1 with no sensitive information returned.

When we try to change the value from 1 to 1.1, 1.2, 2, etc, the 2 value gives us a different and pleasantly unexpected output as seen below. 

As you can see, by changing the value, we get different results. With /2/, we get the email address and the zipPassword related to the user we entered in the first stage. Now we have valuable information, but what if we changed the userID to another user? You’ll get the email and password of another user.

For this scenario, the user contains only 5 characters in the form of digits and numbers, so it’s not hard for one to brute forced or guess/predict values – specially because the first four characters are numbers and the fifth one is a character. 

Here’s some tips and tricks regarding this scenario: 

  1. Work on every subdomain one by one. Don’t miss anything, even if you think it’s a static sub.
  2. Grab every subdomain’s historical records from wayback machine and your proxy history and check for some interesting words like
    • api
    • v1/v2/v3
    • user
    • dev
    • Or you can use gf tool (@tomnomnom) to automate this step.
  3. Don’t give up if you face rate limit protection. If you need to enumerate more users, try to bypass using the following steps
    • Append some custom headers like
      • X-Forwarded-For: internalIP or localhostIP
      • X-Forwarded-Host: internalIP or localhostIP
      • X-Client-IP: internalIP or localhostIP
      • X-Originating-IP: internalIP or localhostIP
      • X-WAP-Profile: https://internalIP or https://localhostIP
      • True-Client-IP: internalIP or localhostIP
      • Referer: https://internalIP or https://localhostIP
    • Append null byte or hex characters.
  4. Change the API version to different versions, you may find misconfigured features.

In Conclusion

Logical bugs are a unique class of bugs that will not be identified by scanners or typical security tools – and as such, they’re an ideal bug class for bounty hunting, or any sort of testing that involves human / contextual intelligence. Taking the time to fully understand your target and how it’s used can often pay significant dividends in allowing you to find bugs that automation and others have missed. Study the documentation, dig into the details of the app, understand the logic, and think outside of the box. If you do those things, you’ll be well on your way to finding and identifying unique and highly valuable vulnerabilities. 

Here some references & resources if you want to learn more about the logical bugs:

PortSwigger 

OWASP 

InfoSecWriteUps

 


 

About the Author

Eslam (@eslam3kll) is a Penetration Tester, Bug Bounty Hunter, and Security Researcher with 10 CVEs  and acknowledgements by Google, MasterCard, FIS, Cisco, Uber, Spotify, and more. You can learn more about Eslam here 

More resources

Guide

Ultimate Guide to AI Security

Read More
Datasheet

Aligning with Binding Operational Directive 20-01

Read More

Get Started with Bugcrowd

Every minute that goes by, your unknown vulnerabilities leave you more exposed to cyber attacks.