A high-level Python API for converting PHP files into a PHP Bytecode Pydantic model. It incorporates additional functions to assist in the analysis of PHP bytecode. The implementation involves a Python module written in C
to convert PHP source files to Zend bytecode (op_arrays) Python objects.
Please visit https://finixbit.github.io/posts/autonomous-Hacking-of-PHP-Web-Applications-at-the-Bytecode-Level/
Docker - Build, test, and deploy applications quickly.
git clone https://github.com/finixbit/php-bytecode-security-framework
cd php-bytecode-security-framework
docker run --rm -it --entrypoint /bin/bash -v ${PWD}/:/app debian:buster-20220801
cd /app
./setup_scripts/install_deps.sh
./setup_scripts/install_framework.sh
Before running any of the test cases below, you need to set the docker container by following the setup above
All tests were done with detection_script/simple_code_injection.py
which only models generic PHP global variables (SOURCES) like $_GET, $_POST, $_REQUEST
and traces data down to potentially vulnerable calls (SINKS) like echo, concat, include, require, cast, etc
.
Name | Vulns | Report | Github |
---|---|---|---|
Damn Vulnerable Web Application (DVWA) | 21 |
Report Link | Github Repo |
OWASP Vulnerable Web Application Project | 10 |
Report Link | Github Repo |
Simple SQL Injection Training App | 15 |
Report Link | Github Repo |
Vulnerable Web application made with PHP/SQL | 6 |
Report Link | Github Repo |
InsecureTrust_Bank - Educational repo demonstrating web app vulnerabilities | 5 |
Report Link | Github Repo |
A high-level Python API for src/php_to_bytecode_converter
, intended for the conversion of PHP files into a defined PHP Bytecode Pydantic model. This includes additional functions to facilitate the analysis of PHP bytecode.
import php_bytecode_api
functions: list[FunctionModel] = php_bytecode_api.convert_and_lift(path_to_php_file)
See Pydantic Models below for more details on the data structure FunctionModel
extracted from the PHP Bytecode.
A Python module is written in C
to convert PHP source files to Zend bytecode (op_arrays), CFG, DFG, and SSA Python objects.
import php_to_bytecode_converter
functions: list[dict] = php_to_bytecode_converter.convert(path_to_php_file)
Below is the data structure extracted from each function found in a PHP file:
- filename: str
- class_name: str
- function_name: str
- num_args: int
- required_num_args: int
- number_of_instructions: int
- extra = {
type: int
number_of_cv_variables: int
number_of_tmp_variables: int
last_live_range: int
last_try_catch: int
arg_flags: list [int, int, int]
last_literal: int
literals: [
{
type: str
value: str
}
]
}
- instructions = [
{
op1: {
type: str
value: str
variable_number: int
}
op2: {
type: str
value: str
variable_number: int
}
result: {
type: str
value: str
variable_number: int
}
num: int
extended_value: int
lineno: int
opcode: int
opcode_name: str
opcode_flags: int
op1_type: int
op2_type: int
result_type: int
}
]
- cfg = {
blocks_count: int
edges_count: int
blocks: [
{
start: int
len: int
successors_count: int
predecessors_count: int
predecessor_offset: int
idom: int
loop_header: int
level: int
children: int
next_child: int
successors_storage: [int, int]
successors: [int, int]
}
]
predecessors: [int, int]
}
- dfg = [
{
block_index: int
var_def: [
{
var_num: int
var_name: str
}
]
var_use: [
{
var_num: int
var_name: str
}
]
var_in: [
{
var_num: int
var_name: str
}
]
var_out: [
{
var_num: int
var_name: str
}
]
var_tmp: [
{
var_num: int
var_name: str
}
]
}
]
- ssa = {
number_of_sccs: int
number_of_ssa_variables: int
ssa_variables: [
{
ssa_var_num: int
var_num: int
var_name: str
definition: int
definition_phi: {
pi: int
variable_index: int
variable: {
var_num: int
var_name: str
}
ssa_variable_index: int
current_block_index: int
visited: int
has_range_constraint: int
constraint: {
range_range_min: int
range_range_max: int
range_range_underflow: int
range_range_overflow: int
range_min_var: int
range_max_var: int
range_min_ssa_var: int
range_max_ssa_var: int
}
sources: [...int]
}
no_val: int
use_chain: int
escape_state: int
strongly_connected_component: int
strongly_connected_component_entry: int
}
]
ssa_instructions: [
{
op1_use: int
op2_use: int
result_use: int
op1_def: int
op2_def: int
result_def: int
op1_use_chain: int
op2_use_chain: int
res_use_chain: int
}
]
ssa_blocks: [
{
block_index; int
phis; [
{
pi: int
variable_index: int
variable: {
var_num: int
var_name: str
}
ssa_variable_index: int
current_block_index: int
visited: int
has_range_constraint: int
constraint: {
range_range_min: int
range_range_max: int
range_range_underflow: int
range_range_overflow: int
range_min_var: int
range_max_var: int
range_min_ssa_var: int
range_max_ssa_var: int
}
sources: [...int]
}
]
}
]
}
Directory to hold all scripts
detectors/template_script.py
- template script to get started.detectors/code_injection.py
- Models generic PHP global variable (SOURCES) like$_GET, $_POST, $_REQUEST
and traces data down to potentially vulnerable calls (SINKS) likeecho, concat, include, etc
.
Directory to store target source files. Follow the Example Test Cases above to set up a target.