diff --git a/bi0sctf23/pow_solver.py b/bi0sctf23/pow_solver.py new file mode 100644 index 0000000..6296aeb --- /dev/null +++ b/bi0sctf23/pow_solver.py @@ -0,0 +1,15 @@ +from time import time +def solve_pow(s, debug=False): + start = time() + g = int(s.split("^")[0]) + p = int(s.split("mod ")[1].split(" == ")[0]) + target = int(s.split(" == ")[1]) + i = 0 + while True: + if pow(g, i, p) == target: + if debug: print(f'Time taken: {time()-start}') + return i + i += 1 + +# Pass the PoW line given by the challenge to this function +print(solve_pow(input(), debug=True)) \ No newline at end of file diff --git a/bi0sctf23/pwn/palindromatic/.config b/bi0sctf23/pwn/palindromatic/.config deleted file mode 100644 index c52c075..0000000 --- a/bi0sctf23/pwn/palindromatic/.config +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_SLUB=y -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLAB_FREELIST_HARDENED=y -CONFIG_SLUB_CPU_PARTIAL=y -CONFIG_RANDOM_KMALLOC_CACHES=y - -CONFIG_STATIC_USERMODEHELPER=y -CONFIG_STATIC_USERMODEHELPER_PATH="" \ No newline at end of file diff --git a/bi0sctf23/pwn/palindromatic/bzImage b/bi0sctf23/pwn/palindromatic/bzImage deleted file mode 100644 index 034249e..0000000 Binary files a/bi0sctf23/pwn/palindromatic/bzImage and /dev/null differ diff --git a/bi0sctf23/pwn/palindromatic/palindromatic.ko b/bi0sctf23/pwn/palindromatic/palindromatic.ko deleted file mode 100644 index 0647fac..0000000 Binary files a/bi0sctf23/pwn/palindromatic/palindromatic.ko and /dev/null differ diff --git a/bi0sctf23/pwn/palindromatic/rootfs.ext3 b/bi0sctf23/pwn/palindromatic/rootfs.ext3 deleted file mode 100644 index a9d5037..0000000 Binary files a/bi0sctf23/pwn/palindromatic/rootfs.ext3 and /dev/null differ diff --git a/bi0sctf23/pwn/palindromatic/run.sh b/bi0sctf23/pwn/palindromatic/run.sh deleted file mode 100644 index 0cc4d59..0000000 --- a/bi0sctf23/pwn/palindromatic/run.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -qemu-system-x86_64 \ - -m 64M \ - -cpu kvm64,+smep,+smap \ - -kernel bzImage \ - -drive file=rootfs.ext3,format=raw \ - -drive file=exploit,format=raw \ - -snapshot \ - -nographic \ - -monitor /dev/null \ - -no-reboot \ - -append "root=/dev/sda rw init=/init console=ttyS0 kaslr kpti=1 loglevel=0 oops=panic panic=-1" diff --git a/bi0sctf23/pwn/palindromatic/src/palindromatic.c b/bi0sctf23/pwn/palindromatic/src/palindromatic.c deleted file mode 100644 index 1270b2a..0000000 --- a/bi0sctf23/pwn/palindromatic/src/palindromatic.c +++ /dev/null @@ -1,241 +0,0 @@ -#include "linux/random.h" -#include "palindromatic_util.c" - -char *temp_buffer; -unsigned long magic; -queue_t incoming_queue; -queue_t outgoing_queue; -bool sanitized = false; - -/* - Copy request from user and add to start of queue -*/ -static noinline long pm_add_request(arg_t *arg) -{ - long idx = -1; - request_t *req = kmem_cache_zalloc(pm_cache, GFP_KERNEL); - if(!req) goto end; - - req->type = RAW; - req->magic = magic; - if(copy_from_user(req->str, arg->buffer, STRING_SZ)) - { - kfree(req); - goto end; - } - idx = pm_queue_enqueue(&incoming_queue, req); - -end: - return idx; -} - -/* - Accept characters only in [A-Z|a-z] and translate to [A-Z] - Only 1 sanitize is allowed -*/ -static noinline long pm_sanitize_request(void) -{ - long idx = -1; - - request_t *req = pm_queue_peek(&incoming_queue); - if(!req) goto end; - if(req->type == SANITIZED) goto end; - - memset(temp_buffer, 0x0, STRING_SZ); - - int ptr = 0; - for(int i = 0; i < STRING_SZ; i++) - { - if(!req->str[i]) break; - - if(req->str[i] > 0x60 && req->str[i] < 0x7b) - temp_buffer[ptr++] = req->str[i]-0x20; - - else if(req->str[i] > 0x40 && req->str[i] < 0x5b) - temp_buffer[ptr++] = req->str[i]; - - else continue; - } - - temp_buffer[ptr] = 0; - strcpy(req->sanstr, temp_buffer); - req->type = SANITIZED; - - idx = pm_queue_enqueue(&incoming_queue, pm_queue_dequeue(&incoming_queue)); - -end: - return idx; -} - -/* - If request is raw, remove it - else, set it to raw and send it back to start of the queue -*/ -static noinline long pm_reset_request(void) -{ - request_t *req = pm_queue_dequeue(&incoming_queue); - if(!req) return -1; - - if(req->type != RAW) - { - req->type = RAW; - memset(req->sanstr, 0x0, sizeof(req->sanstr)); - pm_queue_enqueue(&incoming_queue, req); - } - - else - { - kfree(req); - } - return 0; -} - -/* - Check if it is a palindrome or not and set type accordingly - Remove from incoming queue and add to outgoing queue -*/ -static noinline long pm_process_request(void) -{ - long idx = -1; - - request_t *req = pm_queue_peek(&incoming_queue); - if(!req) goto end; - if(req->magic != magic) goto end; - int len = req->type==SANITIZED?strlen(req->sanstr):strlen(req->str); - if(!len) goto end; - idx = pm_queue_enqueue(&outgoing_queue, req); - if(idx < 0) goto end; - - memset(temp_buffer, 0x0, STRING_SZ); - if(req->type == RAW) - { - for(int i = (len/2)-1; i > -1; i--) - { - if(req->str[i] < 0x41 || req->str[i] > 0x5a) break; - temp_buffer[i] = req->str[i]; - } - temp_buffer[len/2] = 0; - - if(strcmp(temp_buffer, &req->str[len/2]+len%2)) req->type = NONPALINDROME; - else req->type = PALINDROME; - pm_queue_dequeue(&incoming_queue); - } - - if(req->type == SANITIZED) - { - for(int i = (len/2)-1; i > -1; i--) temp_buffer[i] = req->sanstr[i]; - temp_buffer[len/2] = 0; - - if(strcmp(temp_buffer, &req->sanstr[len/2]+len%2)) req->type = NONPALINDROME; - else req->type = PALINDROME; - pm_queue_dequeue(&incoming_queue); - } - -end: - return idx; -} - -/* - Get result of first request in outgoing queue -*/ -static noinline long pm_reap_request(void) -{ - request_t *req = pm_queue_dequeue(&outgoing_queue); - if(!req) return -1; - if(req->magic != magic) return -1; - - long ret = req->type==PALINDROME?1:0; - kfree(req); - - return ret; -} - -/* - Get the available slots in both queues -*/ -static noinline long pm_query_capacity(void) -{ - long ret = (QUEUE_SZ-pm_queue_count(&outgoing_queue))<<16 - | (QUEUE_SZ-pm_queue_count(&incoming_queue)); - return ret; -} - - -static long pm_ioctl(struct file *file, unsigned int cmd, unsigned long uarg) -{ - arg_t arg; - long ret = -1; - mutex_lock(&lock); - - switch(cmd) - { - case QUEUE: - if(copy_from_user(&arg, (void *)uarg, sizeof(arg_t))) goto end; - ret = pm_add_request(&arg); - break; - - case SANITIZE: - if(sanitized) goto end; - sanitized = true; - ret = pm_sanitize_request(); - break; - - case RESET: - ret = pm_reset_request(); - break; - - case PROCESS: - ret = pm_process_request(); - break; - - case REAP: - ret = pm_reap_request(); - break; - - case QUERY: - ret = pm_query_capacity(); - break; - - default: - goto end; - } - -end: - mutex_unlock(&lock); - return ret; -} - - -static int __init init_palindromatic(void) -{ - if(misc_register(&pm_device) < 0) goto err; - - pm_cache = kmem_cache_create("palindromatic", TARGET_SZ, __alignof__(request_t), - SLAB_ACCOUNT | SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NO_MERGE, NULL); - if(!pm_cache) goto err; - - temp_buffer = kzalloc(TARGET_SZ, GFP_KERNEL); - if(!temp_buffer) goto err; - - get_random_bytes(&magic, sizeof(magic)); - pm_queue_init(&incoming_queue); - pm_queue_init(&outgoing_queue); - - return 0; - -err: - if(pm_cache) kmem_cache_destroy(pm_cache); - printk(KERN_ALERT "[-] Failed to register pipeparty"); - return -1; -} - - -static void __exit exit_palindromatic(void) -{ - kfree(temp_buffer); - kmem_cache_destroy(pm_cache); - misc_deregister(&pm_device); -} - -module_init(init_palindromatic); -module_exit(exit_palindromatic); \ No newline at end of file diff --git a/bi0sctf23/pwn/palindromatic/src/palindromatic.h b/bi0sctf23/pwn/palindromatic/src/palindromatic.h deleted file mode 100644 index 8530c52..0000000 --- a/bi0sctf23/pwn/palindromatic/src/palindromatic.h +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("k1R4"); -MODULE_DESCRIPTION("\"palindromatic\" - bi0s CTF 2023"); -MODULE_LICENSE("GPL"); - -enum : unsigned int -{ - QUEUE = 0xb10500a, - SANITIZE, - RESET, - PROCESS, - REAP, - QUERY -}; - -typedef enum ptype : unsigned long -{ - RAW = 0x1337, - SANITIZED, - PALINDROME, - NONPALINDROME -} ptype; - -#define TARGET_SZ 0x400 -#define STRING_SZ ((TARGET_SZ-2*sizeof(unsigned long))/2) - -typedef struct request_t -{ - ptype type; - unsigned long magic; - char str[STRING_SZ]; - char sanstr[STRING_SZ]; -} request_t; - -typedef struct arg_t -{ - char *buffer; -} arg_t; - -#define QUEUE_SZ 0x100 - -typedef struct queue_t -{ - int front; - int rear; - request_t *reqs[QUEUE_SZ]; -} queue_t; - -DEFINE_MUTEX(lock); -struct kmem_cache *pm_cache; - -static noinline long pm_ioctl(struct file *file, unsigned int cmd, unsigned long uarg); - -static struct file_operations pm_fops = { .unlocked_ioctl = pm_ioctl }; - -struct miscdevice pm_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "palindromatic", - .fops = &pm_fops, -}; \ No newline at end of file diff --git a/bi0sctf23/pwn/palindromatic/src/palindromatic_util.c b/bi0sctf23/pwn/palindromatic/src/palindromatic_util.c deleted file mode 100644 index 4792fb9..0000000 --- a/bi0sctf23/pwn/palindromatic/src/palindromatic_util.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "palindromatic.h" - -static void pm_queue_init(queue_t *queue) -{ - queue->front = queue->rear = -1; - for(int i = 0; ireqs[i] = NULL; -} - - -static long pm_queue_enqueue(queue_t *queue, request_t *req) -{ - if((queue->front == 0 && queue->rear == QUEUE_SZ-1) || (queue->rear+1)%QUEUE_SZ == queue->front) return -1; - - else if(queue->front == -1) - { - queue->front = queue->rear = 0; - queue->reqs[queue->rear] = req; - } - - else if(queue->rear == QUEUE_SZ-1 && queue->front != 0) - { - queue->rear = 0; - queue->reqs[queue->rear] = req; - } - - else - { - queue->rear++; - queue->reqs[queue->rear] = req; - } - - return queue->rear; -} - - -static request_t *pm_queue_dequeue(queue_t *queue) -{ - if(queue->front == -1) return NULL; - - request_t *req = queue->reqs[queue->front]; - queue->reqs[queue->front] = NULL; - - if(queue->front == queue->rear) queue->front = queue->rear = -1; - else if(queue->front == QUEUE_SZ-1) queue->front = 0; - else queue->front++; - - return req; -} - - -static request_t *pm_queue_peek(queue_t *queue) -{ - if(queue->front == -1) return NULL; - else return queue->reqs[queue->front]; -} - - -static int pm_queue_count(queue_t *queue) -{ - if(queue->front == -1) - return 0; - - else if(queue->rear >= queue->front) - return queue->rear-queue->front+1; - - else - return QUEUE_SZ - queue->front + queue->rear + 1; -} \ No newline at end of file diff --git a/bi0sctf23/pwn/virtio-note/.gitignore b/bi0sctf23/pwn/virtio-note/.gitignore new file mode 100644 index 0000000..936206c --- /dev/null +++ b/bi0sctf23/pwn/virtio-note/.gitignore @@ -0,0 +1,3 @@ +./linux/ +./files/ +linux-6.7.2.tar.xz diff --git a/bi0sctf23/pwn/virtio-note/exploit/.Module.symvers.cmd b/bi0sctf23/pwn/virtio-note/exploit/.Module.symvers.cmd new file mode 100644 index 0000000..60470f3 --- /dev/null +++ b/bi0sctf23/pwn/virtio-note/exploit/.Module.symvers.cmd @@ -0,0 +1 @@ +savedcmd_/home/cato/CTF/bi0sctf23/pwn/virtio-note/exploit/Module.symvers := scripts/mod/modpost -M -o /home/cato/CTF/bi0sctf23/pwn/virtio-note/exploit/Module.symvers -T /home/cato/CTF/bi0sctf23/pwn/virtio-note/exploit/modules.order -i Module.symvers -e diff --git a/bi0sctf23/pwn/virtio-note/exploit/.modules.order.cmd b/bi0sctf23/pwn/virtio-note/exploit/.modules.order.cmd new file mode 100644 index 0000000..350ebc6 --- /dev/null +++ b/bi0sctf23/pwn/virtio-note/exploit/.modules.order.cmd @@ -0,0 +1 @@ +savedcmd_/home/cato/CTF/bi0sctf23/pwn/virtio-note/exploit/modules.order := { echo /home/cato/CTF/bi0sctf23/pwn/virtio-note/exploit/malicious_driver.o; :; } > /home/cato/CTF/bi0sctf23/pwn/virtio-note/exploit/modules.order diff --git a/bi0sctf23/pwn/virtio-note/exploit/Makefile b/bi0sctf23/pwn/virtio-note/exploit/Makefile new file mode 100644 index 0000000..532d389 --- /dev/null +++ b/bi0sctf23/pwn/virtio-note/exploit/Makefile @@ -0,0 +1,7 @@ +obj-m += malicious_driver.o + +all: + make -C ../linux M=$(PWD) modules + +clean: + make -C ../linux M=$(PWD) clean diff --git a/bi0sctf23/pwn/virtio-note/exploit/malicious_driver.c b/bi0sctf23/pwn/virtio-note/exploit/malicious_driver.c new file mode 100644 index 0000000..28756be --- /dev/null +++ b/bi0sctf23/pwn/virtio-note/exploit/malicious_driver.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include /* io map */ +#include /* DMA */ +#include /* kstrtoint() func */ +#include /* find_single_vq() func */ + +#include "../files/src/virtio-note.h" + + +#define VIRTIO_NOTE_ID 42 + +static void virtio_note_store(struct device *dev, const char *buf, size_t count){ + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + + +} + +static void virtio_dummy_recv_cb(struct virtqueue *vq) +{ + struct virtio_dummy_dev *dev = vq->vdev->priv; + char *buf; + unsigned int len; + + while ((buf = virtqueue_get_buf(dev->vq, &len)) != NULL) { + pr_info("%s\n", buf); + } +} + +static int virtio_dummy_probe(struct virtio_device *vdev) +{ + struct virtio_dummy_dev *dev = NULL; + + /* initialize device data */ + dev = kzalloc(sizeof(struct virtio_dummy_dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + /* the device has a single virtqueue */ + dev->vq = virtio_find_single_vq(vdev, virtio_dummy_recv_cb, "input"); + if (IS_ERR(dev->vq)) { + kfree(dev); + return PTR_ERR(dev->vq); + + } + vdev->priv = dev; + + /* from this point on, the device can notify and get callbacks */ + virtio_device_ready(vdev); + + return 0; +} + +static void virtio_dummy_remove(struct virtio_device *vdev) +{ + struct virtio_dummy_dev *dev = vdev->priv; + + /* + * disable vq interrupts: equivalent to + * vdev->config->reset(vdev) + */ + virtio_reset_device(vdev); + + char *buf; + /* detach unused buffers */ + while ((buf = virtqueue_detach_unused_buf(dev->vq)) != NULL) { + kfree(buf); + } + + /* remove virtqueues */ + vdev->config->del_vqs(vdev); + + kfree(dev); +} + +static const struct virtio_device_id id_table[] = { + { VIRTIO_NOTE_ID, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static struct virtio_driver virtio_dummy_driver = { + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = virtio_dummy_probe, + .remove = virtio_dummy_remove, +}; + +module_virtio_driver(virtio_dummy_driver); +MODULE_DEVICE_TABLE(virtio, id_table); +MODULE_DESCRIPTION("Dummy virtio driver"); +MODULE_LICENSE("GPL");