Multi-label DNS Heap Overflow Vulnerability #7

Closed
opened 2020-07-18 22:39:17 +00:00 by df · 1 comment
Owner

Former user (2017-11-01) reporter

Summary

An exploitable heap overflow vulnerability exists in the tinysvcmdns library version 2016-07-18. A specially crafted packet can make the library overwrite an arbitrary amount of data on the heap with attacker controlled values. An attacker needs send a dns packet to trigger this vulnerability.

Details

Irrelevant details omitted; see TALOS published advisory for full details.

The nlabel_to_str function in mdns.c is used to turn a series of name labels into a dotted representation of the domain name. For instance, when trying to wget abcd.efgh.cachemonet.com, the dns request will be seperated into parts, as there is more than one suffix. The previous domain would look like this:

0000 04 61 62 63 64 04 65 66 67 68 0a 63 61 63 68 65 .abcd.efgh.cache
0010 6d 6f 6e 65 74 03 63 6f 6d 00 monet.com.

Where by each portion of the domain is seperated by a 1-byte field describing the length of the next segment (\x04 => abcd, etc).

Normally, multi-label DNS names have some restrictions, as set forth by the RFC.

3.1. Name space definitions

Domain names in messages are expressed in terms of a sequence of labels.
Each label is represented as a one octet length field followed by that
number of octets.  Since every domain name ends with the null label of
the root, a domain name is terminated by a length byte of zero.  The
high order two bits of every length octet must be zero, and the
remaining six bits of the length field limit the label to 63 octets or
less.

To simplify implementations, the total length of a domain name (i.e.,
label octets and label length octets) is restricted to 255 octets or
less.

However, the nlabel_to_str function does not do any sort of filtering on this input:

// returns a human-readable name label in dotted form
char *nlabel_to_str(const uint8_t *name) {
    char *label, *labelp;
const uint8_t *p;

    assert(name != NULL);
    label = labelp = malloc(256);   //[1]

    for (p = name; *p; p++) { //[2]
        strncpy(labelp, (char *) p + 1, *p);
        labelp += *p;
        *labelp = '.';
        labelp++;

        p += *p;
    }
   *labelp = '\0';
   return label;
}

We can see there is a fixed heap allocation of size 256 at [1], however, there's no limitation to how many bytes can be copied. As long as the end of a given label is not “\x00” [2], the strncpy's just keep flowing, allowing for an arbitrary write on the heap by anyone with network connectivity to the device.
Credit

Discovered Lilith (>^.^)> Wyatt and Claudio Bozzato of Cisco Talos. http://talosintelligence.com/vulnerability-reports/

TALOS-2017-0439
CVE-2017-12087

# Former user (2017-11-01) reporter ## Summary An exploitable heap overflow vulnerability exists in the tinysvcmdns library version 2016-07-18. A specially crafted packet can make the library overwrite an arbitrary amount of data on the heap with attacker controlled values. An attacker needs send a dns packet to trigger this vulnerability. ## Details Irrelevant details omitted; see TALOS published advisory for full details. The nlabel_to_str function in mdns.c is used to turn a series of name labels into a dotted representation of the domain name. For instance, when trying to wget abcd.efgh.cachemonet.com, the dns request will be seperated into parts, as there is more than one suffix. The previous domain would look like this: 0000 04 61 62 63 64 04 65 66 67 68 0a 63 61 63 68 65 .abcd.efgh.cache 0010 6d 6f 6e 65 74 03 63 6f 6d 00 monet.com. Where by each portion of the domain is seperated by a 1-byte field describing the length of the next segment (\x04 => abcd, etc). Normally, multi-label DNS names have some restrictions, as set forth by the RFC. ``` 3.1. Name space definitions Domain names in messages are expressed in terms of a sequence of labels. Each label is represented as a one octet length field followed by that number of octets. Since every domain name ends with the null label of the root, a domain name is terminated by a length byte of zero. The high order two bits of every length octet must be zero, and the remaining six bits of the length field limit the label to 63 octets or less. To simplify implementations, the total length of a domain name (i.e., label octets and label length octets) is restricted to 255 octets or less. ``` However, the nlabel_to_str function does not do any sort of filtering on this input: ``` // returns a human-readable name label in dotted form char *nlabel_to_str(const uint8_t *name) { char *label, *labelp; const uint8_t *p; assert(name != NULL); label = labelp = malloc(256); //[1] for (p = name; *p; p++) { //[2] strncpy(labelp, (char *) p + 1, *p); labelp += *p; *labelp = '.'; labelp++; p += *p; } *labelp = '\0'; return label; } ``` We can see there is a fixed heap allocation of size 256 at [1], however, there's no limitation to how many bytes can be copied. As long as the end of a given label is not “\x00” [2], the strncpy's just keep flowing, allowing for an arbitrary write on the heap by anyone with network connectivity to the device. Credit Discovered Lilith (>^.^)> Wyatt and Claudio Bozzato of Cisco Talos. http://talosintelligence.com/vulnerability-reports/ TALOS-2017-0439 CVE-2017-12087
Author
Owner

geekman (2018-01-16) repo owner

changed title to Multi-label DNS Heap Overflow Vulnerability

changed status to resolved

Fixed in 48c73fb and 29ea1b9.

# geekman (2018-01-16) repo owner changed title to Multi-label DNS Heap Overflow Vulnerability changed status to resolved Fixed in 48c73fb and 29ea1b9.
df closed this issue 2020-07-18 22:41:04 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: df/zeroconf#7