Moving files from a linux kernel module - linux-kernel

My goal is to write a kernel module that deletes the binary for /bin/ps and then moves and renames a file from the /tmp directory to replace ps in the /bin directory. It's basically a proof of concept of a rootkit that replaces a utility. I'm trying to find either functions that duplicate the functionality of link() and unlink(). I haven't been able to find any functions defined by the kernel that do that. Is that a possibility? Or would I have to do something like manually modifying dentrys?

Related

execute shell commands within contents of node package [duplicate]

My book states:
Every program that runs on your computer has a current working directory, or cwd. Any filenames or paths that do not begin with the root folder are assumed to be under the current working directory
As I am on OSX, my root folder is /. When I type in os.getcwd() in my Python shell, I get /Users/apple/Documents. Why am I getting the Documents folder in my cwd? Is it saying that Python is using Documents folder? Isn't there any path heading to Python that begins with / (the root folder)? Also, does every program have a different cwd?
Every process has a current directory. When a process starts, it simply inherits the current directory from its parent process; and it's not, for example, set to the directory which contains the program you are running.
For a more detailed explanation, read on.
When disks became large enough that you did not want all your files in the same place, operating system vendors came up with a way to structure files in directories. So instead of saving everything in the same directory (or "folder" as beginners are now taught to call it) you could create new collections and other new collections inside of those (except in some early implementations directories could not contain other directories!)
Fundamentally, a directory is just a peculiar type of file, whose contents is a collection of other files, which can also include other directories.
On a primitive operating system, that was where the story ended. If you wanted to print a file called term_paper.txt which was in the directory spring_semester which in turn was in the directory 2021 which was in the directory studies in the directory mine, you would have to say
print mine/studies/2021/spring_semester/term_paper.txt
(except the command was probably something more arcane than print, and the directory separator might have been something crazy like square brackets and colons, or something;
lpr [mine:studies:2021:spring_semester]term_paper.txt
but this is unimportant for this exposition) and if you wanted to copy the file, you would have to spell out the whole enchilada twice:
copy mine/studies/2021/spring_semester/term_paper.txt mine/studies/2021/spring_semester/term_paper.backup
Then came the concept of a current working directory. What if you could say "from now on, until I say otherwise, all the files I am talking about will be in this particular directory". Thus was the cd command born (except on old systems like VMS it was called something clunkier, like SET DEFAULT).
cd mine/studies/2021/spring_semester
print term_paper.txt
copy term_paper.txt term_paper.backup
That's really all there is to it. When you cd (or, in Python, os.chdir()), you change your current working directory. It stays until you log out (or otherwise exit this process), or until you cd to a different working directory, or switch to a different process or window where you are running a separate command which has its own current working directory. Just like you can have your file browser (Explorer or Finder or Nautilus or whatever it's called) open with multiple windows in different directories, you can have multiple terminals open, and each one runs a shell which has its own independent current working directory.
So when you type pwd into a terminal (or cwd or whatever the command is called in your command language) the result will pretty much depend on what you happened to do in that window or process before, and probably depends on how you created that window or process. On many Unix-like systems, when you create a new terminal window with an associated shell process, it is originally opened in your home directory (/home/you on many Unix systems, /Users/you on a Mac, something more or less like C:\Users\you on recent Windows) though probably your terminal can be configured to open somewhere else (commonly Desktop or Documents inside your home directory on some ostensibly "modern" and "friendly" systems).
Many beginners have a vague and incomplete mental model of what happens when you run a program. Many will incessantly cd into whichever directory contains their script or program, and be genuinely scared and confused when you tell them that you don't have to. If frobozz is in /home/you/bin then you don't have to
cd /home/you/bin
./frobozz
because you can simply run it directly with
/home/you/bin/frobozz
and similarly if ls is in /bin you most definitely don't
cd /bin
./ls
just to get a directory listing.
Furthermore, like the ls (or on Windows, dir) example should readily convince you, any program you run will look in your current directory for files. Not the directory the program or script was saved in. Because if that were the case, ls could only produce a listing of the directory it's in (/bin) -- there is nothing special about the directory listing program, or the copy program, or the word processor program; they all, by design, look in the current working directory (though again, some GUI programs will start with e.g. your Documents directory as their current working directory, by design, at least if you don't tell them otherwise).
Many beginners write scripts which demand that the input and output files are in a particular directory inside a particular user's home directory, but this is just poor design; a well-written program will simply look in the current working directory for its input files unless instructed otherwise, and write output to the current directory (or perhaps create a new directory in the current directory for its output if it consists of multiple files).
Python, then, is no different from any other programs. If your current working directory is /Users/you/Documents when you run python then that directory is what os.getcwd() inside your Python script or interpreter will produce (unless you separately os.chdir() to a different directory during runtime; but again, this is probably unnecessary, and often a sign that a script was written by a beginner). And if your Python script accepts a file name parameter, it probably should simply get the operating system to open whatever the user passed in, which means relative file names are relative to the invoking user's current working directory.
python /home/you/bin/script.py file.txt
should simply open(sys.argv[1]) and fail with an error if file.txt does not exist in the current directory. Let's say that again; it doesn't look in /home/you/bin for file.txt -- unless of course that is also the current working directory of you, the invoking user, in which case of course you could simply write
python script.py file.txt
On a related note, many beginners needlessly try something like
with open(os.path.join(os.getcwd(), "input.txt")) as data:
...
which needlessly calls os.getcwd(). Why is it needless? If you have been following along, you know the answer already: the operating system will look for relative file names (like here, input.txt) in the current working directory anyway. So all you need is
with open("input.txt") as data:
...
One final remark. On Unix-like systems, all files are ultimately inside the root directory / which contains a number of other directories (and usually regular users are not allowed to write anything there, and system administrators with the privilege to do it typically don't want to). Every relative file name can be turned into an absolute file name by tracing the path from the root directory to the current directory. So if the file we want to access is in /home/you/Documents/file.txt it means that home is in the root directory, and contains you, which contains Documents, which contains file.txt. If your current working directory were /home you could refer to the same file by the relative path you/Documents/file.txt; and if your current directory was /home/you, the relative path to it would be Documents/file.txt (and if your current directory was /home/you/Music you could say ../Documents/file.txt but let's not take this example any further now).
Windows has a slightly different arrangement, with a number of drives with single-letter identifiers, each with its own root directory; so the root of the C: drive is C:\ and the root of the D: drive is D:\ etc. (and the directory separator is a backslash instead of a slash, although you can use a slash instead pretty much everywhere, which is often a good idea for preserving your sanity).
Your python interpreter location is based off of how you launched it, as well as subsequent actions taken after launching it like use of the os module to navigate your file system. Merely starting the interpreter will place you in the directory of your python installation (not the same on different operating systems). On the other hand, if you start by editing or running a file within a specific directory, your location will be the folder of the file you were editing. If you need to run the interpreter in a certain directory and you are using idle for example, it is easiest to start by creating a python file there one way or another and when you edit it you can start a shell with Run > Python Shell which will already be in that directory. If you are using the command line interpreter, navigate to the folder where you want to run your interpreter before running the python/python3/py command. If you need to navigate manually, you can of course use the following which has already been mentioned:
import os
os.chdir('full_path_to_your_directory')
This has nothing to do with osx in particular, it's more of a concept shared by all unix-based systems, and I believe Windows as well. os.getcwd() is the equivalent of the bash pwd command - it simply returns the full path of the current location in which you are in. In other words:
alex#suse:~> cd /
alex#suse:/> python
Python 2.7.12 (default, Jul 01 2016, 15:34:22) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/'
It depends from where you started the python shell/script.
Python is usually (except if you are working with virtual environments) accessible from any of your directory. You can check the variables in your path and Python should be available. So the directory you get when you ask Python is the one in which you started Python. Change directory in your shell before starting Python and you will see you will it.
os.getcwd() has nothing to do with OSX in particular. It simply returns the directory/location of the source-file. If my source-file is on my desktop it would return C:\Users\Dave\Desktop\ or let say the source-file is saved on an external storage device it could return something like G:\Programs\. It is the same for both unix-based and Windows systems.

Building a binary executable for a MacOS app, on Linux

I have at the core a very simple program. A shell script that can run on either mac or ubuntu. I have the requirement to distribute it on both platforms (in the mac case, must be a .app), however, I must build it exclusively on Ubuntu.
I was looking in to what is a mac '.app', and it seems like it's just a unique directory structure with executable, metadata, etc. For example, here are Apple's docs on the matter which explains it.
https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
It seems like the metadata, etc. can all be put together, however in the Contents/MacOS folder, this is where the executable (the app's entrypoint) goes. This is the part I am confused on. For example, is there a way to make my shell script as an 'executable'? Or does this need to be a proper binary file (like you would get by compiling a C program?). If it is the latter, is there a way to do this on a Linux machine? (Noting that, this shell script, or C script I could make it in to, is so simple - essentially a single if/else statement which calls another utility.)
You need to have two things:
Put your executable into the Contents/MacOS directory, and make sure it is world-executable (just call chmod 755 on it). I think a shell script should work here, as long as it's got the correct "shebang" in front. For an actual binary, you'd need to find a way to compile a Mach-O binary on Linux.
Next, you need to make an Info.plist file in the Contents directory. Just dig out any Apple plist file as a template, and put these keys in it:
a. CFBundleExecutable—this should be the filename of your executable in Contents/MacOS
b. CFBundleIdentifier—this should be a unique bundle ID for your application, in reverse-DNS notation, i.e. com.yourwebsitename.yourappname
If you have these components in your .app bundle, it should launch when you double-click on it.

How to set a program's working directory?

I have a program that exists in the /usr/local/flower directory - flower.rb. It requires loading libraries that also exist in the same directory. I've included this flower directory in my OS environment's path. And my choice of OS is Ubuntu.
When I execute flower.rb from any other directory other than /usr/local/flower, I get error messages indicating the program can't load the libraries that also exist in the /usr/local/flower directory b/c they are being loaded as ./[library] from source code.
I realize I could change the Ruby program to hard code the /usr/local/flower/[libraries], but I'm curious if there's a way to execute this program from my home directory, e.g. /home/seattle, w/o doing this.
Also, when the program executes, it creates output via the -o switch.
My solution was to create a bash script that changed to the /usr/local/flower directory, executed the program, and then return to the PWD directory from where the flower.rb program was called. The problem is the -o switch. If I do a -o [file] the [file] gets written to the /usr/local/flower directory as opposed to where I am when the flower.rb program is run.
What is a good solution for this problem?
It's not quite clear from your question, but it appears that you are using require wrongly. require is for loading scripts from the $LOAD_PATH. If you want to load a script relative to the directory of the current script, use require_relative.
You should never load scripts relative to the current working directory. The current working directory is under the control of the user, not your script. You have no idea what it is gonna be. There is a reason why the current working directory was removed from the $LOAD_PATH in 2008: because it's broken.

Making checks before rsyncing external drive on OSX

I have the following issue on OSX though I guess this could equally be filed under bash. I have several encrypted portable drives that I use to sync an offsite data store or as an on-the-go data store etc. I keep these updated using rsync with several options including --del and an includes file.
This is currently done very statically i.e.
rsync <options> --include-file=... /Volumes /Volumes/PortableData
where the includes file would read something like
+ /Abc/
+ /Def/
...
- *
I would like to do the following:
Check the correct drive is mounted and find its mount-point
Check that all the + /...../ entries are mounted under /Volumes
rsync
To achieve 1 I was intending to store the uuid of the drives in variables in my profile so that I could search for them and find the relevant mount point. A bash function in .bashrc that takes a uuid and returns a mount point. I have seen some web entries for achieving this.
2 I am a little more stuck on. What is the best way of retrieving only those entries that are both + and top level folder designations in the include files then iterating to check they are mounted and readable? Again, I'm thinking of trying to put some of this logic in functions for re-usability.
Is there a better way of achieving this? I have thought of CCC, but like the idea of scripting in bash and using rsync as it is a good way of getting to know the command line.
rsync can call in a file that is a list of exclusions.
I would write a script that dumped directories to text file that are NOT + and top level folder designations in the include files
You are going to want an exclusion to look like this:(you can use wildcards if it helps)
dirtoexlude1
dirtoexlude2
dirtoexlude
Then just direct an rsync to that exclusion file.
Your Rsync command will be something like this:
rsync -aP --exclude-from=rsyncexclusion.txt
a is for recursive essentially (with hand waving) and P is for verbose.
good luck.

cocoa -- determine directory from which a tool was launched?

I have a command-line tool written in Cocoa. Let's call it processFile. So if I am in the terminal and I type in the command ./processFile foo, it looks for a file named foo.html in the same directory as the executable of processFile. If it finds one, it reads it and does some stuff to create fooProcessed.html.
Now I want to modify my tool so that it looks for foo.html in the directory from which it was launched. So if I am in the terminal with current directory ~/documents/html, and processFile executable is in usr/bin, and I type in
processFile foo
it will find and process the file ~/documents/foo.html.
The problem is that I don't know how to get the directory from which the tool was invoked. How can I do that?
That's the current working directory. First of all, any attempt to access the file just using its name and no path will automatically use the working directory. So, if you simply take "foo", append ".html", and attempt to open the file, that will work. If the user specified a relative path, like "subdir/foo", that would also work. It would resolve the relative path starting from the current working directory.
You can also query the working directory using the getcwd() routine.

Resources