├── Dockerfile
├── LICENSE.md
├── README.md
├── config
├── piof.ini
└── rsyslog.conf
├── images
├── headerlogo.png
├── icon90.png
├── icon_black.png
├── icon_transparent.png
├── logo.html
└── logo.png
├── run.sh
└── src
├── .gitignore
├── config.m4
├── hooks
├── include
│ ├── hook.c
│ └── hook.h
├── md5
│ ├── hook.c
│ └── hook.h
└── system
│ ├── hook.c
│ └── hook.h
├── hooks_disabled
└── eval
│ ├── hook.c
│ └── hook.h
├── piof.c
├── piof_config.h
├── piof_globals.c
├── piof_globals.h
└── scripts
├── buildall.sh
├── buildhooks.sh
└── tests.sh
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:7.2-apache
2 |
3 | RUN apt update
4 |
5 | RUN docker-php-source extract
6 |
7 | RUN apt install nano -y
8 |
9 | RUN apt install rsyslog --fix-missing -y
10 |
11 | COPY config/piof.ini /usr/local/etc/php/conf.d
12 |
13 | COPY config/rsyslog.conf /etc/rsyslog.conf
14 |
15 |
16 | COPY src /opt/piof
17 |
18 | WORKDIR /opt/piof/
19 |
20 | RUN ./scripts/buildall.sh
21 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 |
2 | Copyright 2019 Martino Lessio - Alessandro Braccio
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 |
8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 |
10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://opensource.org/licenses/BSD-3-Clause)
2 | 
3 | 
4 |
5 |
6 | # PIOF - PHP Instrumentation Open Framework
7 | 
8 |
9 | # What
10 | PIOF - Is a dynamic and modular instrumentation framework for PHP.
11 |
12 | # Why
13 | It is useful for Developers, Reverse Engineers, Malware Analyst and Vulnerability Researcher.
14 | With PIOF you can:
15 |
16 | - Perform debugging, tracing and performance analysis
17 | - Instrument PHP code on the interpreter layer
18 | - Instrument obfuscated PHP code
19 | - Virtual Patching
20 | - Prototype IAST and RASP technologies
21 |
22 | # Where
23 | Tested on:
24 | ```
25 | PHP 7.2.10-0ubuntu0.18.04.1 (cli) (built: Sep 13 2018 13:45:02) ( NTS )
26 | Copyright (c) 1997-2018 The PHP Group
27 | Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
28 | with Zend OPcache v7.2.10-0ubuntu0.18.04.1, Copyright (c) 1999-2018, by Zend Technologies
29 | ```
30 | # Who
31 | Martino - twitter.com/martinolessio
32 |
33 | Alessandro - twitter.com/rhpco
34 |
35 | # Quick Start
36 | ```
37 | git clone https://github.com/ingenuity-ninja/piof.git
38 | cd piof
39 | ./run.sh
40 | ```
41 | ## Docker
42 | A Docker container is used for the building and testing stages. Use the container shell to interact with the PIOF environment:
43 | ```
44 | root@4e7b7dd9f362:/opt/piof/modules#
45 | ```
46 | ## Extension
47 | The generated PHP extension is available in `/opt/piof/modules`
48 | ```
49 | root@4e7b7dd9f362:/opt/piof/modules# ls -lah
50 | total 100K
51 | drwxr-xr-x 2 root root 4.0K Feb 19 20:55 .
52 | drwxr-xr-x 1 root root 4.0K Feb 19 20:55 ..
53 | -rwxr-xr-x 1 root root 91K Feb 19 20:55 piof.so
54 | ```
55 | You can either include it in your php.ini or use it from the command line.
56 |
57 | ## Command line run
58 | When the extension is enabled in `php.ini` you can execute php as usual, for example:
59 | ```
60 | root@4e7b7dd9f362:/etc# php -r "system("ls");"
61 |
62 | adduser.conf
63 | aliases
64 | alternatives
65 | apache2
66 | apt
67 | bash.bashrc
68 | bindresvport.blacklist
69 | ca-certificates
70 | ca-certificates.conf
71 | cron.d
72 | [...]
73 | ```
74 | To use the module at runtime you can use the following command:
75 | ```
76 | php -dextension=/opt/piof/modules/piof.so -r "system("ls");"
77 |
78 | ```
79 |
80 | ## Logger
81 | PIOF logs in `/var/log/piof*`
82 |
83 | ### Informational
84 | The hooking modules logs information about sink execution:
85 | ```
86 | root@4e7b7dd9f362:/etc# tail -f /var/log/piof.info.log
87 |
88 | Feb 19 21:05:15 4e7b7dd9f362 piof - system - hook[155]: Arguments 1
89 | Feb 19 21:05:15 4e7b7dd9f362 piof - system - hook[155]: Parameter ls
90 | Feb 19 21:12:17 4e7b7dd9f362 piof - md5 - hook[160]: Arguments 1
91 | Feb 19 21:12:17 4e7b7dd9f362 piof - md5 - hook[160]: Parameter admin
92 | ```
93 | ### Error
94 | All internal error are logged in `/var/log/piof.error.log`
95 |
96 | ## Hooks Modules
97 | Hooking modules are in located in `/opt/piof/hooks`. These modules are dynamically built and loaded by the PIOF core extension so they need to be always available with `piof.so`.
98 | The modules are organized hierarchically in directories: each directory is associated to a sink, and each one contains a `hook.c` and a `hook.h` file.
99 |
100 | ```
101 | root@42e0da0df931:/opt/piof/hooks# ls -lah
102 | total 28K
103 | drwxrwxr-x 1 root root 4.0K Feb 19 20:55 .
104 | drwxr-xr-x 1 root root 4.0K Feb 19 20:55 ..
105 | drwxr-xr-x 2 root root 4.0K Feb 19 20:55 build
106 | drwxrwxr-x 2 root root 4.0K Feb 19 20:24 eval
107 | drwxrwxr-x 2 root root 4.0K Feb 19 20:24 include
108 | drwxrwxr-x 2 root root 4.0K Feb 19 20:24 md5
109 | drwxrwxr-x 2 root root 4.0K Feb 19 20:24 system
110 | ```
111 | and
112 | ```
113 | root@42e0da0df931:/opt/piof/hooks# ls -lah include/
114 | total 16K
115 | drwxrwxr-x 2 root root 4.0K Feb 19 20:24 .
116 | drwxrwxr-x 1 root root 4.0K Feb 19 20:55 ..
117 | -rw-rw-r-- 1 root root 943 Feb 19 20:24 hook.c
118 | -rw-rw-r-- 1 root root 356 Feb 19 20:24 hook.h
119 | ```
120 | During the building stage PIOF compiles all modules and move the generated `.so` files in `/opt/piof/hooks/build`
121 |
122 | ```
123 | root@42e0da0df931:/opt/piof/hooks/build# ls -lah
124 | total 184K
125 | drwxr-xr-x 2 root root 4.0K Feb 19 20:55 .
126 | drwxrwxr-x 1 root root 4.0K Feb 19 20:55 ..
127 | -rwxr-xr-x 1 root root 43K Feb 19 20:55 eval.so
128 | -rwxr-xr-x 1 root root 43K Feb 19 20:55 include.so
129 | -rwxr-xr-x 1 root root 44K Feb 19 20:55 md5.so
130 | -rwxr-xr-x 1 root root 44K Feb 19 20:55 system.so
131 | ```
132 |
133 |
134 | ## Manual Extension Building
135 | ```
136 | make clean
137 | phpize
138 | ./configure
139 | make
140 | ```
141 | ## Manuale Modules Building
142 | ```
143 | cd /opt/piof/hooks/eval/
144 | gcc -shared -o eval.so -fPIC hook.c -g -Wall -I -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -I ../../
145 | mv eval.so ../build
146 | ```
147 |
148 | ## Manual Testing
149 |
150 | ### Hooked function `md5`
151 | ```
152 | php -dextension=/opt/piof/modules/piof.so -r "echo md5("admin");"
153 |
154 | ```
155 |
156 | ### Hooked function `system`
157 | ```
158 | php -dextension=/opt/piof/modules/piof.so -r "system("ls");"
159 |
160 | ```
161 |
162 | # License
163 | 3-clause BSD license (BSD-3-Clause)
164 |
--------------------------------------------------------------------------------
/config/piof.ini:
--------------------------------------------------------------------------------
1 | extension=piof.so
--------------------------------------------------------------------------------
/config/rsyslog.conf:
--------------------------------------------------------------------------------
1 | # /etc/rsyslog.conf Configuration file for rsyslog.
2 | #
3 | # For more information see
4 | # /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html
5 |
6 |
7 | #################
8 | #### MODULES ####
9 | #################
10 |
11 | module(load="imuxsock") # provides support for local system logging
12 | module(load="imklog") # provides kernel logging support
13 | #module(load="immark") # provides --MARK-- message capability
14 |
15 | # provides UDP syslog reception
16 | #module(load="imudp")
17 | #input(type="imudp" port="514")
18 |
19 | # provides TCP syslog reception
20 | #module(load="imtcp")
21 | #input(type="imtcp" port="514")
22 |
23 |
24 | ###########################
25 | #### GLOBAL DIRECTIVES ####
26 | ###########################
27 |
28 | #
29 | # Use traditional timestamp format.
30 | # To enable high precision timestamps, comment out the following line.
31 | #
32 | $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
33 |
34 | #
35 | # Set the default permissions for all log files.
36 | #
37 | $FileOwner root
38 | $FileGroup adm
39 | $FileCreateMode 0640
40 | $DirCreateMode 0755
41 | $Umask 0022
42 |
43 | #
44 | # Where to place spool and state files
45 | #
46 | $WorkDirectory /var/spool/rsyslog
47 |
48 | #
49 | # Include all config files in /etc/rsyslog.d/
50 | #
51 | $IncludeConfig /etc/rsyslog.d/*.conf
52 |
53 | $DebugFile /var/log/rsyslog-debug.log
54 | $DebugLevel 0 # settare a 2 per full debug
55 |
56 | local0.* /var/log/piof.log
57 | local0.=alert /var/log/piof.alert.log
58 | local0.=crit /var/log/piof.critical.log
59 | local0.=debug /var/log/piof.debug.log
60 | local0.=emerg /var/log/piof.emergency.log
61 | local0.=err /var/log/piof.error.log
62 | local0.=info /var/log/piof.info.log
63 | local0.=notice /var/log/piof.notice.log
64 | local0.=warning /var/log/piof.warning.log
65 | &~
--------------------------------------------------------------------------------
/images/headerlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ingenuity-Fainting-Goats/piof/5b26dbfe87506747228784c156b4db1c76fda2dc/images/headerlogo.png
--------------------------------------------------------------------------------
/images/icon90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ingenuity-Fainting-Goats/piof/5b26dbfe87506747228784c156b4db1c76fda2dc/images/icon90.png
--------------------------------------------------------------------------------
/images/icon_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ingenuity-Fainting-Goats/piof/5b26dbfe87506747228784c156b4db1c76fda2dc/images/icon_black.png
--------------------------------------------------------------------------------
/images/icon_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ingenuity-Fainting-Goats/piof/5b26dbfe87506747228784c156b4db1c76fda2dc/images/icon_transparent.png
--------------------------------------------------------------------------------
/images/logo.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ingenuity-Fainting-Goats/piof/5b26dbfe87506747228784c156b4db1c76fda2dc/images/logo.png
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | docker stop piof-instance
4 | docker rm piof-instance
5 | docker build -t piof .
6 |
7 | docker run -d --name piof-instance piof
8 |
9 | docker exec -i -t piof-instance "/opt/piof/scripts/tests.sh"
10 | docker exec -i -t piof-instance "/bin/bash"
--------------------------------------------------------------------------------
/src/.gitignore:
--------------------------------------------------------------------------------
1 | .deps
2 | *.lo
3 | *.la
4 | Makefile*
5 | ac*.m4
6 | build/
7 | .libs/
8 | autom4te.cache/
9 | config.guess
10 | config.h
11 | config.h.in
12 | config.log
13 | config.nice
14 | config.status
15 | config.sub
16 | configure
17 | configure.in
18 | configure.ac
19 | install-sh
20 | libtool
21 | ltmain.sh
22 | missing
23 | mkinstalldirs
24 | modules/
25 | run-tests.php
26 | *.tgz
27 | *.a
28 | src/*.lo
29 | **/*.so
30 |
31 | *.db
32 | a.out
33 |
34 | *.o
--------------------------------------------------------------------------------
/src/config.m4:
--------------------------------------------------------------------------------
1 | PHP_ARG_ENABLE(piof, whether to enable my extension,
2 | [ --enable-piof Enable piof])
3 |
4 | #if test "$PHP_PIOF" = "yes"; then
5 | # AC_DEFINE(HAVE_PIOF, 1, [Whether you have piof])
6 | # PHP_NEW_EXTENSION(piof, piof.c hooks/system/hook.c hooks/md5/hook.c piof_globals.c, $ext_shared)
7 | # CFLAGS="$CFLAGS -ldl"
8 | #fi
9 | if test "$PHP_PIOF" = "yes"; then
10 | AC_DEFINE(HAVE_PIOF, 1, [Whether you have piof])
11 | PHP_NEW_EXTENSION(piof, piof.c piof_globals.c, $ext_shared)
12 | CFLAGS="$CFLAGS -ldl -Wl,-rpath,\$(srcdir)/hooks_build"
13 | fi
14 |
--------------------------------------------------------------------------------
/src/hooks/include/hook.c:
--------------------------------------------------------------------------------
1 | /// * gcc -shared -o include.so -fPIC hook.c -g -Wall -I -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -I ../../
2 |
3 |
4 | #include "hook.h"
5 | #include
6 |
7 |
8 | zend_op_array* hook(zend_file_handle *file_handle, int type){
9 | openlog("piof - include - hook", LOG_PID, LOG_LOCAL0);
10 | includeHookStructure running_structure;
11 | running_structure.pipeline_status.status = 0;
12 | running_structure.file_handle = file_handle;
13 | syslog(LOG_INFO | LOG_LOCAL0, "Parameter %s",running_structure.file_handle->filename);
14 | closelog();
15 | return old_compile_file(file_handle, type);
16 | }
17 |
--------------------------------------------------------------------------------
/src/hooks/include/hook.h:
--------------------------------------------------------------------------------
1 | #include "php.h"
2 | #include "piof_config.h"
3 |
4 |
5 | typedef struct{
6 | pipeline_message pipeline_status;
7 | zend_file_handle *file_handle;
8 | } include_hook_structure;
9 | typedef include_hook_structure includeHookStructure;
10 | //
11 | zend_op_array* hook(zend_file_handle *file_handle, int type);
12 | zend_op_array *(*old_compile_file)(zend_file_handle *file_handle, int type);
13 |
14 |
--------------------------------------------------------------------------------
/src/hooks/md5/hook.c:
--------------------------------------------------------------------------------
1 | /// * gcc -shared -o md5.so -fPIC hook.c -g -Wall -I -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -I ../../
2 |
3 | #include "hook.h"
4 | #include
5 |
6 | PipelineMessage hook(INTERNAL_FUNCTION_PARAMETERS, t_executor_internal executor){
7 | openlog("piof - md5 - hook", LOG_PID, LOG_LOCAL0);
8 | md5HookStructure running_structure;
9 | running_structure.pipeline_status.status = 0;
10 | ZEND_PARSE_PARAMETERS_START(1, 1);
11 | Z_PARAM_STR(running_structure.parameter);
12 | ZEND_PARSE_PARAMETERS_END();
13 | syslog(LOG_INFO | LOG_LOCAL0, "Arguments %d",ZEND_CALL_NUM_ARGS(execute_data));
14 | syslog(LOG_INFO | LOG_LOCAL0, "Parameter %s",ZSTR_VAL(running_structure.parameter));
15 | closelog();
16 | executor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
17 | return running_structure.pipeline_status;
18 | }
19 |
--------------------------------------------------------------------------------
/src/hooks/md5/hook.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file hook.h
3 | * @author your name (you@domain.com)
4 | * @brief
5 | * @version 0.1
6 | * @date 2019-02-11
7 | *
8 | * @copyright Copyright (c) 2019
9 | *
10 | * gcc -shared -o md5.so -fPIC hook.c -g -Wall -I. -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend-I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -I ../../
11 | */
12 |
13 | #include "php.h"
14 | #include "piof_config.h"
15 | /**
16 | * md5_hook_struture
17 | **/
18 | typedef struct{
19 | pipeline_message pipeline_status;
20 | zend_string *parameter;
21 | } md5_hook_structure;
22 | typedef md5_hook_structure md5HookStructure;
23 | //
24 | PipelineMessage hook(INTERNAL_FUNCTION_PARAMETERS, t_executor_internal executor);
--------------------------------------------------------------------------------
/src/hooks/system/hook.c:
--------------------------------------------------------------------------------
1 | /// * gcc -shared -o system.so -fPIC hook.c -g -Wall -I -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -I ../../
2 |
3 | #include "hook.h"
4 | #include
5 |
6 | PipelineMessage hook(INTERNAL_FUNCTION_PARAMETERS, t_executor_internal executor)
7 | {
8 | openlog("piof - system - hook", LOG_PID, LOG_LOCAL0);
9 | systemHookStructure running_structure;
10 | running_structure.pipeline_status.status = 0;
11 | ZEND_PARSE_PARAMETERS_START(1, 1);
12 | Z_PARAM_STR(running_structure.parameter);
13 | ZEND_PARSE_PARAMETERS_END();
14 | syslog(LOG_INFO | LOG_LOCAL0, "Arguments %d",ZEND_CALL_NUM_ARGS(execute_data));
15 | syslog(LOG_INFO | LOG_LOCAL0, "Parameter %s",ZSTR_VAL(running_structure.parameter));
16 | closelog();
17 | executor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
18 | return running_structure.pipeline_status;
19 | }
20 |
--------------------------------------------------------------------------------
/src/hooks/system/hook.h:
--------------------------------------------------------------------------------
1 | #include "php.h"
2 | #include "piof_config.h"
3 | /**
4 | * system_hook_struture
5 | **/
6 | typedef struct{
7 | pipeline_message pipeline_status;
8 | zend_string *parameter;
9 | } system_hook_structure;
10 | typedef system_hook_structure systemHookStructure;
11 | //
12 | PipelineMessage hook(INTERNAL_FUNCTION_PARAMETERS, t_executor_internal executor);
--------------------------------------------------------------------------------
/src/hooks_disabled/eval/hook.c:
--------------------------------------------------------------------------------
1 | /// * gcc -shared -o eval.so -fPIC hook.c -g -Wall -I -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib -I ../../
2 |
3 |
4 | #include "hook.h"
5 | #include
6 |
7 |
8 | zend_op_array* hook(zval *source_string, char *filename TSRMLS_DC){
9 | openlog("piof - eval - hook", LOG_PID, LOG_LOCAL0);
10 | evalHookStructure running_structure;
11 | running_structure.pipeline_status.status = 0;
12 | running_structure.filename = filename;
13 | running_structure.source_string = Z_STRVAL_P(source_string);
14 | syslog(LOG_INFO | LOG_LOCAL0, "Parameter Source String: %s",running_structure.source_string);
15 | syslog(LOG_INFO | LOG_LOCAL0, "Parameter Filename: %s",running_structure.filename);
16 |
17 | closelog();
18 | return old_compile_string(source_string, filename TSRMLS_CC);
19 | }
20 |
--------------------------------------------------------------------------------
/src/hooks_disabled/eval/hook.h:
--------------------------------------------------------------------------------
1 | #include "php.h"
2 | #include "piof_config.h"
3 |
4 |
5 | typedef struct{
6 | pipeline_message pipeline_status;
7 | char *source_string;
8 | char *filename TSRMLS_CC;
9 | } eval_hook_structure;
10 | typedef eval_hook_structure evalHookStructure;
11 | //
12 | zend_op_array* hook(zval *source_string, char *filename TSRMLS_DC);
13 | zend_op_array *(*old_compile_string)(zval *source_string, char *filename TSRMLS_DC);
14 |
15 |
--------------------------------------------------------------------------------
/src/piof.c:
--------------------------------------------------------------------------------
1 | #include "php.h"
2 | #include "piof_config.h"
3 | #include "piof_globals.h"
4 | #include "Zend/zend_ini.h"
5 | #include "zend_exceptions.h"
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #define HANDLERS_POSITIONS "/opt/piof/hooks/build/"
16 | #define HANDLER_EXTENSION ".so"
17 |
18 | void (*original_zend_execute_ex)(zend_execute_data *execute_data);
19 | void (*original_zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
20 | zend_op_array *(*old_compile_string)(zval *source_string, char *filename TSRMLS_DC);
21 | zend_op_array *(*old_compile_file)(zend_file_handle *file_handle, int type);
22 | void piof_zend_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
23 | void piof_zend_execute_internal(INTERNAL_FUNCTION_PARAMETERS);
24 |
25 | zend_class_entry *piof_exception;
26 | void piof_init_exception(TSRMLS_D)
27 | {
28 | zend_class_entry e;
29 | INIT_CLASS_ENTRY(e, "piofException", NULL);
30 | piof_exception = zend_register_internal_class_ex(&e, zend_exception_get_default());
31 | }
32 |
33 | ZEND_DECLARE_MODULE_GLOBALS(piof)
34 | zend_module_entry piof_module_entry = {
35 | STANDARD_MODULE_HEADER,
36 | PIOF_NAME,
37 | NULL, /* All exposed functions, only to test POC, will get removed later */
38 | PHP_MINIT(piof), /* On module startup */
39 | PHP_MSHUTDOWN(piof),
40 | PHP_RINIT(piof),
41 | PHP_RSHUTDOWN(piof),
42 | NULL, /* Module info, used in phpinfo(); */
43 | PIOF_VERSION,
44 | STANDARD_MODULE_PROPERTIES};
45 |
46 | ZEND_GET_MODULE(piof)
47 |
48 | void piof_zend_execute_ex(zend_execute_data *execute_data)
49 | {
50 | original_zend_execute_ex(execute_data);
51 | return;
52 | }
53 |
54 | void resume_execute_internal(INTERNAL_FUNCTION_PARAMETERS)
55 | {
56 | if (original_zend_execute_internal)
57 | {
58 | original_zend_execute_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
59 | }
60 | else
61 | {
62 | execute_data->func->internal_function.handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
63 | }
64 | }
65 |
66 | void piof_zend_execute_internal(INTERNAL_FUNCTION_PARAMETERS)
67 | {
68 | zend_string *function_name = get_function_name(
69 | EG(current_execute_data)->func->common.function_name);
70 | zval *piof_pre_hook;
71 | zval *piof_validator;
72 |
73 | zend_string *validator_name;
74 |
75 | if (function_name == NULL)
76 | {
77 | resume_execute_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
78 | return;
79 | }
80 |
81 | piof_pre_hook = zend_hash_find(PIOF_G(piof_hooked_functions), function_name);
82 |
83 | if (piof_pre_hook == NULL)
84 | {
85 | resume_execute_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
86 | zend_string_release(function_name);
87 | }
88 | else
89 | {
90 | t_hook *hook_ptr = (t_hook *)(Z_LVAL(*piof_pre_hook));
91 | PipelineMessage result = hook_ptr(INTERNAL_FUNCTION_PARAM_PASSTHRU, resume_execute_internal);
92 | if (result.status < 0)
93 | {
94 | zend_throw_exception(piof_exception, "piof.c Custom Exception zend_throw_exception", 0L);
95 | }
96 | }
97 | }
98 |
99 | bool piof_hook_function(const char *method_name, t_hook *hook)
100 | {
101 | openlog("piof - piof_hook_function", LOG_PID, LOG_LOCAL0);
102 | zend_function *function;
103 | zend_string *f_name = zend_string_init(method_name, strlen(method_name), 0);
104 | if (!hook)
105 | {
106 | syslog(LOG_DEBUG | LOG_LOCAL0, "[ERROR] Unable to apply hook, no hook address provided");
107 | return false;
108 | }
109 | if ((function = zend_hash_str_find_ptr(CG(function_table), method_name, strlen(method_name))) != NULL)
110 | {
111 | if (hook != NULL)
112 | {
113 | zval zv;
114 | ZVAL_LONG(&zv, (long)*hook);
115 | zend_hash_update(PIOF_G(piof_hooked_functions), f_name, &zv);
116 | syslog(LOG_DEBUG | LOG_LOCAL0, "Hooked function %s with handler %p", method_name, *hook);
117 | }
118 | closelog();
119 | return true;
120 | }
121 | else
122 | {
123 | syslog(LOG_DEBUG | LOG_LOCAL0, "[ERROR] Unable to locate function '%s' in global function table", method_name);
124 | closelog();
125 | return false;
126 | }
127 | }
128 |
129 |
130 | int load_shared_objects()
131 | {
132 | openlog("piof - load_shared_objects", LOG_PID, LOG_LOCAL0);
133 | syslog(LOG_DEBUG | LOG_LOCAL0, "Loading hooking modules from %s", HANDLERS_POSITIONS);
134 | DIR *directory_ptr;
135 | struct dirent *dir;
136 | directory_ptr = opendir(HANDLERS_POSITIONS);
137 | if (directory_ptr) {
138 | while ((dir = readdir(directory_ptr)) != NULL) {
139 | char *file_extension = strrchr(dir->d_name, '.');
140 | if(strcmp(file_extension, HANDLER_EXTENSION)==0){
141 | void* handle = NULL;
142 | const char* error_message = NULL;
143 | char module_path[256];
144 | memset(module_path, '\0', sizeof(module_path));
145 | strncat(module_path,HANDLERS_POSITIONS,sizeof(module_path));
146 | strncat(module_path,dir->d_name,sizeof(module_path));
147 | handle = dlopen(module_path, RTLD_LAZY );
148 | if( !handle ){
149 | syslog(LOG_DEBUG | LOG_LOCAL0, "[ERROR] - dlopen() %s", dlerror() );
150 | return 1;
151 | }
152 |
153 | // method router
154 | if (strcmp(dir->d_name, "include.so") == 0){
155 | t_hook_compiler *hook= dlsym(handle, "hook");
156 | if ((error_message = dlerror()) != NULL) {
157 | syslog(LOG_DEBUG | LOG_LOCAL0, "[ERROR] - dlopen() %s", error_message );
158 | dlclose( handle );
159 | return 1;
160 | }
161 | old_compile_file = zend_compile_file;
162 | zend_compile_file = hook;
163 | syslog(LOG_DEBUG | LOG_LOCAL0, "Hooked function zend_compile_file with handler %p", *hook);
164 | } else if(strcmp(dir->d_name, "eval.so") == 0){
165 | t_hook_string_compiler *hook= dlsym(handle, "hook");
166 | if ((error_message = dlerror()) != NULL) {
167 | syslog(LOG_DEBUG | LOG_LOCAL0, "[ERROR] - dlopen() %s", error_message );
168 | dlclose( handle );
169 | return 1;
170 | }
171 | old_compile_string = zend_compile_string;
172 | zend_compile_string = hook;
173 | syslog(LOG_DEBUG | LOG_LOCAL0, "Hooked function zend_compile_string with handler %p", *hook);
174 | }else {
175 | t_hook *hook = dlsym(handle, "hook");
176 | if ((error_message = dlerror()) != NULL) {
177 | syslog(LOG_DEBUG | LOG_LOCAL0, "[ERROR] - dlopen() %s", error_message );
178 | dlclose( handle );
179 | return 1;
180 | }
181 | char *hook_name = malloc(strlen(dir->d_name));
182 | memset(hook_name, '\0', sizeof(hook_name));
183 | memcpy(hook_name, dir->d_name, strlen(dir->d_name)-3);
184 | hook_name[strlen(dir->d_name)-3] = '\0';
185 | piof_hook_function(hook_name, hook);
186 | free(hook_name);
187 | }
188 | }
189 | }
190 | closedir(directory_ptr);
191 | }
192 | closelog();
193 | return 0;
194 | }
195 |
196 | PHP_MINIT_FUNCTION(piof)
197 | {
198 | openlog("piof - MINIT", LOG_PID, LOG_LOCAL0);
199 | ALLOC_HASHTABLE(PIOF_G(piof_hooked_functions));
200 | zend_hash_init(PIOF_G(piof_hooked_functions), 16, NULL, ZVAL_PTR_DTOR, 0);
201 |
202 | load_shared_objects();
203 |
204 | original_zend_execute_ex = zend_execute_ex;
205 | zend_execute_ex = piof_zend_execute_ex;
206 | syslog(LOG_DEBUG | LOG_LOCAL0, "Hooked zend_execute_ex %p", *piof_zend_execute_ex);
207 |
208 | original_zend_execute_internal = zend_execute_internal;
209 | zend_execute_internal = piof_zend_execute_internal;
210 | syslog(LOG_DEBUG | LOG_LOCAL0, "Hooked zend_execute_internal %p", *piof_zend_execute_internal);
211 |
212 |
213 | closelog();
214 | return SUCCESS;
215 | }
216 |
217 | PHP_MSHUTDOWN_FUNCTION(piof)
218 | {
219 | openlog("piof - MSHUTDOWN", LOG_PID, LOG_LOCAL0);
220 | closelog();
221 | return SUCCESS;
222 | }
223 |
224 | PHP_RINIT_FUNCTION(piof)
225 | {
226 | openlog("piof - RINIT", LOG_PID, LOG_LOCAL0);
227 | closelog();
228 | return SUCCESS;
229 |
230 | }
231 |
232 | PHP_RSHUTDOWN_FUNCTION(piof)
233 | {
234 | openlog("piof - RSHUTDOWN", LOG_PID, LOG_LOCAL0);
235 | syslog(LOG_DEBUG | LOG_LOCAL0, "Cleaning hooked functions... ");
236 | zend_execute_ex = original_zend_execute_ex;
237 | zend_execute_internal = original_zend_execute_internal;
238 | zend_compile_string = old_compile_string;
239 | zend_compile_file = old_compile_file;
240 | zend_hash_destroy(PIOF_G(piof_hooked_functions));
241 | FREE_HASHTABLE(PIOF_G(piof_hooked_functions));
242 | closelog();
243 | return SUCCESS;
244 | }
245 |
--------------------------------------------------------------------------------
/src/piof_config.h:
--------------------------------------------------------------------------------
1 | #ifndef PIOF_CONFIG_H
2 | #define PIOF_CONFIG_H
3 |
4 | #include "php.h"
5 |
6 | #define PIOF_NAME "piof"
7 | #define PIOF_VERSION "0.0.1"
8 |
9 | #define PIOF_DEBUG 1
10 | #define PIOF_INTERCEPT_OUTPUT "/tmp/php-module-piof.txt"
11 |
12 |
13 | #ifndef MYBOOLEAN_H
14 | #define MYBOOLEAN_H
15 | #define false 0
16 | #define true 1
17 | typedef int bool;
18 | #endif
19 |
20 |
21 | #if PIOF_DEBUG == 1
22 | #define PIOF_PRINTF(...) php_printf(__VA_ARGS__)
23 | #else
24 | #define PIOF_PRINTF(...) ((void) 0)
25 | #endif
26 |
27 | extern zend_module_entry piof_module_entry;
28 | #define phpext_piof_ptr &piof_module_entry
29 |
30 | typedef struct{
31 | int status;
32 | char *message;
33 | } pipeline_message;
34 | typedef pipeline_message PipelineMessage;
35 |
36 | typedef struct {
37 | const char *message;
38 | int result;
39 | int error;
40 | } ValidatorData;
41 |
42 | typedef void t_executor_internal(INTERNAL_FUNCTION_PARAMETERS);
43 |
44 | typedef PipelineMessage t_hook(INTERNAL_FUNCTION_PARAMETERS, t_executor_internal e);
45 |
46 | typedef zend_op_array* t_hook_compiler(zend_file_handle *file_handle, int type);
47 |
48 | typedef zend_op_array* t_hook_string_compiler(zval *source_string, char *filename TSRMLS_DC);
49 |
50 | PHP_MINIT_FUNCTION(piof);
51 | PHP_MSHUTDOWN_FUNCTION(piof);
52 | PHP_RINIT_FUNCTION(piof);
53 | PHP_RSHUTDOWN_FUNCTION(piof);
54 |
55 | ZEND_BEGIN_MODULE_GLOBALS(piof)
56 | HashTable *piof_hooked_functions;
57 | ZEND_END_MODULE_GLOBALS(piof)
58 |
59 | extern ZEND_DECLARE_MODULE_GLOBALS(piof)
60 |
61 | #ifdef ZTS
62 | #define PIOF_G(v) TSRMG(piof_globals_id, zend_piof_globals *, v)
63 | #else
64 | #define PIOF_G(v) (piof_globals.v)
65 | #endif
66 |
67 | #define piof_write_output(format, args...) \
68 | FILE *output = fopen(PIOF_INTERCEPT_OUTPUT, "a+"); \
69 | fprintf(output, format, ## args); \
70 | fclose(output);
71 |
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/src/piof_globals.c:
--------------------------------------------------------------------------------
1 | #include "piof_globals.h"
2 | #include "php.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 |
11 |
12 |
13 | int file_exists(const char *filename)
14 | {
15 | FILE *file;
16 | if (file = fopen(filename, "r"))
17 | {
18 | fclose(file);
19 | return 1;
20 | }
21 | return 0;
22 | }
23 |
24 | void piof_copy_args(zend_execute_data *execute_data, zval **args, int *ret_num_args)
25 | {
26 | int i, num_args = ZEND_CALL_NUM_ARGS(execute_data), has_scope = 0;
27 | zval *arguments = emalloc((num_args + 1) * sizeof(zval));
28 | *args = arguments;
29 |
30 | if (getThis() != NULL)
31 | {
32 | has_scope = 1;
33 | ZVAL_COPY(&arguments[0], getThis());
34 | }
35 |
36 | for (i = 0; i < num_args; i++)
37 | {
38 | ZVAL_COPY(&arguments[i + has_scope], ZEND_CALL_VAR_NUM(execute_data, i));
39 | }
40 | *ret_num_args = num_args + has_scope;
41 | }
42 |
43 | char *piof_get_ini_value(char *k)
44 | {
45 | char *v;
46 | zval *zv;
47 |
48 | v = zend_ini_string(k, strlen(k), 0);
49 |
50 | if (v)
51 | return v;
52 |
53 | zv = cfg_get_entry(k, strlen(k));
54 |
55 | if (zv)
56 | {
57 | return Z_STRVAL_P(zv);
58 | }
59 |
60 | return v;
61 | }
62 |
63 | zend_string *get_function_name(zend_string *function_name)
64 | {
65 | zend_string *result;
66 | if (!function_name)
67 | {
68 | return NULL;
69 | }
70 |
71 | return zend_string_copy(function_name);
72 | }
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/piof_globals.h:
--------------------------------------------------------------------------------
1 | #include "piof_config.h"
2 | #include "php.h"
3 | #include "Zend/zend_ini.h"
4 | #include "zend_exceptions.h"
5 |
6 | char *piof_get_ini_value(char *k);
7 | zend_string *get_function_name(zend_string *function_name);
8 | void piof_copy_args(zend_execute_data *execute_data, zval **args, int *ret_num_args);
9 |
--------------------------------------------------------------------------------
/src/scripts/buildall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | pushd () {
4 | command pushd "$@" > /dev/null
5 | }
6 |
7 | popd () {
8 | command popd "$@" > /dev/null
9 | }
10 |
11 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
12 | SRCPATH=$SCRIPTPATH/..
13 |
14 | make clean
15 | phpize clean
16 | pwd
17 | ./scripts/buildhooks.sh
18 |
19 | pushd $SRCPATH
20 |
21 | echo "[+] Building Extension....\n"
22 |
23 |
24 |
25 |
26 | phpize
27 | ./configure --enable-piof
28 |
29 | make
30 | make install
31 |
32 | popd
--------------------------------------------------------------------------------
/src/scripts/buildhooks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | pushd () {
4 | command pushd "$@" > /dev/null
5 | }
6 |
7 | popd () {
8 | command popd "$@" > /dev/null
9 | }
10 |
11 | CFLAGS="-g -Wall -I. -I/opt/piof -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/Zend -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib -I/usr/include/php/20170718 -I/usr/include/php/20170718/main -I/usr/include/php/20170718/TSRM -I/usr/include/php/20170718/Zend -I/usr/include/php/20170718/ext -I/usr/include/php/20170718/ext/date/lib"
12 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
13 | HOOKSPATH=$SCRIPTPATH/../hooks
14 |
15 | pushd $HOOKSPATH
16 |
17 |
18 | echo "cleaning up compiled artifacts..."
19 | rm -rf *.h *.so
20 | rm -rf build/
21 |
22 | for dir in */
23 | do
24 | mkdir -p build
25 | pushd $dir
26 | CFILE=${dir::-1}
27 | echo "compiling file $CFILE from $(pwd)..."
28 | gcc -shared -Wall -fPIC $CFLAGS -o ../build/$CFILE.so hook.c
29 | popd
30 | done
31 |
32 | popd
33 |
--------------------------------------------------------------------------------
/src/scripts/tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | service rsyslog restart
4 | sleep 2
5 | echo "[+] Testing Hooks....\n"
6 |
7 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
8 | SRCPATH=$SCRIPTPATH/..
9 |
10 | testCode(){
11 | echo "#############################"
12 | echo "Testing command: $1"
13 | #(cd $SRCPATH/modules && php -dextension=./piof.so -r "$1")
14 | (cd $SRCPATH/modules && php -r "$1")
15 | echo "#############################"
16 | }
17 |
18 | testCode 'echo md5( "ciao");'
19 | testCode 'echo md5( "asd" );'
20 | testCode 'include("notfound.php");'
21 | testCode 'system( "id");'
22 | #testCode 'eval("$var = 41;");'
23 | sleep 2
24 | echo "[i] Log Debug /var/log/piof.debug.log...."
25 | tail /var/log/piof.debug.log
26 | echo ""
27 | echo "[i] Log Info /var/log/piof.info.log...."
28 | tail /var/log/piof.info.log
--------------------------------------------------------------------------------