Lecture Notes

By: Doug Kang, Kenny Wong, Alex Eng, Jason Jolley, Jooeun Lee

 

NFS Performance: www.specbench.org

            SPEC SFS9ZR1 v. 3.0

Text Box: Avg. response time (ms)            measures throughput and response time

 

 

 

 

 

NetAp FAS3040A

Specifications:

4 disk controllers

Text Box: Throughput (ops/s)224 disks (each 72 GB 1.5k RPM FGAL)

 

double-parity RAID:                                        double parity RAID      16 disks/group

(requires three disks to fail                                RAID4

before we get into trouble.)                               CPU: 1 2.4 gHz AMD Opteron

NVRAM: type of memory that              8 GiB RAM

retains its memory even after                             1 GiB NVRAM

power is cut.

 

Note: System is built for reliability & robustness (important features are bolded).

 

Security

Remark: When users cannot be trusted, things get complicated very quickly.  It doesn’t matter what kind of application you are creating.

            In the real world: security defends against force and fraud.

In the virtual world: we only have to worry about fraud.  (Let users worry about force.

 

There are 3 main forms of attacks in the virtual world:

o       Against privacy ( unauthorized release of information )

o       Against integrity ( tampering with other people’s data )

o       Against service ( denial of service a.k.a. DoS )

Goals:

1.      Allow authorized access (this is the easiest goal to accomplish)

2.      Deny unauthorized access (this is the most difficult, because we cannot foresee all possible backdoors)

3.      Authorization must match the intent of the user(s)

4.      Efficiency in the presence of DoS attacks (this is simple to test for – just run denial of service attacks against yourself)

 

Threat Modeling: “thinking like the bad guy”

            This is a crucial part of designing secure systems

                        Possible Threats:

o       Insiders – authorized users doing unauthorized things

o       Social engineering – unauthorized user pretending to be someone he/she is not

o       Network attacks – viruses and drive by downloads (DBDs)

o       DoS

o       Buffer overruns

o       Device threats – USB viruses, CD ROM viruses etc.

How are we going to defend against these threats?

 

Functions needed in security methods:

            Authentication: way of proving “you are who you really are”

Passwords, etc…

Integrity: detect when someone tampers with data

            Checksums, etc…

Authorization: prove that you are authorized to do an action

            Access Control Lists (ACLs), etc…

Auditing: log actions that people do (Assuming that Authorization is does not always match the intent of users)

Logs (keep track of what was changed and its original value before it was changed) etc…

Concerns with these mechanisms:

Correctness (there is a greater premium in networks than private systems, due to the presence of adversaries)

Efficiency (besides the CPU/Hardware performance issues, don’t get in the way of the user who is not doing anything wrong)

 

ACLs (Access Control Lists)

            e.g. on Solaris:  $ getfacl . (get the ACL of the current directory

                                                this yields:

                                                            user::rwx                       Usual UNIX permissions

                                                            group::r-x                     represented as

                                                            others::r-x                     an ACL

                                                            (+ other stuff)

                                                $ setfacl –r –m groups:tas:rwx .

we are setting the group tas to have rwx access to the current directory

if we run getfacl again, we see an extra line that has been added:

user::rwx

group::r-x

                                                            others::r-x

                                                            group:tas:rwx

                                                            (+ other stuff)

ACL Management Policies:

            To check access / list ACLs / enumerate

                        For each principal (another word for user)

                                    For each object

                                                List rights available (r w x)

This creates a huge 3-dimensional array of booleans that is hard to maintain and too bulky. ( see diagram above )

Instead, we can take advantage of the fact that there are patterns within the ACL and make this more efficient:

 

            Standard Method (Object-based Access Control)

e.g. for each new object created, have the user specify an ACL

                        1) ‘new’ has to extract the ACL arg

2) use the default ACL for the new objects (in Solaris, default ACL is stored in the directory.

            This is considered the standard method.

 

Role-based Access Control (RBAC) – this is common as well (Solaris, FreeBSD)

§         Users can assume roles

·        e.g. user eggert can assume the following roles: (faculty, sysadmin, developer)

§         Rights are associated with the role, not the identity

·        same user can have multiple sessions with different roles

            Another difference between role-based and the standard (file-based)

                        Finer grained attitude towards operations

                                    (e.g. creating a hard link to a file you don’t own: )

                                                User can create a link to the passwd:

                                                $ ln /etc/passwd hello

(/etc/passwd contains all the password information for root, etc. rwxr--r-- )

 

                                                Then ask the root to copy the link:

                                                root $ cd /tmp

                                                root $ cp hello1 hello

 

The user now has all access to this file. (note: hard linking a file that you don’t own can be revoked in Solaris)

 

 

How to authenticate

            There are 3 methods to authenticate in this world. One is based on who the principal is. Identification unique to individuals would apply here – methods such as an EEG scan or fingerprint scanning. The 2nd method to authenticate is based on what the principal has. Materials such as keys to a car or house would fall under this category. The final method is the most common, especially when dealing with the internet. It is what the principal knows. Stuff like passwords, family history, addresses and such – all common methods of authentication online.

            These methods are the basis behind design principles behind crypto systems. Kerchkoff’s algorithm says that what needs to be secret should be minimized. The algorithm should be public so that good people can give feedback to further improve the product. If the algorithm were made secret, the only people to access it would be bad people (e.g. hackers) and no feedback would be give to improve the algorithm. One such example is DVD encryption, where copy protection methods have all been rendered useless in this age of burning.

 

Building blocks for authentication

            Cryptographic hash functions are used for protection and verification. One such function is SHA1, which produces a 160-bit hash value. Knowing the hash value tells you nothing about the original message M (feasibly). However, since there is a 1:1 correspondence between a hash value and message, one can use the algorithm on every possible message to discover which message corresponds to the hash value of interest. This isn’t feasible for messages of any significant length however.

            Another encryption method is symmetric encryption (e.g. triple – DES). Given a plain text message P and a key K, one will get an encrypted message {P}K. If you know the encrypted message {P}K, and the key K, you can get the original message P back. However, if you only know {P}K, you cannot get the original message back. Also if you know {P}K and P, you cannot get the original key K back.

            There is also asymmetric-encryption. This method has a plain text message P, a public key B, and a private key K. Given P and V, you can get an encrypted message {P}V. Afterwards, you can get the original message P back by knowing this encrypted message {P}V and K. If you know {P}V and V, you will not be able to decrypt the original message P. Furthermore, there is no relation between the public and private key, so knowing the public key will not allow that person to discover the private key.

Examples

Alice authenticates herself to Bob. They both have a shared secret key K.

            Communication                         Message

o       A -> B                                           {“I’m Alice”}K - eavesdropper can see this

o       B -> A                                           OK

Now, we introduce nonces. A nonce is a string of random data blocks that is used for encryption and authentication.

            Communcation                         Message

-         A -> B                                           “I’m Alice”

-         B -> A                                           Nonce

-           A -> B                                           {Nonce}K

-         B -> A                                           OK

Typical authentication is more multi-phase.

            Communcation                         Message

-           A -> B                                           {Nonce A ∩ “Hi, I’m Alice”}VB

-           B -> A                                           {Nonce A ∩ Nonce B}VA

-           A -> B                                           {Nonce B ∩ session key}VB

 

 

Message Authentication

HMAC Algorithm (keyed-Hash Message Authentication Code)

(Algorithm assumes shared key K + encryption algorithm)

 

(Ç - Concatenation, Å - XOR)

SHA1( (KÅpad1) Ç SHA( (KÅpad2) Ç M ) )

            pad1 – known pad (usually 5c5c)

            pad2 – known pad

            M – message

 

Above algorithm produces a cryptographically secure checksum.

 

Why don't we use SHA1(KM), which produces a 160-bit hash value?

o       It can be broken by brute force

-         It can theoretically be broken many orders less than brute force (attack found in February 2005 by Xiaoyun Wang, Yiqun Lisa Yin, and Hongbo Yu)

 

SHA1(KÇMÇm)

m – short (addition easier to compute if this is known)

 

SSH does this!

 

Initial Key Exchange (IKE)  is used as before - connection layer uses shared private key (via nonces); private key gets renewed for long transmissions.

 

Server:

            ~/.ssh/authorized_keys              list of public keyes

 

Client:

            ~/.ssh/id_rsa.pub                                  public key

            ~/.ssh/id_rsa                                         private key

            ~/.ssh/known_hosts                              public keys of hosts we've connected to

 

NFS & Security

For example, SAMBA, etc., etc. tend to be used in “trusted” environment/subnets.

 

One problem in NFS is that clients can impersonate others.  A solution is to (loosely) use NFS authentication from SSH.  Another issue is when clients disagree on (username, userid) mapping.  In this case, the NFS protocol can send a user name that is suitably authenticated.  However, these methods are kind of slow.  For example, UCLA's own SEASNET does not use this.

 

Trusted Computing Base (TCB)

Lesson: You've got to trust someone

Reflections on Trusting Trust (K. Thompson)

http://www.acm.org/classics/sep95/

 

How to break into any Unix system:

Method 1:

            Change login.c to grant a certain user root access

                        if (strcmp(user, “ken”) == 0)

                                    OK(0);             // 0 for root userid

            Compile the changed login.c (call it login.c') with gcc to produce login' with the backdoor.  Now you've got a backdoor in every Unix system that has this login' program.

 

But this is open source (or at least Linux is)!  Surely people will examine login.c carefully, find this back door, and raise an alarm.

 

Method 2:

            Compile a legitimate login.c using a changed gcc compiler (gcc', which is compiled from gcc.c') which says the following:

                        if (source == “login.c”)

                                    generate(login');

            Now people examining login.c will be oblivious to the fact that the problem is elsewhere and will happily build the login' program without knowing any better.

 

But there are more paranoid people out there and surely someone takes a look at gcc.c' and finds the problem!

 

Method 3:

            There is one way to fool both groups of scrutinizers.  This can be achieved by adding in gcc.c':

                        if (source == “gcc.c'”)

                                    generate(gcc');

            The catch is to ship login', gcc', login.c, and gcc.c – in other words, clean source code and tainted executables.

 

The whole idea of Trusted Computing Base is that you can decide to trust no one.  But in order for that to work, you MUST trust your starting point, or otherwise, TCB does not work.