Skip to content

Comment on Show HN: Run unknown shell script with a line-by-line confirmation prompt

Comments

What would be amazing is a tool that analyses the script first, figures out folders and files (and networking) it influences and allows to sandbox it accordingly.

This script wants to modify:

- /usr/local/program/*

- /etc/program/*

- $HOME/.program

Do you want to execute this? [Yes/No]

..because you know, what happens when you execute a script that does rm -rf /usr in the 100th step?

In its full generality this runs afoul of the halting problem.

That doesn't mean what you want is completely unattainable, you just need to figure out whether you're okay with false positives, false negatives, or your tool just giving up on certain scripts (or some combination thereof).

I would be fine with a static analyser doing the last one (giving up in doubt), considering that install scripts are a smaller subset of all possible shell scripts.

Such a static analyser would have two interesting aspects: on the end user side, the one mentioned of outputting the touched paths, and also doubling as being a linter for the script developer.

Or just raising attention to the weird commands that trips its analysis up, just in case they are path obfuscation. That should be easy to spot for the admin...

False positives (this program could access these file locations) seems like a reasonable tradeoff.

You could do this by running your script pivot mounted into a namespace that mounts your "real" filesystem as readonly and layers with overlayfs to log changes. You can then terminate the script if the overlay diff gets too large (I assume on a 100GB disk you don't want 60GB of changes, and in any case you could tell it what to expect beforehand). That saves you having to do all this complicated analysing for files and folders and replaces it with something relatively foolproof.

Not without danger or failure if the scripts depend on internet connectivity, since they could either ex-filtrate data or change their behavior based on the connection being present or not.

Such can be easily implemented on top of Docker filesystem overlays/snapshots. You just run the script in question e.g. in fresh Ubuntu container and then compare overlay directories to see what changed.

If you are happy with running it only once in the container, yes.

But if you run it first in the container to see whether is does anything bad and then run it on the host (or a more valuable container), no.

The script might check whether it runs in a container. It might depend on the wall clock time. On /dev/urandom, whatever. As somebody already mentioned, the halting problem. No can do.

doesn't the halting problem only hold if you have infinite memory?

That's probably correct. But any reasonable execution environment has so many states that doing a full enumeration is infeasible.

I've seen this argument that 'halting problem is undecideable': http://www.lel.ed.ac.uk/~gpullum/loopsnoop.html

The argument doesn't rely on infinite memory.

With finite memory and no external inputs an observer can enumerate all possible states.

In real systems external inputs provide an infinite source of "memory" to read from.

Very difficult to do in any kind of robust way. A script can run all kinds of things and use myriad forms of obfuscation, causing all kinds of obscure side effects.

When trying OPs code out, I had all the "linux binaries" in mind, aka all the shitty self-unpacking installers that concat their binaries and dump it in /tmp before executing it.

(you know, like proprietary drivers almost always do)

It would be a huge improvement for sysadmins if a linter could be run in advance of executing a shell script, and use chroot and other sandboxing like creating a user without net cap rights etc in case it found something potentially malicious.

I imagine this could be done by actually running the script in some sort of sandbox, having file changes written to overlayfs at first.

This would still allow the script to steal data though, as installer script generally require internet access.

This would still be defeated by any script that is nondeterministic which is a real possibility if you're trying to defend against malicious scripts or against very poorly written scripts.

You wouldn't need to run the script twice. Just apply the file modifications when the user okays them.

But the modifications might not be valid in the real system. For example, imagine a script that adds a new user to the system: in the container, it picks a new user ID that is free. A diff of the filesystem will show a new line being added to /etc/passwd - seems OK, right? But the user ID picked might clash with one on the real system, causing everything to fail when you apply the change.

The sandbox would provide a copy-on-write view of the actual filesystem (hence the possibility of data being stolen), so that scenario would work fine. (Though race conditions may be a concern.)

Sandboxing is plausible. Statically analyzing for potential changes a priori not so much.

That sounds a lot like what maybe[1] does.

[1] https://github.com/p-e-w/maybe

This tool sounds amazing. Do you know what happened or the reason why the project got archived by the author?

Back on windows xp I ran a tool called black ice that did this.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.