• 二、PHP函数


    一、PHP函数

    1.基本函数

    1. 创建数组:array(1,2,3)
    2. 数字或数字字符串检测:is_numeric检测变量是否为数字或数字字符串
    $input = array('2',2,3);
    echo is_numeric($input[0]);// 可以通过类似2025abc的绕过,这让其既不是数字也不是数字字符串,但是比较大小时2025abc>2024
    
    // 注意16进制的内容 如何0x12,is_numeric返回false,即不认为其是数字或数字字符
    // 结果:1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 生成随机数echo rand(1,5);表示生成1-5范围内一个随机的数字

    2. 脚本睡眠:sleep(2)表示当前脚本睡眠2秒

    3. 检查变量是否已设置并且不为NULL:echo isset($input);

    4. 输出一条结束消息同时退出脚本:die('end...000');

    5. md5加解密:

      // 情况一:md5相等,但两值不相等的情况
      //解释:在CTF常常遇到这样的题目if($v1 != $v2 && md5($v1) == md5($v2)),v1和v2不能相等,但是他们的md5值还要相等,此时利用到==判断会自动类型转换的问题
      比如v1=240610708 v2=QNKCDZO
      他们的md5 v1=0e462097431906509019562988736854 v2=0e830400451993494058024219903391
      因为:0exxx意思为0的xxx次方,它们结果都为0(科学计数法)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      // 情况二:md5函数无法正确解析数组(===强比较会成立)
      //解释:在CTF常常遇到这样的题目if($v1 != $v2 && md5($v1) == md5($v2)),v1和v2不能相等,但是他们的md5值还要相等
      	此时如果$v1=['1'] $v2=['2']
      	此时md5($v1) === md5($v2)是成立的(strcmp也有这种情况)
      	//示例(没有@时不会报错,否则复现的时候就报错了但也会输出结果):
      	if(@md5(['1','2'])===@md5([])){    echo '相等';}
      // 注意php get参数传递数组格式:http://114.67.175.224:11551/uname[]=1
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    6. 函数特点:当传输参数不符那个函数的返回值就会为NULL

    7. 调用函数call_user_func_array($functionName, $parameters)可以根据自己需要调用函数

      // call_user_func('system','ls');其能够调用系统命令
      function myFunction($param1, $param2) {
          // 执行一些操作
      }
      
      $functionName = 'myFunction';
      $parameters = array('parameter1', 'parameter2');
      
      call_user_func_array($functionName, $parameters);
      // 在上面这个例子里面call_user_func_array调用了myFunction这个函数并向其传递了参数
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    8. 对字符串进行ROT13编码:str_rot13($s)

      // (原理在字母表中选择当前字母13位后的字母,类如对a进行编码,输出为n)
      echo str_rot13('a'); //结果n
      echo str_rot13('n'); //结果a
      //由上可知解码只需要再执行一遍即可
      
      • 1
      • 2
      • 3
      • 4
    9. 获取字符串ascii码:ord

      echo ord('a'); //结果97
      
      • 1
    10. 将数字转换为ascii对应字符串:

      echo chr(97);//结果a
      
      • 1

    2.正则函数

    1. 正则匹配函数:preg_match(pattern,content,result)pattern表示匹配规则,content表示需要进行正则匹配的内容,result是匹配结果(数组)preg_match只找第一个匹配项目,preg_match_all()函数用于找到所有匹配项并返回结果

      // 注意点:"/world/i"这个i表示大写WORLD或小写world都会匹配,如果没有i就是精确匹配(比如黑名单里面有select(即服务端会去匹配用户输入是否包含select)我就可以通过SELECT绕过)
      if (preg_match("/world/i", "Hello World!", $matches)) {
          echo "找到匹配项!";
          print_r($matches);
      } else {
          echo "未找到匹配项!";
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    2. 过滤和替换:$out=preg_filter(pattern,content,str)pattern表示匹配规则,content表示将匹配到的内容的位置替换为何内容,str表示对哪个字符串变量进行正则替换操作,过滤后的内容会赋值给$out

      //下面的例子演示了preg_filter的语法,也展现了,写两遍()避免被过滤达到执行代码的效果
      $str='echo getcwd(());';
      $pattern = '/\(\)/';
      $replacement = '';
      echo $str;//echo getcwd(());
      echo '*';
      $out = preg_filter($pattern, $replacement,$str);
      echo $out;//echo getcwd();
      echo '**';
      echo eval($out);//C:\phpstorm\test
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    3.字符串

    1. 截取:mb_substr(字符串,开始位置,长度)

      $str = "Hello, World!";
      $substr = mb_substr($str, 0, 5);
      echo $substr; // 输出:Hello
      
      • 1
      • 2
      • 3
    2. 字符串位置:mb_strpos(字符串,需要寻找的字符,开始的位置)

      $str = "Hello, Hello, World!";
      $position = mb_strpos($str, "Hwello", 7);
      echo $position; // 输出:13 找不到返回false
      
      • 1
      • 2
      • 3
      1. strpos():查找字符串在另一字符串中第一次出现的位置(区分大小写,汉字占两个位置)
        //安全问题
        //解释:下面的内容heo在hello第一次出现的位置是0,就会导致0==false
        <?php
        $str1 = "hello";
        $str2 = "heo";
        if(strpos($str1,$str2)==false)
        {
        	echo "flag";
        }
        ?>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
    3. 替换:str_replace(需要替换的内容,替换为的内容,字符串)(区分大小写)

      //安全问题:可以通过双写或者大小写进行绕过如下例子
      $str = "Hello, worworldld!";
      //$str = "hello, WORLD"; 因为区分大小写,这个WORLD并不会被替换
      $newStr = str_replace("world", "", $str);
      echo $newStr; // 输出:Hello, world!
      
      • 1
      • 2
      • 3
      • 4
      • 5
    4. 查找:strstr(字符串,字串)(区分大小写;stristr不区分大小写)

      $str = "Hello, World!";
      $str1 = "";
      $substring = "World";
      $result = strstr($str, $substring);
      echo $result;  // 输出:World!
      // 找不到返回false
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    5. 比较:strcmp(字符串1,字符串2);(它逐字节比较两个字符串,并返回一个整数。如果两个字符串相等,strcmp 函数返回0;如果第一个字符串小于第二个字符串,strcmp 返回负数;如果第一个字符串大于第二个字符串,返回正数)

      $str1 = "Hello World";
      $str2 = "hello world";
      $result = strcmp($str1, $str2);
      if ($result == 0) {
          echo "The strings are equal.";
      } else if ($result < 0) {
          echo "str1 is less than str2.";
      } else {
          echo "str1 is greater than str2.";
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      // 安全问题:当对比字符串与数组或者数组与数组时,strcmp都会返回0(@符号避免其报错(报错不会影响其运行))
      if(!@strcmp(['1','2'],1)){
          echo '相等';
      }
      
      • 1
      • 2
      • 3
      • 4

    4.数组

    1. 返回内容下标:array_search('name',$a);返回内容下标(参数一查找内容,参数二查找函数,可设参数三设true这样对比为’==='而不是 ‘==’)

      // php绕过
      // 解释array_search在$bug数组里面寻找对比"bug",但是使用的是==号,此时$bug=array(0)即,"bug"==0的,想要避免可以在array_search加第三个参数为true即可
      $bug=array(0);
      $a=array_search("bug", $bug);
      $a=== false?die("die"):NULL;
      foreach($bug as $key=>$val){
          $val==="bug"?die("die....."):NULL;
      }
      echo 'youflag';
      //输出:youflag
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    2. 是否在数组中:is_array('name',$a);不在数组返回false参数一查找内容,参数二为数组

      //php绕过,解释如上
      $bug=array(0);
      $a=in_array("bug", $bug);
      $a=== false?die("die"):NULL;
      foreach($bug as $key=>$val){
          $val==="bug"?die("die....."):NULL;
      }
      echo 'youflag';
      //输出:youflag
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    5.过滤函数

    1. html过滤
      解释:htmlspecialchars($url)本质上是为了安全,其能将以下字符进行转码(单引号不会被转码),避免xss的发生,但是htmlspecialchars不是绝对安全,还要取决与上下代码环境,如下面例子

      1. & (和号)成为 &
      2. " (双引号)成为 "
      3. < (小于)成为 <
      4. > (大于)成为 >
      // 下面点击Link将弹出XSS
      $url = 'javascript:alert("XSS")';
      echo '. htmlspecialchars($url) . '">Link';
      
      • 1
      • 2
      • 3
    2. HTML、XML 以及 PHP 的标签过滤
      解释:strip_tags(字符串,要保留的内容)剥去字符串中的 HTML、XML 以及 PHP 的标签,第二个参数是过滤时,不删除某标签,如下例所示

      $str = "

      This is a link to a website.

      "
      ; $clean_str = strip_tags($str,'

      '); echo $clean_str;//结果:

      This is a link to a website.

      • 1
      • 2
      • 3
    3. 在预定义的字符前添加反斜杠
      解释:其会在\ " '前面加入反斜杠,避免通过引号闭合,造成问题

      $str = "It's a beautiful day!";
      $escapedStr = addslashes($str);
      echo $escapedStr;//It\'s a beautiful day!
      //在上述示例中,原始字符串是 "It's a beautiful day!"。调用 addslashes 函数后,单引号被转义为 \',从而避免将其解释为字符串的结束标记
      // 但是在注入过程中遇到addslashes还是有解决办法,例如下面这种情节,通过不输入引号,直接在内部再次调用eval函数
      $val="${eval($_GET[1])}&1=phpinfo();";
      eval('$value="' . addslashes($val) . '";');
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    6.文件有关函数

    1. include:使用 include,你可以将包含其他 PHP 文件的代码插入到主文件中,从而在执行期间将这些文件和主文件合并为一个整体(多次引用会多次执行)
      a文件

      
          $flag=123;
      ?>
      
      • 1
      • 2
      • 3

      b文件

      
      include 'a.php';
      echo $flag;//123
      ?>
      
      • 1
      • 2
      • 3
      • 4
    2. require:require 函数与 include 关键字类似,也用于将外部文件包含到当前文件中。但与 include 不同的是,当被包含的文件不存在或路径不正确时,require 会生成一个致命错误,并终止脚本的执行(多次引用也只会引用一次)

    3. highlight_file:让代码高亮显示,highlight_file(要显示的文件,返回值)

      
          $filename = "myfile.php";
          $highlightedCode = highlight_file($filename, true);
          echo $highlightedCode;
      ?>
      
      • 1
      • 2
      • 3
      • 4
      • 5
    4. file_get_contents:把整个文件读入一个字符串

      $filename = "a.txt";
      $content = file_get_contents($filename);
      echo $content;// a.txt的内容
      
      • 1
      • 2
      • 3
    5. file:把整个文件读入一个数组,数组中的每个单元都是文件中相应的一行

      $filename = "a.txt";
      $content = file($filename);
      echo $content;
      print_r($content);
      
      • 1
      • 2
      • 3
      • 4

    7.其它函数

    1. extract :将数组转换为变量
    $var_array = array("color" => "blue",
        "size"  => "medium",
        "shape" => "sphere");
    extract($var_array);
    
    echo $color . $size . $shape;
    // bluemediumsphere
    
    extract($_GET)
    http://127.0.0.1/?user_name=123
    // 执行后
    echo user_name; // 123
    // 简单绕过
    // 比如过滤_
    // 我们可以http://127.0.0.1/?user name=123或http://127.0.0.1/?user[name=123
    // 因为变量名正常不能如user name或user[name一般,有错误时,执行extract函数都会自动转换为user_name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二.PHP危险函数

    1. eval:执行php语法内容(通过php也能执行系统命令)

      eval('echo 1;')
      // 输出 1
      
      • 1
      • 2
      eval和assert都有一个要注意的点如下
      eval('$value="'  . '";');
      1.可以用字符串拼接
      2.$val="${eval($_GET[1])}&1=phpinfo();";使用${}(eval里面遇到addslashes过滤函数的情况)
      
      • 1
      • 2
      • 3
      • 4
    2. exec:直接执行系统命令,执行结果会返回给php

      exec('ipconfig', $result);
      var_dump($result);
      // 输出 0 => string '' (length=0)
        1 => string 'Windows IP ����' (length=15)
        2 => string '' (length=0)
        3 => string '' (length=0)
        4 => string '���߾����������� ��������* 28:' (length=30)
        5 => string '' (length=0)
        6 => string '   ý��״̬  . . . . . . . . . . . . : ý���ѶϿ�����' (length=53)
        7 => string '   �����ض��� DNS ��׺ . . . . . . . :' (length=38)
        8 => string '' (length=0)
        9 => string '���߾����������� ��������* 31:' (length=30)
        10 => string '' (length=0)
        11 => string '   ý��״̬  . . . . . . . . . . . . : ý���ѶϿ�����' (length=53)
        12 => string '   �����ض��� DNS ��׺ . . . . . . . :' (length=38)
        13 => string '' (length=0)
        14 => string '��̫�������� ��̫��:' (length=20)
        15 => string '' (length=0)
        16 => string '   ý��״̬  . . . . . . . . . . . . : ý���ѶϿ�����' (length=53)
        17 => string '   �����ض��� DNS ��׺ . . . . . . . :' (length=38)
        18 => string '' (length=0)
        19 => string '���߾����������� WLAN:' (length=22)
        20 => string '' (length=0)
        21 => string '   �����ض��� DNS ��׺ . . . . . . . :' (length=38)
        22 => string '   IPv6 ��ַ . . . . . . . . . . . . : 2408:841e:410:3a93:511e:9cf3:9989:3565' (length=77)
        23 => string '   ��ʱ IPv6 ��ַ. . . . . . . . . . : 2408:841e:410:3a93:1c15:66d3:f014:32ae' (length=77)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
    3. system:也能直接执行系统命令,执行内容会直接打印输出出来

      $command = 'ipconfig';
      system($command);
      Wireless LAN adapter ��������* 28:
      
         Media State . . . . . . . . . . . : Media disconnected
         Connection-specific DNS Suffix  . : 
      
      Wireless LAN adapter ��������* 31:
      
         Media State . . . . . . . . . . . : Media disconnected
         Connection-specific DNS Suffix  . : 
      
      Ethernet adapter ��̫��:
      
         Media State . . . . . . . . . . . : Media disconnected
         Connection-specific DNS Suffix  . : 
      
      Wireless LAN adapter WLAN:
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    4. assert:断言一个表达式的真实性

      // 危险在于字符串可构造类似eval,例如下面$name是用户输入的
      $name = 'flag.php';
      // 意思是检查$name有没有php字符串如果有就die执行停止,否则包含某文件
      assert("strpos('$name', 'php') === false") or die("die!!!");
      require_once $name;
      // 恶意构造
      $name = 'flag.php\',\'123\')===false and system(\'ipconfig\') and strpos(\'2';
      // 相当于执行了
      assert("strpos('flag.php','123')===false and system('ipconfig') and strpos('2', 'php') === false") or die("die!!!");
      // 其中system('ipconfig')可以执行任意语句
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      	eval和assert都有一个要注意的点如下
      	eval('$value="'  . '";');
      	1.可以用字符串拼接
      	2.$val="${eval($_GET[1])}&1=phpinfo();";使用${}(eval里面遇到addslashes过滤函数的情况)
      
      • 1
      • 2
      • 3
      • 4
    5. preg_replace:用于通过正则表达式进行字符串替换

      用法示例:
      $string = "Hello World";
      $pattern = "/World/";
      $replacement = "Universe";
      $result = preg_replace($pattern, $replacement, $string);
      echo $result;  // 输出:Hello Universe
      恶意用法(该漏洞存在于php5.5.4以下版本)1./e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码,并且在preg_replace的正则被触发时会去执行replacement 里面的php代码
      例如:preg_replace('/cat/e','system("ipconfig")',$data); // 当$data含有cat时,system("ipconfig")将会被执行
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
  • 相关阅读:
    2023CSPS 种树 —— 二分+前缀和
    Windows网络系统架构
    wins10安装ffmpeg
    【mysql】—— 函数的基本介绍
    nginx日志切割/截断
    Spring事务和事务传播机制
    Java并发技术基础
    【Maven】高级应用
    MQ进阶面试题
    用 JHipster Azure Spring Apps 构建和部署 Spring 应用
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/134059064