Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Tue, 13 Dec 2005 22:12:42 +0100
From: "Frank Dittrich" <frank_dittrich@...mail.com>
To: john-users@...ts.openwall.com
Subject: Re: MSSQL/SAP hashes?

Solar Designer wrote:

>Although I don't know German, I had a look at your articles and I'd
>appreciate your summarizing your findings on this mailing list.  I think
>that this is on topic, although a _lengthy_ discussion might not be
>since there's no publicly available patch to John the Ripper to support
>those hashes.

OK, I'll try my best to summarize what I've published so far, and
skip parts which should be obvious for the mailing list members.

Some information will be difficult to comprehend without basic
knowledge of the SAP R/3 architecture.

I may be forced to somewhat simplify the description, but I hope not
to provide incorrect information due to the simplification.
Nevertheless, the desription might still become lengthy;)


1. General remarks, not neccessarily related to SAP password security

SAP can be run on a variety of oprerating systems with different
DBMS, Oracle is probably the most commonly used one.
Since all SAP processes have the same uid, and connect to the DB as
the same user, OS and DB cannot distingush different SAP users.
Almost all SAP functionality is implemented in ABAP, the ABAP source
code of (almost all) SAP standard programs is readable and modifyable
by SAP customers.
Customer specific programs and third party add-ons are developed
in ABAP as well. SAP provides separate name spaces for those.

The ABAP programs use the run time environment provided by the
SAP kernel. (A machine dependent byte code is generated from the ABAP
source code.)

A minimal SAP system landscape usually looks like this:
development system -> test system -> production system.

In an SAP environment, authority checks have to be implemented in
the ABAP source code.
Nothing prevents a developer from copying a SAP standard program
and starting the copy after removing the AUTHORITY-CHECK statements.
There are only two exceptions, where the authority check is
hard coded into the SAP kernel:
-for accessing files on the operating system
-for executing arbitrary OS commands using a SAP kernel function
Even worse, the authorizations are stored in database tables which
the developer has write access to.

While this problem affects only development systems, a developer can
compromize subsequent systems as well, if no proper code review
procedure is in use.
Even with a code review, it's very hard to prevent a malicious
developer from compromizing subsequent systems.
A developer who is able to execute the programs he created in the
development system can modify any SAP standard program, among others
the programs of the development workbench (e.g. the editor, the
SAP standard tools to create and release transport requests to
subsequent systems, view the transport logs, the contents of a
transport request, ...)
Other possible ways to compromize a production system:
-"remote function calls" from development system or test system
to the production system, e.g. if logon credentials of a
dialog user instead of a communication user are stored in table
RFCDES (the password will is encrypted, but can easily be decrypted)
or if the communication user has unnecessary authorizations
-0-day exploits
(there's a large number of programs available in source code,
and ABAP even provides it's own parser as part of the syntax,
or wait until SAP puplishes a fix (and the source code diff)
in an OSS note)

Since SAP allows to include "special objects" into a transport
request which cause automatic program execution in the destination
system, it's possible to automatically manipulate SAP standard
programs in the destination system.

After manipulating those SAP standard tools, you can't rely on the
fact that the source code you see in the editor really is the
source code which is stored in the database, and which gets
executed when running the program.
So, the only way to _know_ you really see the source code that is
stored in the DB, you'll have to use the debugger and single-step
through the program which reads and displays the source codes in
question.
Even then, you'll need a very skilled person to perform the
review, otherwise it's very unlikely to discover all potentially
dangerous ABAP programs.
Detecting maiciously modified SAP standard programs is rather
difficult, since a develpoper can change any program without
modifying the "last-changed date" and "last changed by"
fields  in the repository (TRDIR-UDAT and TRDIR-UNAM).
In addition, the SAP standard doesn't provide support to calculate
and compare checksums for repository objects, like tools on Unix
systems, e.g. tripwire or aide do.
In a default configuration, a version history for repository
objects is only created in the development system, not in
subsequent systems.
A developer can easily manipulate the version history, because
(meanwhile you might guess it) he has write access to the tables
where it is stored.


2. Protection against attackers with special authorizations/skills

2.1. Measures to protect the clear text passwords

When logging in into a SAP system, the start screen of program
SAPMSYST will be processed.
SAPMSYST is one of the few programs which are not readable using the
SAP development workbench transactions or the ABAAP command
READ REPORT.
This is how SAP wants to ensure this program cannot be modified.

Nevertheless, a skilled developer can read and modify the source code
of this program, e.g., to capture the passwords entered during login.
While "protecting" the source code of this program does indeed
require additional skills to manipulate the source, it also makes it
more difficult to detect such manipulations.
Modifying the source code of SAPMSYST is not the only way a skilled
developer can use to capture the passwords.

2.2 Protection of SAP password hashes

SAP stores password hashes and the version of the password hash
alggorithm of the currrently used password and of 5 previously
used passwords in the database table USR02.
In addition, the password hash (but not the CODVN of the algorithm)
is stored in a newly created record in DB table USH02, whenever the
user changes his password, or whenever an admin changes the
valid-from or valid-to date of a user, locks or unlocks a user, etc.
(That means, DB table USH02 stores _all_ password hashes of all
users since the SAP system has been installed, with user name,
date and time as key fields.)

In a development system, you cannot prevent developers from accessing
the contents of USR02 and USH02.
Since a developer even has write access to these tables, he can
modify USR02-BCODE, to logon as another user.
The SAP user name is used as a salt, so all he has to do is:
Install a MiniSAP system (delivered on a CD with various ABAP books)
or a Linux TestDrive system (can be ordered at no cost, see
http://www50.sap.com/linux/eval/index.asp) on his private PC,
create a new user with a known password, and copy the hash.

Even in production systems, there might be possibilities to gain
read access to password hashes.
To directly access the contents of tables USR02 or USH02, a user
needs the authorization to start transaction SE16 (authority-check
object S_TCODE) and the authorization for authority-check object
S_TABU_DIS, authorization group SC.
(Depending on the release or on the authorization to release batch
jobs, the user can also directly start the programs generated by
SE16 via transaction codes SA38 or SE38.)

In a development or test system, authorizations are often not
as much restricted as in the production system.
(This is a problem, if the test system is frequently re-built
from the production system, or if passwords are synchroized across
systems, e.g. via CUA ("Central User Administration").)

Without direct access to the contents of the DB table, it's
possible to see password hashes of other users if you have
debugging authorization, even without the authorization to
overwrite the contents of variables during debugging.
You just have to debug one of the many programs which check the
validity of a SAP user name by
SELECT SINGLE * FROM USR02
     WHERE BNAME = name_entered_in_some_dialog_screen ...
Because checking the validity of a SAP user name like this is the
most commonly used method across all SAP programs, it's also
infeasible to detect "unauthorized" USR02 access by switching on
the SAP SQL trace for USR02.

2.3. Protection of the hash algorithm

SAP tries to prevent illegitimate calls of the SAP kernel function
which calculates the password hash.
If SAP detects such an illeggitimate call of the kernel function,
a SAP system log entry will be created, the user will be locked and
immediately logged out of the system.
That means, since SAP R/3 release 4.6B it's somewhat harder to
write an ABAP program which tries to crack SAP passwords than it
has been in earlier releases.
But a skilled developer can easily bypass SAP's check.
So, even without knowledge of the hash algorithm, it's possible
to develop a SAP password cracking program implemented in ABAP.

On a Linux PC with an AMD Athlon(TM) XP 2100+ processsor and 1 GB
RAM, an ABAP program can try about 8 million user name / password
combinations per minute (compute the hash and compare it with the
hashes from USR02/USH02).


2.4 Weakness of the SAP hash algorithm(s)
    (as mentioned in my 1st article)

CODVN A

The previously used hash algorithm (USR02-CODVN = 'A' for the
currently used password, or USR02-CODV1 - USR02-CODV5 for the
5 previously used passwords, respectively) had serious flaws:
-just the first 6 characters of the SAP user name have been used
as a salt, so that an attacker could crack the passwords of several
users who's user names started with the same characters without the
need to calculate each hash separately
-frequently occuring hash collissions, so that a trivial password
often had the same hash as a really complicated password
-password hashes of the same password, but for totally different
user names, usually "looked" very similar, so that probably attacks
much more effective than trying arbitrary passwords should be
possible

(That's why, you should take care that no USR02 record with CODVN 'A'
exists.
Since CODVN 'A' has been depreciated a long time ago, this CODVN
should, if at all, only occur for dialog user IDs which are still
valid, but the password hasn't been changed for years, or for
non-dialog users like RFC users (here "RFC" means "remote function
call")

Because of those weaknesses, SAP introduced a new hash algorithm,
CODVN B, many years ago (about 10 years ago, I think).
SAP didn't publish the algorithm.
All high-level information that's "publicly" available can be
found in SAP OSS note 2467 and related notes.
(SAP OSS notes are accessible for SAP customers via the
SAP Service Marketplace, https://service.sap.com/notes.)

CODVN B

The hash algorithm which replaced CODVN A also has it's
flaws/problems:
The SAP documentation up to R/3 release 4.6C mentions that
the system does not distinguish between upper and lower case
characters, but otherwise you can use all characters which
can be entered into a terminal when composing a password.
The documentation for release 6.20 mentions that letters A-Z,
digit's 0-9, and punctuation marks can be used.

Problems when using 8bit characters (not 7bit ASCII characters)
have not been mentioned.

Analyzing the hashes computed by the system, you'll see that all
characters which are not 7bit ASCII characters can be replaced by
an accent circumflex ('^') without changing the hash.
(These predictable collisions occur for non-ASCII characters in
SAP user names as well:
If SAP users M▄LLER and MÍLLER (both very common German names)
use the same password, the hash will also be the same.
It should be obvios how this knowledge can be used by an attacker.)

The reason for not distinguishing non-ASCII character has probably
been the fact that SAP runs on a variety of platforms, and wanted
the hashes to be independent of the code pages in use.

(BTW, for CODVN A all non-ACII characters in the user name or
password caused collisions with an apostrophe ('\'') instead of an
acccent circumflex.)


3. Protection against unauthorized login attempts

3.1 Detection of failed login atttempts

To prevent unauthorized logins, it's mandatory to deal with
failed login attempts. Otherwise, an attacker might sooner or
later succeed by simply trying different passwords.

SAP logs failed dialog login attempts in the system log.
(I'll skip mentioning the SAP security audit log, since it hasn't
been covered in my articles, and since it's not activated in a
default configuration.)
In addition, the number of failed login attempts since the last
successful login is stored in the user master record (USR02-LOCNT).
The problem is that usually only SAP system administrators have the
authorization to check the system log or the number of failed login
attempts for a particular user.
But a system administrator will usually not be able to distinguish
between an unauthorized login attempt and an authorized user who
accidently mis-typed the password.
You can only assume the authorized user mis-typed his password,
if immediately afterwards the user logs in successfully.
Even then, you cannot be sure.
Neither the terminal ID nore the IP address of the client PC are
sufficient to prove who tried to login.
(The terminal ID which is reported in transaction SM04 can be
easily manipulated by users who are authorized to change
environment variables on the operating system of the client PC.
If the SAPGUI is started from a WBT server, or if the user connects
via a SAProuter, the SAP application server only "knows" the
IP address of the WBT server or SAProuter.)

Only the user will know whether or not he mis-typed the password
in a previous login attempt.
That's why, the user should be informed about failed login attempts.
But the SAP standard doesn't provide this functionality.
Even in the SAP login user exit (so-called "user exits" allow
to plug-in customer specific code without modifying SAP standard
programs) such a function cannot easily be provided, since the
counter of failed login attempts will have been reset to 0 before
the login user exit is processed.
(The only way would be to define an update trigger on DB level,
which increases a counter in a customer specific table,
check this customer specific table in the login user exit,
inform the user about failed login attemts, reset the counter...)

3.2 Locking users after failed login attempts

The SAP system profile parameter login/fails_to_user_lock determines
how many failed login attempts may occur before a user will be
automatically locked by the system.
There was an issue with the sapinfo tool which allowed to try
passwords via RFC connects without locking the user, see
http://seccurityfocus.com/bid/7007/discusssion/
(Meanwhile the problem has been fixed, I think.)

3.3 Password change frequency

To make successful password cracking attempts more difficult,
it is required to frequently change the password. (So that the
time to crack a password is hopefully larger than the time the
password is valid.)

The SAP system profile parameter login/password_expiration_time
determines how long a password can be used.
If the specified number of days since the last password change is
over, the user is forced to change his password during login.

There's no prior warning before the password expires, and no
possibility to specify a number of grace logins without
requiring to change a password which has been expired.

As a result, users are either picking passwords which can easliy
be guessed, or they frequently forget their password.

A warning about passwords which expire in a few working days can
be easily implemented in the SAP login user exit.
It's even possible to let each user configure how many working days
in advance he wants to be informed about a password expiry.

3.4 SAP specific password restrictions

For SAP systems, several restrictions apply:
-minimal length is 3 characters (can be _increased_ by
adjusting a SAP profile parameter)
The minimal password length is not checked during login,
only when changing the password. (If you know the hash algorithm
and have write access to the hash, you can login with a
one character password, but not with an empty password.)
-maximal length is 8 characters
-trailing spaces are ignored (they'll be removed before
computing the hash)
-no distinction between upper and lower case
-the first character cannot be '!' or '?'
(according to SAP's documentation, there cannot be a space
among the first 3 characters of the password, however, this
restriction does not longer apply to current SAP kernel versions)
-among the first 3 characters, there have to be at least 2
different characters, not counting upper/lower case differences
(this restriction is only checked when changing the password,
so that a user who picks the password ─Í▄▀Á▓│░ can login with
the password ──────── or ^^^^^^^^, if CODVN B has been used to
compute the hash)
-the password cannor be PASS or SAP
-the 5 previously used passwords cannot be reused
-the user cannot change the password more than once per day,
except if the password has been reset by an administrator
(to prevent bypassing the password reuse restriction)

(The restriction that the first 3 characters of the password
may not occur in the same sequence in the user name, which is still
mentioned in SAP's documentation, does not longer apply - checked
for R/3 releases >= 6.10)

There's also a DB table USR40, which can be maintained by the
administrator.
This table is designed to store forbidden passwords and password
patterns (? is used as a placeholder for a single character,
and * as a placeholder for any sequence of characters).

In releases >= 6.10, additional restrictions can be activated
via SAP profile parameters, see appendix)

3.5 Enforcing strong passwords/detecting weak passswords

In earlier releases, SAP allowed to plugin customer specific
password checks (in program SAPMS01J), to reject weak passwords.
Because this plugin could have been mis-used, such a possibility
no longer exists.

('m afraid I have to postpone covering most of the findings
mentioned in my second article.
The most detailed part is the description of hash collisions
which occur due to a minor flaw in the implementation, and how
CODVN B and the newly created CODVN D hash algorithms are affected.)


Appendix

SAP profile parameters related to password policy:

login/min_password_length
minimal password length, checked when changing a password
(values less than 3 will be ignored)

login/min_password_diff (R/3 release >= 6.10)
minimum number of characters that differ, when comparing old and new
password (simple shifting, like GJP$EUB7 -> P$EUB7GJ, doesn't count
as a difference.)

login/min_password_digits (R/3 release >= 6.10)
minimum number of digits (0-9) in a password,
checked when changing a password

login/min_password_letters (R/3 release >= 6.10)
minimum number of letters (A-Z) in a password,
checked when changing a password

login/min_password_specials (R/3 release >= 6.10)
minimum number of other characters (not 0-9A-Z) in a password,
checked when changing a password

login/password_expiration_time
number of days before a user password expires
(0: password doesn't expire)

login/password_max_new_valid
number of days a password of a newly created user is valid

login/password_max_reset_valid
number of days a user password reset by the admin is valid

login/fails_to_session_end
number of failed login attempts after which the current
SAPGUI session is closed

login/fails_to_user_lock
number of failed login attempts after which a user will be locked

login/failed_user_auto_unlock
determines whether a user who is locked due to the number of
failed login attempts will be automatically unlocked at midnight

login/no_automatic_user_sapstar
(default 0 means, if no record for user SAP* exist in table USR02
for a particular client, login as SAP* is possible with password
PASS, and the user SAP* will have unlimited authorization,
value 1 means, no login as user SAP* with password PASS possible,
if no such USR02 record exists)


SAP documentation on the web:
http://help.sap.com/


> > I'm, however, not going to publish the patch or mention details
> > about the algorithms being used.
> > (I'd like to contribute work to John the Ripper, because I
> > appreatiate the work done by Solar Designer and others, but I think
> > publishing the patch wouldn't be a good idea.
> > The reason is that it's very hard, if not impossible, to protect
> > SAP password hashes against unauthorized access.
> > That's why, publishing the algorithm IMO would have a disastrous
> > effect on the security of SAP systems, instead of increasing the
> > security by allowing the admin to discover weak passwords.)
>
>Well, if Unix password crackers were not publicly available, most
>vendors wouldn't bother implementing shadow passwords.  Isn't publishing
>the algorithm the only way to persuade SAP to start fixing things?

You might be right.
Adressing the issues would, however, require a few,
not easily to implement, changes in the SAP R/3 architecture.
That's why I doubt they'll implement significant improvements
in releases which are currently in use by customers.
(And migrating to a new SAP release is usually not that simple,
either.)

Regards, Frank


Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ