[riot-notifications] [RIOT-OS/RIOT] gnrc_sock_dns: Security issues (including remote code execution) (#10739)

nmeum notifications at github.com
Wed Jan 9 17:26:30 CET 2019


## Description

`gnrc_sock_dns` doesn't perform sufficient sanity checks on the DNS
response it receives from the configured DNS server.

Here is a non-exhaustive list of issues:

1. The `QDCOUNT` contained in the DNS response is not verified. This
   causes an out-of-bounds buffer access in the `_skip_hostname` function if
   `QDCOUNT` is set to a value larger than the buf `len` supplied to
   `_parse_dns_reply`.
2. The `RDLENGTH` bounds-check for the answer section is incorrect for
   two reasons: (a) `buf + len` is the first invalid address, so `>=` needs
   to be used as a comparison operator (b) The result of `bufpos + addrlen`
   might cause a pointer overflow (especially due to the fact that
   `addrlen` is attacker controlled). If pointer overflows wrap around
   (undefined behaviour) this would allow an attacker to circumvent the
   bounds-check and exposes a buffer overflow vulnerability since the
   attacker controlled `addrlen` is later used in `memcpy(addr_out, bufpos,
   addrlen)`, potentially allowing a code execution.
3. The size of the caller allocated buffer `addr_out` is not passed to
   the `_parse_dns_reply` function at all. This makes checking whether the
   attacker controlled address actually fits in the buffer impossible and
   allows an easy buffer overflow and potential code execution.

All of these are especially critical due to the fact that DNS responses
can easily be spoofed, especially since all spoofing protection mechanisms
of DNS were not implemented. So an attacker doesn't even need to control the
configured DNS server in order to exploit this.

## Steps to reproduce the issue

1. Flash an unmodified version of `tests/gnrc_sock_dns` to your RIOT node.
2. Adjust your radvd.conf on your border router and add a RDNSS definition.

### Causing a crash

Constantly send a DNS response with an excessive qdcount on the computer
associated with the IP-Address you configured in the radvd RDNSS
definition. For example

```shell
while sleep 1; do
    echo AACEAwkmAAAAAAAAKioqKioqKioqKioqKioqKioqKio= | \
        base64 -d | \
        socat fd:0 udp6-sendto:'[address-of-riot-node]':49152,sourceport=53
done
```

### Remote code execution

This is (obviously) highly platform specific. We did
this with `BOARD=pba-d-01-kw2x`. We wrote some ARM assembler code which
toggles the LED and stored the machine code for it in the `RDATA` field
of the answer section in the DNS response, thereby overflowing the
`addr` buffer in the `main` stack frame. Our payload exactly fits into
the stack frame of the main function and overwrites the return address
of that function, jumping to the `addr` buffer and executing our
payload.

Exploit written by @PyroPeter. See: https://github.com/beduino-project/exploit-riot-dns
We also working on documenting how to adapt the payload for slightly different binaries (depending on toolchain, board, … the exploit might not work because of hardcoded memory addresses).  

## Versions

RIOT-Version: 5e03f58746633404393413eb674c938b5e31c144
Build environment:

```
Operating System Environment
-----------------------------
       Operating System: "Arch Linux" 
                 Kernel: Linux 4.19.4-arch1-1-ARCH x86_64 unknown

Installed compiler toolchains
-----------------------------
             native gcc: gcc (GCC) 8.2.1 20181127
      arm-none-eabi-gcc: arm-none-eabi-gcc (Arch Repository) 8.2.0
                avr-gcc: avr-gcc (GCC) 8.2.0
       mips-mti-elf-gcc: missing
             msp430-gcc: missing
   riscv-none-embed-gcc: missing
                  clang: clang version 7.0.0 (tags/RELEASE_700/final)

Installed compiler libs
-----------------------
   arm-none-eabi-newlib: "3.0.0"
    mips-mti-elf-newlib: missing
riscv-none-embed-newlib: missing
               avr-libc: "2.0.0" ("20150208")

Installed development tools
---------------------------
                  cmake: cmake version 3.13.1
               cppcheck: missing
                doxygen: 1.8.14
                 flake8: missing
                    git: git version 2.19.2
                   make: GNU Make 4.2.1
                openocd: Open On-Chip Debugger 0.10.0+dev-00436-g0fdf48f1 (2018-06-18-18:19)
                 python: Python 3.7.1
                python2: Python 2.7.15
                python3: Python 3.7.1
             coccinelle: missing
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/issues/10739
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190109/5dfd9be5/attachment.html>


More information about the notifications mailing list