Change system calls function pointers at runtime in Linux - c

I have a huge project that is creating a lot of files and folders that I want to track them.
In order to debug the code, I would like to replace a system call behavior to check what is going on.
My idea is to hook a new function in the same place where the system call is being used and see the behavior of the application, after it has started. To be more clear, here is an example of what I need:
The application is creating a annoying folder like /tmp/annoying_folder. So I would like to intercept every mkdir system call and check if the it's argument is the annoying_folder and if it is the case, force it to return an error, so I can locate which process is doing this and also know it's stack call.
What I have tried up to now is using LD_PRELOAD, which is not working in the case of this application, because it is doing direct system calls, instead of going through libc.
I'm having trouble using gdb, because I'm not sure which process is doing these calls, because the application is started by a script that calls multiple other processes.
Through strace I'm able to see the mkdir call that I'm looking for, but it doesn't help me much, because I need to also know the stack trace call of the application to figure out where is the code that is generating this.
So one option that thought to be interesting is to use LD_PRELOAD to load a library with a constructor function that would change the hook point of mkdir and redirect it to my custom function. But I need directions on how to do that for Linux system calls.
Do someone knows how to change System calls function pointers at runtime?

I wasn't able to intercept those system calls as I expected, but I've found an interesting workaround with stap utility.
I've created the following script:
#! /bin/stap -g
probe nd_syscall.mkdir.return {
folder_name = user_string(#entry(pointer_arg(1)), "-");
folder_name_prefix = substr(folder_name, 0, 9);
if(folder_name_prefix == "/tmp/test") {
printf("[%d] [%d] [%16s] [%s]\n", uid(), pid(), execname(), folder_name);
raise(%{ SIGSTOP %});
}
Then I was able to send a signal stop to the process and after that connect gdb to analyze the application stack trace.

Related

C programming - execute another program with sudo privileges

i have a C program that opens an mp3 and extract the jpg artwork in the same folder. If i execute this program with no root privileges i get a crash. If i execute it with sudo it works normally.
Now, i need another C programs who launch the previous program when it needs a jpg artwork for the selected mp3.
I tried to call popen("./firstProgram test.mp3" , "r") function or system("/(absolute path)/firstProgram test.mp3") function by calling them even with sudo in the command or not and either with relative or absolute paths. But no version seems to work.
How can i launch the first program from the second one with success?
Thanks!
fork and then use execl
char sudo[]="/usr/bin/sudo";
char pbin[]="/usr/local/bin/puppet";
NOTICE("running puppet: %s %s",sudo,pbin);
errno=0;
execl(sudo,sudo,pbin,(char *)NULL);
/* we should never get as far as this */
obviously I recommend reading man execl for further info
Unix (Linux) systems have contained a C Programming Manual in them since possibly forever. Look in Section 2, "System Calls".
This Wikipedia Page explains the Unix Manual "sections"
It is section 2 of the manual you can read about "System Calls"
Try the command: man 2 setuid
This will give you the manual for the setuid() system call which I think is what you want.
That manual page will also list references to other related system calls that may be what you want.
Remember when compiling C programs and using system calls that do low-level hardware access, to use the -O2, or -O3 option to gcc. There is a mention of it in the manual.
Ultimately the setuid() system call makes a running process started by one user change the UID of that running process to be running as some other user. (For example, you may see the Apache running as "apache", even though it was started by root).
setuid(0) lets you be root.

How do I trace coreutils down to a syscall?

I am trying to navigate and understand whoami (and other coreutils) all the way down to the lowest level source code, just as an exercise.
My dive so far:
Where is the actual binary?
which whoami
/usr/bin/whoami
Where is it maintained?
http://www.gnu.org/software/coreutils/coreutils.html
How do I get source?
git clone git://git.sv.gnu.org/coreutils
Where is whoami source code within the repository?
# find . | grep whoami
./man/whoami.x
./man/whoami.1
./src/whoami.c
./src/whoami
./src/whoami.o
./src/.deps/src_libsinglebin_whoami_a-whoami.Po
./src/.deps/whoami.Po
relevant line (84):
uid = geteuid ();
This is approximately where my rabbit hole stops. geteuid() is mentioned in gnulib/lib/euidaccess.c, but not explicitly defined AFAICT. It's also referenced in /usr/local/unistd.h as extern but there's no heavy lifting related to grabbing a uid that I can see.
I got here by mostly grepping for geteuid within known system headers and includes as I'm having trouble backtracing its definition.
Question: How can I dive down further and explore the source code of geteuid()? What is the most efficient way to explore this codebase quickly without grepping around?
I'm on Ubuntu server 15.04 using Vim and some ctags (which hasn't been very helpful for navigating existing system headers). I'm a terrible developer and this is my method of learning, though I can't get through this roadblock.
Normally you should read the documentation for geteuid. You can either read GNU documentation, the specification from the Open Group or consult the man page.
If that doesn't help you could install the debug symbols for the c-library (it's called libc6-dbg or something similar) and download the source code for libc6) then you point out the path to the source file when you step into the library.
In this case I don't think this would take you much further, what probably happens in geteuid is that it simply issues an actual syscall and then it's into kernel space. You cannot debug that (kernel) code in the same way as you would debug a normal program.
So in your case you should better consult the documentation and read it carefully and try to figure out why geteuid doesn't return what you expect. Probably this will lead to you changing your expectation of what geteuid should return to match what's actually returned.

Windows C API: Create and name a new process that sleeps

What I want to do is use the Windows C API from my own single command line application to create a brand new process. (A couple of them actually). I want to be able to name this process whatever I want and all I want it to do is do a sleep(30) to get me going.
Im having trouble doing this with the CreateFile() API as it wants me to specify an executable to run the new process from. What I am after is something a bit like Fork() on Linux.
How do I go about doing this? Do I have to do something complex like embed an exe that calls sleep() in the resource section of my program, drop it then run CreateProcess() on it?
Reading around and talking to people, this is what I have found for anyone who has the same question as me.
CreateProcess() requires an executable to launch. There is no equivalent of fork() on windows. You need to pass it an executable file.
There are two ways of doing this:
1) embed a new executable in the resource section, drop it to disk and then call CreateProcess() on this from the main executable.
2) Have your main process call CreateProcess() on its own executable file, and handle what happens when it is called again dynamically. For example, if I run myApp.exe with no arguments, Perform its main tasks such as calling CreateFile() on its own executable. To tell that its not just running normally you could do something like this time handing the executable an argument. You can then handle this accordingly. eg if you then call myapp.exe with the argument "foo", the application then knows its being run differently and handle execution accordingly. Eg in main, when it see's the argument foo, it could walk its own PEB and change the process name to foo.exe (so it looks like a new executable) and then perform any actions you want.
I hope my explanation makes sense there.
Thanks for the help

Exploiting SUID files with LD_PRELOAD and IFS

I've been reading about IFS exploitation and LD_PRELOAD Privilege escalation by overriding functions. Although these are two completely different questions, I've decided to post them together and hope that isn't a problem. Though both of these are very old, I've been told that they can both still be used for privilege escalation and I would love to look into that. However, I've ran into some problems.
So, let's begin by making the SUID file, /tmp/suid.
#include <unistd.h>
int main() {
system("/bin/date");
}
This calls /bin/date. The idea is that we can change the internal field separator and deceive the file into running something else with the privileges that it currently holds. This can be done (or can it?) by making a new file called bin contain the malicious code that the attacker put in a custom location. Then we change the $PATH variable and make it so that locations are first searched inside our custom path, where our malicious fake binary is located. Then by changing the internal field separator to '/', instead of running /bin/date the program will run /tmp/fakepath/bin with argument date, which can potentially trigger privilege escalation.
When I attempt the method described dankalia.com, it fails. /bin/date gets executed instead. If I just type bin date into the console the malicious binary does get started, but it doesn't when it's being invoked through /tmp/suid.
I thought that the vulnerability is patched and that it simply ignores the IFS variable, but then a post on stackoverflow got me interested. (C: IFS System() Vulnerability). Can anyone confirm to me if this works or not, and what I am doing wrong? Thanks.
As for the LD_PRELOAD, I'll keep it rather simple.
define _GNU_SOURCE
#include <stdio.h>
int puts(const char *str) {
printf("lel");
}
Use the following command line to compile:
gcc –Wall –fPIC –shared –o puts.so puts.c –ldl
Then, override the function puts with preload tricks:
LD_PRELOAD=./puts.so ./vuln_program_that_uses_puts
This works quite well. However, when dealing with a SUID file and when we're talking about privilege escalation, this ain't happening. LD_PRELOAD doesn't work well with SUID files and for a good reason. I've been told that "you can get it to work but that it's hard". Ideas?
Thanks in advance, and sorry for the long questions.
I've been told that "you can get it to work but that it's hard". Ideas?
The operating system is wise to these sorts of tricks, and most are remediated now. Te general idea is setuid, sudo and friends don't use an unprivileged user's environment.
The following offers more reading:
suid-binary vulnerabilities
Breaking the links: Exploiting the linker
If all you want is a setuid binary to break into the system:
shutdown the computer
mount the hard drive
rename ls (or other program like date)
copy sudo to ls (or other program like date)
unmount and reboot

Apache APR function apr_procattr_cmdtype_set confusion

I've been following tutorials online on C coding, and the code is using the Apache APR library.
It uses the apr_proc_t structure to execute an external app.
I'm confused about this function, could someone explain what this function means:
apr_status_t apr_procattr_cmdtype_set ( apr_procattr_t * attr,
apr_cmdtype_e cmd
)
Set what type of command the child process will call.
Parameters:
attr The procattr we care about.
cmd The type of command. One of:
APR_SHELLCMD -- Anything that the shell can handle
APR_PROGRAM -- Executable program (default)
APR_PROGRAM_ENV -- Executable program, copy environment
APR_PROGRAM_PATH -- Executable program on PATH, copy env
The apr_procattr_cmdtype_set function is used to tell APR how you want to execute the external command, it probably just sets an internal flag and does a bit of bookkeeping.
Let us look at the enum apr_cmdtype_e:
APR_SHELLCMD
use the shell to invoke the program
APR_PROGRAM
invoke the program directly, no copied env
APR_PROGRAM_ENV
invoke the program, replicating our environment
APR_PROGRAM_PATH
find program on PATH, use our environment
APR_SHELLCMD_ENV
use the shell to invoke the program, replicating our environment
The first and last options (APR_SHELLCMD and APR_SHELLCMD_ENV) pretty much say "use a portable version of system" (with or without copying the current environment variables to the new process). The others are just variations on the Unix fork/exec pair with the flag choosing which of the exec family of functions to use.

Resources