-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from sigseg5/ref-global
Global refactoring: fix proper device shutdown and proc kill
- Loading branch information
Showing
9 changed files
with
271 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,74 @@ | ||
# kernKill | ||
Repo for DemHack-5 | ||
|
||
kernKill is a work-in-progress Linux kernel loadable module designed for emergency system management. It's primary function is to enable immediate shutdown or termination specific processes when a specified USB device is removed from a machine running a compatible Linux operating system. | ||
|
||
## Warning about the USB Stack | ||
|
||
It's important to be aware of the nuances and potential risks associated with the USB stack when using kernKill. Detailed information about these aspects is provided in the following sections. | ||
|
||
## Configuration process | ||
|
||
To configure kernKill, you need to know some system information about your system's USB devices. You can gather this information using the following commands: | ||
|
||
```bash | ||
# List all connected USB devices | ||
lsusb | ||
|
||
# Display driver information for USB devices | ||
lsusb -t | ||
``` | ||
|
||
You'll need to note USB Vendor and Product IDs. Next you should set these as environment variables with `export ...` or pass IDs like `USB_PRODUCT_ID=0xXXXX USB_VENDOR_ID=XXXX ...`. If you don't pass any IDs, the default values from the [Makefile](/Makefile) will be used. | ||
|
||
## Building the module | ||
|
||
### About build modes | ||
|
||
There are two modes: | ||
|
||
- `kill` (default) – in this mode, processes specified in [proc_list.h](/proc_list.h) are immediately killed from kernel space via SIGKILL. | ||
- `reboot` – in this mode, the kernel module will perform `emergency_restart()` exec from kernel space. | ||
|
||
kernKill is configurable via the [Makefile](/Makefile) included in the source code. By default, it operates in 'kill' mode, but you can switch to 'reboot' mode if necessary. Here's how to build in each mode: | ||
|
||
```bash | ||
# Building in 'kill' mode (default) | ||
USB_PRODUCT_ID=0x5678 \ | ||
USB_VENDOR_ID=0x1234 \ | ||
make | ||
|
||
# Building in 'reboot' mode | ||
USB_PRODUCT_ID=0x5678 \ | ||
USB_VENDOR_ID=0x1234 \ | ||
make MODE=reboot | ||
``` | ||
|
||
## Installation guide | ||
|
||
To install kernKill, run the provided script. This installation will also disable the `uas` and `usb-storage` drivers. This is to prevent the standard usb-storage stack from taking control of the USB device. In fact, it is enough to write a udev-rule to achieve feature parity with this kernel module. But that's boring, right? :) | ||
|
||
```bash | ||
./install.sh | ||
``` | ||
|
||
## Uninstallation procedure | ||
|
||
To uninstall kernKill and revert all changes made to your system, including re-enabling the `uas` and `usb-storage` drivers, use the following command: | ||
|
||
```bash | ||
./rollback.sh | ||
``` | ||
|
||
## Debugging tips | ||
|
||
For debugging, you can monitor kernel messages related to kernKill using: | ||
|
||
```bash | ||
sudo dmesg | grep kernKill | ||
``` | ||
|
||
## Additional information | ||
|
||
Note: This module was developed during dem-hack5 and is currently not recommended for real-world use. It has been tested on the x86_64 architecture with the Linux kernel version `6.5.6-76060506-generic`. The module theoretically supports any x86/x86_64 machine with relatively modern linux kernel, but has not been extensively tested in different environments. | ||
|
||
Always use caution and don't use it in a production environment. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/bin/bash | ||
|
||
sudo rmmod uas | ||
if [ $? -ne 0 ]; then | ||
echo "Error in removing uas module" | ||
fi | ||
|
||
sudo rmmod usb_storage | ||
if [ $? -ne 0 ]; then | ||
echo "Error in removing usb_storage module" | ||
fi | ||
|
||
sudo insmod kern_kill.ko | ||
if [ $? -ne 0 ]; then | ||
echo "Error in inserting kern_kill module" | ||
fi |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/******************************************************************************* | ||
* \file kern_kill.c | ||
* | ||
* \details kern_kill USB driver | ||
* | ||
* \author sigseg5 | ||
* | ||
* \Tested on 6.5.6-76060506-generic Linux kernel | ||
* | ||
*******************************************************************************/ | ||
|
||
#define _GNU_SOURCE | ||
|
||
#include <linux/reboot.h> | ||
#include <linux/usb.h> | ||
|
||
#include "proc_list.h" | ||
|
||
static int usb_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
{ | ||
struct usb_device *udev = interface_to_usbdev(interface); | ||
char serial_number[256]; | ||
if (udev->descriptor.iSerialNumber > 0) | ||
{ | ||
int ret = usb_string(udev, | ||
udev->descriptor.iSerialNumber, | ||
serial_number, | ||
sizeof(serial_number)); | ||
if (ret > 0) | ||
{ | ||
printk(KERN_INFO "kernKill: USB device connected (Vendor ID: 0x%04X, Product ID: 0x%04X, Serial Number: %s)\n", | ||
le16_to_cpu(udev->descriptor.idVendor), | ||
le16_to_cpu(udev->descriptor.idProduct), | ||
serial_number); | ||
} | ||
else | ||
{ | ||
printk(KERN_INFO "kernKill: Error retrieving USB device serial number\n"); | ||
} | ||
} | ||
else | ||
{ | ||
printk(KERN_INFO "kernKill: USB device does not have a serial number\n"); | ||
} | ||
return 0; | ||
} | ||
|
||
static void usb_disconnect(struct usb_interface *interface) | ||
{ | ||
struct usb_device *udev = interface_to_usbdev(interface); | ||
printk(KERN_INFO "kernKill: USB device disconnected (Vendor ID: 0x%04X, Product ID: 0x%04X)\n", | ||
le16_to_cpu(udev->descriptor.idVendor), | ||
le16_to_cpu(udev->descriptor.idProduct)); | ||
|
||
if (unlikely(udev->descriptor.idVendor == USB_VENDOR_ID && udev->descriptor.idProduct)) | ||
{ | ||
printk(KERN_INFO "kernKill: USB device signature matches!"); | ||
|
||
#ifdef MODE_REBOOT | ||
emergency_restart(); | ||
|
||
// Thus, this code is only compatible with x86_64 | ||
// The __NR_REBOOT system call is used | ||
// But it doesn't really work as expected :) | ||
|
||
// asm volatile( | ||
// "mov $0xa9, %al\n\t" | ||
// "mov $0xfee1dead, %edi\n\t" | ||
// "mov $0x28121969, %esi\n\t" | ||
// "mov $0x4321fedc, %edx\n\t" | ||
// "syscall\n\t"); | ||
|
||
// This for some reason disables bluetooth and the ability to correctly perform a kekw shutdown | ||
// STP instruction (0xDB): | ||
// STP stops the clock input of the 65C02, effectively shutting down the 65C02 until a hardware reset occurs | ||
|
||
// asm volatile("mov $0xDB, %ax\n\t" | ||
// "ltr %ax"); | ||
#endif | ||
|
||
#ifdef MODE_KILL | ||
struct task_struct *task; | ||
for_each_process(task) | ||
{ | ||
for (int i = 0; i < PROC_COUNT; i++) | ||
{ | ||
if (unlikely(strcmp(task->comm, KILL_PROC[i]) == 0)) | ||
{ | ||
printk(KERN_INFO "kernKill: Matched proc: %s, pid = %d\n", task->comm, task->pid); | ||
struct siginfo info; | ||
memset(&info, 0, sizeof(struct siginfo)); | ||
info.si_signo = SIGKILL; | ||
info.si_code = SI_QUEUE; | ||
info.si_int = 1; | ||
if (task != NULL) | ||
{ | ||
printk(KERN_INFO "kernKill: Sending signal to app\n"); | ||
if (send_sig_info(SIGKILL, (struct kernel_siginfo *)&info, task) < 0) | ||
{ | ||
printk(KERN_WARNING "kernKill: Unable to send signal\n"); | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
#endif | ||
} | ||
} | ||
|
||
static struct usb_device_id usb_table[] = { | ||
{USB_DEVICE(USB_VENDOR_ID, USB_PRODUCT_ID)}, | ||
{} | ||
}; | ||
|
||
MODULE_DEVICE_TABLE(usb, usb_table); | ||
|
||
static struct usb_driver usb_driver = { | ||
.name = "kern_kill", | ||
.probe = usb_probe, | ||
.disconnect = usb_disconnect, | ||
.id_table = usb_table, | ||
}; | ||
|
||
static int __init usb_notify_init(void) | ||
{ | ||
int result = usb_register(&usb_driver); | ||
if (result) | ||
printk(KERN_ERR "kernKill: USB driver registration failed: %d\n", result); | ||
return result; | ||
} | ||
|
||
static void __exit usb_notify_exit(void) | ||
{ | ||
usb_deregister(&usb_driver); | ||
} | ||
|
||
module_init(usb_notify_init); | ||
module_exit(usb_notify_exit); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("sigseg5"); | ||
MODULE_DESCRIPTION("kern_kill"); | ||
MODULE_VERSION("0.1"); |
Oops, something went wrong.