[riot-notifications] [RIOT-OS/RIOT] gnrc_sock_dns: Security issues (including remote code execution) (#10739)
notifications at github.com
Wed Jan 9 17:26:30 CET 2019
`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
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
while sleep 1; do
echo AACEAwkmAAAAAAAAKioqKioqKioqKioqKioqKioqKio= | \
base64 -d | \
socat fd:0 udp6-sendto:'[address-of-riot-node]':49152,sourceport=53
### 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
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).
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
clang: clang version 7.0.0 (tags/RELEASE_700/final)
Installed compiler libs
avr-libc: "2.0.0" ("20150208")
Installed development tools
cmake: cmake version 3.13.1
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
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the notifications