Vista Normal

Hay nuevos artículos disponibles. Pincha para refrescar la página.
AnteayerSalida Principal

Linux Fu: Kernel Modules Have Privileges

19 Junio 2024 at 14:00

I did something recently I haven’t done in a long time: I recompiled the Linux kernel. There was a time when this was a common occurrence. You might want a feature that the default kernel didn’t support, or you might have an odd piece of hardware. But these days, in almost all the cases where you need something like this, you’ll use loadable kernel modules (LKM) instead. These are modules that the kernel can load and unload at run time, which means you can add that new device or strange file system without having to rebuild or even restart the kernel.

Normally, when you write programs for Linux, they don’t have any special permissions. You typically can’t do direct port I/O, for example, or arbitrarily access memory. The kernel, however, including modules, has no such restriction. That can make debugging modules tricky because you can easily bring the system to its knees. If possible, you might think about developing on a virtual machine until you have what you want. That way, an errant module just brings down your virtual machine.

History

Some form of module support has been around since Linux 1.2. However, modern kernels can be built to include support for things or support them as modules. For example, you probably don’t want to put drivers for every single known video card in your kernel. But it is perfectly fine to build dozens or hundreds of modules you might need and then load the one you need at run time.

LKMs are at the heart of device drivers, file system drivers, and network drivers. In addition, modules can add new system calls, override existing system calls, add TTY line disciplines, and handle how executables run.

In Use

If you want to know what modules you have loaded, that’s the lsmod command. You’ll see that some modules depend on other modules and some don’t. There are two ways to load modules: insmod and modprobe. The insmod command simply tries to load a module. The modprobe command tries to determine if the module it is loading needs other modules and picks them up from a known location.

You can also remove modules with rmmod assuming they aren’t in use. Of course, adding and removing modules requires root access. You can usually run lsmod as a normal user if you like. You might also be interested in depmod to determine dependencies, and modinfo which shows information about modules.

Writing a Module

It is actually quite easy to write your own module. In fact, it is so simple that the first example I want to look at is a little more complex than necessary.

This simple module can load and unload. It leaves a message in the system messages (use dmesg, for example) to tell you it is there. In addition, it allows you to specify a key (just an arbitrary integer) when you load it. That number will show up in the output data. Here’s the code:

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/printk.h>

MODULE_AUTHOR("Al Williams");
MODULE_DESCRIPTION("Hackaday LKM");
MODULE_LICENSE("GPLv2"); // many options, GPL, GPLv2, Proprietary, etc.

static int somedata __initdata=0xbeef; // this is just some static variable available only at init
static int key=0xAA; // you can override this using insmod
// Note 0644 means that the sysfs entry will be rw-r--r--
module_param(key,int,0644); // use module_param_named if you want different names internal vs external
MODULE_PARM_DESC(key,"An integer ID unique to this module");

static int __init had_init(void)
{
  // This is the usual way to do this (don't forget \n and note no comma after KERN_INFO), but...
  printk(KERN_INFO "Hackaday is in control (%x %x)\n",key,somedata);
  return 0;
}

static void __exit had_exit(void)
{
  // ... you can also use the pr_info macro which does the same thing
  pr_info("Returning control of your system to you (%x)!\n",key);
}

module_init(had_init);
module_exit(had_exit);&lt;/pre&gt;

This isn’t hard to puzzle out. Most of it is include files and macros that give modinfo something to print out. There are some variables: somedata is just a set variable that is readable during initialization. The key variable has a default but can be set using insmod. What’s more, is because module_param specifies 0644 — an octal Linux permission — there will be an entry in the /sys/modules directory that will let the root set or read the value of the key.

At the end, there are two calls that register what happens when the module loads and unloads. The rest of the code is just something to print some info when those events happen.

I printed data in two ways: the traditional printk and using the pr_info macro which uses printk underneath, anyway. You should probably pick one and stick with it. I’d normally just use pr_info.

Building the modules is simple assuming you have the entire build environment and the headers for the kernel. Here’s a simple makefile (don’t forget to use tabs in your makefile):

<pre>obj-m += hadmod1.o

PWD := $(CURDIR) # not needed in most cases, but useful if using sudo

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean</pre>

Once you build things, you should have a .ko file (like hadmod.ko). That’s the module. Try a few things:

  1. sudo insmod hadmod.ko   # load the module
  2. sudo dmesg  # see the module output
  3. cat /sys/modules/hadmodule/key   # see the key (you can set it, too, if you are root)
  4. sudo rmmod hadmod.ko  # unload the module
  5. sudo insmod hadmod.ko key=128   # set key this time and repeat the other steps

That’s It?

That is it. Of course, the real details lie in how you interact with the kernel or hardware devices, but that’s up to you. Just to give a slightly meatier example, I made a second version of the module that adds /proc/jollywrencher to the /proc filesystem. Here’s the code:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/printk.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/proc_fs.h> // Module metadata
#include <linux/version.h>

MODULE_AUTHOR("Al Williams");
MODULE_DESCRIPTION("Hackaday LKM1");
MODULE_LICENSE("GPLv2"); // many options, GPL, GPLv2, Proprietary, etc.


static char logo[]=
"                                                                                \n"\
"                                                                                \n"\
"                                                                                \n"\
"           #@@@@@@                                            ,@@@@@@           \n"\
"              &@@@@@*                                       &@@@@@,             \n"\
"               @@@@@@%                                     @@@@@@#              \n"\
"   @@       .@@@@@@@@@                                    .@@@@@@@@@       .@#  \n"\
"   &@@@&  /@@@@@@@@@@@@                                   @@@@@@@@@@@@   @@@@*  \n"\
"    @@@@@@@@@@@@@@@@@@@@@#                             @@@@@@@@@@@@@@@@@@@@@,   \n"\
"      &@@@@@@@@@@@@@@@@@@@@@*    ,@@@@@@@@@@@@%     &@@@@@@@@@@@@@@@@@@@@@*     \n"\
"           ,*.  @@@@@@@@@@@/ .@@@@@@@@@@@@@@@@@@@@&  &@@@@@@@@@@#  **           \n"\
"                   @@@@@@, &@@@@@@@@@@@@@@@@@@@@@@@@@, %@@@@@&                  \n"\
"                     ,@& /@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@                     \n"\
"                        &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*                       \n"\
"                       %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.                      \n"\
"                       @@@@@@       #@@@@@@@.      /@@@@@@                      \n"\
"                      /@@@@&         @@@@@@.         @@@@@                      \n"\
"                      ,@@@@%      (@@@@@@@@@@&*      @@@@@                      \n"\
"                       @@@@@#  @@@@@@@@@@@@@@@@@@%  @@@@@&                      \n"\
"                       /@@@@@@@@@@@@@@@, #@@@@@@@@@@@@@@@                       \n"\
"                     @@ *@@@@@@@@@@@@@& ( @@@@@@@@@@@@@@ .@(                    \n"\
"                  %@@@@@. @@@@@@@@@@@@@@@@@@@@@@@@@@@@% #@@@@@*                 \n"\
"          (%&%((@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@% ,@@@@@@@@@@*#&&#/         \n"\
"      @@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@(  @@@@@@@@@@@@@@@@@@@@@&     \n"\
"    @@@@@@@@@@@@@@@@@@@@@     @@@@@@*@@@@@@/%@@@@@&    *@@@@@@@@@@@@@@@@@@@@#   \n"\
"   @@@@.   @@@@@@@@@@@.         ..      .      .          (@@@@@@@@@@#   /@@@*  \n"\
"   @,        %@@@@@@@@                                    .@@@@@@@@.        &#  \n"\
"               ,@@@@@(                                     @@@@@@               \n"\
"             *@@@@@@                                        (@@@@@@             \n"\
"           @@@@@@,                                             %@@@@@@          \n"\
"                                                                                \n"\
"                                                                                ";

static struct proc_dir_entry *proc_entry;
static ssize_t had_read(struct file *f, char __user * user_buffer, size_t count, loff_t * offset)
  {
  size_t len;
  if (*offset>0) return 0; // no seeking, please!
  copy_to_user(user_buffer,logo,len=strlen(logo)); // skipped error check
  *offset=len;
  return len;
  }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
static struct proc_ops procop = // prior to Linux 5.6 you needed file_operations
{
  .proc_read=had_read
};
#else
static struct file_operations procop =
{
  .owner=THIS_MODULE,
  .read=had_read
#endif

static int __init had_init(void)
{
  // This is the usual way to do this (don't forget \n and note no comma after KERN_INFO), but...
  printk(KERN_INFO "Hackaday<1>; is in control\n");
  proc_entry=proc_create("jollywrencher",0644,NULL,&amp;procop);
  return 0;
}

static void __exit had_exit(void)
{
  // ... you can also use the pr_info macro which does the same thing
  pr_info("Returning control of your system to you...\n");
  proc_remove(proc_entry);
}

module_init(had_init);
module_exit(had_exit);

The only thing here is you have an extra function that you have to register and deregister with the kernel. However, that interface changed in Kernel 5.6, so the code tries to do the right thing. Until, of course, it gets changed again.

Once you load this module using insmod, you can cat /proc/jollywrencher to see your favorite web site’s logo.

Of course, this is a dead simple example, but it is enough to get you started. You can grab all the source code online. One great way to learn more is to find something similar to what you want to build and take it apart.

We don’t suggest it, but you can write an LKM in Scratch. If you really want to learn the kernel, maybe start at the beginning.

Lindroid Promises True Linux on Android

19 Junio 2024 at 02:00

Since Android uses Linux, you’d think it would be easier to run Linux apps on your Android phone or tablet. There are some solutions out there, but the experience is usually less than stellar. A new player, Lindroid, claims to provide real Linux distributions with hardware-accelerated Wayland on phones. How capable is it? The suggested window manager is KDE’s KWIN. That software is fairly difficult to run on anything but a full-blown system with dbus, hardware accelerations, and similar features.

There are, however, a few problems. First, you need a rooted phone, which isn’t totally surprising. Second, there are no clear instructions yet about how to install the software. The bulk of the information available is on an X thread. You can go about 4 hours into the very long video below to see a slide presentation about Lindroid.

While it appears Linux is running inside a container, it looks like they’ve opened up device access, which allows a full Linux experience even though Linux is technically, in this case, an Android app.

We are interested in seeing how this works, and when the instructions show up, we might root an old phone to try it out. Of course, there are other methods. Termux seems to be the most popular, but running GUI programs on it isn’t always the best experience. Not that we haven’t done it.

Raspberry Pi Saves Printer from Junk Pile

13 Junio 2024 at 08:00

Around here, printers have a life expectancy of about two years if we are lucky. But [techtipsy] has a family member who has milked a long life from an old Canon PIXMA printer. That is, until Microsoft or Canon decided it was too old to print anymore. With Windows 10, it took some hacking to get it to work, but Windows 11 was the death knell. Well, it would have been if not for [techtipsy’s] ingenuity with a Raspberry Pi.

The Pi uses Linux, and, of course, Linux will happily continue to print without difficulty. If you are Linux savvy, you can probably see where this is going.

It is a simple task to connect the printer to the Pi, set up CUPS, and then share the printer over the network. While Windows doesn’t want to drive the printer directly, it is more than happy to talk to it as a network printer.

While [techtipsy] was happy enough just to use Linux to start with, not everyone appreciates that option either because they are familiar with Windows or there’s some reason (e.g., hardware or work rules) that requires Windows. Once the printer is set up with the Pi, it doesn’t require any special knowledge to use it.

We’ve thought about doing something like this to put cheap thermal printers on the network. CUPS supports 3D printers, too, but we’ve never seen anyone really using it that way.

FLOSS Weekly Episode 786: What Easy Install Script?

5 Junio 2024 at 23:00

This week Jonathan Bennett and Rob Campbell chat with Brodie Robertson about Linux, Wayland, YouTube, Microsoft’s Windows Recall and more. Is Linux ready for new users? Is Recall going to kick off a migration? All this and more!

Main Channel: https://www.youtube.com/@BrodieRobertson

Podcast: https://www.youtube.com/@TechOverTea

Did you know you can watch the live recording of the show right in the Hackaday Discord? Have someone you’d like use to interview? Let us know, or contact the guest and have them contact us!

Direct Download in DRM-free MP3.

If you’d rather read along, here’s the transcript for this week’s episode.

Places to follow the FLOSS Weekly Podcast:

This Windows Installer Installs Linux

Por: Jenny List
5 Mayo 2024 at 20:00

It may be a very long time since some readers have installed a copy of Windows, but it appears at one point during the installation there’s a step that asks you which OS version you would like to install. Normally this is populated by whichever Windows flavours come on the install medium, but [Naman Sood] has other ideas. How about a Windows installer with Alpine Linux as one of the choices? Sounds good to us.

You can see it in action in the video below the break. Indeed Alpine Linux appears as one of the choices, followed by the normal Windows licence accept screen featuring the GPL instead of any MS text. The rest of the installer talks about installing Windows, but we can forgive it not expecting a Linux install instead.

So, the question we’re all asking is: how is it done? The answer lies in a WIM file, a stock Windows image which the installer unpacks onto your hard drive. The Linux distro needs to be installable onto an NTFS root partition, and to make it installable there’s a trick involving the Windows pre-installation environment.

This is an amusing hack, but the guide admits it’s fragile and perhaps not the most useful. Even so, the sight of Linux in a Windows installer has to be worth it.

This Week in Security: Default Passwords, Lock Slapping, and Mastodown

3 Mayo 2024 at 14:00

The UK has the answer to all our IoT problems: banning bad default passwords. Additionally, the new UK law requires device makers to provide contact info for vulnerability disclosures, as well as a requirement to advertise vulnerability fix schedules. Is this going to help the security of routers, cameras, and other devices? Maybe a bit.

I would argue that default passwords are in themselves the problem, and complexity requirements only nominally help security. Why? Because a good default password becomes worthless once the password, or algorithm leaks. Let’s lay out some scenarios here. First is the static default password. Manufacturer X makes device Y, and sets the devices to username/password admin/new_Complex_P@ssword1!. Those credentials make it onto a default password list, and any extra security is lost.

What about those devices that have a different, random-looking password for each device? Those use an algorithm to derive that password from the MAC address and/or serial number. That may help the situation, but the algorithm can be retrieved from the firmware, and most serial numbers are predictable in one way or another. This approach is better, but not a silver bullet.

So what would a real solution to the password problem look like? How about no default password at all, but no device functionality until the new password passes a cracklib complexity and uniqueness check. I have seen a few devices that do exactly this. The requirement for a disclosure address is a great idea, which we’ve talked about before regarding the similar EU legislation.

Lock Vulnerabilities

Vulnerabilities and bypasses aren’t unique to software. They are, however, much harder to patch in hardware. Take for instance, the Mul-T-Lock SBNE12 padlock. This lock really looks like it was carefully made to be secure. If you’re not familiar with [LockPickingLawyer]’s videos, the two minutes it takes him to pick this lock is a ringing endorsement. However, the lock does have a weakness, and LPL challenges us to figure it out. I’ll give you a hint, that the problem can be seen during the lock teardown at 2:25. See below the video for the explanation.

The problem here is demonstrated by [Trevor], AKA @McNallyOfficial. It’s the springs. The retainer pin is also the lock pin, and that pin is held in place by a pair of springs. The lock is probably designed such that you can lock the shackle without the key, and that means that there is enough play in those springs to slip the pin over the locking lip. Just a good smack in the right place uses the inertia of the locking pin to compress the springs and slip the shackle. It’s a bit disconcerting how many locks can be opened this way.

Fuzzing!

First up we have a walk-through to setting up a function fuzzing run with American Fuzzy Loop (AFL). First let’s cover *why* you might want to do this. We’re looking for vulnerabilities, and the scenario [Craig Young] lays out is one where we have a binary listening for HTTP calls on port 8080, and using some internal code to parse the request bodies. We want to throw a bunch of weird data at that parser to see how it breaks, and using real HTTP requests is way too slow when compared to direct function calls.

AFL is quite clever about its approach, particularly when you run it with “instrumentation”, or injected code that tracks what target code is being run in response to the AFL input. This allows AFL to track what fuzzing input resulted in exercising new target code paths. (It did something new, make a note!) That only works when re-compiling a program from source. The approach to use with a pre-compiled binary is to run it under QEMU so AFL can spy on execution. And in this case, that executable into a shared library to get to the target function directly.

To make that bit of magic work, the Library to Instrument Executable Files (LIEF) is used. When given the function address, this spits out a cooked shared object .so file. The actual harness is a bit of trivial code to call into that function and capture the output. And with that, you can start throwing interesting fuzz data at compiled code.

Fuzzing the Kernel

The Linux kernel has support for NVMe-oF, or Non-Volatile Memory express over Fabric, a high speed data storage link that can run over fiber, Ethernet, or simple TCP. That TCP support is interesting, as it means the kernel itself is opening INET sockets directly, which is why [Alon Zahavi] found it a juicy target for finding vulnerabilities. Because we’re talking the kernel, we can’t just trivially connect AFL like above. Thankfully there’s a fuzzer that’s written specifically for kernel fuzzing: syzkaller.

This one is a bit more complicated, and code has to be added for each subsystem that is supported. But NVME-oF is a supported module. The kernel also has the KCOV subsystem, for collecting coverage data during a run. It took quite a bit of work to add all the necessary bits, but [Alon] but the time in, and came up with 5 nice bug finds in the targeted code. Nice!

Water Hacking

We’ve looked at reported hacks against water treatment plants in the past, and so far there has been lots of splash, and very little substance. That hasn’t kept government agencies from beating the proverbial wardrum about attacks. That said, there is a lot of room for improvement in how these critical systems are secured. Apparently there was one actual breach that caused a tank to overflow, and a second attempt, where 37,000 credential were stuffed into a public-facing firewall over a span of about four days. If our critical systems actually have Internet-facing login pages, then something has truly gone wrong in a fundamental way.

Windows Registry Continued

The ongoing dive into the Windows registry continues over at Google Project Zero. This time with a blast from the past: The registry as it was in Windows 3.1. Way back then it was strictly for file type handling and OLE and COM object handling. Then Windows NT came along with NT 3.1, and started stuffing more and more setting data into the registry. Today, we’re at a crazy 100,000 lines of registry code in the Windows kernel. It’s no wonder this struck Project Zero as a good place to look for Windows vulnerabilities.

Mastodown

We got a bit of a chuckle out of this one, as the folks at It’s FOSS are asking readers not to share links to itsfoss.com stories on Mastodon. Why? Because apparently posting a link to Mastodon triggers a micro-DDOS, as each of the federated Mastodon instances pull a copy of the linked site, to generate a preview. The Mastodon code currently uses a random delay of up to 60 seconds to mitigate the issue. But for some sites that’s just not enough, and the traffic spike from multiple servers pulling a preview copy can be enough to take the site temporarily offline.

A bit of research was done back in 2022, which found that a moderately well-connected Mastodon server would generate just shy of 400 page loads per minute, when a link was shared. It’s likely those numbers are higher now, but still unlikely to be the sort of volume that a post going viral on a link aggregator would generate. Put another way, this seems to be a smaller problem than the classic “Slashdot Effect”.

So on one hand, it would be nice if the Mastodon project could puzzle out a way to keep every federated server from having to pull an independent copy of the site just to generate a preview. But on the other hand, a site that is actively trying to attract attention and visitors needs to be big enough to handle this level of traffic. But for now, at least for “It’s FOSS”, if you want to post a link to Mastodon, please Mastodon’t.

[Editor’s note: Hackaday has a pretty robust CDN. Toot away!]

Bits and Bytes

Hopefully you’re aware that there are malicious images on Docker Hub. Some images mine cryptocurrency in the background, while others try to steal credentials. Researchers at Jfrog have found a class of repositories that plant malicious links in their descriptions. From phishing, to malware, to straight up spam, these repositories are a real pain, and make up nearly 20% of the Docker Hub library. That apparently doesn’t even include the cryptocurrency miners. Oof. It’s probably a good idea to stick to the “Trusted Content” section of Docker Hub.

Nettitude Labs got their hands on a Cisco C195 email security appliance, and went through the steps to make it fully their own. That includes BIOS modification to run arbitrary code, finding a command injection attack in the Cisco firmware, building a full exploit, and finally running Doom on the box. It’s an epic hack and a great write-up.

And finally, HPE Aruba has published fixes for four critical vulnerabilities that allow unauthorized attackers to execute arbitrary code on affected devices. In a refreshing turn of events, these aren’t being used in-the-wild, and there hasn’t been any public Proof-of-concept code published yet. The HPE advisory has a few more details. As always, expect these to eventually get exploited in the wild.

❌
❌