Skip to content

Heap out-of-bounds write in uams_pam.c

High
rdmark published GHSA-8r68-857c-4rqc Jun 29, 2024

Package

netatalk

Affected versions

< 3.2.1

Patched versions

3.2.1

Description

Impact

The latest version of Netatalk (v3.2.0) contains a security vulnerability. This vulnerability arises due to a lack of validation for the length field after parsing user-provided data, leading to an out-of-bounds heap write of one byte (\0). Under specific configurations, this can result in an out-of-bounds write to the metadata of the next heap block, allowing an attacker to execute code in the root context.

Patches

Users should upgrade their systems to Netatalk 3.2.1 as soon as possible.

Workarounds

Disable the uams_clrtxt.so or uams_pam.so authentication module in your afp.conf file.

References

https://netatalk.io/support

Original bug report

The body of the issue ticket filed by @flysoar follows below.

Describe the bug
The latest version of Netatalk (v3.2.0) contains a security vulnerability. This vulnerability arises due to a lack of validation for the length field after parsing user-provided data, leading to an out-of-bounds heap write of one byte (\0). Under specific configurations, this can result in an out-of-bounds write to the metadata of the next heap block, allowing an attacker to execute code in the root context.

The vulnerability is located in the FPLoginExt operation of Netatalk, in the lgoin function found in /etc/uams/uams_pam.c.
uams_pam.c
ibuf[ PASSWDLEN ] = '\0';

To Reproduce
Compile the Netatalk with ASAN enabled.
The afp.conf file content is thefolloing.

[ Global ]
uam list = uams_guest.so,uams_clrtxt.so,uams_pam.so
save password = no
set password = yes
unix charset = UTF8
use sendfile = yes
zeroconf = no
guest account = nobody
server quantum = 33000

 [ Public ] 
path =/tmp/afp_tmp/Public
ea = auto 
convert appledouble = no 
stat vol = no 
file perm = 777 
directory perm = 777
veto files = '/Network Trash Folder/.!@#$recycle/.systemfile/lost+found/Nas_Prog/.!@$mmc/'
rwlist = "admin","nobody","@allaccount"
valid users = "admin","nobody","@allaccount"
invalid users = 

 [ test ] 
path = /tmp/afp_tmp/test
ea = auto 
convert appledouble = no 
stat vol = no 
file perm = 777 
directory perm = 777
veto files = '/Network Trash Folder/.!@#$recycle/.systemfile/lost+found/Nas_Prog/.!@$mmc/'
rwlist = "admin","nobody","@allaccount"
valid users = "admin","nobody","@allaccount"
invalid users = 

Expected behavior
Under specific configurations, this can result in an out-of-bounds write to the metadata of the next heap block, allowing an attacker to execute code in the root context.

Environment

  • Server OS: Ubuntu2204
  • Netatalk 3.2.0

Additional context

$rax   : 0x000062d00001042c  →  0x0000000000000000
$rbx   : 0x00005555556156cb  →  0x0000000000000000
$rcx   : 0x0               
$rdx   : 0xff              
$rsp   : 0x00007fffffffe000  →  0x0000000000000000
$rbp   : 0x000062d00000041c  →  0xff03414141030003
$rsi   : 0x4               
$rdi   : 0x00005555556154c0  →  0x0000603000000040  →  "/netatalk/fploginext2/afp.conf"
$rip   : 0x00007ffff430e623  →  <pwd_login+74> mov BYTE PTR [r12+0x8], 0x0
$r8    : 0x000062d000010424  →  0x0000000000000000
$r9    : 0x00000000ffff0015  →  0x0000000000000000
$r10   : 0x0               
$r11   : 0x246             
$r12   : 0x000062d000010424  →  0x0000000000000000
$r13   : 0x00007fffffffe0a0  →  0x0000000041b58ab3
$r14   : 0x00000ffffffffc14  →  0x0000000000000000
$r15   : 0x0000631000010ef0  →  0x0000000000000000
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
──────────────────────────────────────────────────── stack ────
0x00007fffffffe000│+0x0000: 0x0000000000000000   ← $rsp
0x00007fffffffe008│+0x0008: 0x00007fffffffe1c0  →  0x0000000000000000
0x00007fffffffe010│+0x0010: 0x00005555556156c8  →  0x0000000000414141 ("AAA"?)
0x00007fffffffe018│+0x0018: 0x0000000000000000
0x00007fffffffe020│+0x0020: 0x0000000000000000
0x00007fffffffe028│+0x0028: 0x00005555556156cb  →  0x0000000000000000
0x00007fffffffe030│+0x0030: 0x000062d00000041c  →  0xff03414141030003
0x00007fffffffe038│+0x0038: 0x00007fffffffe120  →  0x00007fffffffe150  →  0x00007fffffffe200  →  0x00005555555fd5c4  →  0x0000000000000004
────────────────────────────────────────────── code:x86:64 ────
   0x7ffff430e619 <pwd_login+64>   jg     0x7ffff430e623 <pwd_login+74>
   0x7ffff430e61b <pwd_login+66>   test   cl, cl
   0x7ffff430e61d <pwd_login+68>   jne    0x7ffff430e7c2 <pwd_login+489>
 → 0x7ffff430e623 <pwd_login+74>   mov    BYTE PTR [r12+0x8], 0x0
   0x7ffff430e629 <pwd_login+80>   mov    rsi, QWORD PTR [rsp+0x10]
   0x7ffff430e62e <pwd_login+85>   call   0x7ffff430e380 <uam_getname@plt>
   0x7ffff430e633 <pwd_login+90>   mov    rbx, rax
   0x7ffff430e636 <pwd_login+93>   test   rax, rax
   0x7ffff430e639 <pwd_login+96>   je     0x7ffff430eb20 <pwd_login+1351>
────────────────────────────────── source:uams_passwd.c+61 ────
     56  #endif /* SHADOWPW */
     57  
     58      if (ibuflen < PASSWDLEN) {
     59          return( AFPERR_PARAM );
     60      }
 →   61      ibuf[ PASSWDLEN ] = '\0';
     62  
     63      if (( pwd = uam_getname(obj, username, ulen)) == NULL ) {
     64          return AFPERR_NOTAUTH;
     65      }
     66  
────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "afpd", stopped 0x7ffff430e623 in pwd_login (), reason: SIGSEGV
──────────────────────────────────────────────────── trace ────
[#0] 0x7ffff430e623 → pwd_login(obj=0x5555556154c0 <obj>, username=0x5555556156c8 <obj+520> "AAA", ulen=0xff, uam_pwd=0x7fffffffe1c0, ibuf=0x62d000010424 "", ibuflen=0xffff0015, rbuf=0x631000000ef0 "", rbuflen=0x631000010ef0)
[#1] 0x7ffff430fbcb → passwd_login_ext(obj=<optimized out>, uname=0x62d00000041d "", uam_pwd=<optimized out>, ibuf=<optimized out>, ibuflen=<optimized out>, rbuf=<optimized out>, rbuflen=<optimized out>)
[#2] 0x55555557f2f7 → afp_login_ext(obj=<optimized out>, ibuf=0x62d000010424 "", ibuflen=0xffffffffffff0015, rbuf=<optimized out>, rbuflen=<optimized out>)
[#3] 0x555555576696 → afp_over_dsi(obj=0x5555556154c0 <obj>)
[#4] 0x5555555c0468 → dsi_start(server_children=<optimized out>, dsi=0x631000000800, obj=0x5555556154c0 <obj>)
[#5] 0x5555555c0468 → main(ac=<optimized out>, av=<optimized out>)

pocw.zip

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L

CVE ID

CVE-2024-38439

Weaknesses

No CWEs

Credits