Apache: como executar arquivos PHP via CGI como usuário normal e sem que eles sejam executáveis

1

Antecedentes

Configuração do servidor que eu quero imitar

Eu tenho acesso a um servidor do CentOS 7 com o cPanel / WHM instalado, executando o EasyApache4 com a seguinte configuração:

# /usr/local/cpanel/bin/rebuild_phpconf --current
DEFAULT PHP: ea-php56
ea-php55 SAPI: cgi
ea-php56 SAPI: cgi
ea-php70 SAPI: cgi
# rpm -qa|grep ruid2
# rpm -qa|grep suexec
ea-apache24-mod_suexec-2.4.33-5.5.1.cpanel.x86_64

Acredito que suEXEC esteja ativado, porque /var/log/apache2/error_log contém entradas como AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec) .

Acredito que mod_ruid2 , nem suPHP , nem PHP-FPM , nem FastCGI , nem DSO (aka mod_php ) estão ativados.

Este servidor tem um usuário, myuser , cujo diretório ~/public_html/public/ é usado como a raiz do documento para o site mywebsite.com . (Estes não são os nomes reais, obviamente.)

Se eu colocar, nesse diretório, um arquivo PHP chamado whoami.php com o seguinte conteúdo (observe a falta de um shebang ):

<html>
<body>
<p>sapi_name:      <?php print php_sapi_name();    ?></p>
<p>exec whoami:    <?php print exec('whoami');     ?></p>
<p>system whoami:  <?php system('whoami');         ?></p>
<p>system id -a:   <?php system("id -a");          ?></p>
<p>getcurrentuser: <?php print get_current_user(); ?></p>
</body>
</html>

e visite-o no navegador em http://mywebsite.com/whoami.php (observe que isso não usa o formato de URL http://mywebsite.com/~myuser/whoami.php UserDir), renderiza como:

sapi_name: cgi-fcgi
exec whoami: myuser
system whoami: myuser
system id -a: uid=1002(myuser) gid=1003(myuser) groups=1003(myuser)
getcurrentuser: myuser

Comportamento que quero imitar

Isso é verdadeiro mesmo se não tiver a permissão executável, como segue:

$ ls -l /home/myuser/public_html/public/whoami.php | cut -d' ' -f1,3,4,9
-r-------- myuser myuser /home/myuser/public_html/public/whoami.php

Normalmente, o Apache 2.4 no modo CGI não pode executar um arquivo não executável como este, se eu entendi documentação corretamente:

Of course, the file will have to exist, and be executable, and return output in a particular way, or Apache will return an error message.

No entanto, cPanel / WHM parece fazer alguma coisa para alterar este fato. De acordo com a documentação do WHM :

CGI

The CGI handler executes PHP applications through the mod_cgi or the mod_cgid Apache modules. If you install the suEXEC module, the system executes PHP applications as the user that owns the VirtualHost that served the request. If you uninstall the suEXEC module, the system executes PHP applications as the nobody system user. The system provides mod_cgi and mod_ruid2 by default.

You can customize the CGI handler's settings in the PHP .user.ini file. […]

Important:

If you enable a per-user module, such as suEXEC or Ruid2, you can execute PHP scripts with permissions of 0400. If you disable a per-user module, such as suEXEC or Ruid2, you can execute PHP scripts with permissions of 0444.

Ou seja. mesmo sem suEXEC ou Ruid2 ativado, o EasyApache4 é de alguma forma capaz de fazer com que o Apache processe arquivos PHP não executáveis como scripts CGI, em vez de apenas servi-los como arquivos estáticos.

Perguntas

Eu tenho uma máquina diferente do CentOS 7, não roteável da internet e apenas para desenvolvimento. Não não tem o cPanel / WHM instalado. A segurança é não uma prioridade para esta máquina, e o SELinux está desativado. Imitando o comportamento do cPanel / WHM é uma prioridade para esta máquina: prioridade máxima.

  1. Nessa máquina, como convenceria o Apache 2.4 a executar arquivos PHP cujas permissões são 0400 ou 0444 e que não possuem um shebang, como scripts CGI via PHP 5.6, em vez de apenas servi-los como arquivos estáticos? Ou seja Como eu alcançaria o algo aludido acima? Fico feliz em compilar o Apache com opções de configuração suEXEC não padrão, se necessário.
  2. Em particular, como posso fazer isso ao veiculá-los sem precisar usar um URL UserDir (ou seja, sem a parte /~myuser de um URL como http://mywebsite.com/~myuser/mypage.php )?
  3. Como eu faria tudo isso também garantindo que esses arquivos sejam executados pelo myuser , via suEXEC, em vez de pelo apache ou Usuário link ou ninguém ?

Se você puder responder a todas as três perguntas de uma só vez, melhor ainda, mas mesmo que possa responder apenas a primeira, isso seria muito útil! Obrigado :)

    
por sampablokuper 28.04.2018 / 20:40

1 resposta

0

Aqui está uma maneira de conseguir isso, o que é OK para um ambiente de desenvolvimento privado que está sendo usado apenas para essa finalidade, mas deve ser nunca usado em uma máquina com roteamento da Internet.

Execute estes comandos bastante radicais:

# chown myuser:myser /usr/bin
# chown myuser:myser /usr/bin/php-cgi

então:

# chmod 711 /home/myuser
# chmod 755 /home/myuser/public_html
#

Além disso, (re) compile o Apache para ter o AP_DOC_ROOT="/" do suEXEC e (re) instalá-lo.

Modifique /etc/httpd/conf/httpd.conf ao longo destas linhas:

ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
ServerAdmin root@localhost
#ServerName example.local
ServerName localhost    
User apache
Group apache
<Directory />
    AllowOverride none
    Require all granted
</Directory>
<VirtualHost *:80>
  DocumentRoot "/home/myuser/public_html/public"
  SuexecUserGroup myuser myuser
  <IfModule alias_module>
    ScriptAlias /cgi-bin/ /home/myuser/public_html/public/cgi-bin/
  </IfModule>
  <Directory "/home/myuser/public_html/public">
    Options Indexes FollowSymLinks ExecCGI
    AllowOverride None
    Require all granted
    AddHandler cgi-script .cgi .pl
  </Directory>
</VirtualHost>
<IfModule dir_module>
  DirectoryIndex index.php index.cgi index.html index.htm
</IfModule>

e modifique /etc/httpd/conf.d/php.conf da seguinte forma:

ScriptAlias /local-bin /usr/bin
AddHandler application/x-httpd-php5 php
Action application/x-httpd-php5 /local-bin/php-cgi

Finalmente, (re) inicie o Apache.

Esta é a melhor abordagem que encontrei antes de fazer a pergunta acima. No entanto, há quase certamente melhores alternativas, e eu gostaria de aprender sobre elas, daí a minha postagem da pergunta. (Por exemplo, instalar um binário php-cgi no diretório pessoal do usuário deve, em princípio, ser uma medida viável e menos drástica do que modificar a propriedade do binário do sistema e seu diretório.)

Então, sinta-se à vontade para inventar essa resposta se ela te ajudar, ou para comentar de forma construtiva se isso não o ajudou, mas vou adiar marcá-la como "correta" por um tempo, na esperança de que melhores respostas apareçam .

    
por 01.05.2018 / 02:40