Created
January 14, 2023 08:46
-
-
Save brant-ruan/d19805a90480ca6cbb4027a6a004c095 to your computer and use it in GitHub Desktop.
Pawnyable LK06
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "bpf_insn.h" | |
#include <linux/bpf.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/socket.h> | |
#include <sys/syscall.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
void fatal(const char *msg) { | |
perror(msg); | |
exit(1); | |
} | |
int bpf(int cmd, union bpf_attr *attrs) { | |
return syscall(__NR_bpf, cmd, attrs, sizeof(*attrs)); | |
} | |
int map_create(int val_size, int max_entries) { | |
union bpf_attr attr = { | |
.map_type = BPF_MAP_TYPE_ARRAY, | |
.key_size = sizeof(int), | |
.value_size = val_size, | |
.max_entries = max_entries}; | |
int mapfd = bpf(BPF_MAP_CREATE, &attr); | |
if (mapfd == -1) | |
fatal("bpf(BPF_MAP_CREATE)"); | |
return mapfd; | |
} | |
int map_update(int mapfd, int key, void *pval) { | |
union bpf_attr attr = { | |
.map_fd = mapfd, | |
.key = (uint64_t)&key, | |
.value = (uint64_t)pval, | |
.flags = BPF_ANY}; | |
int res = bpf(BPF_MAP_UPDATE_ELEM, &attr); | |
if (res == -1) | |
fatal("bpf(BPF_MAP_UPDATE_ELEM)"); | |
return res; | |
} | |
int map_lookup(int mapfd, int key, void *pval) { | |
union bpf_attr attr = { | |
.map_fd = mapfd, | |
.key = (uint64_t)&key, | |
.value = (uint64_t)pval, | |
.flags = BPF_ANY}; | |
return bpf(BPF_MAP_LOOKUP_ELEM, &attr); | |
} | |
int main() { | |
unsigned long val; | |
int mapfd = map_create(sizeof(val), 4); | |
val = 0xdeadbeefcafebabe; | |
map_update(mapfd, 1, &val); | |
// prepare BPF program | |
struct bpf_insn insns[] = { | |
BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x08, 1), // key = 1 | |
BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x10, 0x1337), // val = 0x1337 | |
// arg1: mapfd | |
BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd), | |
// arg2: key pointer | |
BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), | |
BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8), | |
// arg3: value pointer | |
BPF_MOV64_REG(BPF_REG_ARG3, BPF_REG_2), | |
BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG3, -8), | |
// arg4: flags | |
BPF_MOV64_IMM(BPF_REG_4, 0), | |
BPF_EMIT_CALL(BPF_FUNC_map_update_elem), | |
BPF_MOV64_IMM(BPF_REG_0, 0), | |
BPF_EXIT_INSN(), | |
}; | |
char verifier_log[0x10000]; | |
// set usage | |
union bpf_attr prog_attr = { | |
.prog_type = BPF_PROG_TYPE_SOCKET_FILTER, | |
.insn_cnt = sizeof(insns) / sizeof(insns[0]), | |
.insns = (uint64_t)insns, | |
.license = (uint64_t) "GPL v2", | |
.log_level = 2, | |
.log_size = sizeof(verifier_log), | |
.log_buf = (uint64_t)verifier_log}; | |
// load BPF program | |
int progfd = bpf(BPF_PROG_LOAD, &prog_attr); | |
if (progfd == -1) | |
fatal("bpf(BPF_PROG_LOAD)"); | |
// create socket | |
int socks[2]; | |
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks)) | |
fatal("socketpair"); | |
if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(int))) | |
fatal("setsockopt"); | |
map_lookup(mapfd, 1, &val); | |
printf("val (before): 0x%lx\n", val); | |
// use socket | |
write(socks[1], "Hello", 5); | |
map_lookup(mapfd, 1, &val); | |
; | |
printf("val (after): 0x%lx\n", val); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment