-
Notifications
You must be signed in to change notification settings - Fork 416
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add CVE-2023-4004 * Change exploit.md * Change exploit.md * Change exploit.md * Change metadata.json * Change metadata.json * Change metadata.json * Change lts exploit for test * Change lts exploit for test * Change cos and mig exploit * Change cos exploit * Change cos exploit * Change cos exploit * Change cos exploit * Change cos exploit * Change cos exploit * Add CVE-2023-6111_lts * Change metadata.json * Add exploit * Change exploit for check * Add CVE-2023-6111_cos * Del CVE-2023-6111_cos
- Loading branch information
Showing
12 changed files
with
1,163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# Exploit detail about CVE-2023-6111 | ||
If you want to get some base information about CVE-2023-6111, please read [vulnerability.md](./vulnerability.md) first. | ||
|
||
## Background | ||
nftables is a netfilter project that aims to replace the existing {ip,ip6,arp,eb}tables framework, providing a new packet filtering framework for {ip,ip6}tables, a new userspace utility (nft) and A compatibility layer. It uses existing hooks, link tracking system, user space queuing component and netfilter logging subsystem. | ||
|
||
It consists of three main components: kernel implementation, libnl netlink communication and nftables user space front-end. The kernel provides a netlink configuration interface and runtime rule set evaluation. libnl contains basic functions for communicating with the kernel. The nftables front end is for user interaction through nft. | ||
|
||
nftables implements data packet filtering by using some components like `table`, `set`, `chain`, `rule`. | ||
|
||
## Cause anaylysis | ||
|
||
In the function nft_trans_gc_catchall, maintainers forget to remove the catchall set element from the catchall_list when the argument sync is true. So if you create a catchall set element with NFT_SET_EXT_EXPIRATION in a pipapo set, it's possible to free the catchall set element many times. | ||
|
||
``` | ||
void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans) | ||
{ | ||
WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net)); | ||
if (trans->count == 0) { | ||
nft_trans_gc_destroy(trans); | ||
return; | ||
} | ||
call_rcu(&trans->rcu, nft_trans_gc_trans_free); | ||
} | ||
``` | ||
|
||
|
||
## Triggering the vulnerability | ||
|
||
It's easy to trigger it by following this steps: | ||
|
||
- Create a pipapo set with flag NFT_SET_TIMEOUT | ||
- Insert an element A into the set with NFT_SET_ELEM_CATCHALL, NFTA_SET_ELEM_TIMEOUT and NFTA_SET_ELEM_EXPIRATION | ||
- Wait some seconds(Let element A timeout ) | ||
- Insert another element B infto the set. Finally the following call chain is triggered: `nft_set_commit_update` -> `nft_pipapo_commit` -> `pipapo_gc` -> `nft_trans_gc_queue_sync_done`. | ||
|
||
## Exploit it | ||
CVE-2023-6111 is very easy to exploit because you can free the element many times. My exploit is basically the same as CVE-2023-4004, with only minor modifications to the success rate requirements in the rules. If you want to get more detail about the object we use here, please read [the exploit of CVE-2023-4004](https://github.com/google/security-research/blob/master/pocs/linux/kernelctf/CVE-2023-4004_lts_cos_mitigation/docs/exploit.md) first. | ||
|
||
### Leak info | ||
|
||
I leak some useful infomation by the following steps. | ||
|
||
- Create pipapo `set A` with flag NFT_SET_TIMEOUT. | ||
- Insert `element B` into `set A` with NFT_SET_ELEM_CATCHALL, NFTA_SET_ELEM_TIMEOUT and NFTA_SET_ELEM_EXPIRATION. | ||
- Insert another element to trigger the vulnerability. The `element B` will be freed. | ||
- Create many tables with NFTA_TABLE_USERDATA to get the heap of `element B` back, the length of `NFTA_TABLE_USERDATA` should equal to sizeof(`element B`). We should hold some memory of the `element B` same to make it possiable to free it again. | ||
- Insert another element to trigger the vulnerability again. The `element B` will be freed again. | ||
- Create many objects, the size of the objects should equal to sizeof(`element B`). One of them will get the heap of `element B` back. | ||
- Dump/Get all the tables we spray. The `NFTA_TABLE_USERDATA` of one of them should be a strcture of a object. | ||
|
||
There is a doubly linked list at the head of the object pointing to the objects before and after it. We can get the name of the next object and the pointer of it. So I choose to use it as the ROP gadget which will be used in `Control RIP`. | ||
Steps: | ||
- Delete the next object. | ||
- Create many tables with NFTA_TABLE_USERDATA to get the heap of the next object back. | ||
|
||
### Control RIP | ||
I control the RIP by the following steps which is very similar I used for leaking useful information: | ||
|
||
- Create pipapo `set A` with flag NFT_SET_TIMEOUT. | ||
- Insert `element B` into `set A` with NFT_SET_ELEM_CATCHALL, NFTA_SET_ELEM_TIMEOUT and NFTA_SET_ELEM_EXPIRATION. | ||
- Insert another element to trigger the vulnerability. The `element B` will be freed. | ||
- Create many tables with NFTA_TABLE_USERDATA to get the heap of `element B` back, the length of `NFTA_TABLE_USERDATA` should equal to sizeof(`element B`). We should hold some memory of the `element B` same to make it possiable to free it again. | ||
- Insert another element to trigger the vulnerability again. The `element B` will be freed again. | ||
- Create many objects, the size of the objects should equal to sizeof(`element B`). One of them will get the heap of `element B` back. | ||
- Dump/Get all the tables we spray. Find the target tables. The `NFTA_TABLE_USERDATA` of one of them should be a strcture of a object. | ||
- Delete the target table to free the heap of the object. | ||
- Spray many tables with NFTA_TABLE_USERDATA to get the heap of the object back. After this, we will fill fake data of the object. I overwrite object->ops to control RIP. | ||
- Get target object, and we will finally jump to ROP. | ||
``` | ||
static int nft_object_dump(struct sk_buff *skb, unsigned int attr, | ||
struct nft_object *obj, bool reset){ | ||
struct nlattr *nest; | ||
nest = nla_nest_start_noflag(skb, attr); | ||
if (!nest) | ||
goto nla_put_failure; | ||
if (obj->ops->dump(skb, obj, reset) < 0)//After overwrite the ops, we can control RIP here. | ||
goto nla_put_failure; | ||
nla_nest_end(skb, nest); | ||
return 0; | ||
... | ||
``` | ||
### ROP detail | ||
I fill the fake data of the object by this: | ||
``` | ||
//ops is the pointer of the memory we will fill in NFTA_OBJ_USERDATA | ||
//the filed at 0x20 of ops is ops->dump. | ||
*(uint64_t *)&ops[0x20] = kernel_off + 0xffffffff8198954b;//push rsi ; jmp qword ptr [rsi + 0x39] | ||
... | ||
//Now we try to fill fake data of the object | ||
//stack migration first time | ||
*(uint64_t *)(&leak_obj[0x39]) = kernel_off + 0xffffffff811b365b;//pop rsp ; ret | ||
*(uint64_t *)(&leak_obj[0]) = kernel_off + 0xffffffff811b365b;//pop rsp ; ret | ||
*(uint64_t *)(&leak_obj[8]) = target_rop + 0x60;//Finally we jmp to our target ROP + 0x60 | ||
*(uint64_t *)(&leak_obj[0x80]) = target_rop; // make obj->ops = our target ROP memory; | ||
... | ||
``` | ||
|
||
And the step of ROP looks like this: | ||
``` | ||
obj->ops->dump(skb, obj, reset) -> | ||
push rsi ; jmp qword ptr [rsi + 0x39] -> //RSI will be the pointer of the object | ||
pop rsp ; ret -> //stack migration, the rsp will be the pointer of the object | ||
pop rsp ; ret -> //stack migration again, the rsp will be target_rop + 0x60(the pointer of the NFTA_OBJ_USERDATA + 0x60) | ||
now we can do normal ROP here | ||
``` |
25 changes: 25 additions & 0 deletions
25
pocs/linux/kernelctf/CVE-2023-6111_lts/docs/vulnerability.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Vulneribility | ||
In the function nft_trans_gc_catchall, maintainers forget to remove the catchall set element from the catchall_list when the argument sync is true. So if you create a catchall set element with NFT_SET_EXT_EXPIRATION in a pipapo set, it's possible to free the catchall set element many times. | ||
|
||
|
||
## Requirements to trigger the vulnerability | ||
- Capabilities: `CAP_NET_ADMIN` capability is required. | ||
- Kernel configuration: `CONFIG_NETFILTER`, `CONFIG_NF_TABLES` | ||
- Are user namespaces needed?: Yes | ||
|
||
## Commit which introduced the vulnerability | ||
- [commit 4a9e12ea7e70223555ec010bec9f711089ce96f6](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/net/netfilter?id=4a9e12ea7e70223555ec010bec9f711089ce96f6) | ||
|
||
## Commit which fixed the vulnerability | ||
- [commit 93995bf4af2c5a99e2a87f0cd5ce547d31eb7630](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=93995bf4af2c5a99e2a87f0cd5ce547d31eb7630) | ||
|
||
## Affected kernel versions | ||
- 6.1.56 and later | ||
- 5.15.134 and later | ||
|
||
## Affected component, subsystem | ||
- net/netfilter (nf_tables) | ||
|
||
## Cause | ||
- UAF | ||
|
9 changes: 9 additions & 0 deletions
9
pocs/linux/kernelctf/CVE-2023-6111_lts/exploit/lts-6.1.60/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
exploit: | ||
gcc -o exploit exploit.c -I/usr/include/libnl3 -lnl-nf-3 -lnl-route-3 -lnl-3 -static | ||
prerequisites: | ||
sudo apt-get install libnl-nf-3-dev | ||
run: | ||
./exploit | ||
|
||
clean: | ||
rm exploit |
2 changes: 2 additions & 0 deletions
2
pocs/linux/kernelctf/CVE-2023-6111_lts/exploit/lts-6.1.60/README
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Exploit for kctf LTS 6.1.60 | ||
Run command "nsenter --target 1 -m -p" after run the poc. |
Binary file not shown.
Oops, something went wrong.