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
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.