SmartDNS Stack Buffer Overflow in _dns_encode_domain

Apr 21, 2023

CVE Number

CVE-2023-31470

Credits

Huascar Tejeda of Pentraze Cybersecurity

CVSS

9.8 (Critical) - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Details

A stack buffer overflow vulnerability exists in the _dns_encode_domain function in the dns.c file, which can be triggered by crafting a DNS request that causes the program to write outside the bounds of the packet_buff variable.

Suggested Fix:

I added the following code to the beginning of the function, which prevents the overflow:

if (_dns_left_len(context) <= 0) {
    return -1;
}

ASAN

=================================================================
==2457317==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffffdd8e at pc 0x000000305a31 bp 0x7fffffffaf00 sp 0x7fffffffaef8
WRITE of size 1 at 0x7fffffffdd8e thread T0
    #0 0x305a30 in _dns_encode_domain /opt/smartdns/src/dns.c:298:11
    #1 0x30bdea in _dns_add_qr_head /opt/smartdns/src/dns.c:461:12
    #2 0x30bdea in _dns_add_rr_head /opt/smartdns/src/dns.c:509:8
    #3 0x30bdea in dns_add_rr_nested_start /opt/smartdns/src/dns.c:568:8
    #4 0x30bdea in dns_add_HTTPS_start /opt/smartdns/src/dns.c:1074:20
    #5 0x30bdea in _dns_decode_HTTPS /opt/smartdns/src/dns.c:2007:2
    #6 0x30bdea in _dns_decode_an /opt/smartdns/src/dns.c:2192:9
    #7 0x30954d in _dns_decode_body /opt/smartdns/src/dns.c:2329:9
    #8 0x30954d in dns_decode /opt/smartdns/src/dns.c:2469:8
    #9 0x31750d in main /opt/smartdns/src/smartdns.c:49:13
    #10 0x7ffff7c29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #11 0x7ffff7c29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #12 0x2558d4 in _start (/opt/smartdns/src/smartdns+0x2558d4)

Address 0x7fffffffdd8e is located in stack of thread T0 at offset 6190 in frame
    #0 0x316cdf in main /opt/smartdns/src/smartdns.c

  This frame has 5 object(s):
    [32, 6176) 'packet_buff' (line 45) <== Memory access at offset 6190 overflows this variable
    [6432, 6436) 'rr_count' (line 53)
    [6448, 6452) 'qtype' (line 54)
    [6464, 6468) 'qclass' (line 55)
    [6480, 6736) 'domain' (line 56)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /opt/smartdns/src/dns.c:298:11 in _dns_encode_domain
Shadow bytes around the buggy address:
  0x10007fff7b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007fff7bb0: f2[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
  0x10007fff7bc0: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
  0x10007fff7bd0: f8 f2 f8 f2 f8 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x10007fff7be0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x10007fff7bf0: f8 f8 f8 f8 f8 f8 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3
  0x10007fff7c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2457317==ABORTING

GDB Backtrace

#0  __pthread_kill_implementation (no_tid=0x0, signo=0x6, threadid=0x7ffff7ee1000) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=0x6, threadid=0x7ffff7ee1000) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=0x7ffff7ee1000, signo=signo@entry=0x6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7642476 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff76287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff76896f6 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff77db943 "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff773676a in __GI___fortify_fail (msg=msg@entry=0x7ffff77db92b "stack smashing detected") at ./debug/fortify_fail.c:26
#7  0x00007ffff7736736 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8  0x0000555555576b19 in _dns_server_recv (conn=conn@entry=0x55555575a3e0, inpacket=inpacket@entry=0x7fffffff3500 "0000", inpacket_len=<optimized out>, local=local@entry=0x7fffffff2870, local_len=0x10, from=from@entry=0x7fffffff27f0, from_len=0x1c) at dns_server.c:5308
#9  0x0000555555577dfe in _dns_server_process_udp_one (event=<optimized out>, now=<optimized out>, udpconn=<optimized out>) at dns_server.c:5441
#10 _dns_server_process_udp (event=<optimized out>, now=<optimized out>, udpconn=<optimized out>) at dns_server.c:5448
#11 _dns_server_process (now=0x1504f191, event=0x7fffffff28f0, conn=<optimized out>) at dns_server.c:6056
#12 dns_server_run () at dns_server.c:6429
#13 0x000055555555d837 in _smartdns_run () at smartdns.c:536
#14 main (argc=<optimized out>, argv=<optimized out>) at smartdns.c:776

¿Ver el sitio en español?