From 399dc651e364bc4ad03991a29f2cc8b555eded4f Mon Sep 17 00:00:00 2001 From: kevinrich1337 Date: Sat, 19 Oct 2024 07:41:33 -0700 Subject: [PATCH] update exploit.md and exploit.c --- .../CVE-2023-4147_lts_cos/docs/exploit.md | 14 +++++++------- .../exploit/cos-105-17412.101.42/exploit.c | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/docs/exploit.md b/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/docs/exploit.md index aaffaff5..0eb64d31 100644 --- a/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/docs/exploit.md +++ b/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/docs/exploit.md @@ -41,8 +41,8 @@ We can trigger the vulnerability in LTS as follows: - Create three chains, `Base`, `Vulnerable`, and `Victim`. Set `NFT_CHAIN_BINDING` flag for `Vulnerable`. If a chain with the `NFT_CHAIN_BINDING` flag set is bound to an immediate expr, when this expr is destroyed, the bound chain and its rules will also be destroyed. - Create a rule in `Base` with an immediate expr referencing the `Vulnerable`. - Create a rule in `Vulnerable` with an immediate expr referencing `Victim`. -- Trigger the vulnerability by replacing the rule in `Vulnerable`. This results in the `Victim` having a reference count of 0 `(nft_chain->use)`. -- Delete the rule in `Base` to deactivate the `Vulnerable` again. This results in the `Victim` having a reference count of -1. +- Trigger the vulnerability by replacing the rule in `Vulnerable`. This results in the `Victim` having a reference count `(nft_chain->use)` of 0. +- Delete the rule in `Base` to deactivate the `Vulnerable` again. This results in the `Victim` having a reference count `(nft_chain->use)` of -1. We can trigger the vulnerability in COS as follows: @@ -80,9 +80,9 @@ The KASLR address is leaked through `chain->name`, which is stored in the verdic - Create three chains, `Base`, `Vulnerable`, and `Victim`. Set `NFT_CHAIN_BINDING` flag for `Vulnerable`. If a chain with the `NFT_CHAIN_BINDING` flag set is bound to an immediate expr, when this expr is destroyed, the bound chain and its rules will also be destroyed. - Create a rule in `Base` with an immediate expr referencing the `Vulnerable`. - Create a rule in `Vulnerable` with an immediate expr referencing `Victim`. -- Trigger the vulnerability by replacing the rule in `Vulnerable`. This results in the `Victim` having a reference count of 0 `(nft_chain->use)`. -- Delete the rule in `Base` to deactivate the `Vulnerable` again. This results in the `Victim` having a reference count of -1. -- Create an immediate expr in `Base` that references to the Victim, making the `Victim`'s reference count 0, and destroy the `Victim`. +- Trigger the vulnerability by replacing the rule in `Vulnerable`. This results in the `Victim` having a reference count `(nft_chain->use)` of 0. +- Delete the rule in `Base` to deactivate the `Vulnerable` again. This results in the `Victim` having a reference count `(nft_chain->use)` of -1. +- Create an immediate expr in `Base` that references to the Victim, making the `Victim`'s reference count `(nft_chain->use)` 0, and destroy the `Victim`. - Spray counter exprs (struct nft_expr) to place it at `Victim`'s chain->name. At this time, the counter exprs are allocated in the `kmalloc-cg-16`. - We dump the immediate expr of `Base` using `GETRULE` command, we can get the ops address of counter expr through the freed `chain->name` to get the kernel base address [5]. @@ -294,7 +294,7 @@ Starting with commit [4bedf9ee] (https://git.kernel.org/pub/scm/linux/kernel/git The KASLR address and heap address are leaked through `nft_rule` allocated in `kmalloc-cg-192`. The leak process is as follows: - Create four chains, `Base`, `Vulnerable`, `Chain_Victim`, and `Target`. Set `NFT_CHAIN_BINDING` flag for `Vulnerable`. If a chain with the `NFT_CHAIN_BINDING` flag set is bound to an immediate expr, when this expr is destroyed, the bound chain and its rules will also be destroyed. -- Create chains `Chain_Victim2_n`. In this exploit, 0x30 chains are sprayed. +- Create chains `Chain_Victim2_n` for the victim rules created in the next step. In this exploit, 0x30 chains are sprayed. - Create an anonymous rhash set `Set_Victim`. - Create a set element in set `Set_Victim`. The element is allocated in `kmalloc-cg-256`. @@ -328,7 +328,7 @@ static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set, } ``` -- Spray rhash sets `Set_Spray_n`. When destroying an `nf_tables_set_elem_destroy` element, `nft_set_ext` is used [10], and `nft_set_ext` is retrieved by referencing `set->ops->elemsize` [12]. Thus, a rhash set with `elemsize` of 8 is overwritten by an rbtree set with `elemsize` of 24, causing the `nft_set_elem_expr_destroy` to reference the wrong `nft_set_ext`. We manipulate the offset to destroy the `immedieate expr` in `Rule_Victim_n`, that is allocated after the element, in [11]. This frees `Rule_Victim2_n` of `Chain_Victim2_n` in the `nft_immediate_destroy`. However, `Chain_Victim2_n` and `Rule_Victim2_n` are remain accessible. +- Spray rhash sets `Set_Spray_n`. When destroying an `nf_tables_set_elem_destroy` element, `nft_set_ext` is used [10], and `nft_set_ext` is retrieved by referencing `set->ops->elemsize` [12]. Thus, a rhash set with `elemsize` of 8 is overwritten by an rbtree set with `elemsize` of 24, causing the `nft_set_elem_expr_destroy` to reference the wrong `nft_set_ext`. We manipulate the offset to destroy the `immedieate expr` in `Rule_Victim_n`, that is allocated after the element, in [11]. This frees `Rule_Victim2_n` of `Chain_Victim2_n` in the `nft_immediate_destroy`. However, `Chain_Victim2_n` and `Rule_Victim2_n` remain accessible. - Spray fake rules using `nft_table->udata` into freed `Rule_Victim2_n` (`kmalloc-cg-192`). Set `nft_rule->udata` of the fake rule to 1 and `nft_rule->udata->len` to 0xff. - Get the fake rule will read 0xff bytes start from `nft_rule->udata`. As a result, we can obtain kbase (`nft_last_ops`) and heap address (`nft_rule.list.next` and `nft_rule.list.prev`) of `Rule_Targret_n`. diff --git a/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/exploit/cos-105-17412.101.42/exploit.c b/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/exploit/cos-105-17412.101.42/exploit.c index ba5f59a5..9ecfde22 100644 --- a/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/exploit/cos-105-17412.101.42/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-4147_lts_cos/exploit/cos-105-17412.101.42/exploit.c @@ -112,6 +112,7 @@ void save_state(void) { return; } +// We can put everthing in the Table1. Just need to change the rule_handle. char * table1_name = "table1"; char * table2_name = "table2"; char * table3_name = "table3"; @@ -573,6 +574,7 @@ void trig(){ nftnl_rule_nlmsg_build_payload(nlh, rule_bind_chain_1_2_del); mnl_nlmsg_batch_next(batch); + // create a delay to spray sets_rbtree[] nlh = nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch), NFT_MSG_DELSET, family, 0, seq++); nftnl_set_nlmsg_build_payload(nlh, set_delay); mnl_nlmsg_batch_next(batch);