POC详情: ae6dd4f60ade4b119b4c579bf444eb4b5bc94509

来源
关联漏洞
标题: Linux kernel 缓冲区错误漏洞 (CVE-2022-1015)
描述:Linux kernel是美国Linux基金会的开源操作系统Linux所使用的内核。 Linux 内核存在安全漏洞,该漏洞源于在netfilter子系统的linux/net/netfilter/nf_tables_api.c中存在Linux内核的一个缺陷。 此漏洞允许本地用户导致越界写入问题。 攻击者可以通过nft_expr_payload触发 Linux 内核的内存损坏,从而触发拒绝服务,并可能运行代码。
描述
Linux Kernel 1-Day Analysis & Exploitation
介绍
# CVE-2022-1015
## Route Cause

`nft_parse_register` 함수에서 arg가 default로 넘어갈 때에 대한 검증을 하지 않아 `nft_do_chain` 함수의 stack에서 oob가 터짐. 

이때 payload expression을 이용하면 read, write를 둘 다 할 수 있다.

payload는 아래와 같은 동작을 하게 된다.

![image](https://github.com/more-kohii/CVE-2022-1015/assets/87258637/8e739fe5-f667-4e23-bd4a-4066e149f9e6)

즉, 인덱스를 적절히 조절하면 stack에서 oob read, write를 할 수 있음.

하지만, regs는 validation을 하는 함수가 존재한다.

```c
default:
		if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
			return -EINVAL;
		if (len == 0)
			return -EINVAL;
		if (reg * NFT_REG32_SIZE + len >
		    sizeof_field(struct nft_regs, data))
			return -ERANGE;

		if (data != NULL && type != NFT_DATA_VALUE)
			return -EINVAL;
		return 0;
```

위의 코드를 보면, reg * NFT_REG32_SIZE + len > sizeof_field(struct nft_regs, data) 를 만족해야한다.

상수 넣어주면 reg * 4 + len > 80 이거 만족하면 된다.

즉, reg에 맞게 적당히 len를 조절해줘야한다.

## 참고할 소스 코드

- `nft_regs`
    
    ```c
    struct nft_regs {
    	union {
    		u32			data[20];
    		struct nft_verdict	verdict;
    	};
    };
    ```
    
- `nft_do_chain`
    
    ```c
    unsigned int
    nft_do_chain(struct nft_pktinfo *pkt, void *priv)
    {
    	const struct nft_chain *chain = priv, *basechain = chain;
    	const struct net *net = nft_net(pkt);
    	struct nft_rule *const *rules;
    	const struct nft_rule *rule;
    	const struct nft_expr *expr, *last;
    	struct nft_regs regs;
    	...
    }
    ```
    
- `nft_parse_register`
    
    ```c
    static unsigned int nft_parse_register(const struct nlattr *attr)
    {
    	unsigned int reg;
    
    	reg = ntohl(nla_get_be32(attr));
    	switch (reg) {
    	case NFT_REG_VERDICT...NFT_REG_4:
    		return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
    	default:
    		return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
    	}
    }
    ```
文件快照

[4.0K] /data/pocs/ae6dd4f60ade4b119b4c579bf444eb4b5bc94509 ├── [7.4K] ex.c ├── [ 96] Makefile ├── [2.0K] README.md └── [ 11K] utils.h 0 directories, 4 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。