https://github.com/oops-org-php/mod_execdir
mod_execdir: jailed system function. Run only the shell command in the specified directory
https://github.com/oops-org-php/mod_execdir
jail php8 security shell-injection
Last synced: 6 months ago
JSON representation
mod_execdir: jailed system function. Run only the shell command in the specified directory
- Host: GitHub
- URL: https://github.com/oops-org-php/mod_execdir
- Owner: OOPS-ORG-PHP
- Created: 2016-06-17T20:41:16.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2022-02-12T10:07:37.000Z (over 3 years ago)
- Last Synced: 2025-04-04T05:40:14.090Z (6 months ago)
- Topics: jail, php8, security, shell-injection
- Language: C
- Homepage:
- Size: 484 KB
- Stars: 7
- Watchers: 3
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.ko.md
Awesome Lists containing this project
README
PHP execdir extension
===
[](https://raw.githubusercontent.com/php/php-src/master/LICENSE) [](https://github.com/OOPS-ORG-PHP/mod_execdir/issues) [](https://github.com/OOPS-ORG-PHP/mod_execdir/network) [](https://github.com/OOPS-ORG-PHP/mod_execdir/stargazers)## 1. License
Copyright 2022. JoungKyun.Kim <http://oops.org> All rights reserved.
This program is under PHP License.
## 2. Description
***mod_execdir*** 확장은 특정 디렉토리에 있는 명령만 실행할 수 있도록 제한을 하여, web shell이나 system shell injection 공격을 원천적으로 방어할 수 있습니다. open_basedir과 같이 사용을 하면 hosting 서버에서의 각 계정간의 침해도 완벽하게 방어할 수 있습니다.
이 기능은 PHP 5.4 이전의 ***safe_mode_exec_dir*** 기능을 향상 구현한 것입니다.
***safe_mode_exec_dir*** 기능은 오직 ***SAFE MODE*** 에서만 사용이 가능하며, PHP 5.4 이후 부터는 ***SAFE MODE*** 가 제거 되면서 더 이상 사용을 할 수가 없습니다. 또한, ***safe_mode_exec_dir*** 의 parser는 너무나 간단하게 되어 있어 사용을 하기에 제약이 많았습니다.
execdir 기능은 이런 ***safe_mode_exec_dir*** 기능의 단점을 보완하여, ***SAFE MODE*** 가 아니고, 또한 PHP 5.4 이후 버전에서도 사용할 수 있도록 지원을 합니다.
2005년 5월 PHPBB의 highlight syntax security hole 때문에 만들어 졌으며, 대형 비지니스 사이트와 안녕 리눅스 배포본에 적용이 되어 10년 이상 검증이 되었습니다.
이 기능은 소스 코드에 직접 patch를 하거나, 또는 php dynamic extension으로 사용할 수 있으며, 이 기능은 다음의 PHP 함수에 영향을 미칩니다:
* exec
* system
* passthru
* shell_exec
* popen
* proc_open
* pcntl_exec
* shell_exec
* backtick operator## 3. Installation
### 3.1. Requirement
PHP 5 와 PHP 7, PHP 8 이상에서 사용이 가능합니다.
PHP 확장 모듈의 경우, PHP 5 호환 코드로 작성 하였지만, 실제 테스트는 PHP 5.1 이후 버전에서만 테스트 되었습니다.
이 기능을 사용하기 위해서는 2가지의 방법이 있습니다. 이 중에서 원하는 방법을 선택 하십시오.
1. PHP source에 직접 패치
* 코드에 직접 패치를 하기 때문에 mod_execdir 보다 성능이 좋음.
2. mod_execdir 확장 사용
* 원 함수를 hooking 및 alias를 하기 때문에 소스 패치보다는 성능이 미세하게 떨어짐.
* ***pcntl_exec*** call 실패 시에, pcntl_get_last_error() 함수 사용을 못함. 코드 수정이 필요 함.### 3.2. PHP source 에 직접 patch를 하는 경우
이 기능은 확장 모듈로서 사용을 할 수도 있고, PHP 소스에 직접 패치를 할 수도 있습니다. 확장 기능으로 사용하는 것 보다 PHP에 직접 패치를 해서 사용하는 것을 선호 한다면, [Patch 파일에 대한 설명](https://github.com/OOPS-ORG-PHP/mod_execdir/blob/master/patches/README.ko.md)을 참조 하십시오.
### 3.3. 동적 확장으로 사용할 경우
```shell
[root@host mod_execdir]$ phpize
[root@host mod_execdir]$ ./configure --with-execdir=/var/lib/php/bin
[root@host mod_execdir]$ make test PHP_EXECUTABLE=/usr/bin/php
[root@host mod_execdir]$ make install
```***configure*** 시에 ***--with-execdir*** 옵션을 이용하여 jail을 시킬 기본 디렉토리를 지정할 수 있습니다.
## 4.Usage
### 4.1. 설정
#### 4.1.1 module loading
php.ini에 다음의 설정을 추가 합니다. php 동적 확장으로 빌드를 했을 경우에는 execdir.so 를 php.ini에서 로딩해 줘야 합니다.
```ini
; for php 7.1 and before
extension = execdir.so; for php 7.2 and after
; default extension dir
extension = execdir
; use absolute path
extension = /path/execdir.so; if you use with opcache, follow option is set false
; When used with opcache, the proc_close function does not work properly.
; opcache.fast_shutdown = 0
```이 모듈은 기존의 system 함수들을 바꿔치기 하는 것이므로, 가장 마지막에 로딩되도록 추가해 줍니다.
#### 4.1.2 ini 설정
***exec_dir*** 옵션을 이용하여, jail 시킬 디렉토리를 지정할 수 있습니다.
```ini
; only executables located in the exec_dir will be allowed to be executed
; via the exec family of functions. This is only AnNyung LInux patch
; see also https://github.com/OOPS-ORG-PHP/mod_execdir/
exec_dir = /var/lib/php/bin
```아래와 같이 ***exec_dir*** 옵션이 설정이 되어 있지 않을 경우에는, ***configure*** 시에 지정한 ***--with-execdir*** 값이 사용이 됩니다. ***configure*** 시에 ***--with-execdir*** 옵션을 주지 않았다면, 이 경우 ***exec_dir*** 의 값은 빈 값이 됩니다.
```ini
; only executables located in the exec_dir will be allowed to be executed
; via the exec family of functions. This is only AnNyung LInux patch
; see also https://github.com/OOPS-ORG-PHP/mod_execdir/
;exec_dir =
```만약, jail을 하고 싶지 않다면 다음과 같이 빈 값을 지정해 놓아야 합니다.
```ini
; only executables located in the exec_dir will be allowed to be executed
; via the exec family of functions. This is only AnNyung LInux patch
; see also https://github.com/OOPS-ORG-PHP/mod_execdir/
exec_dir =
```#### 4.1.3 Apache VirtualHost
***PHP*** 를 ***apache module*** 로 사용할 경우 ***php_admin_value*** 지시자를 이용하여 가상 호스트마다 설정을 다르게 할 수 있습니다.
```apacheServerName domain.com
DocumentRoot /var/www/domain.com
php_admin_flag exec_dir /var/php/domain.com/bin
ServerName domain-other.com
DocumentRoot /var/www/domain-other.com
php_admin_flag exec_dir /var/php/domain-other.com/bin
```
이 설정을 응용하면 ``````, `````` 등의 블럭에서도 사용이 가능 합니다.
***exec_dir*** 옵션은 ***PHP_INI_SYSTEM*** 으로 할당이 되어 있기 때문에, ***.htaccess*** 에서는 사용이 불가능 합니다.
#### 4.1.4 PHP FPM pool
***PHP*** 를 ***fpm*** 모드로 사용할 경우에는, FPM pool 별로 설정이 가능 합니다.
```ini
[www]
php_admin_flag[exec_dir] = /var/php/pool/www/bin[www1]
php_admin_flag[exec_dir] = /var/php/pool/www1/bin
```### 4.2. 명령어 파서 지원 형식
paser에서 지원하는 형식은 다음과 같습니다:
```
command
$(command)
`command`
command; command
command $(command)
command $(command $(command))
command $(command `command`)
command `command`
command | command
command && command
command || command
```파서 적용 예는 다음과 같습니다:
```php
exec ('ls -al /etc/hosts', $o, $r);
exec ('ls -al /etc/ | grep hosts', $o, $r);
exec ('/bin/ls /etc/ | grep hosts', $o, $r);
exec ('cat $(echo "/etc/passwd") | grep root; ls -al', $o, $r);
exec ('cat `echo "/etc/passwd"` | grep root; ls -al', $o, $r);
exec ("echo '$(ls -l | grep abc)' | grep abc");
exec ('echo "$(ls -l | grep abc)" | grep abc');
```execdir 설정이 되어 있을 경우, 위의 코드들은 실제로는 다음과 같이 실행이 됩니다:
```php
exec ('/var/lib/php/bin/ls -al /etc/hosts', $o, $r);
exec ('/var/lib/php/bin/ls -al /etc/ | /var/lib/php/bin/grep hosts', $o, $r);
exec ('/var/lib/php/bin/ls -al /etc/ | /var/lib/php/bin/grep hosts', $o, $r);
exec ('/var/lib/php/bin/cat $(/var/lib/php/bin/echo "/etc/passwd") | /var/lib/php/bin/grep root; /var/lib/php/bin/ls -al', $o, $r);
exec ('/var/lib/php/bin/cat $(/var/lib/php/bin/echo "/etc/passwd") | /var/lib/php/bin/grep root; /var/lib/php/bin/ls -al', $o, $r);
exec ("/var/lib/php/bin/echo '$(ls -l | grep abc)' | /var/lib/php/bin/grep abc");
exec ('/var/lib/php/bin/echo "$(/var/lib/php/bin/ls -l | /var/lib/php/bin/grep abc)" | /var/lib/php/bin/grep abc');
```### 4.3. APIs
mod_execdir 확장 패키지로 빌드를 했을 경우에만 해당 됩니다.
#### 4.3.1. Original functions
기존의 함수들은 ***_orig*** 접미사를 이용하여 호출을 할 수 있습니다.
```php
```
원 함수 목록은 다음과 같습니다.
* exec_orig
* system_orig
* passthru_orig
* shell_exec_orig
* popen_orig
* proc_open_orig
* proc_close_orig
* proc_terminate_orig
* proc_get_status_orig이 기능은 ```1.0.2``` 부터는 ***configure*** 시에 ***--enable-execdir-addon*** 옵션을 주어야 호출할 수 있습니다.
#### 4.3.2. mod_execdir APIs
* ***exec_re*** : mapping ***exec*** function
* ***system_re*** : mapping ***system*** function
* ***passthru_re*** : mapping ***passthru*** function
* ***shell_exec_re*** : mapping ***shell_exec*** function
* ***popen_re*** : mapping ***popen*** function
* ***proc_open_re*** : mapping ***proc_open*** function
* ***proc_close_re*** : mapping ***proc_close*** function
* ***proc_terminate_re*** : mapping ***proc_terminate*** function
* ***proc_get_status_re*** : mapping ***proc_get_status*** function
* ***pcntl_exec_re*** : mapping ***pcntl_exec*** function
***pcntl_exec*** 함수 호출 에러시에, ***pcntl_get_last_error()*** 함수를 사용할 수 없습니다. 그러므로, 다음과 같이 약간의 소스 수정이 필요 합니다.
***이전:***```php
```
***이후:***```php
```
* ***jailed_shellcmd*** : return jailed shell command strings
```
Prototype: (string) jailed_shellcmd (string path)
```
```php
```## 5.Contributors
JoungKyun.Kim