# [SOLVED] Apache PHP and sudo

## ROGA

Hi all,

I'm using Gentoo and the Apache-Server to learn PHP scripting. Unfortunality I'm not able to run the php command "exec" so that I can do something that needs root right. For example: 

```
exec('sudo route add -host 192.168.x.y reject')
```

This doesn't work for me  :Sad: 

I received the error:

```
sudo: Effective UID is not 0. Is /usr/bin/sudo on a file system with a set nosuid option or on an NFS file system without root privileges?
```

I have checked with:

```

ls -l /usr/bin/sudo

-rwsr-xr-x 1 root root 134048  9. Nov 12:35 /usr/bin/sudo

```

and everything seams to be ok.

Why I cant't execute sudo on my Gentoo with the user apache?

Please help me! It makes me nuts  :Sad: 

If you need more information, please ask for it. 

kind regards

RolandLast edited by ROGA on Sun Nov 11, 2018 9:22 am; edited 3 times in total

----------

## Hu

Why are you trying to run something privileged from PHP?  PHP is infamous for being hard to use safely, so deliberately granting it even more privilege seems very dangerous.

You might be running from a process with the NO_NEW_PRIVS flag set.  Check the output of setpriv -d, as run by the PHP script.

----------

## ROGA

Hello Hu,

Thank you very much for your support!

The reason why I'm trying to run a script with root Privilege is, because I had seen Firewall-Software based on Web-GUI that can do all this Things like creating iptables-chains and so on.

I also want to make somthing similar.

But back to my problem! I think you are absolutly Right with your hint.  :Cool:   :Cool: 

I checked the Output from setpriv -d when it's running under the account as the web-Server. The result was:

```
setpriv -d

Output="uid: 81

euid: 81

gid: 81

egid: 81

Zusätzliche Gruppen:81

no_new_privs: 1

Vererbbare Fähigkeiten:[kein]

Ambient capabilities: [kein]

Einschränkungen der Fähigkeit: chown,dac_override,kill,setgid,setuid,net_bind_service,ipc_lock

Securebits: noroot_locked

SELinux-Bezeichnung: kernel"

 Return="0"

 Value="SELinux-Bezeichnung: kernel"

```

And as you can see her, the NO_NEW_PRIVS flag is really set as you said.

My Question is now, how can I Change this behavior? Can you put me in the Right direction?

Kind regards

Roland

PS: sorry for my bad english!Last edited by ROGA on Sun Nov 11, 2018 9:24 am; edited 1 time in total

----------

## Hu

Your English is good enough that your point comes across clearly.  :Smile: 

The no_new_privs flag is set by a process calling prctl.  Once set, that flag cannot be unset.  Any child processes created afterward inherit the flag.  By design, the flag affects the entire tree of children, however far down it goes.  You need to examine that flag on the web server process and each of its parents, find which one set it, and then configure that process not to set it.  Examine the line NoNewPrivs: in /proc/PID/status for each process you suspect might have set it.  Alternatively, search the documentation (or common question&answer sites) for references to those components (PHP interpreter, web server, supervisor, etc. on up) and the NO_NEW_PRIVS option (sometimes also spelled as PR_SET_NO_NEW_PRIVS when discussing the argument used with prctl).  Once you know which process enables it, you can try to find how to prevent that.

If you intend to use this as anything more than a learning exercise, I recommend against disabling this, especially when PHP is involved.

----------

## ROGA

Hi Hu,

You are great!!!   :Laughing: 

Thank you for your exact explaining. Now that I have understand how all this works, I could examine wich process is involved. I found out that the Apache-Webserver himself has set this flag. So my next step was, to find out, how would the Apache-Server fired up. My Gentoo has a Systemd, so I examine the Start-/Stop Script for the Apache-Server and there I found it what I was searching for.

In the directory /etc/systemd/System/multi-user.target.wants/ there is a start/stop script for the Web-Server named apache2.service

In the Section [Service] I found the flag NoNewPrivileges set to true

```
[Service]

EnvironmentFile=/etc/conf.d/apache2

ExecStart=/usr/sbin/apache2 $APACHE2_OPTS -DFOREGROUND

ExecReload=/usr/sbin/apache2 $APACHE2_OPTS -k graceful

ExecStop=/usr/sbin/apache2 $APACHE2_OPTS -k graceful-stop

# We want systemd to give httpd some time to finish gracefully, but still want

# it to kill httpd after TimeoutStopSec if something went wrong during the

# graceful stop. Normally, Systemd sends SIGTERM signal right after the

# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give

# httpd time to finish.

KillSignal=SIGCONT

PrivateTmp=true

#Hardening

PrivateTmp=true

CapabilityBoundingSet=CAP_CHOWN CAP_SETGID CAP_SETUID CAP_DAC_OVERRIDE CAP_KILL CAP_NET_BIND_SERVICE

SecureBits=noroot-locked

ProtectSystem=full

NoNewPrivileges=true

PrivateDevices=true

MemoryDenyWriteExecute=true
```

I than changed the flag to false and restarted the apache-service.  After that I was able to run my PHP-Script with root-privileges! GREAT!!!   :Laughing:   :Laughing:   :Laughing: 

I was wondering why other distros do not have set this flag like for example Ubuntu. Is this really dangerous?? What would be the right way to run commands that needs root-right?

I plane for the future, to develope my own web-application with my raspperry pi. So it would be pretty nice to be able to control my hole Linux-System through the web-Server. 

Is there another solution to achieve this goal?

I would like to thank you again for your help! I mark this thread as solved!

kind regards

Roland

----------

## Ant P.

The right way to do it would be another process run as root that reads messages from the exposed webserver.

e.g. 

```
perl -TE 'while (<>) { system("route add -host $1 reject") if /^(\d+\.\d+\.\d+\.\d+)$/ }' < ips.fifo
```

----------

## ROGA

Hi Ant P.,

that sounds very good! But I'm new in Gentoo and also in programming with PHP and PERL. I would like to learn this things, but your example does not explaining me exactly how I have to do it. (or better, I don't understand your hint correctly)

ok, as far as I understand your example does do the following:

you first call the Interpreter "perl" with two Options -T and -E. But what does this two options achive?  (ok, I found out myself: -T is for more security (tainting checks) and -E is for one line program)

Then we have two conditions. The first condition is the while condition. What does it makes exactly?

Then next you have a second condition if with a Statement System(). The Condition is a regex check that must match a IP-Address, Right? The IP-Address Comes from ips.fifo. When the condition is true, then you call a System-function that does the Job that I want to do as root, Right?

So is this correct, that for every command that I would like to run as root, I have to make a PERL Process that is waiting for a Input? The Input is in your example the file ips.fifo, Right?

But how can I achive, that my Perl-Script then is running automaticly like a System Service? And how do I create this file ips.fifo?

It would be nice if you could push me a little bit more in the right direction?

kind regards,

Roland

----------

## Hu

 *ROGA wrote:*   

> I found out that the Apache-Webserver himself has set this flag. So my next step was, to find out, how would the Apache-Server fired up. My Gentoo has a Systemd, so I examine the Start-/Stop Script for the Apache-Server and there I found it what I was searching for.

 Thank you for describing your method and findings.  This may help someone else who has a similar question and finds your thread. *ROGA wrote:*   

> 
> 
> I was wondering why other distros do not have set this flag like for example Ubuntu. Is this really dangerous?? What would be the right way to run commands that needs root-right?

 I cannot say why others have it set differently.  Setting no-new-privs is safer than not setting it, since it mitigates the ability of exploits to compromise the system.  As Ant P. says, the right way to run something that needs root is to have a broker process that receives just enough information to perform the desired operation, validates it carefully, and then does the operation on behalf of the web server.  You could get the same effect by doing as you did here, but your way means that anything run by the server can escalate to root and have full access to all root's capabilities.  This is far more dangerous, since you then rely on the absence of security vulnerabilities in a large and complex system.

----------

