Home
Blog
Burp suite
Burp intruder
Burp proxy
Burp spider
Burp sequencer
Burp repeater
Books
Misc
RSS
|
|

skip to main |
skip to sidebar
Readers who are relatively long in the tooth will remember the sweet, carefree days before the web was blighted by cross-site request forgery (XSRF). Like or loathe these vulnerabilities, they are here to stay, and as penetration testers we need to look for and report them. One often overlooked aspect of the arrival of XSRF is that it obliges us to reassess the threat ratings associated with some other types of vulnerability. Here is one example. Consider an application which contains a function for administrators to view a user's details: https://myapp/admin/ViewUser.asp?UID=123 The UID parameter is inserted into a dynamic SQL query, which is passed to MS-SQL Server, and so the application is vulnerable to SQL injection. However, the ViewUser function is protected by robust access controls which prevent lower privileged users from accessing it. Only administrators, who are fully trusted in any case, can exploit the bug. In days gone by, we would have called this a low risk issue, probably worth fixing from a defence-in-depth perspective, but nothing to get excited about. Enter XSRF. Consider a different application which implements a function for administrators to issue SQL queries directly to the database. This is done using URLs like the following: https://otherapp/admin/doSQL.php?query= SELECT+*+FROM+ORDERS This function is wide open to XSRF. An attacker can create a malicious web page which, if viewed by a logged-in administrator, will perform arbitrary queries on the database. For example: <img src="https://otherapp/admin/doSQL.php?query= INSERT+INTO+USERS+(username,password,isAdmin)+ VALUES+('jlo','secrets',true)"> We might classify this XSRF vulnerability as a medium or (if we are feeling excited) high risk issue. Now, each of the functions described enables a crafted request to perform arbitrary actions on the database - the only difference is that this is the intended purpose of the second function, and is the consequence of bad coding in the previous example. But from an attacker's perspective, it doesn't matter whether the application's behaviour was intended or not - a vulnerability is simply a condition that can be exploited for some illicit purpose. And the first vulnerability can be exploited via XSRF just as easily as the second: <img src="https://myapp/admin/ViewUser.asp?UID= 123;+INSERT+INTO+USERS+(username,password,isAdmin)+ VALUES+('wade','congrats',true)"> Hence, regardless of the access controls protecting direct exploitation of the SQL injection vulnerability, the threat rating we assign to this issue should be at least as serious as that which we assign to the second vulnerability. The arrival of XSRF as a recognised attack vector obliges us to identify ways of exploiting some other bugs that we may previously have overlooked.
It is common to be faced with a web application where you have no credentials to log in. Very often, the application contains a wealth of functionality that can be accessed without authentication and which you can start working on to find a way in. Typically, the most promising initial targets are the more peripheral functions supporting the authentication logic, like user registration, password change and account recovery. But occasionally you will face a narrower challenge. Suppose the web root of the server returns a simple login form, with no other functions and no links anywhere else. You can try to guess a username and password, but is that all? Here are just a few of the things to think about in this restricted situation: Looking for names, email addresses and other information in the HTML source. Fingerprinting the web server software, application platform and any other identifiable technologies in use, and researching these for vulnerabilities. Enumerating the content that is currently hidden, by brute forcing file and directory names, running Nikto, etc., and checking whether the content discovered is properly access controlled. Checking search engines and Internet archives for references to the target. Tampering with any hidden parameters and cookies in the login request that may affect server-side logic. Checking for any disabled form elements that may still be processed if you re-enable them. Adding common debug parameters (like test=true) to your request. Inspecting the ASP.NET ViewState (if present). Testing for username enumeration via informative failed login messages or other differences. Testing susceptibility to brute force attacks. If the application issues session tokens prior to login, testing these for predictability. Testing all request parameters and headers for common code-level flaws like SQL injection, XSS, script inclusion, etc. Probing for logic flaws within the login function, by omitting parameters, interfering with the request sequence if multi-stage, etc. If the application is hosted in a shared environment, looking for co-hosted applications that you may be able to leverage to attack your target.
Any one of these attacks might give you a sufficient foot in the door to get past the login and into the protected functionality behind it. If they do not, then the login mechanism is a lot more robust than most are, and it is probably time to try to get hold of credentials, or move on to another target.
Most web applications contain enough serious security defects to produce an impressive pen test report, demonstrate a job well done, and (implicitly) justify your fee. In this situation, it is easy to overlook, or fail to report, a wide range of less exciting vulnerabilities that do not provide a direct means of compromising the application. Just occasionally, you encounter an application which is so nailed down that you can find little bad to say about it. I think I even remember one app that didn't have any XSS, but I may be wrong. Even here, there are usually a bunch of "lame" issues you can identify, to at least demonstrate your attention to detail. Some common examples include: names and email addresses appearing in HTML comments; overly liberal cookie scope; autocomplete enabled; failure to timeout user sessions; broken logout functions; informative error messages; sensitive information transmitted in the query string; session fixation; directory listings; caching of sensitive data; arbitrary redirection.
Why do we think these bugs are lame? Presumably, because you cannot normally exploit them to do anything seriously malicious against your target. But this thought overlooks the possibility of chaining multiple low-risk flaws together. Very often, vulnerabilities that present no threat in isolation can, in skilled hands, be leveraged to completely compromise an application. RSnake's entertaining Death By A Thousand Cuts provides a classic example of this. If we are doing our jobs properly, we should be reporting all of these issues any time they arise, regardless of whether it is raining.
I've been taking a look at the ASP.NET ViewState recently, and have done a (rather unscientific) survey of the way it is currently used on Internet-facing web applications. Here are a few statistics, based on a sample of more than 10,000 applications: version 1.1 - 54% version 2.0 - 46% MAC-enabled (v1.1) - 93% MAC-enabled (v2.0) - 89% encrypted - 4% average size - 16.8Kb
The largest ViewState I discovered was a whopping 3.8Mb in size, which appeared in a government web application displaying tables of statistics. Given that the ViewState is posted back to the server with each request, this application is seriously sluggish to use, even with a relatively fast connection. I was surprised at the number of applications not using the EnableViewStateMac option, given that this is now set by default in ASP.NET. Without this option, the contents of the ViewState can be modified by the user, potentially affecting the application's processing in nefarious ways. Even with EnableViewStateMac set, users can still decode and read the contents of the ViewState if it has not been encrypted. Application developers may use the ViewState to store arbitrary data, beyond the default serialisation of UI controls. I wonder how many attackers bother to decode and inspect the ViewState to check whether it contains anything of interest. The next version of Burp Suite will include a utility to deserialise and render the ViewState contents, to make this task trivial. A sneak preview is shown below:

When you are attacking a web application, automation is your friend. Not only if you are lazy, but also because automation can make your attacks faster, more reliable and more effective. This is the first in a series of posts exploring ways of using automation in web application testing, and the limitations that exist on its effective use. Web application vulnerability scanners seek to automate many of the tasks involved in attacking an application, from initial mapping through to probing for common vulnerabilities. I've used several of the available products, and they do a decent job of carrying out these tasks. But even the best current scanners do not detect all or even a majority of the vulnerabilities in a typical application. Scanners are effective at detecting vulnerabilities which have a standard signature. The scanner works by sending a crafted request designed to trigger that signature if the vulnerability is present. It then reviews the response to determine whether it contains the signature; if so, the scanner reports the vulnerability. Plenty of important bugs can be detected in this way with a degree of reliability, for example: In some SQL injection flaws, sending a standard attack string will result in a database error message. In some reflected XSS vulnerabilities, a submitted string containing HTML mark-up will be copied unmodified into the application's response. In some command injection vulnerabilities, sending crafted input will result in a time delay before the application responds.
However, not every vulnerability in the above categories will be detected using standard signature-based checks. Further, there are many categories of vulnerability which cannot be probed for in this manner, and which today's scanners are not able to detect in an automated way. These limitations arise from various inherent barriers to automation that affect computers in general: Computers only process syntax. Scanners are effective at recognizing syntactic items like HTTP status codes and standard error messages. However, they do not have any semantic understanding of the content they process, nor are they able to make any normative judgments about it. For example, a function to update a shopping cart may involve submitting various parameters. A scanner is not able to understand that one of these parameters represents a quantity and that another parameter represents a price. Nor, therefore, is it able to assess that being able to modify the quantity is insignificant while being able to modify the price indicates a security flaw. Computers do not improvise. Many web applications implement rudimentary defences against common attacks, which can be circumvented by an attacker. For example, an anti-XSS filter may strip the expression <script> from user input; however, the filter can be bypassed by using the expression <scr<script>ipt>. A human attacker will quickly understand what validation is being performed and (presumably) identify the bypass. However, a scanner which simply submits standard attack strings and monitors responses for signatures will miss the vulnerability. Computers are not intuitive. When a human being is attacking a web application, they often have a sense that something doesn't "feel right" in a particular function, leading them to probe carefully how it handles all kinds of unexpected input, including modifying several parameters at once, removing individual parameters, accessing the function's steps out of sequence, etc. Many significant bugs can only be detected through these kind of actions, however for an automated scanner to detect them it would need to perform these checks against every function of the application, and every sequence of requests. Taking this approach would increase exponentially the number of requests which the scanner needs to issue, making it practically infeasible.
The barriers to automation described above will only really be addressed through the incorporation of full artificial intelligence capabilities into vulnerability scanners. In the meantime, these barriers entail that many important categories of vulnerability cannot be reliably detected by today's automated scanners, for example: Logic flaws, for instance where an attacker can bypass one step of a multi-stage login process by proceeding directly to the next step and manually setting the necessary request parameters. Even if a scanner performs the requests necessary to do this, it cannot interpret the non-standard navigation path as a security flaw, because it does not understand the significance of the content returned at each stage. Broken access controls, in which an attacker can access other users' data by modifying the value of an identifier in a request parameter. Because a scanner does not understand the role played by the parameter, or the meaning of the different content which is received when this is modified, it cannot diagnose the vulnerability. Information leakage, in which poorly designed functionality discloses listings of session tokens or other sensitive items. A scanner cannot distinguish between these listings and any other normal content. Design weaknesses in specific functions, such as weak password quality rules, or easily guessable forgotten password challenges.
Further, even amongst the types of vulnerability that scanners are able to detect, such as SQL injection and XSS, there are many instances of these flaws which scanners do not identify, because they can only be exploited by modifying several parameters at once, or by using crafted input to beat defective input validation, or by exploiting several different pieces of observed behaviour which together make the application vulnerable to attack. Current scanners implement manual workarounds to help them identify some of the vulnerabilities that are inherently problematic for them. For example, some scanners can be configured with multiple sets of credentials for accounts with different types of access. They will attempt to access all of the discovered functionality within each user context, to identify what segregation of access is actually implemented. However, this still requires an intelligent user to review the results, and determine whether the actual segregation of access is in line with the application's requirements for access control. Automated scanners are often useful as a means of discovering some of an application's vulnerabilities quickly, and of obtaining an overview of its content and functionality. However, no serious security tester should be willing to rely solely upon the results of a scanner. Many of the defects which scanners are inherently unable to detect can be classified as "low hanging fruit" - that is, capable of being discovered and exploited by a human attacker with modest skills. Receiving a clean bill of health from today's scanners provides no assurance that an application does not contain many important vulnerabilities in this category.
|
|