You are on page 1of 22

Case study: SSH

Lecture Notes for 91.561 UMass Lowell Computer Science David Martin

Secure Shell
Not really a shell Originally replacement for rcommands
Encryption Good authentication
Generally, interactive secure sessions
Login Remote command execution Port and X forwarding Authentication forwarding Flow control Terminal handling Signal propagation Compression

Secure Shell
Program versus protocol versus company Will concentrate on SSH-2 protocol
Mercury, Saturn ssh command is OpenSSH_3.1p1, SSH protocols 1.5/2.0 scp, sftp commands

http://www.ietf.org/html.charters/secshcharter.html See also http://library.uml.edu Safari books

SSH Layers
SSH application User authentication Connection management

Host transport TCP

Transport protocol
1. Introduction (from draft-ietf-secsh-transport-15.txt) The SSH transport layer is a secure low level transport protocol. It provides strong encryption, cryptographic host authentication, and integrity protection. Authentication in this protocol level is hostbased; this protocol does not perform user authentication. A higher level protocol for user authentication can be designed on top of this protocol. ... Key exchange method, public key algorithm, symmetric encryption algorithm, message authentication algorithm, and hash algorithm are all negotiated. It is expected that in most environments, only 2 round-trips will be needed for full key exchange, server authentication, service request, and acceptance notification of service request. The worst case is 3 round-trips.

Example session
% telnet mercury 22 SSH-1.5-foo vs SSH-2.0-foo % ssh v mercury (Host keys) (User authentication methods)

4. Binary Packet Protocol


Each packet is in the following format: uint32 packet_length byte padding_length byte[n1] payload; n1 = packet_length padding_length - 1 byte[n2] random padding (4..255 bytes); n2 = padding_length byte[m] mac (message authentication code); m = mac_length

4.3 Encryption
An encryption algorithm and a key will be negotiated during the key exchange. When encryption is in effect, the packet length, padding length, payload and padding fields of each packet MUST be encrypted with the given algorithm. The encrypted data in all packets sent in one direction SHOULD be considered a single data stream. For example, initialization vectors SHOULD be passed from the end of one packet to the beginning of the next packet. All ciphers SHOULD use keys with an effective key length of 128 bits or more. The ciphers in each direction MUST run independently of each other, and implementations MUST allow independently choosing the algorithm for each direction (if multiple algorithms are allowed by local policy). 3des-cbc blowfish-cbc ... aes256-cbc REQUIRED RECOMMENDED OPTIONAL three-key 3DES in CBC mode Blowfish in CBC mode AES (Rijndael), CBC, 256-bit key

4.5 Key exchange methods


The key exchange method specifies how one-time session keys are generated for encryption and for authentication, and how the server authentication is done. Only one REQUIRED key exchange method has been defined: diffie-hellman-group1-sha1

Additional methods may be defined as specified in [SSH-ARCH].

6. DH with Server Authentication


2. S generates a random number y (0 < y < q) and computes f = g^y mod p. S receives "e". It computes K = e^y mod p, H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K) (these elements are encoded according to their types; see below), and signature s on H with its private host key. S sends "K_S || f || s" to C. ... 3. C verifies that K_S really is the host key for S (e.g. using certificates or a local database). C is also allowed to accept the key without verification; however, doing so will render the protocol insecure against active attacks (but may be desirable for practical reasons in the short term in many environments). C then computes K = f^x mod p,

5.2 Output from Key Exchange


The key exchange produces two values: a shared secret K, and an exchange hash H. Encryption and authentication keys are derived from these. The exchange hash H from the first key exchange is additionally used as the session identifier, which is a unique identifier for this connection.

5.2 Output from Key Exchange


Encryption keys MUST be computed as HASH of a known value and K as follows (sid is session ID): Initial IV client to server: HASH(K || H || "A" || sid) Initial IV server to client: HASH(K || H || "B" || sid) Encryption key client to server: HASH(K || H || "C" || sid) Encryption key server to client: HASH(K || H || "D" || sid) Integrity key client to server: HASH(K || H || "E" || sid) Integrity key server to client: HASH(K || H || "F" || sid)

User authentication
rhosts (severely deprecated; v 1 only)
Network layer tests only

Passwords
Protocol sends username/password as unit, not interactively
But chained connections

Public keys
Authentication agent forwarding with A

Kerberos Host keys

Connection Management
Think of an embedded set of TCP streams Each has:
Local and remote ID Window size Max packet size (bulk vs interactive)

Handles most UI aspects


Pseudo-terminals Remote commands X11 Flow control

SSH as building block


Port forwarding
ssh L localport:tohost:toport remotehost Tunnels localhost:localport to remotehost's resolution of tohost:toport Can use to punch through firewalls

VPNs
Can run PPP connection over SSH A bit convoluted, but it works

Project 3
Would handle confidentiality, integrity, and authentication Not sure which toolkit to suggest though; openssh?

Example: submit program


Needs to read arbitrary files and deliver them to instructor's directory So instructors add line like this to their authorized_keys file:
command="/usr/local/bin/submit" ssh-dss AAAAB3NzaC1kc3MAAACBAM+AKQ7sJVEkwNFLw YEZaEB4hvFr0Z... the submit command then tars up files and sends them through ssh instructor@mercury using the appropriate key Allows submitting from any host that has the key

Interesting attacks
The user authentication protocol is subject to man-in-the-middle attacks if the encryption is disabled. [Secsh-arch] Herbivore keystroke analysis (Usenix Security 2001)
50x advantage over brute force

Bellare Kohno Namprempre (ACM CCS 2002)


Verifying plaintext guesses
Through IV chaining Through MAC wraparound

CRC32 compensation detector attack in SSH-1 security patch (next slides)

deattack.c bug
Taken from CORE-SDI, http://www1.corest.com/common/showdoc.php?idxseccion=10&idx=81 Technical Description - Exploit/Concept Code: Most SSH distributions incorporated the file deattack.c released by CORE SDI in 1998. The file implements an algorithm to detect attempts to exploit the CRC-32 compensation attack by passing the ssh packets received from the network to the detect_attack() function in deattack.c ... /* detect_attack Detects a crc32 compensation attack on a packet */ int detect_attack(unsigned char *buf, word32 len, unsigned char *IV) { static word16 *h = (word16 *) NULL; static word16 n = HASH_MINSIZE / HASH_ENTRYSIZE; register word32 i, j; word32 l; ... buf is the ssh packet received, len is the length of that packet. The received packet is comprised of several blocks of cipher text of size SSH_BLOCKSIZE and each of them is checked against the others to verify that different packets dont have the same CRC value, such behavior is symptom of an attack. The detection is done using a hash table that is dynamically allocated based on the size of the received packet.

deattack.c continued
... for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2); if (h == NULL) { debug("Installing crc compensation attack detector."); n = l; h = (word16 *) xmalloc(n * sizeof(word16)); } else ... Due to the improper declaration of 'n' above (it should be a word32) by sending crafted large ssh packets (length > 2^16) it is possible to make the vulnerable code perform a call to xmalloc() with an argument of 0, which will return a pointer into the program's address space. It is worth mentioning that existing standards promote two possible behaviors for malloc() when it is called with an argument of 0: - Failure, returning NULL - Success, returning a valid address pointing at a zero-sized object. Most modern systems implement the later behaviors and are thus vulnerable. Systems which have the older behaviors will abort the connection due to checks within xmalloc() It is then possible to abuse the following code to in order write to arbitrary memory locations in the program (ssh server or client) address space, thus allowing an attacker to execute arbitrary code on the vulnerable machine

deattack.c continued
for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; i = (i + 1) & (n - 1)) { if (h[i] == HASH_IV) { if (!CMP(c, IV)) { if (check_crc(c, buf, len, IV)) return (DEATTACK_DETECTED); else break; } } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { if (check_crc(c, buf, len, IV)) return (DEATTACK_DETECTED); else break; } } h[i] = j; } A would-be attacker does not need to authenticate to the SSH server first or to have the packets encrypted in a meaningful way to perform the attack. Even if that was the case, the session key used for encrypting is chosen by the ssh client and it is therefore trivial to implement an exploit (in the sense of the cryptography knowledge required to do it). However, a small degree of knowledge in exploit code development would be needed to implement a working exploit.

Local Statistics (Spring 2003)


Users with .ssh directories who also have private keys: 10 (18%) Users with .ssh directories who also have authorized_keys: 44 (79%) CS cluster users: 2419 CS users with .ssh directories: 56 (2%) So most users just type their passwords

Biggest Problem?
Host keys
Works right out of the box What happens when key changes?
ssh.fi version: warning, type y to continue openssh version: error, instruction on how to fix

Much better than cleartext or rhosts

You might also like