Internet Security Association and Key Management Protocol


The demand for virtual private network (VPN) technology has increased, so protocols that enable VPN functionality have seen an explosion in use over the past five years or so. VPN technology requires establishing encrypted tunnels between two previously unrelated hosts for some duration of time. Establishing these tunnels requires some sort of authentication mechanism (unidirectional or bidirectional) to verify the other party in the tunnel setup and a mechanism to securely create an encrypted channel. Enter Internet Security Association and Key Management Protocol (ISAKMP), a protocol designed to allow parties to authenticate each other and securely derive an encryption key that can be used for subsequent encrypted communications.

An ISAKMP packet is composed of an ISAKMP header followed by a variable number of payloads, each of which can be a variable length. The header layout is shown in Figure 16-1.

Figure 16-1. ISAKMP protocol header


The fields in the header are as follows.

  • Initiator cookie (64 bits) This unique value is generated by the party wanting to establish a new secure tunnel (and, therefore, initiating the ISAKMP communications). It's used to keep track of the session.

  • Responder cookie (64 bits) This unique value is generated by the other party to which a client wants to establish a secure tunnel. It uniquely identifies the session for the responder.

  • Next payload (8 bits) This type value describes the first payload following the ISAKMP header (explained in "Payload Types" later in this chapter).

  • Major version (4 bits) This field is the major protocol version used by the sender.

  • Minor version (4 bits) This field is the minor protocol version used by the sender.

  • Exchange type (8 bits) This field describes the way in which ISAKMP negotiation occurs.

  • Flags (8 bits) This field indicates the options set for the ISAKMP exchange.

  • Message ID (32 bits) This field is used to uniquely identify a message.

  • Length (32 bits) This field is the total length of the packet in bytes (including the ISAKMP header).

The ISAKMP packet header contains a 32-bit length field. Application programmers can easily make mistakes with binary protocols handling untrusted 32-bit integers, so you should examine code that deals with this integer carefully. Primarily, signed issues and integer overflows could happen if code fails to deal appropriately with data received from the network. Here's a typical example:

#define ROUNDUP(x) ((x + 7) & 0xFFFFFFF8) void *mymalloc(size_t length) {    return malloc(ROUNDUP(length)); } int process_incoming_packet(int sock) {     struct isakmp_hdr header;     unsigned char *packet;     unsigned long length;     int n;     if((n = read(sock, (void *)&header, sizeof(header))) !=                                             sizeof(header))         return -1;     length = ntohl(header.length);     if((packet = (unsigned char *)mymalloc(length)) == NULL)         return 1;     ... process data ... }


The mymalloc() function rounds up the integer passed to it, so this code is vulnerable to an integer overflow. Using the allocator scorecards from Chapter 7, "Program Building Blocks," you would see this bug straight away. It's a textbook example of an allocation wrapper proving dangerous for functions that make use of it.

Another interesting thing about the length field in the header is that it's the total length of the packet, including the ISAKMP header, which means developers might assume the length field is larger than (or equal to) the ISAKMP header's size (8 bytes). If this assumption were made, integer underflow conditions might result. A slightly modified version of the previous example is shown:

#define ROUNDUP(x) ((x + 7) & 0xFFFFFFF8) #define ISAKMP_MAXPACKET        (1024*16) void *mymalloc(size_t length) {     return malloc(ROUNDUP(length)); } int process_incoming_packet(int sock) {     struct isakmp_hdr header;     unsigned char *packet;     unsigned long length;     int n;     if((n = read(sock, (void *)&header, sizeof(header))) !=                                             sizeof(header))         return -1;     length = ntohs(header.length);     if(length > ISAKMP_MAXPACKET)         return 1;     if((packet = (unsigned char *)mymalloc(length                    sizeof(struct isakmp_hdr))) == NULL)         return 1;     ... process data ... }


In this example, there's a sanity check for unusually large length values, so an integer overflow couldn't be triggered as in the previous example. However, length is assumed to be larger than or equal to sizeof(struct isakmp_hdr), but no explicit check is ever made. Therefore, a length value less than sizeof(struct isakmp_hdr) causes the argument to mymalloc() to underflow, resulting in a very large integer. If this argument is passed to directly to malloc(), this large allocation might just fail. However, because the mymalloc() function rounds up its size parameter, it can be made to wrap over the integer boundary again. This causes a small allocation that's probably followed by another read() operation with a large size argument.

Payloads

As mentioned, the remainder of an ISAKMP packet is composed of a varying number of payloads. All payloads have the same basic structure, although the data fields in the payload are interpreted differently, depending on their type. The payload structure is shown in Figure 16-2.

Figure 16-2. ISAKMP payload header structure


  • Next payload (8 bits) This field identifies the type of the next payload in the packet. If there's no payload following this one, the next payload type is set to none (0).

  • Reserved (8 bits) Not yet used.

  • Length (16 bits) This field specifies the length of the payload (including the four header bytes).

  • Data This field represents the payload data. Its meaning depends on the payload type.

The length field is, of course, significant when processing payloads. The issues in dealing with this length value are similar to those you might encounter when dealing with the ISAKMP header length, but you need to consider some unique factors. First, the length field in the payload header is 16 bits, not 32 bits. This means less chance of an integer overflow condition occurring unless 16-bit variables are used in the code. Even then, the chances of an integer overflow are reduced. To see how this works, look at the following code:

#define ROUNDUP(x) ((x + 7) & 0xFFFFFFF8) struct _payload {     unsigned char type;     unsigned short length;     unsigned char *data; }; void *mymalloc(unsigned short length) {     length = ROUNDUP(length);     return malloc(length); } struct payload *payload_read(char *srcptr, size_t srcsize,        unsigned char type, unsigned char *nexttype) {     struct _payload *payload;     if(srcsize < 4)         return NULL;     if((payload = (struct _payload *)calloc(1,                    sizeof(struct _payload))) == NULL)         return NULL;     payload->type = type;     payload->length = ntohs(*(unsigned short *)(srcptr+2));     *nexttype = *(unsigned char *)srcptr;     if((payload->data =         (unsigned char *)mymalloc(length)) == NULL){         free(payload);         return NULL;     }     memcpy(payload->data, srcptr+4, payload->length);     return payload; }


The payload_read() function is vulnerable to a 16-bit integer overflow in the mymalloc() call but only because mymalloc() takes a 16-bit argument now (as opposed to a 32-bit size_t argument in the previous example). Although possible, it's unlikely that developers code allocation routines to deal with only 16-bit values. Still, it does happen from time to time and is worth keeping an eye out for.

Similar to the ISAKMP packet length, payload lengths might underflow if they're assumed to be a certain size. Specifically, because the payload size includes the size of the payload header (four bytes), code might assume the specified payload length is at least four bytes. This assumption might lead to memory corruption, most likely a negative memcpy() error. In fact, the CheckPoint VPN-1 ISAKMP implementation had two such vulnerabilities when processing ID and certificate payloads. Listing 16-2 shows the vulnerable portion of the certificate payload-handling code. For this example, assume the payload length of the certificate payload is stored in eax and a pointer to the payload data is in esi.

Listing 16-2. Certificate Payload Integer Underflow in CheckPoint ISAKMP

.text:0042B17A           add   eax, 0FFFFFFFBh .text:0042B17D           push   eax .text:0042B17E           push   [ebp+arg_C] .text:0042B181           add    esi, 5 .text:0042B184           push   esi .text:0042B185           mov    [edi], eax .text:0042B187           call   ebx ; __imp_bcopy

As you can see, no check is done to ensure that the payload length is greater than or equal to five before five is subtracted from it. A payload length of four or less results in an integer underflow condition, and the result is passed to bcopy().

Another issue to watch out for with payload length is the relationship it shares with the original length value in the ISAKMP header. Specifically, the following must be true:

Amt of bytes already processed + current payload length <= isakmp packet length


If there's no explicit check for this relationship, data could be read out of bounds or a memory corruption related to an incorrect integer calculation could be triggered. Here's a simple example:

struct _payload {     unsigned char type;     unsigned short length;     unsigned char *data; }; int payload_process(unsigned char *packet,                     size_t length, int firsttype) {     char *srcptr;     struct _payload *payload;     struct _list *list;        int rc, type = firsttype;     list = list_alloc();     for(srcptr = packet; length; ){         payload = payload_read(srcptr, length, type, &type);         if(payload == NULL)             return 1;         list_add(list, payload);         srcptr += payload->length;         length -= payload->length;     } }


Assume the same payload_read() function from the previous examples is being used. The payload_read() function in this code simply scans through the ISAKMP packet, breaking it up into its constituent payloads, which are placed in a linked list. The payload_read() function from previous examples never verifies the length variable against the real length of the packet, so it reads data out of bounds. This little error causes additional problems during payload_process(). Because length is decremented by a value that's too large, it underflows, and length becomes a very large number. As a result, this program will probably keep trying to interpret random heap data as ISAKMP payloads until it runs off the end of the heap.

Payload Types

ISAKMP packets are composed of a series of payloads. Data in each payload is interpreted according to its type, as described in the following sections.

Security Association Payload

The security association (SA) payload is used in the initial phases of a negotiation to specify a domain of interpretation (DOI) and a situation. Figure 16-3 shows the structure of the SA payload header:

Figure 16-3. ISAKMP security association payload header


The DOI field describes how the situation data should be interpreted. Currently, there are only two DOI values you need to know: 0 and 1. The 0 value specifies a generic security association (one that can be used with any protocol), whereas a 1 value means an IPsec situation, and the negotiations are for establishing an IPsec key.

The situation field is composed of a number of encapsulated proposal payloads (explained in the next section). SA payloads don't have too many issues (apart from dealing with unknown DOIs incorrectly), but an SA payload containing embedded proposal payloads establishes a relationship between the length of the SA payload and the size of the embedded proposal payloads. These issues are discussed in the next section.

Proposal Payload

The proposal payload appears inside an SA payload and is used to communicate a series of security mechanisms the sender supports. The proposal payload header is shown in Figure 16-4.

Figure 16-4. ISAKMP proposal payload header


The first issue is the payload length field. In addition to the standard problems in parsing payloads (as discussed in the "Payloads" section), the proposal payload length field must be checked against the SA payload length containing it. Because the proposal payload field is encapsulated inside the SA, a proposal payload that's larger than its containing SA payload can cause problems, as shown in the following example:

unsigned short process_proposal(unsigned char *packet) {     unsigned char next, res;     unsigned short length;     next = *packet++;     res = *packet++;     length = get16(packet);     ... process proposal ... } int process_sa_payload(unsigned char *packet, size_t length) {     unsigned char next, res;     unsigned short payload_length, prop_length;     unsigned long doi;     if(length < 8)         return 1;     next = *packet++;     res = *packet++;     payload_length = get16(packet);     packet += 2;     doi = get32(packet);     packet += 4;     if(payload_length > length)         return 1;     for(payload_length -= 4; payload_length;         payload_length -= prop_length){         prop_length = process_proposal(packet);         if(trans_length == 0)            return -1;     }     return 0; }


This code has some obvious flaws. The process_proposal() function doesn't take a length argument! Consequently, the length field in the proposal payload isn't validated, and it could point past the end of the SA payload that's supposed to contain it. If this happened, the payload_length value in process_sa_payload() would underflow, resulting in the program evaluating the SA payload's size incorrectly. This error might lead to denial of service or exploitable memory corruption vulnerabilities.

The proposal payload contains an 8-bit SPI (Security Parameter Index) size field that indicates the length of the SPI that follows. In ISAKMP, the SPI size is usually 0 or 16 (because the SPI for ISKAMP is the initiator and responder cookies in the ISAKMP header). The SPI size in this context is interesting. Applications that parse proposals can be vulnerable to incorrectly sign-extending the SPI size or suffer from memory corruption issues caused by failure to validate the SPI size against the payload length field to ensure that the SPI size is smaller. The SPI size field appears in numerous payloads; these issues are discussed in "Notification Payload" later in this chapter.

Transform Payload

Transform payloads are encapsulated inside proposal payloads and consist of a series of SA attributes that combine to describe a transform (also referred to as a "security mechanism"). The structure of a transform payload is shown in Figure 16-5.

Figure 16-5. ISAKMP transform payload header


Like the proposal payload, problems can happen when processing the payload length if it's not validated correctly because this payload appears only encapsulated in another.

Key Exchange Payload

The key exchange payload has a simple structure shown in Figure 16-6.

Figure 16-6. ISAKMP key exchange payload header


The key exchange field contains only one more element than the generic payload: the key exchange data field, which contains information required to generate a session key. The contents of key exchange data depend on the key exchange algorithm selected earlier in the negotiations. There are no parsing complexities in dealing with the key exchange payload because keys are usually a precise size for an algorithm. However, an unusually large key might result in a buffer overflow if no checks are made to ensure that a provided key is the correct size. Take a look at this simple example:

struct _session {     int key_type;     union {         unsigned char rsa_key[RSA_KEY_MAX_SIZE];         unsigned char dsa_key[DSA_KEY_MAX_SIZE];     } key;     ... other stuff ... }; int process_key_payload(struct _session *session,                         unsigned char *packet, size_t length) {     unsigned char next, res;     unsigned short payload_length;     if(length < 4)         return 1;     next = *packet++;     res = *packet++;     payload_length = get16(packet);     packet += 2;     switch(session->key_type){         case RSA:             memcpy(session->key.rsa_key, packet,                    payload_length);             do_rsa_stuff(session);             break;         case DSA:             memcpy(session->key.dsa_key, packet,                    payload_length);             do_dsa_stuff(session);             break;         default:             return 1;     }     return 0; }


This code carelessly neglects to verify that the specified key isn't larger than RSA_KEY_MAX_SIZE or DSA_KEY_MAX_SIZE. If an attacker specified a key larger than either size, other structure members could be corrupted as well as the program heap.

Identification Payload

The identification payload, shown in Figure 16-7, uniquely identifies the entity wanting to authenticate itself to the other party in the communication.

Figure 16-7. ISAKMP identification payload header


Identification can be expressed in numerous ways. The identification data in this payload has different meanings depending on the specified DOI and ID type. In IPsec DOI, the following forms of identification are possible:

  • IP address (IPv4 or IPv6)

  • Fully qualified domain name (FQDN)

  • User FQDN

  • IP subnet (IPv4 or IPv6)

  • IP address range (IPv4 or IPv6)

  • DER-encoded X.500 distinguished name (DN)

  • DER-encoded X.500 general name (GN)

  • Key ID

Because there's a range of choices for identification, parsing this payload is usually involved and has more opportunities for things to go wrong. Most of the ID representations are quite simple, but a few issues can occur. First, making assumptions about fixed-length fields might lead to simple buffer overflows. In the following example, an IP address is being used for identification:

int parse_identification_payload(unsigned char *packet,                                  size_t length) {     unsigned short payload_length, port;     unsigned char next, res;     unsigned char type, id;     unsigned char ip_address[4];     if(length < IDENT_MINSIZE)         return 1;     next = *packet++;     res = *packet++;     payload_length = get16(packet);     packet += 2;     if(payload_length < IDENT_MINSIZE)         return 1;     type = *packet++;     id = *packet++;     port = get16(packet);     packet += 2;     payload_length -= IDENT_MINSIZE;     switch(type){         case IPV4_ADDR:             if(payload_length < 4)                 return 1;             memcpy(ip_address, packet, payload_length);             break;     ... other stuff ... }


This code has a simple buffer overflow because it's expecting the specified IP address to be only four bytes, but there are no length checks to enforce this size.

A few other fields also involve parsing strings into constituent elements, primarily the FQDN method (takes hostnames, such as my.host.com) and user FQDNs (takes names and hosts in the form username@my.host.com). The material from Chapter 7 is particularly relevant; simple buffer overflows, pointer arithmetic errors, off-by-one errors, and incrementing a pointer past a NUL byte are a few things that can happen when trying to interpret these fields.

DER-encoded mechanisms, a binary encoding format discussed in "Distinguished Encoding Rules" later in this chapter, have had a host of problems recently, mostly integer-related issues.

Certificate Payload

As the name suggests, the certificate payload contains certificate data used to authenticate one participant in the connection setup to another (usually client to server, but it works both ways). Figure 16-8 shows the certificate payload header.

Figure 16-8. ISAKMP certificate payload header


The certificate-encoding byte specifies how to interpret the certificate data trailing it. RFC 2408 defines these encodings for a certificate:

  • None

  • PKCS#7 wrapped X.509 certificate

  • PGP certificate

  • X.509 certificatesignature

  • X.509 certificatekey exchange

  • Kerberos tokens

  • Certificate Revocation List (CRL)

  • Authority Revocation List (ARL)

  • SPKI certificate

  • X.509 certificateattribute

What's interesting about the certificate payload is that a certificate can be supplied in a multitude of formats, provided the participant supports them. The variety of formats makes it possible to use a series of code paths (PGP parsing, Kerberos parsing, PKCS parsing, and so on) that need to be flawless; otherwise, the ISAKMP application can be exploited by remote unauthenticated clients.

Certificate Request Payload

The certificate request payload is used by either participant in a connection to request a certificate of its peer. It has an identical structure to the certificate payload, except it has certificate authority data instead of certificate data. Certificate authority data can be encoded in the same ways certificate data can.

Hash Payload

The hash payload contains a hash of some part of the ISAKMP message and is used for authentication or message integrity purposes (to prevent third parties from changing data en route). The hash payload header is shown in Figure 16-9.

Figure 16-9. ISAKMP hash payload header


The size of the hash data message depends primarily on the hashing algorithm used in the ISAKMP session, which is established earlier in the negotiation by using the SA payload data. As you can see, there are no extraneous length fields in the hash payload or decoding steps, so there are no real complications in parsing a hash payload. One thing to look out for, however, might be generic buffer overflows resulting from the program failing to verify the hash payload's size. This failure could happen when hashes are expected to be a particular size and memory for holding the hash data has been preallocated. Therefore, if an abnormally large hash payload is supplied, a generic buffer overflow would occur.

Hash data is used to verify message integrity by using message data as input to a hashing function, which calculates a value and stores it in the hash payload. When the receiving party applies the same algorithm to the data, any modifications result in inconsistencies with the hash payload data.

Signature Payload

The signature payload is much like the hash payload, except it contains data created by the selected digital signature algorithm (if signatures are in use) rather than data the hash function created. The signature payload is shown in Figure 16-10.

Figure 16-10. ISAKMP signature payload header


Like the hash payload, signature payloads have no additional complications, except they might be expected to be a specific size. If so, abnormally large messages might not be handled correctly.

Nonce Payload

The nonce payload contains random data used for generating hashes with certain protocols. It's used to help guarantee uniqueness of a key exchange and prevent against man-in-the-middle attacks. The nonce payload is shown in Figure 16-11.

Figure 16-11. ISAKMP nonce payload header


Again, the nonce payload has no additional complications other than general payload-parsing problems. As with hash and signature payloads, nonce payloads that are unusually large might cause problems if no length validation is done on the payload.

Notification Payload

The notification payload conveys information about an error condition that has occurred during protocol exchange. It does this by transmitting a type code that represents a predefined error condition encountered during processing. Figure 16-12 shows the notification payload.

Figure 16-12. ISAKMP notification payload header


This payload has a slightly more complex structure than the previous payloads. It's obviously required to be a minimum size (12 bytes, plus the size of the SPI and notification data). Failure to ensure that the payload is at least this size might lead to vulnerabilities similar to those in general payload types of a size smaller than four. An example of an invalid notification payload parser is shown:

int parse_notification_payload(unsigned char *data, size_t length) {     unsigned long doi;     unsigned short mtype;     unsigned char spi_size, protocol_id;     doi = get_32(data);     protocol_id = get_8(data+4);     spi_size = get_8(data+5);     mtype = get_16(data+6);     length -= 8;     data += 8;     ... get SPI and notification data ... }


You can see a vulnerability with the way length is subtracted. No check is made to ensure that length is at least eight bytes to start, so an unexpected small notification payload results in an integer underflow that likely leads to memory corruption. Although this bug is much the same as the one in general payloads with a length less than four, this error of small notification payloads is slightly more likely to occur in code you audit. The reason is that ISAKMP implementations commonly have generic payload parsers that sort packets into structures, and these parsers tend to be more robust than individual payload parsers because they have been through more rigorous testing.

Note

In a review of several popular implementations at one stage, Neel Mehta and Mark Dowd found that generic packet parsers seem to be safe in general, but specific payload handling was often performed by much less robust code.


Another element of interest in the notification payload is the SPI size parameter. RFC 2408 describes this field as follows:

SPI Size (1 octet) - Length in octets of the SPI as defined by the Protocol-ID. In the case of ISAKMP, the Initiator and Responder cookie pair from the ISAKMP Header is the ISAKMP SPI; therefore, the SPI Size is irrelevant and MAY be from zero (0) to sixteen (16). If the SPI Size is non-zero, the content of the SPI field MUST be ignored. The Domain of Interpretation (DOI) will dictate the SPI Size for other protocols.

As stated, the SPI size in an ISAKMP packet should be a value between 0 and 16 (inclusive). Whenever a field in a protocol can represent more values than are legal, there's the potential for causing problems if developers neglect to check for illegal values correctly. Also, because SPI size is a single-byte field, remember there's the possibility of sign-extension vulnerabilities for illegal values, as in the following example:

int parse_notification_payload(char *data, size_t length) {     long doi;     unsigned short mtype, payload_size, notification_size;     char spi_size, protocol_id;     payload_size = ntohs(*(data+2));     spi_size = *(data+6);     if(spi_size > payload_size)         return 1;     notification_size = payload_size  spi_size;     ... do more stuff ... }


A couple of typing issues make this code vulnerable to attack. First, there's a sign-extension issue in the comparison of spi_size and payload_size. Because spi_size is a signed character data type, when the integer promotion occurs, spi_size is sign-extended. So if the top bit is set, all bits in the most significant three bytes are also set (making spi_size a negative 32-bit integer). Usually, when comparing against an unsigned value, spi_size is cast to unsigned as well, but because payload_size is an unsigned short value (which is only 16 bits), it's also promoted to a signed 32-bit integer; so this comparison is a signed comparison. Therefore, a negative spi_size causes notification_size to contain an incorrect value that's larger than payload_size. (payload_size with a negative integer subtracted from it is just like an addition.)

Second, you might have noticed that SPI is directly related to the payload size. So failure to ensure that it's less than the payload size also results in an integer underflow condition (or memory corruption) that might allow reading arbitrary data from the process memory.

Delete Payload

The delete payload is used to inform a responder that the initiator has invalidated certain SPIs. The structure of a delete payload is shown in Figure 16-13.

Figure 16-13. ISAKMP delete payload header


Vulnerabilities from processing a delete payload might be similar to those from processing a notification payload because delete payloads also have a predefined minimum size requirement and contain the SPI size. The SPI size has a slightly different meaning in the delete payload, however. The delete payload supplies multiple SPIs, each one the size indicated by the SPI size. The SPI count parameter indicates how many SPIs are included in this payload, so the total number of bytes of SPI data in a delete payload is the multiplication of these two fields. This multiplication might introduce two additional complications; the first is sign extensions of the SPI size or SPI count because they result in a multiplication integer wrap, as shown in the following code:

int process_delete(unsigned char *data, size_t length) {     short spi_count;     char spi_size, *spi_data;     int i;     ... read values from data ...     spi_data = (char *)calloc(spi_size*spi_count, sizeof(char));     data += DELETE_PAYLOAD_SIZE;     for(i = 0; i < spi_count; i++){         if(read_spi(data+(i*spi_size)) < 0){             free(spi_data);             return 1;         }     }     ... more stuff ... }


The allocation of spi_data is going to be an incorrect size if spi_size or spi_count is negative. Both values are sign-extended, so multiplication results in an incorrect size allocation.

The second complication caused by multiplying two fields is the possibility of 16-bit integer wraps if a program uses 16-bit size variables in certain areas, as shown in the following example:

int process_delete(unsigned char *data, size_t length) {     unsigned short spi_count, total_size;     unsigned char spi_size, *spi_data;     int i;     ... read values from data ...     total_size = spi_size * spi_count;     spi_data = (char *)calloc(total_size, sizeof(char));     data += DELETE_PAYLOAD_SIZE;     for(i = 0; i < spi_count; i++){         if(read_spi(data+(i*spi_size)) < 0){             free(spi_data);             return 1;         }     }     ... more stuff ... }


Disaster! Because total_size is only 16 bits in this function, causing an integer wrap when multiplying spi_count and spi_size is possible. This error results in a very small allocation with a fairly large amount of data read into it.

Vendor ID Payload

The vendor ID payload simply contains data to uniquely identify vendors. The content of a vendor ID payload is supposed to be a hash of the vendor and the software version the sender uses, but it can be anything that uniquely identifies the vendor. Clients and servers typically send it during the initial phase of negotiation, but it's not a required payload. The only problem when dealing with a vendor ID is if a version parser interprets the data in some manner or the vendor ID is blindly copied into a buffer without first checking that it fits in that buffer, as in this example:

#define MYVERSION    "MyISAKMPVersion" int parse_version(struct _payload *vendor) {     char buffer[1024];     if(vendor->length != sizeof(MYVERSION) || memcmp(vendor->data, MYVERSION, sizeof(MYVERSION)){         sprintf(buffer, "warning, unknown client version: %s\n",                 vendor->data);         log(buffer);         return 0;      }      return 1; }


Obviously, a straightforward buffer overflow exists if a vendor ID larger than 1,024 bytes is supplied to the parse_version() function.

Encryption Vulnerabilities

ISAKMP is now a widely accepted and used standard, and finding cryptography-related problems in applications that implement public protocols is much harder. The reason is that standards committees usually have a protocol scrutinized before accepting it, and then spell out to application developers how to implement cryptographic components. Still, vulnerabilities occur from time to time in cryptography implementations of protocols, so you need to be aware of potential attack vectors that might allow decrypting communications, along with other issues. Over time, some generic attacks against ISAKMP when operating in various modes (especially aggressive mode) have taken place. In late 1999, John Pliam published an interesting paper detailing several attacks related to weak preshared secrets (www.ima.umn.edu/~pliam/xauth/). In 2003, Michael Thumann and Enno Rey demonstrated an attack against ISAKMP in aggressive mode that allowed them to discover preshared keys (PSKs). This presentation is available at www.ernw.de/download/pskattack.pdf. It's entirely possible that implementations are still vulnerable to these attacks if they support aggressive mode and make use of PSKs. Apart from finding new and exciting ways to break ISAKMP's cryptography model, the only other thing left to do is ensure that the implementation you're examining conforms to the specification exactly. In most cases, it does; otherwise, it wouldn't work with other VPN clients.




The Art of Software Security Assessment. Identifying and Preventing Software Vulnerabilities
The Art of Software Security Assessment: Identifying and Preventing Software Vulnerabilities
ISBN: 0321444426
EAN: 2147483647
Year: 2004
Pages: 194

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net