Code Review

Code review is another important aspect of full-knowledge analysis. The most critical components of the application should have code review performed on them. The determination of what qualifies as "critical" is usually driven by the thread-modeling exercise: any components with threats that rank above the threshold should probably be reviewed (this coincidentally is a great example of how threat modeling drives much of the subsequent security development effort).

This section covers how to identify basic code-level problems that might exist in a web application. It is organized around the key approaches to code review: manual, automated, and binary analysis.

Manual Source Code Review

Manual code review (by competent reviewers!) is still considered the gold standard for security. However, line-by-line manual review on the whole code base of a large application is likely to produce diminishing returns, since most important security vulnerabilities will be concentrated in modules of highest risk. Thus, assuming limited resources, manual code review is best performed on only the most critical components of an application.

Tip 

Relying on the development team itself to peercode review each others' work before checking in code can achieve broad manual code review coverage.

As we noted earlier, "critical" is best defined during the threat-modeling process (and should be fairly obvious from the DFDs). Some classic considerations for manual code review include the following:

  • Any modules that receive or handle user input directly, especially data sanitization routines and modules that interface with the network

  • Authentication components

  • Authorization/session management

  • Administration/user management

  • Error and exception handling

  • Cryptographic components

  • Code that runs with excessive privilege/crosses multiple security contexts

  • Client-side code that may be subject to debugging or usurpation by rogue software

  • Code that has a history of prior vulnerabilities

The process of manual code review has been documented extensively in other resources. Some of our favorites are listed in the "References and Further Reading" section at the end of this chapter. Next , we'll discuss some examples of common web application security issues that turn up during code review.

Common Security Problems Identified Using Code Review

There are numerous security- impacting issues that can be identified using code review. In this section, we'll provide examples of those most relevant to web applications, including:

  • Poor input handling

  • Poor SQL statement composition

  • Storing secrets in code

  • Poor authorization/session management

  • Leaving debug switched on in production

Examples of Poor Input Handling   One of our favorite mantras of secure coding is "All input received should be treated as malicious until otherwise proven innocent." Within web applications, critical input to consider includes these:

  • All data that is received from the client

  • Data received by SQL statements or stored procedures

Failure to implement proper input validation and output encoding routines around this data can result in devastating security holes in an application, as we've seen throughout this book. Here are some examples of how to identify these issues at the code level.

In the shopping cart example we provided in our earlier discussion of threat modeling, if the username received from the client is not encoded and is displayed back to the client (which typically is displayed back once a user is logged in), an XSS attack could be performed in the username field. If the username is not encoded and is passed to SQL, SQL injection could result. Since a lot of web data is collected using forms, the first thing to identify in code is the <form> tag within the input pages. Then you can identify how the data is being handled. Here we've listed some ASP methods that are used to parse web form data:

  • request.form

  • request.querystring (This should be avoided for sensitive data, since the data will appear in web logs and client cache.)

  • request.cookies

  • response.write

If these ASP methods are used to handle data, they should be protected using Server.HTMLEncode or Server.URLEncode to reduce the chances of XSS and SQL injection.

More generically, input and output should be sanitized. Sanitization routines should be closely examined during code review, as developers often assume that they are totally immunized from input attacks once they've implemented validation of one sort or another. Input validation is actually quite challenging, especially for applications that need to accept a broad range of input. We discussed input validation countermeasures in depth in Chapter 6, but some common examples of what to look for in input validation routines include these:

  • The use of black lists instead of white lists (black lists are more prone to defeat since it's practically impossible to predict the entire set of malicious input).

  • For applications written in Java, the Java built-in regular expression class (java.util.regex.*) or the Struts Framework is commonly used. Implementation of the Struts Framework does require some level of overhaul in the application environment.

  • .NET provides a regular expressions class to perform input validation (System.Text.RegularExpressions). The .NET framework also has the built-in ability to provide functionality equivalent to the Struts Framework. The properties of the control allow you to configure input validation.

Here is an example "white list" input validation code snippet (str.replace is available within PHP and ASP.NET):

 function Sanitize(str) { str = str.replace(/[^a-zA-Z]/g,""); return str; } The corresponding "black list" approach might look like this: function Sanitize(str) { str = str.replace(/\<\>\"\'\%\;\(\)\&\+\-/g,""); return str; } 

Another good example of input validation problems in code is the HTTP response splitting attack (see "References and Further Reading" for link). HTTP response splitting involves injection of a malicious payload into HTTP header fields using a carriage return and line feed (%0d%0a) to prematurely terminate one response and insert another. It targets web applications that perform response redirection to other URLs using programmatic means, such as when an ASP.NET Response.Redirect is sent to a Request.QueryString value. Special attention should be paid to code that sets cookies and redirects users to a different page, as this invites cookie poisoning via a response splitting attack. A sample response splitting attack is illustrated next.

Assume a vulnerable web application page called "redir.aspx" contains code similar to the following:

 <% Response.Redirect(?/redir.aspx?var2=?      + Request.QueryString(?item?)) %> 

This takes the value of the var2 variable and rewrites it to the item variable in the query string. A malicious attacker could construct the following URL:

 http://victim.com/redir.aspx?var1=blah&var2=blah%0d%0a Content-Length:%200%0d%0a HTTP/1.1%20200%20OK%0d%0a Content-Type:%20text/html%0d%0a Set-Cookie:%20xyzzy%0d%0a Content-Length:%2020%0d%0a <html>Vulnerable</html> 

Take a look at the strategic placement of %0d%0a values. The first one inserts a carriage return line feed, followed closely by a Content-Length: 0 HTTP header. This prematurely terminates the valid response, making room for the attacker to insert a forged one beginning with the HTTP/1.1 syntax. Farther down in the forged response, the attacker sets a cookie on the victim's machine. If the attacker can get the victim to click this link (which looks for all the world like it originates within victim.com), he can perform something similar to an XSS attack. Here's what the HTTP response from the vulnerable server to the victim client looks like (with inline commentary to illustrate where the forged response is injected):

 HTTP/1.1 302 Object moved Expires: Tue, 23 Mar 2004 23:26:39 GMT Date: Tue, 23 Mar 2004 23:27:38 GMT Location: https:// victim.com/redir.aspx?var1=blah&var2=blah  (here's the injected forged response)  Content-Length: 0 HTTP/1.1 200 OK Content-Type: text/html Set-Cookie: xyzzy Content-Length: 20 <html>Vulnerable</html>  (the rest of the legitimate response follows, not interpreted)  Content-Type: text/html Server: Microsoft-IIS/5.0 Pragma: No-Cache ReponseSplitting: header Cache-control: private <head><title>Object moved</title></head> <body><h1>Object Moved</h1>This object may be found <a HREF="">here</ a>.</body> 

To prevent such an attack, filter out carriage returns and line feeds before embedding data into any HTTP response headers.

Note 

See Chapter 6 for more examples of input validation attacks and countermeasures.

Examples of Poor SQL Statement Composition   As we saw in Chapter 7, SQL statements are key to the workings of most web applications. Improperly written dynamic SQL statements can lead to SQL injection attacks against an application. For example, in the select statement shown next, there is no validation (input or output) being performed. The attacker can simply inject a 1=1 (to make the SQL statement true) and gain access to the application.

 <% strQuery= "SELECT custid, last, first, mi, cadd, city, state, zip FROM customer WHERE username = '" & strUsername & "' AND password = '" & strPassword & "'" Set rsCust= connCW.Execute(strQuery) If Not rsCust.BOF And Not rsCust.EOF Then     Do While NOT rsCust.EOF %> <TR> <TD> <B>Cust ID :</B> <% =rsCust("CUSTID") %></TR> </TD> <TR> <TD> <B> First </B><% = rsCust("First") %> <% =rsCust("MI") %> <B> Last Name</B> <% =rsCust("Last") %> </TR></TD> <% rsCust.MoveNext %> <% Loop %> <!-- Attack: password=a'+OR+'1'='1 --> 

Usage of exec () inside stored procedures would also lead to SQL injection attacks, since OR 1=1 can still be used to perform a SQL injection attack against the stored procedure, as shown here:

 CREATE PROCEDURE GetInfo (@Username VARCHAR(100)) AS exec('SELECT custid, last, first, mi, cadd, city, state, zip FROM customer WHERE username =''' + @Username '''') GO 

Whenever possible, stored procedures should be used instead of SQL statements in server-side scripts. It's more difficult to perform SQL injection on stored procedures.

Also, use ADO Command Object Parameters or Prepared Statements (Java) whenever possible. These eliminate the chances of SQL injection attacks against applications.

Examples of Secrets in Code   Web developers often end up storing some secrets in their code. We'll see a particularly grievous example of this in our "Binary Analysis" section later in this chapter, which will illustrate well why hard-coding secrets in code is heavily discouraged. It should never be done where the code has even the slightest chance of direct interaction with an end user.

If it's absolutely necessary to store secrets, they should be encrypted. On Windows, the Data Protection API (DPAPI) should be used for encrypting secrets and storing them (see "References and Further Reading" at the end of this chapter for a link). The Java Cryptography Extension (JCE) can be used to store secrets in a UNIX environment.

Examples of Authorization Mistakes in Code   As we saw in Chapter 5, web developers often attempt to implement their own authorization/session management functionality, leading to possible server problems with access control for the application.

Here's an example of what poor session management looks like behind the scenes, as might be caught in code review. In the following example, userid is an integer and is also used as the session ID. userid is also the primary key in the User table, thus making it relatively easy for the developer to track the users' state. The session ID is set on a successful login.

 <!-- The code is run on welcome page --> createSessionID(request, response, userid); String value = "userid="userid; Cookie sessioncookie = new Cookie(propertyFileName, value); 

On subsequent pages to maintain state, the session ID is requested from the client and appropriate content is displayed back to the client based on the session ID.

 <!-- The following code is run on all pages --> String userId = (String)cookieProps.get("userid"); 

In this example, userid is stored in a cookie on the client and thus is exposed to trivial tampering, which can lead to session hijacking.

The obvious countermeasure for custom session management is to use off-the-shelf session management routines. For example, session IDs should be created using the Session Objects provided within popular off-the-shelf development frameworks, such as the JSPSESSIONID or JSESSIONID provided by J2EE, or ASPSESSIONID provided by ASP.NET. Application servers like Tomcat and ASP.NET provide well-vetted session management functionality, such as a configurable option in web.xml and web.config to expire the session after a certain period of inactivity. More advanced authorization routines are also provided by many platforms, such as Microsoft's Authorization Manger (AzMan) or ASP.NET IsInRole offerings that enable role-based access control (RBAC). On non-Microsoft platforms, Jakarta Struts provides configuration-based RBAC.

Poor session management can have even deeper implications for an application at the data layer. Continuing with our previous example, let's assume the userid from the cookie is passed to a SQL statement that executes a query and returns the data associated with the respective userid. Code for such an arrangement might look something like the following:

 String userId = (String)cookieProps.get("userid"); sqlBalance = select a.acct_id, balance from acct_history a, users b " + "where a.user_id = b.user_id and a.user_id= " + userId + " group by a.acct_id"; 

This is a fairly classic concatenation of SQL statements that blindly assembles input from the user and executes a query based upon it. You should always scrutinize concatenated SQL logic like this very closely.

Obviously, our previous advice about using stored procedures and parameterized queries instead of raw SQL concatenation applies here. However, we also want to emphasize the authorization implications of this example: it illustrates once again the ease with which trivial client-side tampering with userid provides access to sensitive information, sqlBalance in this case. In order to avoid these sorts of authorization issues, session ID management should be performed by an off-the-shelf application server, or it can be implemented by creating temporary tables in memory at the database level. The latter typically doesn't scale well to large applications, so the former tends to be the most popular.

Access control can also be implemented using various frameworks like Java Authentication and Authorization Service (JAAS) and ASP.NET (see "References and Further Reading").

Examples of Debug Mistakes in Code   One of the oldest code-level security vulnerabilities of web applications is leaving "debug" functionality enabled in production deployments. A common example of this is providing debug parameters to view additional information about an application. These parameters are usually sent on the query string or as part of the cookie.

 if("true".equalsIgnoreCase(request.getParameter("debug"))) <%= sql %> 

The entire SQL statement is displayed on the client if the debug parameter is set to "true". Another similar example of this problem is the isAdmin parameter. Setting this value to "true" grants administrator-equivalent access to the application, effectively creating a vertical privilege escalation attack (see Chapter 5).

Obviously, debug/admin mode switches should never be implemented in a production environment.

Automated Source Code Review

Automated code analysis can be far more efficient than manual ones, but modern tools are far from comprehensive and generally not as accurate as human reviewers. Nevertheless, there are some good tools available, and every simple input validation issue identified before release is worth its weight in gold versus being found in the wild. Table 12-1 lists some tools for improving code security. As you'll note, nearly all of these are for C and C++ code languages, which is not that helpful to web developers who typically use web-centric development platforms like ASP.NET, Java, and PHP.

Caution 

These tools should not be considered a replacement for manual code review and secure programming practices. These tools also have a high false-positive rate and need a lot of tuning to produce useful results.

Table 12-1: Tools for Assessing and Improving Code Security

Name

Language

Link

/GS flag

C/C++

http://msdn.microsoft.com/library/en-us/vccore/html/vclrfGSBufferSecurity.asp

Inspector (formerly Bugscan)

C/C++ binaries

http://www.hbgary.com

CodeAssure

C/C++, Java

http://www.securesw.com/products/

DevInspect

ASP.NET (Visual Basic and C#)

http://www.spidynamics.com/

Flawfinder

C/C++

http://www.dwheeler.com/flawfinder/

RATS

C/C++, Python, Perl, PHP

http://www.securesw.com/resources/tools.html

SPLINT

C

http://lclint.cs. virginia .edu/

FXCop

.NET

http://www.gotdotnet.com/team/fxcop/

ITS4

C/C++

http://www. cigital .com/

PREfast

C/C++

Available in Microsoft Visual Studio 2005

Prexis

C/C++, Java

http://www.ouncelabs.com/

Fortify Source Code Analysis Suite

ASP.NET, C, C++, C#, Java, JSP, PL/ SQL, T-SQL, VB.NET, XML

http://www.fortifysoftware.com

Coverity

C/C++

http://www.coverity.com

DevPartner SecurityChecker

C#, VB.NET

http://www. compuware .com/

Binary Analysis

Binary analysis is the art of dissecting binaries at the machine code level, typically without the benefit of access to source code (see "References and Further Reading" at the end of this chapter for more background information). Historically, binary analysis was performed by companies on competing products to understand the design philosophy or internal workings of an application. More recently, binary analysis has become a mainstay of the security assessment industry because of its ability to quickly ferret out the functionality of software viruses, worms, and other malware. This section will describe the role of binary analysis in full-knowledge web application security reviews, and then will demonstrate the basics of binary analysis as applied to a sample web application binary.

Caution 

Performing binary analysis on software may violate the terms of the end-user license agreement (EULA), and in some cases criminal penalties may result from reverse engineering of code.

The Role of Binary Analysis in Full-knowledge Reviews

Before we demonstrate the basic techniques of binary analysis, it's important to clarify its role in full-knowledge assessment of web application security.

The primary question to be addressed is "Assuming I've got the source code, why expend the effort to analyze the binaries?" Many security researchers have found that binary analysis strongly complements source code review. This is primarily because binary analysis examines the application in its native deployment environment, as it is actually executed, which can reveal many other issues not readily apparent when viewing the source code in isolation. Such issues include modifications to the code incorporated by the compiler, code interactions and variables introduced by the runtime environment, or race conditions that only become apparent during execution.

Most importantly, binary analysis can identify vulnerabilities introduced by third-party librarieseven those for which the user does not have source code. Increasingly, in our consulting work we've seen a lot of external code used in developing new software. In many cases, the source code for these components is not available. So, even if you are a member of an internal security audit team, it's not a safe assumption that you'll have access to all the source code for your in-house web apps, so binary analysis is an important part of the auditor 's toolkit.

Finally, it's important to note the historic importance of compiled code within web applications. As we note in Chapter 1, the Web grew out of a static document-serving technology, evolving increasingly sophisticated mechanisms for providing dynamic, scalable, high-performance functionality. Microsoft's ISAPI (Internet Server Application Program Interface) and Apache loadable modules are the latest example of this evolution. They offer programmatic integration with the web server that typically provides much faster application performance than external Common Gateway Interface (CGI) executables. It has become common practice to use ISAPI and Apache loadable modules in high-performance web applications, and thus we'll use ISAPI to illustrate binary analysis on a real-world web app in the next section.

An Example of Binary Analysis

We'll refer to an example ISAPI we created called "secret.dll" throughout the following section (and elsewhere in this chapter). The primary function of the ISAPI is to accept a string from the user and display a "Successful" or "Unsuccessful" page depending on the value input by the user. Secret.dll is available via a typical web interface deployed on a Microsoft IIS web server so that it can be accessed via HTTP, as shown in Figure 12-5. Providing the right secret allows access to the "Successful" page, else the "Unsuccessful" page is displayed. A static secret is stored in the ISAPI DLL so that it can be compared to the input provided by the user. The goal of this section is to illustrate how to obtain this secret using binary analysis, performed using a Windows platform. We'll assume in the following discussion that secret.dll is properly installed and running on a Windows IIS machine, and that we have the ability to debug the system.


Figure 12-5: The web interface to our sample ISAPI DLL
Tip 

Secret.dll is available for download on http://www.webhackingexposed.com if you want to follow along!

Debugging 101

The fist step in binary analysis is to load it into your favorite debugger. In this example, we'll use Ollydbg, a free Win32 debugger written by Oleh Yuschuk. It's one of the most intuitive free debuggers available at the time of this writing. IDA Pro, a commercial tool from DataRescue SA, is another popular debugging suite.

Figure 12-6 shows the main interface for Ollydbg, including the CPU window, where most debugging work occurs. The CPU window contains five panes: Disassembler, Information, Register, Dump, and Stack. The Disassembler pane displays code of debugged program, the Information pane decodes arguments of the first command selected in the Disassembler pane, the Register pane interprets the contents of CPU registers for the currently selected thread, the Dump pane displays the contents of memory, and the Stack pane displays the stack of the current thread.


Figure 12-6: Ollydbg

An application can be debugged by opening it directly in Ollydbg (File Open ), or by attaching Ollydbg to the running application process (File Attach < Process Exe Name > Attach). Debugging a live application while it is processing input is the best way to reverse engineer its functionality, so this is the approach we'll take with secret.dll. Since secret.dll is an ISAPI, it runs inside the IIS web server process. Thus, we will attach the main IIS process (inetinfo) using Ollydbg (File Attach inetinfo.exe Attach).

Once attached, we quickly discover that secret.dll contains a function called IsDebuggerPresent that terminates execution as we try to step through it. This is a common technique used to discourage debugging, but it's easily circumvented. The simplest way to do this is to load Ollydbg's command-line plug-in (ALT-F1) and insert the following command:

 set byte ptr ds:[fs:[30]+2]] = 0 

This command sets the IsDebuggerPresent API to always return "false", effectively disguising the presence of the debugger.

Alternatively, we could set a breakpoint on the IsDebuggerPresent function and manually change its value to 0. This requires more effort, but we'll describe it here since it illustrates some basic debugging techniques. We'll first reload secret.dll (using Ollydbg's CTRL-F2 shortcut key), and once the debugger has paused , we'll load the command-line plug-in (ALT-F1) and set a breakpoint on the function call IsDebuggerPresent, (type bp IsDebuggerPresent ), as shown in Figure 12-7.


Figure 12-7: Setting a breakpoint on the IsDebuggerPresent function
Tip 

Plug-ins should be visible as part of the toolbar; if they are not, then the plug-in path needs to be set. To set the plug-in path, browse to Options Plugin path and then update the location of the plug-in (typically, the home directory of Ollydbg).

We continue to load the DLL (SHIFT-F9) until we reach the breakpoint at IsDebuggerPresent (see "Note 1" in Figure 12-8). We then execute the next two instructions (SHIFT-F7) and stop at the function indicated in Note 2 in Figure 12-8. By right clicking in the Disassembler pane and selecting Follow in Dump Memory Address, the location and value of the IsDebuggerPresent function is displayed in the Dump pane. The location is 7FFDA002 and the contents are


Figure 12-8: Bypassing the IsDebuggerPresent function
 01 00 FF FF FF FF 00 00 40 00 A0 1E 19 00 

Right-clicking the first value in this string (01) and selecting "Binary\Fill with 00's" should update the results of the function to 00, as illustrated in "Note 3" in Figure 12-8.

We've now manually changed the return value of the IsDebuggerPresent API to always be 0. Thus, the DLL can now be loaded without being terminated by the presence of the Ollydbg.

Binary Analysis Techniques   Now, we can start getting to the nuts and bolts of binary analysis. The primary techniques we'll use include these:

  • Enumerate functions. We'll look for functions commonly associated with security problems, like string manipulation APIs such as strcpy and strcat.

  • Identify ASCII strings. These may include hidden secret strings, or may point out common routines (which can help further analysis by "mapping" the functionality of the binary for us).

  • Step-through key functionality. Once we've got a basic inventory of functions and strings, we can step through the execution of the binary, set breakpoints on interesting routines, and so on. This will ultimately expose any key security vulnerabilities.

First, we'll enumerate all the functions that are used by secret.dll. Back in Ollydbg, right-clicking the Secret.dll option from the list of executable modules loaded (View Executable Modules) and selecting View Names will display a list of the functions used by secret.dll. They contain both the list of imported and exported function calls. Some functions that might be of interest include strcpy and strcat (since string manipulation using these older functions is often vulnerable to buffer overflow attack), as well as memcpy (which suffers from similar issues). Problematic C/C++ functions like these are well-documented; simply searching for " insecure C/C++ functions" on the Internet will turn up several good references.

Tip 

Function calls can also be dumped using the command-line dumpbin.exe utility, which is provided with Visual C++ (dumpbin /EXPORTS secret.dll).

We'll identify ASCII strings inside secret.dll by right-clicking inside the Disassembler pane where secret.dll is loaded and selecting Search for All referenced Text strings.

Tip 

The "strings" utility can also be used to extract ASCII strings inside secret.dll.

Finally, we'll analyze secret.dll's key functionality by probing some of the more intriguing functions a little more deeply. First, we'll try right-clicking MSVCR71.strcpy to select references on import. A new pane with a list of references pops up, and we'll set a breakpoint on the references (Ollydbg's F2 shortcut key is handy for setting breakpoints). We'll repeat the task for MSVCR71.strcat and MSVCR71.memcpy.

We'll also set breakpoints on ASCII string by right-clicking in the Disassemble Window and selecting Search for All referenced text strings. Immediately, we spy something interesting in the output: "You don't have a valid key, The key you attempted was". This is likely the error message that is printed back on invalid string input, potentially pointing the way towards the function that compares the input with the secret string!

Tip 

In some applications, developers change the error message into a character array to avoid such attacks, thus making it a little more difficult to find the string.

Let's actually provide some input to secret.dll at this point and see what it shows us. We'll browse to the web page shown in Figure 12-5 and input the arbitrary string "AAAAAAAA." Ollydbg pauses at the "Failed Secret Test" error message. Right-click in the Disassembler pane and select Analysis Analyze Code. Reviewing the code a few lines above the breakpoint after the analysis has completed, we note another ASCII string, "SecurityCompass". Our discovery is shown in Figure 12-9.


Figure 12-9: Discovering an interesting ASCII string in secet.dll

Examining the code further, we note that the string "SecurityCompass" is being compared with Arg2. Arg2 is assigned the value passed via the Web and pushed onto the stack using the EDX register (Memory location 1000117D). Once both the values are loaded onto the stack, the values are compared (Memory location 10001183 CALL secret.10001280) in the function call, the result is the update of the EAX register. The register is set to 1 or 0. If EAX (TEST EAX,EAX) is set to 0, then the compare jumps to the "Fail Message"; else it jumps to the "Successful Message". Thus, if the string "SecurityCompass" is provided in the web interface, a "Successful Message" is displayed; else a "Fail Message" is displayed. Jackpot! We've discovered the equivalent of "opensesame" for this web application.

But waitthere's more! Continuing to execute the next few lines of instructions (using the Ollydbg SHIFT-F9 shortcut key), the execution should pause at the "strcat" breakpoint. We'll add additional breakpoints at "src" and "dst", the arguments to strcat. We'll then go back and provide some arbitrary input to the application again to watch execution in the debugger. The application should now stop at "src", which should contain the string "SecurityCompass" that was passed from the interface, and the "dst" should contain the "Successful Message" string. Thus, strcat is being used to generate the final string that is displayed back to the client.

As we noted earlier, strcat is a C/C++ string manipulation function with well-known security problems. For example, strcat doesn't take any maximum length value (unlike the safer str n cat). Thus, a long enough string might cause improper behavior when passed to the ISAPI. To determine the length that can cause a problem to the ISAPI, review the code around the strcat function that would give the max length assigned to the destination value, as shown in Figure 12-10.


Figure 12-10: Tracing strcat function

The destination is loaded onto the stack using the instruction LEA ECX,DWORD PTR SS:[EBP-98]. Thus, the maximum value that can be stored is 98 in hexadecimal, i.e., 152 bytes in the decimal system (space declared in the program is140 bytes and the remaining bytes are required for alignment). Providing more than 152 characters of input might cause a buffer overflow in secret.dll. The 152 characters also include the entire page (104 characters) that is displayed back to the client. Therefore, sending a string around 152 characters long would crash the application.

Note 

More detailed errors may be available if the C++ Error Handler compiler option is disabled.

Another simple attack that comes to mind here is cross-site scripting, since secret.dll doesn't appear to be performing any input sanitation. We can easily test for this vulnerability by sending the following input to the web input interface:

 <script>alert('ISAPI XSS')</script>) 

In summary, performing binary analysis not only helps find secrets, but it helps find bugs in applications, too!



Hacking Exposed Web Applications
HACKING EXPOSED WEB APPLICATIONS, 3rd Edition
ISBN: 0071740643
EAN: 2147483647
Year: 2006
Pages: 127

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net