Lucene search

K
talosTalos IntelligenceTALOS-2020-1029
HistoryAug 26, 2020 - 12:00 a.m.

atftpd daemon Denial of Service Vulnerability

2020-08-2600:00:00
Talos Intelligence
www.talosintelligence.com
18
atftpd
denial of service
vulnerability
atftp 0.7.git20120829-3.1+b1
rrq-multicast
assert() call
dos

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

CVSS3

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

EPSS

0.002

Percentile

56.8%

Summary

An exploitable denial of service vulnerability exists in the atftpd daemon functionality of atftp 0.7.git20120829-3.1+b1. A specially crafted sequence of RRQ-Multicast requests trigger an assert() call resulting in denial-of-service. An attacker can send a sequence of malicious packets to trigger this vulnerability.

Tested Versions

atftp 0.7.git20120829-3.1+b1

Product URLs

<https://github.com/seveas/atftp&gt;

CVSSv3 Score

7.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

CWE

CWE-617 - Reachable Assertion

Details

atftp is an open source TFTP server implementation. The โ€˜aโ€™ stands for โ€œadvancedโ€, because itโ€™s intended to be fully compliant with all related RFCs including RFC1350, RFC2090, RFC2347, RFC2348 andRFC2349.

A remote attacker may send a sequence of crafted RRQ-Multicast requests to the atftpd, triggering an assert() call in the atftpd code which results in abort of atftpd.

The vulnerablility can be traced down to the function: sockaddr_print_addr within tftp_def.c. where an unexpected sockaddr_storage *ss data with โ€œss_family=AF_UNSPECโ€ reaches the assert() call in the โ€˜elseโ€™ branch (line #192).

The vulnerable code snippet (tftpd_file.c)

183 char *
184 sockaddr_print_addr(const struct sockaddr_storage *ss, char *buf, size_t len)
185 {
186      const void *addr;
187      if (ss-&gt;ss_family == AF_INET)
188           addr = &((const struct sockaddr_in *)ss)-&gt;sin_addr;
189      else if (ss-&gt;ss_family == AF_INET6)
190           addr = &((const struct sockaddr_in6 *)ss)-&gt;sin6_addr;
191      else
192           assert(!"sockaddr_print: unsupported address family");
193      return (char *)inet_ntop(ss-&gt;ss_family, addr, buf, len);
194 }

An instance of โ€œsa_family=AF_UNSPECโ€ is also seen in the strace output below,

* strace -f -p &lt;pid&gt;

[pid 10723] &lt;... select resumed&gt; )      = 0 (Timeout)
[pid 10723] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3545, ...}) = 0
[pid 10723] uname({sysname="Linux", nodename="kali", ...}) = 0
[pid 10723] getpid()                    = 10654
[pid 10723] write(2, "Nov 13 17:25:02 kali atftpd[1065"..., 73) = 73
[pid 10723] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3545, ...}) = 0
[pid 10723] uname({sysname="Linux", nodename="kali", ...}) = 0
[pid 10723] getpid()                    = 10654
[pid 10723] write(2, "Nov 13 17:25:02 kali atftpd[1065"..., 96) = 96
[pid 10723] sendto(1, "\0\6multicast\000239.239.239.0,1758,1"..., 33, 0, {sa_family=AF_UNSPEC, sa_data="\340\222\300\250X\201\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 128) = 33
[pid 10723] select(1024, [1], NULL, NULL, {tv_sec=5, tv_usec=0} &lt;unfinished ...&gt;
[pid 10726] &lt;... select resumed&gt; )      = 0 (Timeout)
[pid 10726] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3545, ...}) = 0
[pid 10726] uname({sysname="Linux", nodename="kali", ...}) = 0
[pid 10726] getpid()                    = 10654
[pid 10726] write(2, "Nov 13 17:25:04 kali atftpd[1065"..., 73) = 73
[pid 10726] lseek(5, 0, SEEK_SET)       = 0
[pid 10726] read(5, "Hello World! Super Cool!\n", 4096) = 25
[pid 10726] read(5, "", 4096)           = 0
[pid 10726] sendto(4, "\0\3\0\1Hello World! Super Cool!\n", 29, 0, {sa_family=AF_INET, sin_port=htons(1758), sin_addr=inet_addr("239.239.239.1")}, 128) = 29
[pid 10726] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3545, ...}) = 0
[pid 10726] uname({sysname="Linux", nodename="kali", ...}) = 0
[pid 10726] getpid()                    = 10654
[pid 10726] write(2, "Nov 13 17:25:04 kali atftpd[1065"..., 82) = 82
[pid 10726] select(1024, [4], NULL, NULL, {tv_sec=5, tv_usec=0} &lt;unfinished ...&gt;
[pid 10723] &lt;... select resumed&gt; )      = 0 (Timeout)
[pid 10723] write(2, "atftpd: tftp_def.c:192: sockaddr"..., 111) = 111
[pid 10723] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa0e4dd9000
[pid 10723] rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
[pid 10723] rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
[pid 10723] getpid()                    = 10654
[pid 10723] gettid()                    = 10723
[pid 10723] tgkill(10654, 10723, SIGABRT) = 0
[pid 10723] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid 10723] --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=10654, si_uid=65534} ---
[pid 10726] &lt;... select resumed&gt; &lt;unfinished ...&gt;) = ?
[pid 10654] &lt;... select resumed&gt; &lt;unfinished ...&gt;) = ?
[pid 10726] +++ killed by SIGABRT +++
[pid 10723] +++ killed by SIGABRT +++
+++ killed by SIGABRT +++

Crash Information

Below is a backtrace when atftpd aborted under fuzzing test,

atftpd: tftp_def.c:192: sockaddr_print_addr: Assertion `!"sockaddr_print: unsupported address family"' failed.

Thread 78 "atftpd" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff6d09700 (LWP 10623)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7d7b535 in __GI_abort () at abort.c:79
#2  0x00007ffff7d7b40f in __assert_fail_base (fmt=0x7ffff7edd710 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=0x5555555636f0 "!\"sockaddr_print: unsupported address family\"", file=0x555555563608 "tftp_def.c", line=192, function=&lt;optimized out&gt;) at assert.c:92
#3  0x00007ffff7d88b92 in __GI___assert_fail (assertion=assertion@entry=0x5555555636f0 "!\"sockaddr_print: unsupported address family\"",
file=file@entry=0x555555563608 "tftp_def.c", line=line@entry=192, function=function@entry=0x5555555638e0 &lt;__PRETTY_FUNCTION__.4953&gt; "sockaddr_print_addr") at assert.c:101
#4  0x000055555555b2b7 in sockaddr_print_addr (ss=&lt;optimized out&gt;, buf=buf@entry=0x7ffff6d08a80 "", len=len@entry=46) at tftp_def.c:192
#5  0x000055555555d7f6 in tftpd_send_file (data=0x555555571930) at tftpd_file.c:784
#6  0x000055555555865d in tftpd_receive_request (arg=0x555555571930) at tftpd.c:751
#7  0x00007ffff7f92fb7 in start_thread (arg=&lt;optimized out&gt;) at pthread_create.c:486
#8  0x00007ffff7e502ef in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Timeline

2020-04-16 - Vendor Disclosure
2020-05-16 - 30 day follow up

2020-06-02 - 45+ day follow up
2020-06-30 - 60+ day follow up
2020-08-26 - Public Release

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

CVSS3

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

EPSS

0.002

Percentile

56.8%