Skip to content

Instantly share code, notes, and snippets.

@brant-ruan
Created January 14, 2023 08:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brant-ruan/d19805a90480ca6cbb4027a6a004c095 to your computer and use it in GitHub Desktop.
Save brant-ruan/d19805a90480ca6cbb4027a6a004c095 to your computer and use it in GitHub Desktop.
Pawnyable LK06
#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