1. Modifying Host Headers
1.1. Problem
Application servers frequently listen on multiple ports for different
purposes. For example, JBoss listens on one port for regular requests
and exposes the JMX console on a separate port for administration
purposes. Even if the administration port is blocked by a firewall, an
external user could still gain access to it by modifying the Host header in a HTTP request. If your
application server is not configured correctly, an attacker can use this
technique to gain access to the application server’s administrative
functionality.
1.2. Solution
WebScarab can be used to modify HTTP headers in requests. Turn on
WebScarab and set it to intercept requests. Then, initiate a connection
to the target by entering a URL such as http://www.example.com/ in your web browser’s
address bar.
When WebScarab intercepts the request, modify the port in the
Host header to the target application
server’s administration port and submit the request (i.e., modify the
Host header to something like
www.example.com:8000). Some common
application servers and their default administration port numbers are
listed in Table 1.
Table 1. Default administration ports in common application
servers
Application server | Administration port |
---|
Adobe JRun | 8000 |
Apache Geronimo | 8080 |
BEA WebLogic | 7001 |
IBM WebSphere 6.0.x | 9060, 9043 |
IBM WebSphere 5.1 | 9090, 9043 |
IBM WebSphere 4.0.x | 9090 |
Oracle OC4J | 23791 |
RedHat JBoss | 8080 |
If, as a result, your browser displays the application server’s
administration page, the deployed application fails this test. If you
get an error page stating that the request was invalid or if you get the
same response as when you do not modify the host header, then the
application passes this test.
1.3. Discussion
This attack works because the application server is not aware of
the network-layer port used to submit any particular request. Once it
receives a request, it uses the supplied Host header to determine how to service the
request.
Of course, this can expose sensitive functionality to attackers.
The JBoss JMX console, for example, allows the user to display the JNDI
tree, generate a thread dump, display memory pool usage, manage the
deployment scanner, redeploy an application, and shut down JBoss. By
default, this functionality is wide open; however, it can be secured
such that the user needs to authenticate before the application server
will allow her to access the functionality.
Note that even if authentication is required to access the administration
console, it may not be secure. In many application servers, there are
documented default usernames and passwords for administration that
should be tried when performing these tests.
NOTE
This test should be executed in your operational environment or
on staging servers that replicate the production environment’s
configuration. This is a configuration issue that needs to be
addressed during deployment, and so testing servers in the development
or QA environments will not provide accurate results for the
production environment.
2. Brute-Force Guessing Usernames and Passwords
2.1. Problem
Unless an application contains account lockout functionality, an
attacker can attempt to log in by brute-force guessing common usernames
and passwords. This typically involves brute-force guessing to find a
list of valid usernames and then attempting to brute-force
passwords.
2.2. Solution
The goal is to test whether an attacker can obtain some valid
usernames in the application and whether he can continually guess
passwords until he gets one right. Attempt the following to determine
whether the application intentionally or unintentionally reveals
usernames:
Attempt to log in with a username that does not exist. Then,
attempt to log in with a username that does exist, but enter an
incorrect password. If the application’s response in the two cases
is different, then the attacker can enumerate usernames in the
system.
If the application implements password reset functionality for
users that forget their passwords, determine how the password reset
functionality works. Does it require the user to enter a username?
If so, determine whether the application responds differently
depending on whether a valid or invalid username is entered.
Some applications contain functionality to allow users to sign
up for accounts themselves. Since usernames need to be unique, the
application will indicate to the end user whether the username that
she is trying to sign up for already exists. This functionality
could be exploited by an attacker to enumerate usernames. Determine
whether the application contains such functionality.
If in any of these tests the application allows the attacker to
determine valid usernames, the application fails this part of the test.
This may or may not be of interest in your particular application.
However, if the next test fails, then the failure will definitely be of
interest.
The next step is determining whether the application allows
brute-forcing passwords. Even if the attacker cannot conclusively get a
valid list of usernames, he could still attempt to brute-force passwords
for common usernames that may or may not be valid in the application
(e.g., jsmith). Attempt one of the following depending on your circumstances:
If there is a requirement concerning account lockout functionality, test it by entering an
incorrect password for a valid username several times (as dictated
by the requirement) and determine whether the account is locked out
by entering the same username with the corresponding valid password.
Also, if the account is locked out, determine whether the
application provides the same response regardless of whether the
entered password is correct. If after account lockout it provides
different responses depending on whether the password is correct or
not, the attacker can still brute-force the password. However, he
will not be able to actually log in until the account is
unlocked.
If there is no requirement concerning account lockout
functionality, determine whether account lockouts are enforced by
entering an incorrect password for a valid user account a number of
times (10 to 15 times should be sufficient). Then, enter the valid
password and see if the account is locked out. As in the previous
test, even if the account is locked out, determine whether the
application’s response is different depending on whether the entered
password is correct or not.
The application fails this test if it either does not enforce
account lockout functionality, or locks out accounts and then provides
different responses depending on whether the entered password is correct
or not.
2.3. Discussion
Usernames and passwords are frequently brute-forceable even in the
presence of account lockout functionality or other mitigating measures.
Applications often try to be helpful and provide different error
messages to users depending on whether the supplied username is
incorrect or the supplied password is incorrect. This is often true even
after an account gets locked out. The authors have seen an application
that displayed error messages similar to the following. If the username
was incorrect, the application stated that “The username or password is
incorrect”; if the password was incorrect, the user would get the
message “The user could not be authenticated”; if the account was locked
out and the password was correct, the user would get a message stating
“Your account has been locked out.” This provides an easy way to
brute-force usernames and passwords.
In the earlier example, an attacker could enumerate usernames by
entering different values and recording whether the application stated
that “The username or password is incorrect” or “The user could not be
authenticated.” The attacker could then brute-force the password by
waiting to either get logged in or get the message “Your account has
been locked out.” Even if the attacker locks out an account while
brute-forcing, he will just need to wait until the account is unlocked
before accessing it. Many applications unlock accounts automatically
after a predetermined amount of time.
Note that it is typically easy for attackers to guess at least a
small number of usernames and passwords in most systems. This is because
usernames tend to be predictable, and many users tend to choose very
weak passwords.
There are several ways in which an attacker could get valid usernames
depending on the application. Many systems contain usernames that are
essentially public or that can be easily obtained (e.g., performing a
Google search for “gmail.com” reveals a large number of valid Google
user accounts). In other cases, the application may leak information
during log in, password reset, or account signup.
An attacker can guess usernames by getting a list of common
names and then generating usernames from them. In the United States,
the Census Bureau publishes lists of the most common first and last
names. According to the results from the 1990 Census, jsmith and
msmith are probably the most common usernames since Smith was the most
popular last name, James and John were the most popular first names
for males, and Mary was the most popular first name for
females.
Additionally, studies have shown that a significant number of
users choose common weak passwords such as “123,” “password,”
“qwerty,” “letmein,” “monkey,” and their own first names.