专栏首页I0ganKernel pwn 1 [环境搭建]
原创

Kernel pwn 1 [环境搭建]

介绍

对于linux kernel这块的pwn大体跟用户状态差不多,出题人一般都是自己编写了一个驱动模块,由内核进行加载该模块,在用户态可以打开该设备,采用ioctl来与驱动进行交互,若能成功pwn掉该驱动实现提权,那就能以root身份读取flag。

exp一般都是c语言写的,需要编译为静态再上传至远程靶机运行,提升权限后即可查看远程flag。

编译内核

去官网下载一份kernel内核源码, 这里就采用2.6.32版本。我采用docker 下的ubuntu16.04进行编译内核, 编译内核前需要拥有特定的版本的make和gcc, g++

获取不同版本的内核:

获取

安装特定的编译器

sudo apt install gcc-4.7 g++-4.7
sudo ln -s /usr/bin/gcc-4.7 /usr/bin/gcc
sudo ln -s /usr/bin/g++-4.7 /usr/bin/g++

安装必备依赖

sudo apt-get install build-essential libncurses5-dev

获取内核代码

mkdir kernel
cd kernel
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.tar.gz
tar xzvf linux-2.6.32.tar.gz

获取特定的make

wget https://mirrors.tuna.tsinghua.edu.cn/gnu/make/make-3.80.tar.gz
tar -xvf make-3.80.tar.gz
cd make-3.80/
./configure
make

修改三处 2.6 源码文件

  • 1.arch/x86/vdso/Makefile 中第 28 行的 -m elf_x86_64 改成 -m64,第 72 行的-m elf_i386 改成-m32
  • 2.drivers/net/igbvf/igbvf.h 中注释第 128 行
  • 3.kernel/timeconst.pl 中第 373 行 defined(@val) 改成 @val
  • 4.(可选)关闭 canary 保护需要编辑源码中的.config 文件 349 行,注释掉 CONFIG_CC_STACKPROTECTOR=y 这一项

配置kernel

../make-3.80/make menuconfig

进入 kernel hacking,勾选 Kernel debugging,Compile-time checks and compiler options–>Compile the kernel with debug info,Compile the kernel with frame pointers 和 KGDB

编译

../make-3.80/make bzImage

编译时遇到的问题

问题1

fatal error: linux/compiler-gcc5.h: No such file or directory

解决:

拷贝一个自己目录下的compiler-gcc4.h到compiler-gcc5.h

问题2

implicit declaration of function 'tty_port_users'

解决:

将所提示的该函数extern关键字去掉

编译成功

编译成功之后提示如下:

Root device is (0, 78)
Setup is 13688 bytes (padded to 13824 bytes).
System is 3961 kB
CRC e70b803a
Kernel: arch/x86/boot/bzImage is ready  (#1)

vmlinux 在源码根目录下,bzImage 在arch/x86/boot/下

制作镜像

获取busybox

wget https://busybox.net/downloads/busybox-1.27.2.tar.bz2
tar -jxvf busybox-1.27.2.tar.bz2

配置busybox

cd busybox-1.27.2
make menuconfig

勾选 Busybox Settings -> Build Options -> Build Busybox as a static binary

编译并安装busybox

make
make install

打包镜像

编译完成后源码目录下会有一个_install 文件夹

cd _install
mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}
mkdir etc/init.d
touch etc/init.d/init

编辑 etc/inittab 文件,加入以下内容(这一步可以省略)

::sysinit:/etc/init.d/rcS
::askfirst:/bin/ash
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init

编辑 etc/init.d/rcS 文件,加入以下内容

#!/bin/sh
mount -t proc none /proc
mount -t sys none /sys
/bin/mount -n -t sysfs none /sys
/bin/mount -t ramfs none /dev
/sbin/mdev -s

接着就可以打包成 rootfs.cpio

chmod +x ./etc/init.d/rcS
find . | cpio -o --format=newc > ../rootfs.cpio

运行镜像

安装qemu

apt install qemu

得到这三个vmlinux,bzImage,rootfs.cpio 文件后,可以利用 qemu 运行起来,启动脚本 boot

#!/bin/sh
qemu-system-x86_64 \
 -initrd rootfs.cpio \
 -kernel bzImage \
 -nographic \
 -append "console=ttyS0 root=/dev/ram rdinit=/sbin/init" \
 -m 64M \
 -monitor /dev/null \

启动成功如下

Please press Enter to activate this console. [    3.379764] async/1 used greatest stack depth: 5064 bytes left
/bin/ash: can't access tty; job control turned off
/ # ls
bin      etc      proc     sbin     usr

编写与打开内核驱动

内核驱动c代码编写

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
int hello_write(struct file *file, const char *buf, unsigned long len) {
    printk("You write something.");
    return len;
}
static int __init hello_init(void) {
    printk(KERN_ALERT "hello driver init!\n");
    create_proc_entry("hello", 0666, 0)->write_proc = hello_write;
    return 0;
}
static void __exit hello_exit(void) {
    printk(KERN_ALERT "hello driver exit\n");
}
module_init(hello_init);
module_exit(hello_exit);

保存为hello.c

Makefile编写

注意, Makefile中 obj-m 中的名字要与保存c代码的文件名相同

obj-m := hello.o
KERNELDR := /home/kernel/linux-2.6.32
PWD := $(shell pwd)
modules:
        $(MAKE) -C $(KERNELDR) M=$(PWD) modules
modules_install:
        $(MAKE) -C $(KERNELDR) M=$(PWD) modules_install
clean:
        $(MAKE) -C $(KERNELDR) M=$(PWD) clean

make 出来后得到.ko 文件

编写打开程序

命名为call.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
int main() {
    int fd = open("/proc/hello", O_WRONLY);
    write(fd, "I0gan", 5);
    return 0;
}

编译

gcc --static call.c -o call

将hello.ko与call两个文件复制到busybox下的_install目录下重新打包得到rootfs.cpio, 把该文件复制到启动目录下, 重新运行./boot

启动自己的内核驱动

挂载驱动

insmod hello.ko

输出如下

[   75.062554] hello: module license 'unspecified' taints kernel.
[   75.063843] Disabling lock debugging due to kernel taint
[   75.074570] hello driver init!

调用打开自己的驱动

/ # ./call 
[   79.011811] You write something./ 

上面打印了You write somthing说明已经打开了我们的驱动, 那么到这基本上已经差不多了 ^_^

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从一道mips题目学习搭建mips环境及ROP

    本文以一道简单的mips pwn题,讲解mips环境搭建及mips ROP的构造。这道题目是安洵杯的一道pwn题,题目链接https://github.com/...

    用户2202688
  • Linux环境搭建系列(1) —— JAVA 环境的搭建

    求和小熊猫
  • hadoop 1.x环境搭建

    近一直在自学Hadoop,今天花点时间搭建一个开发环境,并整理成文。 首先要了解一下Hadoop的运行模式: 单机模式(standalone)       ...

    猿人谷
  • (1)越狱环境搭建

    czjwarrior
  • 第1天:Python 环境搭建

    其实 Python 已经是一个很老的编程语言了,到现在(2019年) Python 已经高龄 28 岁,比很多程序员的年龄都大。现在之所以这么流行和社区、人工智...

    纯洁的微笑
  • 从0到1搭建k8s(一)——环境搭建

    这一系列文章是学习K8S过程的笔记,使用的是kubeadm来部署。 参考https://kubernetes.io/zh/docs/setup/producti...

    点点寒彬
  • Flutter Lesson 1:Flutter之环境搭建

    就在几天前(2019年05月08日),Google发布了新一版本的Flutter,同时伴随着巨大的更新。之前的Flutter顶多就是跨Android与IOS平台...

    踏浪
  • Day 1 - 搭建python开发环境

    MySQL 5.x数据库,从官方网站下载并安装,安装完毕后,请务必牢记root口令。为避免遗忘口令,建议直接把root口令设置为password;

    php007
  • 1、TypeScript初识及环境搭建

    TypeScript最近很火,有很多开源的项目也是由其开发的,如果你是一名前端开发工程师或准备要成为一名前端开发工程师的话,现在如果再不学习TypeScript...

    用户1272076
  • OpenStack环境搭建1(先电版)

    OpenStack先电版搭建系列教程由五部分组成,该部分为第一步环境搭建步骤,其他部分请在本站查找相关内容

    Weiyang
  • “骇极杯”——pwn复现详解

    当时在做的时候看见是arm的框架就放弃了,环境都不会搭建简直爆炸了,所以就没有继续做了。复现的时候发现其实搭建环境的思路还是很清晰的。

    安恒网络空间安全讲武堂
  • Linux pwn入门教程之环境配置

    作为一个毕业一年多的辣鸡CTF选手,一直苦于pwn题目的入门难,入了门更难的问题。本来网上关于pwn的资料就比较零散,而且经常会碰到师傅们堪比解题过程略的wri...

    用户6543014
  • 从 0 开始学 Linux 内核之 android 内核栈溢出 ROP 利用

    最近在研究一个最简单的android内核的栈溢出利用方法,网上的资料很少,就算有也是旧版内核的,新版的内核有了很大的不同,如果放在x86上本应该是很简单的东西,...

    Seebug漏洞平台
  • 如何安全快速地部署多道 ctf pwn 比赛题目

    一开始接触 pwn 的时候,我们要么本地调试,要么自己用 socat 将程序启动起来远程调试

    信安之路
  • 从 0 开始学 Linux 内核之 android 内核栈溢出 ROP 利用

    最近在研究一个最简单的android内核的栈溢出利用方法,网上的资料很少,就算有也是旧版内核的,新版的内核有了很大的不同,如果放在x86上本应该是很简单的东西,...

    Seebug漏洞平台
  • kubernetes集群搭建(1):环境准备

    肖哥哥
  • [springboot 开发单体web shop] 1. 前言介绍和环境搭建

    springboot 本身是为了做服务化用的,我们为什么要反其道使用它来开发一份单体web应用呢? 在我们现实的开发工作中,还有大量的业务系统使用的是单体应用...

    Isaac Zhang
  • 从0-1搭建DolphinScheduler开发环境

    https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.4.14/zookeeper-3.4.1...

    Eights
  • 【玩转ESP32】1、开发环境搭建

    基本上一路点击下一步即可,记得要添加环境变量,安装之后在“命令提示符”里面输入git --version,出现如下即表示正确安装成功。

    ManInRoad
  • 二进制情报推送记录

    [1] r3kapig HITCON CTF 2019 Writeup https://r3kapig.com/writeup/20191018-hitcon...

    De4dCr0w

扫码关注云+社区

领取腾讯云代金券