Skip to content

Instantly share code, notes, and snippets.

@JasonTurley
Created July 20, 2025 22:44
Show Gist options
  • Select an option

  • Save JasonTurley/f142d08800e1b10ab29a50772d056845 to your computer and use it in GitHub Desktop.

Select an option

Save JasonTurley/f142d08800e1b10ab29a50772d056845 to your computer and use it in GitHub Desktop.
Linux kernel module crackme challenge
/*
* crackme-1: a simple crackme CTF challenge as a kernel module!
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#include <linux/uaccess.h>
#include <linux/string.h> // for strcmp
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
#define HAVE_PROC_OPS
#endif
#define CHALLENGE_NAME "crackme-1"
#define BUF_MAX_LEN 64
#define PASSWORD "59bcc3ad6775562f845953cf01624225"
static struct proc_dir_entry *proc_file;
static bool authorized = false;
// Function definitions
static ssize_t crackme_read(struct file* filp, char __user *buffer, size_t len, loff_t *off);
static ssize_t crackme_write(struct file* filp, const char __user *buffer, size_t len, loff_t *off);
#ifdef HAVE_PROC_OPS
static const struct proc_ops proc_file_fops = {
.proc_read = crackme_read,
.proc_write = crackme_write,
};
#else
static const struct file_operations proc_file_fops = {
.read = crackme_read,
.write = crackme_write,
};
#endif
static int __init crackme_init(void)
{
proc_file = proc_create(CHALLENGE_NAME, 0666, NULL, &proc_file_fops);
if (NULL == proc_file) {
pr_alert("Error: could not initialize /proc/%s\n", CHALLENGE_NAME);
return -ENOMEM;
}
pr_info("Hello! This is a kernel module crackme challenge.\nEnter the correct password to win.\n");
pr_info("/proc/%s created\n", CHALLENGE_NAME);
return 0;
}
/* Called when the /proc file is read from. Prints a message to dmesg. */
static ssize_t crackme_read(struct file* filp, char __user *buffer, size_t len, loff_t *offset)
{
const char *msg;
size_t msg_len;
// Prevent multiple reads from the /proc file
if (*offset > 0)
return 0; // EOF
if (authorized) {
msg = "You won! Please like and subscribe\n";
} else {
msg = "Enter the correct password in order to win!\n";
}
msg_len = strlen(msg);
// Copy message to user-space
if (copy_to_user(buffer, msg, msg_len))
return -EINVAL;
*offset = msg_len; // mark read as done
return msg_len;
}
/* Called when the /proc file is written to. Compares user input with the correct password. */
static ssize_t crackme_write(struct file *file, const char __user *buffer,
size_t len, loff_t *off)
{
char dest[BUF_MAX_LEN];
size_t length = len;
// Truncate buffer size if its about max length
if (length >= BUF_MAX_LEN)
length = BUF_MAX_LEN - 1;
// Read user input into destination buffer
if (copy_from_user(dest, buffer, length)) {
pr_alert("copy_from_user failed\n");
return -EINVAL;
}
// compare user input with correct password
if(!strcmp(dest, PASSWORD))
authorized = true;
return len;
}
static void __exit crackme_exit(void)
{
proc_remove(proc_file);
pr_info("/proc/%s removed\n", CHALLENGE_NAME);
}
module_init(crackme_init);
module_exit(crackme_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("@_jasonturley");
MODULE_DESCRIPTION("A simple crackme challenge");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment