dickon wrote: ↑
Wed Sep 15, 2021 8:21 am
My main objections are:
- It's unsafe
- It won't work if /tmp is mounted noexec (which isn't all that uncommon)
- It won't work if /tmp/pipn.c exists but isn't executable
- It won't work if /tmp/pipn.c exists, is older than your own ~/pipn.c, but isn't owned by you
- It won't work for anyone else if your ~/pipn.c isn't readable by them (for whatever reason)
- I fail to see what it buys you over simply sticking a precompiled copy in /usr/local/bin/
On the very last bullet, "mixed bash and C" execution, or "C scripts".
dickon wrote: ↑
Thu Sep 16, 2021 10:57 am
Yeah. I'm more criticising the approach as implemented, which is extremely dangerous on multiuser machines with potentially hostile users on them. All you'd need to do to exploit it is stick an @reboot entry in a user's crontab to create a script to create a suid-user shell somewhere before doing whatever the untrojaned 'script' was designed to do (one per likely command, so /tmp/pipn.c in this case; others have been mentioned), wait for a reboot, wait for the victim to run it, and you're done, hopefully with your victim none the wiser. It isn't sensible, and it isn't safe, and I can't say I'm entirely happy at it being advocated for on a forum like this where naive newbies might come across it and think it's a good idea.
There are ways to mitigate the problems -- the obvious one would be to put the resultant binaries somewhere not under the control of an attacker, such as a ~/.cscache directory or similar -- but that isn't what's happening here.
First, regarding the subject of this thread, I already agreed with @trejan that "tee" is better than using "|n".
Next, I think I have addressed all that. I completely got rid of need to create any auxiliary filesystem file. The C code extracted from C script and compiled with gcc ends up in an anonymous file that lives in RAM (with memfd_create()
system call), with no links from filesystem. ELF binary gets created every time (in RAM) when script is executed, then ELF gets run from memory, and finally disappears immediately after it was executed (directly when binary execution starts, by MFD_CLOEXEC flag). This was possible by new C memrun tool, see github repo and documentation for details:
https://github.com/Hermann-SW/memrun/tr ... r/C#memrun
With memrun "C++ scripts" that "run from memory" became possible:
Code: Select all
pi@raspberrypi400:~/memrun/C $ echo "2^64" | bc -q | ./run_from_memory_cin.cpp
This is (executable) run_from_memory_cin.cpp
producing above mixed bash and C++ output: