Summary: |
|
||||||||||||||||||||||||
A user with only the ability to connect to the TCP port that the SRB listens to for client connections can create an SRB account. No SRB account of any type or ticket is required. Once an SRB administrator account is created, the user can also gain the ability to run code as the user account running the srbServer. Depending on the configuration, they may also be able to gain access to the account running the database management system (DBMS) used by the SRB. |
|||||||||||||||||||||||||
| |||||||||||||||||||||||||
Access Required: |
remote user with no SRB account |
||||||||||||||||||||||||
This vulnerability only requires that an adversary be able to connect to the TCP port that the SRB server is listening to for client connections. |
|||||||||||||||||||||||||
Effort Required: |
low |
||||||||||||||||||||||||
To exploit this vulnerability requires only the execution of S-commands (SRB client command line utilities), and the ability to find a host running an SRB server. |
|||||||||||||||||||||||||
Impact/Consequences: |
high |
||||||||||||||||||||||||
Since an SRB administrator account can be created, the user can gain complete control of the SRB server. With this privilege, complete control over data in the SRB is obtained and gaining access to run arbitrary code should not be difficult. Under certain configurations, it may be possible to gain access to run code as the operating system account running the DBMS used by the SRB. |
|||||||||||||||||||||||||
Full Details: |
|
||||||||||||||||||||||||
This vulnerability is caused by the architectural design flaw of not properly validating and transforming user-supplied data used to create an SQL statement, resulting in an inherently vulnerable system. The cause of this vulnerability is due to the same type of flaw as described in the vulnerability report SRB-2006-0004. The difference is that this vulnerability can exploited by an attacker with only remote network access, while the other requires an SRB account of some type. The SRB client utilities and libraries pass numeric and string literal values that are user-supplied to an SRB server. The client libraries also generate SQL fragments based on user-supplied data that are passed to an SRB server. The user-supplied data and SQL fragments are then used to create an SQL statement that is evaluated by a DBMS. It is possible for the user-supplied data to terminate a quoted string early, and the remainder of the string could contain text that is able to affect the result of the SQL statement or contain additional arbitrary SQL statements. SQL Injection Introduction An SQL injection occurs when user-supplied data is used to create a string representing an SQL statement, where the user-supplied data changes the intended meaning of the statement. This occurs due to improper validation, where the data is intended to be of a certain form, but due to incorrect validation or transformation, the intended meaning of the SQL statement is changed. SQL injections in the SRB occur in two forms. The first is user-supplied data that is intended to be used as an SQL string literal; this is a problem of data transformation. The second form is user-supplied data that is intended to used as is, such as a numeric literal value, or an SQL fragment. It is easy to see how the second form can be exploited if not properly validated. How an SQL injection in an SQL string literal can occur will now be described. String literals in SQL consist of a series of characters delimited by single
quotes. If the literal contains a single quote, the single quote is escaped
by replacing it with two consecutive single quotes. As an example, the
literal, The user-supplied strings are checked to see if they contain the SQL quote character ('), and an attempt is made to quote or escape the single quote. The problem is that the validation of user-supplied data is done incorrectly for certain values. The code only quotes isolated single quotes, using the SQL standard method of two adjacent single quotes. Isolated quotes are handled correctly. An even number of consecutive single quotes are also not a security concern as they will not cause the quoted string to be unquoted prematurely; although from the user's perspective, the interpretation may be incorrect. The security problem occurs when the user-supplied string contains an odd number of three or more consecutive single quotes. These will be passed to the SQL interpreter untouched, which will interpret pairs of the quotes as one single quote, the final odd quote will prematurely end the quoted string, and the rest of the user string will be interpreted as SQL outside of a string. An example of how an SQL injection occurs is as follows: The system contains a template of an SQL statement, such as where then the following string is what is executed by the server: The result is that all the rows contained in the database table T will be deleted. The sequence '--' is the SQL begin comment sequence, which will cause all text to the end of the line to be ignored. Creating an Administrator Account in the SRB with Only Remote Network Access The difficulty is that certain characters in the user-supplied value are
treated specially and must be substituted with other sequences. Obviously,
the single quote character is one such example. There are two ways to work
around this. Some DBMS's, notably PostgreSQL, allow an alternate quoting
sequence using $$ (or $id$, where id is a valid SQL identifier). A more
universal method is to create the string constant by concatenating a sequence
of characters created with the SQL Other values that the SRB may treat specially for certain values are
The SRB allows users with accounts to issue tickets that refer to a single
object or collection of objects. The ticket allows users, even those who do
not have an SRB account, to access the objects to which the ticket refers.
The If the ticket is read from a file, it is restricted by the client to ten
characters in length, but if it is passed on the command line, it can be up
to 500 characters in length. Some validation is done on the ticket, mainly
that it starts with the letters 'C' or 'D'. The client code also transforms
the tickets using the incorrect single quote escape algorithm described
above. Given this, the only restrictions on the SQL command that can be
injected using this vector is that it must start with a 'C' or 'D', it must
not contain any single quotes, and it must be less than 500 characters in
length. If the client code is changed, then the restriction on single quotes
is removed. To perform an injection of Performing an injection through the attribute query parameter is a bit more
difficult, as there are more restrictions on the the injected string. The
same restrictions apply, but the sequence Below is a series of Bourne shell statements that will create an SRB
administrator account by injecting six SQL statements. This requires that
the attacker know the SRB zone and domain to create the user. The SQL works
by assigning the user a very high user id that is presumably unused.
Acquiring a guaranteed unique user id is simple, although the SQL is more
verbose. If these values are not known, they should be able to be retrieved
through the use of other SQL injections, public data, or social engineering.
This example makes use of the PostgreSQL alternative quoting feature, so it
is specific to a PostgreSQL DBMS, but it could easily be changed as described
above to work with other DBMS's. The password for the new account is 'xx',
and it is stored in the obfuscated form ' At this point, the SRB client configuration can be changed to use the values
set above, with the password of 'xx', and the new SRB administrator can
login. The sysadmin account created with the series of SQL statements does not
have all the access control measures automatically set compared to an account
created through the use of the normal SRB command Once the user has elevated their account type to a sysadmin, they can read,
modify, and delete files as described in the vulnerability report
SRB-2006-0001 using the If PostgreSQL is used as the DBMS and the database account is an
administrator, then arbitrary operating system files can be read, modified,
and created with the same constraints as the DBMS's operating system account.
This can be accomplished using the |
|||||||||||||||||||||||||
Cause: |
SQL injection |
||||||||||||||||||||||||
This vulnerability is caused by the architectural design flaw of not validating and properly transforming user-supplied data, resulting in an SQL injection. The first problem is that the code to transform user-supplied data that will be used as an SQL string literal is incorrect. It only escapes isolated single quotes and does not properly deal with multiple adjacent single quotes. It appears that it was done to make the quoting function idempotent, as the same quote escaping code is run on both the client and the server. It is not possible to have an idempotent quote escaping function if all characters codes are valid in the string to be quoted. The second problem is that other user-supplied data values are not validated. These are values that are used as fragments of SQL or numeric literals, and they are used with little or no change in the construction of SQL statements. For instance, the user-supplied data that forms a query of a set of SRB attributes has a syntax that is very close to SQL. The query string is only minimally transformed to generate the executed SQL statement. What should be numeric and string constants are not validated to be such. This makes an SQL injection easily possible through the use of the fragments, although a few more characters are treated specially (changed in the transformation to other characters) and cannot be used in the user-supplied value, but this is easy to work around using equivalent fragments of SQL without the specially treated characters. |
|||||||||||||||||||||||||
Proposed Fix: |
|
||||||||||||||||||||||||
Two changes are required to mitigate this vulnerability. The first change is that the code to transform user-supplied data used as SQL string literals needs to be done correctly. The second change required is that validation checks need to be performed properly on client-supplied data that is used to construct SQL statements. Proper Transformation of Data Used As SQL String Literals The current SQL quote escaping algorithm is incorrect. The quote-escaping transformation is done in both the client and the server using the same algorithm. It is not possible to create an idempotent escaping function unless some characters are reserved for this escaping purpose. Since SQL escapes quotes using a character sequence that is also a valid SQL string value, this transformation must be once and only once; in either the client or the server, but not both. If it is done in the client, the server must verify that it was done correctly. The quote escaping code needs to be changed to handle arbitrary character
sequences in the user-supplied data used in a string literal, include single
quotes and other characters treated specially by the DBMS parser. This is
made more complicated by DBMS's that provide non-standard quote escape
methods. PostgreSQL is an example of this, where a single quote with a
string literal can be represented by not only One way to handle all cases is to convert a string Another way to handle this would be to check at runtime for \-escaping by
executing a series of statements that are valid in either scheme but produce
different results. This can be accomplished by having a table with a single
text column and then run the following SQL statements: There should be a function that takes a string as input and returns a properly quoted and escaped string that the SQL interpreter will evaluate as identical to the string passed into the function. This function needs to have knowledge of the DBMS used by the SRB to perform this function properly. For this reason, the quoting of strings should be done in the server. Strings should be properly escaped and quoted in the server, preferably only right before they are interpolated into an SQL statement. This way, all strings passed around the system are unquoted and unescaped, and there is no danger of multiple quoting/escaping as a proper quoting/escaping function is not idempotent. In the current server implementation, SQL statement are created using constructs such as If the values are sent unquoted from the server, and a function existed to create an SQL fragment that returns a string representing the SQL string literal that has the same value, then the following idiom could be used (note the lack of single quotes): A further refinement would be to create a function that mimics
In this case, the call to Another option, which is dependent on the database and the database client
driver support, is to use prepared statements. This allows the SQL
statements to be created using Performing Proper Data Validation in the Server The other mitigation that needs to be performed is that data needs to be properly validated for its use in the SRB and its context in the SQL statement. Data that is used in a numeric context needs to be a valid SQL numeric constant, as do dates and truth values. Data that has a special meaning to the SRB, such as a ticket in this example should be further validated to look like a ticket: 10 characters long, starts with a valid ticket type letter, and contains only certain characters. Currently, the client transforms some user input to escape strings containing single quotes and produces SQL fragments. The server performs the same transformation. These are then used to construct an SQL statement in the server. Since performing the correct quote escaping transformation in both the client and the server cannot be done correctly, due to a correct transformation not being idempotent, there are two options for validation. Have the transformations occur only in the server, or have it occur only in the client. There are trade-offs, in the case where the transformation is performed only in the server, the clients become simpler as this code can be removed from them. The server will then get the value the user intended, which will in most cases greatly simplify the validation that the server must do to the data from the client. Much of the validation in the server then becomes validating that values used as SQL literal constants are proper SQL literals and nothing more. For values used as an SQL string literal, only a proper quote escaping transformation needs to be run. The only downside is that it will break backwards compatibility with older clients. If backwards compatibility with older clients is required, then the server will need to support the validation of user-supplied data that has been transformed in the client, as it is done now. Since the data needs to be quote-escaped properly in the server due to the quote escaping transformation being DBMS dependent, the client data should be validated that it is properly quote escaped for standard SQL and rejected if not. The data should then have the quote escaping transformation undone; then it should be validated and transformed as if it was not transformed on the client. The validation in the server needs to be more robust no matter if quote escaping transformation is done in the client or server. Several validation functions should be written for use in the server, including:
Limiting Damage from a Successful Exploit There are several things that can be done to provide security in depth that will limit the damage that a vulnerability of this type can accomplish. The Sregister command should be further restricted; and operationally, multiple operating system account should be used between the SRB and DBMS, and there should be multiple DBMS accounts used by the SRB. These may be done in production systems, but are not documented, nor does the recommended way to install the system, using install.pl, perform these items. The Sregister should be limited to allowing the registration of files to a set of blessed subdirectories. These should not be changeable through the SRB interface, but should instead require a system administrator to change a configuration file or create a symbolic link within a blessed subdirectory to the new directory tree to Sregister. This would disallow reading, modifying and deleting of files with the same privilege as the SRB server's operating system account. It would also prevent the reading of operating system files that are useful in attack and in replacing SRB and DBMS files that can be used in an attack. There should also be at least three operating system accounts for use by the SRB and DBMS. With these three accounts, a compromise of the SRB or the DBMS will limit the damage that an attacker can do to the other and will prevent the compromise of files that should be immutable, such as binaries.
There should also be at least two separate DBMS accounts, ideally three, so a compromise of the software using the DBMS is limited in the damage that it can cause.
|
|||||||||||||||||||||||||
Actual Fix: |
|
||||||||||||||||||||||||
Almost all database queries were modified to use prepared statements, eliminating the possibility of an SQL injection. The only place where it was not possible to use a prepared statement, or to validate the data to prevent SQL injections, was if the server is built with ALLOW_UDF (allow user defined functions) turned on. There is not a good way around this, so sites that require the use of UDF's need to be aware of the security risk and need to restrict access to only trusted users. |
|||||||||||||||||||||||||
Acknowledgment: |
|
||||||||||||||||||||||||
This research funded in part by NATO grant CLG 983049, the National Science Foundation under contract with San Diego Supercomputing Center, and National Science Foundation grants CNS-0627501 and CNS-0716460. |