# Relro

Relro (Read only Relocation) affects the memory permissions similar to NX. The difference is whereas with NX it makes the stack non-executable, RELRO makes certain things read only so we can't write to them. The most common way I've seen this be an obstacle is preventing us from doing a `got` table overwrite, which will be covered later. The `got` table holds addresses for libc functions so that the binary knows what the addresses are and can call them. Let's see what the memory permissions look like for a `got` table entry for a binary with and without relro.

With relro:

```
gef➤  vmmap
Start              End                Offset             Perm Path
0x[PII_REDACTED]554000 0x[PII_REDACTED]555000 0x[PII_REDACTED]000000 r-- /tmp/tryc
0x[PII_REDACTED]555000 0x[PII_REDACTED]556000 0x[PII_REDACTED]001000 r-x /tmp/tryc
0x[PII_REDACTED]556000 0x[PII_REDACTED]557000 0x[PII_REDACTED]002000 r-- /tmp/tryc
0x[PII_REDACTED]557000 0x[PII_REDACTED]558000 0x[PII_REDACTED]002000 r-- /tmp/tryc
0x[PII_REDACTED]558000 0x[PII_REDACTED]559000 0x[PII_REDACTED]003000 rw- /tmp/tryc
0x[PII_REDACTED]559000 0x[PII_REDACTED]57a000 0x[PII_REDACTED]000000 rw- [heap]
0x00007ffff7dcb000 0x00007ffff7df0000 0x[PII_REDACTED]000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x[PII_REDACTED]025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x[PII_REDACTED]198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x[PII_REDACTED]1e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x[PII_REDACTED]1e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x[PII_REDACTED]000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x[PII_REDACTED]000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x[PII_REDACTED]000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x[PII_REDACTED]000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x[PII_REDACTED]001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x[PII_REDACTED]022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x[PII_REDACTED]029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x[PII_REDACTED]02a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x[PII_REDACTED]000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x[PII_REDACTED]000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x[PII_REDACTED]000000 r-x [vsyscall]
gef➤  p fgets
$2 = {char *(char *, int, FILE *)} 0x7ffff7e4d100 <_IO_fgets>
gef➤  search-pattern 0x7ffff7e4d100
[+] Searching '\x00\xd1\xe4\xf7\xff\x7f' in memory
[+] In '/tmp/tryc'(0x[PII_REDACTED]00-0x[PII_REDACTED]00), permission=r--
  0x555555557fd0 - 0x555555557fe8  →   "\x00\xd1\xe4\xf7\xff\x7f[...]"
```

Without relro:

```
gef➤  vmmap
Start              End                Offset             Perm Path
0x[PII_REDACTED]400000 0x[PII_REDACTED]401000 0x[PII_REDACTED]000000 r-- /tmp/try
0x[PII_REDACTED]401000 0x[PII_REDACTED]402000 0x[PII_REDACTED]001000 r-x /tmp/try
0x[PII_REDACTED]402000 0x[PII_REDACTED]403000 0x[PII_REDACTED]002000 r-- /tmp/try
0x[PII_REDACTED]403000 0x[PII_REDACTED]404000 0x[PII_REDACTED]002000 r-- /tmp/try
0x[PII_REDACTED]404000 0x[PII_REDACTED]405000 0x[PII_REDACTED]003000 rw- /tmp/try
0x[PII_REDACTED]405000 0x[PII_REDACTED]426000 0x[PII_REDACTED]000000 rw- [heap]
0x00007ffff7dcb000 0x00007ffff7df0000 0x[PII_REDACTED]000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x[PII_REDACTED]025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x[PII_REDACTED]198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x[PII_REDACTED]1e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x[PII_REDACTED]1e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x[PII_REDACTED]000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x[PII_REDACTED]000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x[PII_REDACTED]000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x[PII_REDACTED]000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x[PII_REDACTED]001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x[PII_REDACTED]022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x[PII_REDACTED]029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x[PII_REDACTED]02a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x[PII_REDACTED]000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x[PII_REDACTED]000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x[PII_REDACTED]000000 r-x [vsyscall]
gef➤  p fgets
$2 = {char *(char *, int, FILE *)} 0x7ffff7e4d100 <_IO_fgets>
gef➤  search-pattern 0x7ffff7e4d100
[+] Searching '\x00\xd1\xe4\xf7\xff\x7f' in memory
[+] In '/tmp/try'(0x404000-0x405000), permission=rw-
  0x404018 - 0x404030  →   "\x00\xd1\xe4\xf7\xff\x7f[...]"
```

For the binary without relro, we can see that the `got` entry address for `fgets` is `0x404018`. Looking at the memory mappings we see that it falls between `0x404000` and `0x405000`, which has the permissions `rw`, meaning we can read and write to it. For the binary with relro, we see that the `got` table address for the run of the binary (pie is enabled so this address will change) is `0x555555557fd0`. In that binary's memory mapping it falls between `0x[PII_REDACTED]557000` and `0x[PII_REDACTED]558000`, which has the memory permission `r`, meaning that we can only read from it.

So what's the bypass? The typical bypass I use is to just don't write to memory regions that relro causes to be read only, and find a different way to get code execution.