CVE-2023-0179: A Buffer Overflow Vulnerability in the Linux Kernel

June 27, 2023
Muhammad Kamran Hasan
Buffer overflow vulnerability
Netfilter subsystem
Linux kernel
CVE-2023-0179
Root privileges
Security vulnerability assessment
Security patching
Local privilege escalation
Attack surface
Kernel security flaw
Security advisories
CVE-2023-0179: A Buffer Overflow Vulnerability in the Linux Kernel

Introduction

A buffer overflow vulnerability was recently discovered in the Netfilter subsystem of the Linux kernel. This vulnerability, tracked as CVE-2023-0179, could allow a local attacker to gain root privileges on the affected system.

Vulnerability Details

The vulnerability exists in the way that the Netfilter subsystem handles VLAN headers. When a VLAN header is received by the kernel, it is parsed and the contents are stored in a buffer. However, the buffer is not large enough to store all of the contents of the VLAN header, which could lead to a buffer overflow.

What is a VLAN header?

A VLAN header is a header that is added to an Ethernet frame to identify the VLAN (Virtual Local Area Network) that the frame belongs to.

Understanding the Exploit Code:

  • The split_struct function takes a jumpstack_t struct and splits its contents into an array of four-byte chunks.

  • The fill_jumpstack function initializes a jumpstack_t struct with specific values. It sets the init field to 'A', rule field to reg0 + 0xf8, last_rule field to 0xffffffffffffffff, eval field to reg0 + 0x108, pivot field to 0xffffffff81134571 + kaslr, and copies a string of 'A's into the pad field.

  • The get_4_bytes function takes an address and splits it into two four-byte chunks.

  • The privesc function sets up a fake modprobe configuration by writing a custom entry to /etc/passwd. It then creates a file, sets some permissions, and executes it.

  • The create_final_chain_rule function is involved in a kernel exploitation technique known as Return-Oriented Programming (ROP). It starts by constructing a Netfilter rule using the provided parameters. The rule is built using the build_rule function, which sets up the necessary components for the rule, such as the table name, chain name, family, and handle.

The function then proceeds to prepare the jumpstack layout, which involves calculating the addresses for the jumpstack based on the provided regs and instr values. The jumpstack is an array of addresses that will be overwritten during the overflow phase of the exploitation.

Next, the function iterates over the register range NFT_REG32_00 to NFT_REG32_15. For each register, it adds immediate data from the jumpstack to the rule using the rule_add_immediate_data function. This step ensures that the necessary addresses are set in the corresponding registers for the subsequent stages of the ROP chain.

After setting up the jumpstack and register values, the function triggers an overflow by adding a payload to the rule using the rule_add_payload function. This payload is designed to overwrite the jumpstack, allowing control over the execution flow.

The following steps involve setting up the ROP chain. The function defines specific gadget addresses and calculates their locations based on the provided kaslr value. These gadgets include instructions such as stack pivots, register pops, and memory writes.

For each gadget, the function extracts the lower and higher order bytes and adds them as immediate data to the appropriate registers using the rule_add_immediate_data function.

Once the ROP chain is set up, the function adds an immediate verdict to break from the register verdict switch and return to the corrupted previous chain. This is done using the rule_add_immediate_verdict function.

Finally, the function sends the constructed rule to the Netfilter subsystem for processing by invoking the send_batch_request function with the necessary parameters.

  • The create_jmp_chain_rule function creates a rule for a jmp chain. It builds a rule with the table name, chain name, family, and handle. It checks the chain name and decides whether to jump to the next jmp chain or to the "final_chain" based on the current chain number.

  • The create_base_chain_rule_pwn function creates a base chain rule for exploitation. It builds a rule with the table name, chain name, family, and handle. It adds an immediate verdict to jump to chain "0".

  • The create_base_chain_rule_leak function creates a base chain rule for leaking information. It builds a rule with the table name, chain name, family, and handle. It adds an immediate verdict to jump to chain "exploit_chain".

  • The create_exploit_chain_rule_leak function creates an exploit chain rule for leaking information. It builds a rule with the table name, chain name, family, and handle. It adds dynamic sets for registers NFT_REG32

  • The pwn function is a technical process that sets up various components required for a kernel exploit. It initializes variables, creates Netfilter tables and chains, establishes rules within the chains, and configures parameters for the final exploit chain. It then triggers the exploit by sending a packet and checks for successful execution. If successful, it proceeds with privilege escalation and reports the outcome. The function encompasses the entire exploit process, from initialization to result reporting, in a concise and organized manner.

Exploiting the Vulnerability

To exploit this vulnerability, the attacker would need to craft a specially crafted VLAN header that is larger than the size of the kernel's buffer. When this VLAN header is received by the kernel, it will cause a buffer overflow. This will overwrite the contents of the buffer, including the return address of the netfilter_vlan_rule_parse() function.

The attacker can then control the value of the return address. This means that they can control which function is called next. If the attacker can control the return address, they can execute arbitrary code as root.

The attacker can craft a specially crafted VLAN header using a variety of tools, such as Wireshark or tcpdump. Once the VLAN header has been crafted, the attacker can send it to the affected system. If the system is vulnerable, the attacker will be able to execute arbitrary code as root.

Mitigation Strategies

Applying the patch that has been released for this vulnerability would be the best mitigation strategy. If you are unable to update to the latest version of nftables and you are running a vulnerable version of nftables, you can mitigate the vulnerability by disabling the affected chains. To do this, you can edit the nftables configuration file and comment out the following lines:

chain rule_leak {

  type filter;

  family ipv4;

  policy accept;

  jump exploit_chain;

}

chain exploit_chain {

  type filter;

  family ipv4;

  policy accept;

  /* ... */

}

Once you have commented out these lines, you can save the nftables configuration file and restart the nftables service.

Conclusion

CVE-2023-0179 is a serious vulnerability that could allow a local attacker to gain root privileges on an affected system. It is important to apply the patch that has been released for this vulnerability as soon as possible.

Reference:

  • https://github.com/H4K6/CVE-2023-0179-PoC

CVE-2024-9264: Command Injection and LFI in Grafana
CVE-2024-9264: Command Injection and LFI in Grafana
2024-10-25
Kamran Hasan
CVE-2024-48914: Arbitrary File Read Vulnerability in Vendure
CVE-2024-48914: Arbitrary File Read Vulnerability in Vendure
2024-10-26
Kamran Hasan
CVE-2022-44268: Arbitrary File Disclosure in ImageMagick
CVE-2022-44268: Arbitrary File Disclosure in ImageMagick
2024-05-26
James McGill
CVE-2021-43798: Path Traversal in Grafana
CVE-2021-43798: Path Traversal in Grafana
2024-03-30
James McGill
CVE-2021-3129: Remote Code Execution in Laravel
CVE-2021-3129: Remote Code Execution in Laravel
2024-02-14
James McGill
CVE-2024-28116: Server-Side Template Injection in Grav CMS
CVE-2024-28116: Server-Side Template Injection in Grav CMS
2024-03-24
James McGill