evilsocket / opensnitch

OpenSnitch is a GNU/Linux interactive application firewall inspired by Little Snitch.
GNU General Public License v3.0
9.93k stars 490 forks source link

[Feature Request] Calculate a checksum for each whitelisted executable #413

Open wirespecter opened 3 years ago

wirespecter commented 3 years ago

Hi there,

First of all, let me say a big thank you for this awesome program! It seems to be working well and I love it!

I think that it would be greatly improved if it calculates a checksum for each file that is in the whitelist. Why? Because a malicious application can replace a whitelisted program with itself in order to avoid detection.

For example: Let's say that /usr/bin/ping is whitelisted, if a malware overwrites ping the malicious ping that resides in the same path is whitelisted as well.

All of this can be avoided if we compare the malicious ping's checksum with the checksum of the "good" ping that we got when it was whitelisted.

I know that this may complicate things when an application gets updated (thus the checksum changes), but we can add this as an option in the menu for users that want an additional level of security.

Thanks for reading so far and please let me know your thoughts below :)

gustavo-iniguez-goya commented 3 years ago

hey @wirespecter ,

This is an interesting feature request. I agree with you in all points.

But maybe we could cause some confusion, if as you said, you've whitelisted a binary and it's updated. So an option to enable it should be mandatory.

On the other hand, when you allow a new process, you don't know if it's goodware or malware.

In any case, at the very least, if the checksum changes we could warn users about it.

wirespecter commented 3 years ago

Thanks @gustavo-iniguez-goya ,

On the other hand, when you allow a new process, you don't know if it's goodware or malware.

As with any other process that we whitelist, it is up to the user to decide.

In any case, at the very least, if the checksum changes we could warn users about it.

I agree with this. However, it depends on the default behavior that is going to be implemented after the warning has taken place.

1) If we are talking about a warning dialog that lets users choose if they still want to allow the executable to communicate with the outside world or not then I'm up for it.

2) If it is something passive that just "warns" about a checksum change with no options or actions to be made, that may not be the best solution in my humble opinion.

dmknght commented 3 years ago

I don't really agree with this idea. I mean yeah it can add more protections for user but in my opinion it has some disadvantages:

  1. For now OpenSnitch is just a firewall so it works on connections of processes only. The binary verification is more like Antivirus thing. It is something like different part.
  2. What if modification is not malicious thing? For example i customized ping and compile it for better performance. Checksum creates false positive.
  3. New method can create new bypass ways and if developers and maintainers want to increase current feature they have to take care of more work -> high development cost.
  4. When binary is infected, it can create normal connections and malicious connections. If we want to detect the malicious connections, opensnitch will be something like IDS. Alternative solution is create blacklist addresses.

In my opinion, alternative solution could be create whitelist of protocol that binary can use. Like ping can't send http requests. I didn't play with OpenSnitch rules so much so i don't know if it is doable.

But i am seeing an interesting point. Let say that, ping is our target. So if user runs ping, it will be called from terminal. So ping is whitelisted, but when ping starts from a random process / system will be different from ping that is started from terminal that user is running? Because OpenSnitch can get process information so i guess this can be used? I think it is not a perfect solution but it can be done?

P/s: I think this is a really really interesting topic to increase protections so i would like to discus more and learn from everybody ^^ Thank you @wirespecter for a very interesting topic :D

NRGLine4Sec commented 3 years ago

To my mind, @dmknght is right. The File Intregrity Monitoring functionality is more a HIDS function than a firewall function. There are already tools to do FIM like Samhain or Wazuh. Let's see what others think about it.

gustavo-iniguez-goya commented 3 years ago

Before dumping some thoughts: how often will this scenario occur? I see 3 possible scenarios:

In the later case, the admin should allow binaries specifying the absolute path to the binary.

it can add more protections for user

More than adding protection I see it as a way of letting the user know that something changed since that binary was allowed (or denied). You can't configure it right now, but I think the checksum is just a property of a rule that it's not configurable.

If you have allowed nc + dst.port 80|443 + dst.ip 1.1.1.1 and something/someone launches it to connect to malicious.com:443 opensnitch will prompt you to allow or deny it, because the properties of the connection don't match the rule you defined.

However we're implicitly allowing nc, trusting that the binary is goodware in both cases, regardless if it's the same binary or not.

What if modification is not malicious thing? For example i customized ping and compile it for better performance

In that case you'd allow your ping binary version, with a fixed checksum. You'd allow it only once. If it happens that you compile it regularly there could be 2 options: a global option to verify checksums, and a rule field to verify the checksum of a particular binary ([x] Verify binary checksum)

The binary verification is more like Antivirus thing. It is something like different part.

We wouldn't be acting as an AV here because we wouldn't be classifying the binary as goodware, grayware or malware, nor killing it and nor moving it to a quarantine.

But I agree that it adds complexity and probably performance penalty.

So if user runs ping, it will be called from terminal. So ping is whitelisted, but when ping starts from a random process / system will be different from ping that is started from terminal that user is running? Because OpenSnitch can get process information so i guess this can be used? I think it is not a perfect solution but it can be done?

In this case, if you have allowed ping, it'll be allowed regardless if it's launched from a terminal or spawned by a different process

The File Intregrity Monitoring functionality is more a HIDS function than a firewall function.

I agree. However opensnitch it's not a traditional firewall where you only allow/deny network connections. There's an extra component that is also part of the connection, which is the binary that initiated it.

Binaries also have their own properties: path, name, arguments, current working directory (from where it was launched), permissions, ownership, checksum, size, parent pid, etc. We're already able to filter by some of these properties. For example:

Filtering by checksum is not something urgent right now, as there're many other things to do first. But it doesn't seem to be that crazy to me.

Anyway, it'd probably be better to implement it as an addon rather than adding it to the codebase.

dmknght commented 3 years ago

I'm having an idea: Can we create some work modes for OpenSnitch? For example: Comodo firewall has safe mode, game mode, ... something like that. So i'm imaging something like

elesiuta commented 2 years ago

I wrote a small program inspired by this one a while back with this exact feature as well as the option to upload the checksums to VirusTotal.

I recently fixed it up a bit but the memory usage still isn't great and I don't plan on giving it much attention in the foreseeable future, and figured @wirespecter and others who see this issue may be interested.

sl805 commented 2 years ago

@gustavo-iniguez-goya Can't tell how much I'm thankful for this piece of software, thanks for all your work. Since this is networking focused we can adjust this feature accordingly. VirusTotal allows domain validation, so in such case if user supplies VT API key can we add an option to validate domain application tries access (via VirusTotal API) and show validation status Bad\Good\Unknown in Allow\Deny connection dialogue ? This way we're keeping focus on networking, yet improving security.

Best regards.

gustavo-iniguez-goya commented 2 years ago

Hi @sl805 , thank you for the kind words :)

I think that making requests to an external url is something that many users would be against with. I created PoC of your idea sometime ago and posted a screenshot somewhere. It's really easy to integrate VT, at least on the GUI, but we need consensus on these new features.

cypherbits commented 2 years ago

I'm against using an external service for AV checking. This is an application firewall not an Antivirus...

But, as an application firewall, we allow "executables" to connect to the Internet. If we cannot ensure our executable is the one we whitelisted and any malware can replace any executable and ping home, then we are failing our firewall mission since that malicious executable is not whitelisted. Because that executable is not actually our executable.

We just actually whitelist paths, not executables.

That is why we should implement an optional hashing. I proposed Blake3 because it should be the fastest but safe.

NRGLine4Sec commented 2 years ago

I'm against too.

NRGLine4Sec commented 2 years ago

I think that we have to be careful with hashing executables because it can be very annoying if we are asked for new connections after an update of one executables that we have already configured/allowed.

cypherbits commented 2 years ago

I think that we have to be careful with hashing executables because it can be very annoying if we are asked for new connections after an update of one executables that we have already configured/allowed.

That's why I say "optional". It can be a type of filtering of a rule. "By executable path" (like now) or "by executable hash"

dmknght commented 2 years ago

There could be a "flexible" solution. On Debian based system, binaries installed by apt has checksum at /var/lib/dpkg/info. For example, /usr/bin/apt has checksum at /var/lib/dpkg/info/apt.md5sums. Value from grep apt.md5sums:c78db41ce6a57d72bea6c7c4a9e52f25 usr/bin/apt. So at least, OpenSnitch can have System checksum to compare checksum with hash database. Pros:

Cons:

p/s:

I think that we have to be careful with hashing executables because it can be very annoying if we are asked for new connections after an update of one executables that we have already configured/allowed.

That was my point as well but at least with this solution we can have flexible solution for binaries installed by system.

cypherbits commented 2 years ago

I think checking the hash is more useful for user owned executables since for system binaries (apt installed) need root for installing and a malware would need to scalate privileges.

dmknght commented 2 years ago

Well i think for malware that has root permission / rootkit is an other scenario and it is more about AV / HIPS solution rather than firewall. For regular binary file, we can have something like

sl805 commented 2 years ago

Hi @sl805 , thank you for the kind words :)

I think that making requests to an external url is something that many users would be against with. I created PoC of your idea sometime ago and posted a screenshot somewhere. It's really easy to integrate VT, at least on the GUI, but we need consensus on these new features.

@gustavo-iniguez-goya Well then it's even easier to implement. Instead of implementing VT integration, or any kind of reputation check. We can implement is as admission-hook! It'll work upon connection attempt, but instead of doing requests to external service:

Daemon will:

{"pid": 1111, "path": "/tmp/something", "src_addr": "...", "src_port": "35000", "dst_addr": "example.someting.com", "dst_port": "12345"} and expecting it to return one of following statuses: -1 - unknown hook execution result. Hook execution failed, evaluation result is unknown due to some error 0 - positive hook execution result. Hook execution complete, evaluation result is positive\good 1 - negative hook execution result. Hook execution complete, evaluation result is negative\bad

UI will:

In such case this feature becomes optional and will give people freedom to trigger any kind of automation they like:

sl805 commented 2 years ago

@gustavo-iniguez-goya Happy New Year Gustavo. Is there any sense in my idea?

gustavo-iniguez-goya commented 2 years ago

hey @sl805 ,

I think that it's quite an elaborated proposal, thank you for taking the time to thing about it. I promise that I'm taking into account all suggestions and ideas. Reading your proposal, the first that comes to my mind is adding it as a plugin :book:

As I said above, for me the checksum is just another property of a binary, so I think I'll end up adding it. Later we can decide what to do with it. I like the idea of start small and simple, and keep adding complexity over time, so we could start with something like this:

If the checksum changes, opensnitch will prompt you to allow or deny the connection (as it already does when a field doesn't match).

Regarding the @dmknght ' s idea of using apt checksums, it could be added as rule of type lists, like what we already do with domains, IPs, etc. The rule would load the checksums on the startup, and the user could decide what to do with those checksums: deny or allow connections that matches application's checksum. But as s/he noted, it's something very specific to Debian based distros, so I think it's a perfect candidate to add as a plugin.

Adding this feature opens the possibility to create lists of IOCs, that could be used to block known malware/badware (for servers mostly), like we already do with domains, IPs, etc.

On the other hand, the user should be able to choose what checksum algorithm to use (md5, sha1, blake3, etc). Mainly because IOCs are created with md5/sha1 algorithm. So for example you could verify firefox's checksums with blake3, and deny everything that matches md5/sha1 checksums from a list.

NRGLine4Sec commented 2 years ago

Hi @gustavo-iniguez-goya, There is some good suggestions in your post. I particularly like this one :

Adding this feature opens the possibility to create lists of IOCs, that could be used to block known malware/badware (for servers mostly), like we already do with domains, IPs, etc.

To clarify my point of view on the subject a little, I am not against the idea of checking that the binary that we want to block and more particularly to allow is the one we want. I am against the fact that this new functionality would automatically ask (by default) to authorize or refuse connections for a rule that we have already created but whose binary has changed, following an update for example. But I would really like the feature to be able to "mark" the rules whose binaries have been changed since the creation of the rule, with a color (orange for example) on the rule in the OpenSnitch rules interface. It would then be necessary to have the possibility (probably with a right click on the rule) to validate that the change of binary is indeed voluntary (and thus to make the marking of the rule disappear). This would avoid having the inconvenience of a new rule creation request when the binary is different while having the possibility of being alerted that it is different. It would also make it possible to have no creation or change of rules other than a simple temporary marking (until we have a little time to investigate the rules concerned).

gustavo-iniguez-goya commented 2 years ago

I am against the fact that this new functionality would automatically ask (by default) to authorize or refuse connections for a rule that we have already created but whose binary has changed, following an update for example.

:+1: understood.

But I would really like the feature to be able to "mark" the rules whose binaries have been changed since the creation of the rule

That's not possible right now, because we don't have an Alerts module. After you create a rule, it remains static for the rest of its lifetime and we can only apply 3 actions on it (allow, deny, ask) If a connection doesn't match with a rule, right now the only option is to ask the user to allow or deny it.

The alerts module could work just like the application rules, a list of rules with fields to check and actions to perform (send desktop notification, send email, colorize a row, etc). I thought about this necessity, because when a list of domains/IPs is reloaded because it has been updated, you don't get any feedback. It'd be cool to configure an alert to display a desktop notification saying: "Ads domains list updated".

dmknght commented 2 years ago

Regarding the @dmknght ' s idea of using apt checksums, it could be added as rule of type lists, like what we already do with domains, IPs, etc. The rule would load the checksums on the startup, and the user could decide what to do with those checksums: deny or allow connections that matches application's checksum. But as s/he noted, it's something very specific to Debian based distros, so I think it's a perfect candidate to add as a plugin.

Hello! I checked the checksum db of dpkg and It doesn't have checksum for all binaries. By quick look, I can see it ignores same checksum for different file paths (like /usr/bin/bash and /bin/bash) but it is too soon to say it works.

gustavo-iniguez-goya commented 2 years ago

As far as I can tell on that particular case, on Sid bash is installed under /bin (dpkg -L bash): /bin/bash Bu there'll be quirks for sure. Post any other particularity you see :+1:

dmknght commented 2 years ago

As far as I can tell on that particular case, on Sid bash is installed under /bin (dpkg -L bash): /bin/bash Bu there'll be quirks for sure. Post any other particularity you see +1

Well bash is in both /bin/bash and /usr/bin/bash. The file in /usr/bin/ is not a symlink image

From dpkg -S, it showed only /bin/bash but not /usr/bin/bash image I guess dpkg-query used list of files from .md5sums. As I remember there are some other cases that binary and its checksum are not in the .md5sums file. I have to check it again to make sure. Overall, the checksum db of dpkg is a promissing method it is not good enough.

dmknght commented 2 years ago

Hello! I played with the code for checksum from debian Db. Here is something I found:

dmknght commented 2 years ago

Update: To make program be more simple, I tried checking only md5sum instead of md5sum and file path. Code is sightly faster image However, again, we don't have similar solution for other distro families.

NRGLine4Sec commented 2 years ago

I think, it could be a lot simpler to don't have to checksum every binary the system could have.. Like you said, it will be difficult to find the same method as debian db for other distros, and this method will not works for applications installed outside of apt repository, like AppImage.. To my mind, we should only checksum binary used when we create the rule (first connection attempt) and keep it in opensnitch db with the fastest hash algorithm and consider to check the checksum each time the binary makes outside connections.

BobSquarePants commented 2 years ago

I agree with @NRGLine4Sec

and I will point to: https://en.wikipedia.org/wiki/Unix_philosophy

Make each program do one thing well.

gustavo-iniguez-goya commented 2 years ago

@dmknght you pointed out some interesting points :+1:

python always checks for python, or other interpreter in general. script.py, either from deb package or untrusted source, will be never checked unless we develop very complex code to parse and check.

This will be a problem if we add checksums. I didn't take it into account. This is also true for java, ruby, perl, bash, etc.

Similar to 1, let say that program ping calls a function from static-lib.so. If static-lib.so was modified ans injected malware, we can't check it unless we do full analysis and scan.

The attack vector is interesting. I just tried it and you're right, even creating a rule for a particular command (e.g.: telnet www.google.com 80), one could place a backdoor that used the allowed command (telnet ww.go... etc), and initiate a new connection to another host that would also be allowed (LD_PRELOAD=./backdoor.so telnet www.google.com 80, where backdoor.so opens a connection to attacker.com:9999)

However, if you filter by "command line" + host (and port, uid, etc), then we prompt the user to allow/deny the connection to the attacker's .domain/IP, because the properties of the connection doesn't match with any rule (verified :heavy_check_mark: ).

Sometimes filtering by application + dest host is not practical, like with web browsers, but checking the checksum wouldn't help here either.

dmknght commented 2 years ago

I think, it could be a lot simpler to don't have to checksum every binary the system could have.. Like you said, it will be difficult to find the same method as debian db for other distros, and this method will not works for applications installed outside of apt repository, like AppImage.. To my mind, we should only checksum binary used when we create the rule (first connection attempt) and keep it in opensnitch db with the fastest hash algorithm and consider to check the checksum each time the binary makes outside connections.

Well I personally not a fan of the idea "OpenSnitch becomes HIPS". I prefer an application firewall only. And as I pointed out, either using system's checksum or custom checksum, there are methods can bypass this check.

However, if you filter by "command line" + host (and port, uid, etc), then we prompt the user to allow/deny the connection to the attacker's .domain/IP, because the properties of the connection doesn't match with a rule (verified heavy_check_mark ).

If you meant the cmdline parsing, then i think we have to do argument parser for all command lines, expect bug-free for so many different data input, and then analysis / parse all arguments. From my point of view right now, it takes so much time and research to make sure it works fine. That doesn't count attackers / malware could use some simple obfuscation methods to bypass this check: echo <base64 payload> | base64 -d | bash -c Or like this image So technically it works, but it's very easy to bypass and it takes a lot of time and resource to take care. And that didn't count different shell (fish, zsh, ..) could have different syntax.

gustavo-iniguez-goya commented 2 years ago

If you meant the cmdline parsing

No, sorry. I meant that if you have a rule that allow traffic initiated by telnet (for example), and someone backdoorizes telnet with a static-lib.so as you said to initiate a connection to a malware domain, one way of avoid that situation is by filtering by process_path + process arguments + destination host + destination port, i.e.: restrict to what IPs/domains/ports an application can connec to.

Similar to 1, let say that program ping calls a function from static-lib.so. If static-lib.so was modified ans injected malware, we can't check it unless we do full analysis and scan.

For example, instead of ping lets use telnet (or gnome-software, synaptic, whatever):

gustavo-iniguez-goya commented 2 years ago

One way of using dpkg's db would be by generating a single file with all the known/installed checksums (md5 or whatever):

cat /var/lib/dpkg/info/*.md5sums > /tmp/dpkg-db.txt

Then you'd create a new rule: [x] Enabel, [x] Action: Allow, [x] List of md5sums: /tmp/dpkg-db.txt

Internally, if such rule is created and enabled, we would 1) get the md5 of an app that is trying to establish and outbound connection, 2) check the path + md5 against the DB. It'd work very similar to the other type of lists that we already have.

The generated list could be autoupdated by adding a post-invoke script to apt: DPkg::Post-Invoke{"cat /var/lib/dpkg/info/*.md5sums > /tmp/dpkg-db.txt"; };

On the other hand, a user could also create a DB of checksums with the help of a simple script: find /bin /sbin /usr/bin /usr/sbin -exec md5sum {} \; > /tmp/custom-db.txt

This db would work on any system, regardless of the package manager, and could also be integrated with apt and probably others package managers, or be added to a cron task.

dmknght commented 2 years ago

check the path + md5 against the DB.

I think no need to check both path and md5. Only md5 is enough. For example cp /usr/bin/nc /tmp/copied-nc-file has the same md5 so we can use the nc rules to treat it

This db would work on any system, regardless of the package manager, and could also be integrated with apt and probably others package managers, or be added to a cron task.

I think it technically works but with issues:

  1. Each OS could have different build platform. That means binary checksum could be different depends on compiler information / metadata.
  2. Different version of package on each distro. Ofc! Can't be something else for checksum db :D
  3. Custom patches of maintainers. IDK about other platforms, but on Debian, some packages have small patches to fix specific issues or just change something. It also brings us different checksum for same package with same version.

Because you mentioned about .txt file for checksum, i'm wondering is it faster than load everything into memory and compare it in memory? Maybe save all sums in a cache file, and then use iterator to compare each line is better for memory usage but performance is questionable.

gustavo-iniguez-goya commented 2 years ago

I think it technically works but with issues:

  1. ...
  2. ...
  3. ...

The "db" (a list of md5 checksums + paths) would be generated on each system with a script, via cron or similar, so the list would be specific to that installation.

Because you mentioned about .txt file for checksum, i'm wondering is it faster than load everything into memory and compare it in memory? Maybe save all sums in a cache file, and then use iterator to compare each line is better for memory usage but performance is questionable.

Nope. the .txt file would be loaded into memory, just like what we do with domains lists. A map of key: hash, value: path

dmknght commented 2 years ago

The "db" (a list of md5 checksums + paths) would be generated on each system with a script, via cron or similar, so the list would be specific to that installation.

So I'm thinking about "hook scripts". APT has config to run a script after user install any package. I don't really know much about this. But this is a good method to reload all checksums to memory.

gustavo-iniguez-goya commented 2 years ago

I've got a PoC working. Some benchmarks:

md5: 497.725253ms, /usr/lib/chromium/chromium, hash: fc5b1708gh7a0a848bfc5f477bb9d39b blake3: 362.768448ms, /usr/lib/chromium/chromium, hash: af1349b9f5f9a1a6a0111dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262

That's a lot of time even for a binary of ~180MB. The bottleneck is not the hash algorithm, but the reading of the file.

[edit] Computing chunks of a file (1kb, 4kb, 1mb...) helps to reduce reading times down to µs.

With this PoC you get alerted if the checksum differs. It can be due to a malicious activity, an update of the binary or if a process is launched from a different namespace/container with the same path + name. There should be a graphical warning stating that the checksum changed.

Regarding the concerns about if this functionality is part of a firewall: We need it to prevent some ways of bypassing the rules (with mount namespace + overlayfs for example). In the end, what we need is more control on processes launched from containers/namespaces. For example: you may allowed a process launched as UID 1000, but if it's sandboxed (running inside an unprivileged container), the UID may be different.

Some notes:

wirespecter commented 2 years ago

@gustavo-iniguez-goya Thanks for working on this. I agree with all your points above.

dmknght commented 1 year ago

@gustavo-iniguez-goya There's "not very famous" EDR called Falco. It uses eBPF to catch syscall. It has so many features so I'm thinking what if there's an application firewall based on this EDR. I think with rules or custom plugins, developers can create a opensnitch-like UI and ofc calculate checksum is possible. What do you think about it?

gustavo-iniguez-goya commented 1 year ago

hey @dmknght , I think that type of software is actually really interesting: falco, tracee, redcanary, tetragon, ehids, ... (there're a lot). But I think they're more server oriented, so I don't know how easy would be to add a desktop GUI, or if it's worth the effort.

Regarding this feature in particular, if someone is willing to test it and give back some feedback, I can publish a branch with the feature. There're some quirks and corner cases (that may c, but all in all it works fairly well.

dmknght commented 1 year ago

hey @dmknght , I think that type of software is actually really interesting: falco, tracee, redcanary, tetragon, ehids, ... (there're a lot). But I think they're more server oriented, so I don't know how easy would be to add a desktop GUI, or if it's worth the effort.

Regarding this feature in particular, if someone is willing to test it and give back some feedback, I can publish a branch with the feature. There're some quirks and corner cases (that may c, but all in all it works fairly well.

I'm not sure about the other but the falco can run standalone in the system. It has grpcio channel so a in theory anybody can write an applet or something like that to get the alert logs. I don't really know about "hold" the process and network connection (to make it be a firewall).

aitorpazos commented 1 year ago

I agree with the point of delegating this problem (asses if the binary is malicious or not) to a different tool, but being in the flow of establishing new connections and having the UI notification mechanism in place gives OpenSnitch a great position to alert users on this.

What about supporting delegating the assessment of the binary to a separate tool?

graph LR
    newCon(["New connection request"]) --> hashChanged{"Binary hash changed"}
    hashChanged -- Yes --> scanBin[["Call binary scan"]]
    scanBin --> binSuspicious{"Binary is suspicious"}
    binSuspicious -- Yes --> alertUser[["Alert User"]]
    hashChanged -- No --> continue(["Continue"])
    binSuspicious -- No --> continue
    alertUser --> userAccepts{"User accepts risk"}
    userAccepts -- Yes --> continue
    userAccepts -- No --> block(["Block"])

What I am not clear is how it could be user-friendly setup-wise.

gustavo-iniguez-goya commented 11 months ago

Some updates on this issue.

I've got this feature working and I'm testing and improving it. Hopefully I expect to add it after v1.6.2. Now that we intercept exec events, the scenario has changed a little bit for the better:

We'll have to deal with packages updates, and how to try not to annoy the users. The only feasible way I see is by making it optional.

Working on it. Probably processes' hashing will be enable only if there's any rule that requires it. Still thinking about it.

On the other hand, when a binary is updated while it's running, every time we'll get the checksum it'll be different from the one loaded in memory. The user should accept the new connection, and if it has matched a rule, the corresponding rule should be modified.

Now the checksum is not recalculated every time a new outbound connection is about to be established. It's cached for the life of the process.

We should think about what to do with regexp rules. For example: process.Path: ^(/usr/sbin/ntpd|/usr/bin/xbrlapi|/usr/bin/dirmngr)$ we can't hash the value of process.Path directly. exclude these rules from calculating hashes? As a starting point sounds reasonable.

With lists of checksums, like the lists we have for domains or IPs, these rules could work by adding the checksums of each path in the regexp.

if the binary that is opening connections is containerized, we should hash the binary inside the container, nor the outer equivalent (this is, the path we receive from the kernel).

Done. And added a workaround for AppImages, which are a little bit special.

For a simple usage of a Linux desktop (office suites, image editing, browse the Internet, reading emails...) , it looks like it doesn't penalize much the user experience, but we'll see how it behaves on different machines.

On the other hand, the work on this feature will unlock new features, like displaying the process' parents that executed the process or filtering by parent PID.

gustavo-iniguez-goya commented 10 months ago

Added: 7a9bb17829ddd1eda0bc09b0725a0c19c428a1fc

This commit is only one piece of the puzzle, it's WIP. TODO list:

As part of this feature there has been added new functionality and code reorganization:

Some caveats:

Notes:

gustavo-iniguez-goya commented 8 months ago

An update on this issue: in general it's working fine. I've only observed a problem with apps that spawn other processes (firejail for example). If you don't know what's going on, the visual warning stating that the checksum has changed can be a bit confusing.

On the other hand, is a bit annoying having to update a rule manually whenever a checksum changes due to an update. Not much, but I guess if you're on a rolling release distro it will be a bit more frustrating. WIP to impove user experience of that scenario.

And some interesting notes about this issue after watching some Linux Plumbers '23 talks.

There're some technologies that we could investigate to replace or complement the current approach (calculate checksums on-demand):

More info:

https://lwn.net/Articles/753276/ https://events19.linuxfoundation.org/wp-content/uploads/2017/12/LSS2018-EU-LinuxIntegrityOverview_Mimi-Zohar.pdf http://downloads.sf.net/project/linux-ima/linux-ima/Integrity_overview.pdf

Logicwax commented 6 months ago

Hopefully this feature gets into the next release that's pushed to the repos soon. Looking forward to it, especially for user-owned binaries!