CTF Web SQL注入 10000字详解

这里写目录标题

  • 涉及的数据库知识
    • union
    • order by
    • database()
    • information_schema
    • limit
    • `--空格`注释
    • replace
    • into outfile
    • like
    • GROUP BY
    • HAVING
    • GROUP BY、HAVING、WHERE之间的关系
    • regexp
  • 原理
  • 信息收集
    • 操作系统
    • 数据库
    • 判断注入点
    • 注入点类型
      • POST注入
      • 数字型注入
      • 字符型注入
      • 搜索型注入
      • Insert/update/delete注入
      • HEADER注入
      • Order By注入
  • 闭合方式
    • 闭合
      • 转义符号报错得到闭合方式
      • 使用表达式来判断是否带括号及引号类型(适用无报错)
      • 时间盲注遍历闭合方式
    • 注释
  • 注入手段
    • 联合查询
      • 判断字段数
      • 判断数据显示位
    • 报错注入
      • XPATH报错注入
        • extractvalue(arg1,arg2)
        • updatexml(arg1,arg2,arg3)
    • 布尔盲注
      • 注入流程
      • 常用函数
      • payload示例
    • 时间盲注
      • 使用场景
      • 判断注入点
    • 宽字节注入
      • 原理
      • 漏洞发现
      • 示例
    • 二次注入
      • 原理
      • 示例
    • 堆叠注入
      • 原理
      • 示例
  • 特殊场景
    • md5()函数
    • 弱类型比较

涉及的数据库知识

union

联合查询:将两条SQL语句的结果一起输出

语法:select语句1 union select语句2

使用条件:前后两个语句的查询结果的字段数相同

order by

结果排序:该函数原本用于将查询结果排序

语法:select * from table_name order by column_name

通过order by遍历字段序号可以得到原有查询语句输出结果有几个字段

database()

输出当前数据库的库名

information_schema

information_schema为系统自带的数据库

里面有一个tables表,该表存放着数据库和数据表的关联,其中table_schema为存储数据库名的字段,table_name为存储表名的字段

select table_name from information_schema.tables where table_schema=database()会输出当前数据库中的所有表名

还有一个columns表,该表存放着数据表和字段的关联,使用该表查询某表中有哪些字段时,需要同时指定是哪个数据的哪个表

select column_name from information_schema.columns where table_name='admin'and table_schema=database()会输出指定数据表中的所有字段名

limit

用于分页

语法:select * from table_name limit n,m;

n表示从第n行开始,m表示取m条数据

--空格注释

遇到引号如 select * from user where id='$id'

可以先将前面的引号闭合,再将后面的引号用 -- qwe注释掉

例如如下的payload

2' union select 1,table_name,3 from information_schema.tables where table_schema=database() -- qwe

此处的qwe只是为了演示出–后面的空格,并无实际意义

replace

用于替换字符串

语法:REPLACE (String,from_str,to_str)

String中所有出现的from_str替换为to_str

into outfile

SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中,常用于创建表的备份复件或者用于对记录进行存档。

在 SELECT 查询语句中使用 INTO OUTFILE 参数可以将查询结果保存到文本文件中。

语法:SELECT ... INTO OUTFILE 'file_name'

如果题目条件允许,可以执行show variables like '%secure_file_priv%'来查看允许导出结果的目录,MySQL服务只允许在这个目录中执行文件的导入和导出操作。

like

LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式

现在,我们希望从上面的 “Persons” 表中选取居住在以 “N” 开始的城市里的人:

我们可以使用下面的 SELECT 语句:

SELECT * FROM Persons
WHERE City LIKE 'N%'

提示:% 可用于定义通配符(模式中缺少的字母)

常见通配符:% 表示可有零个或多个任意字符; _ 表示需要一个任意字符;

GROUP BY

GROUP BY 语句用于结合聚合函数(如 COUNT()、MAX() 等),根据一个或多个列对结果集进行分组。

GROUP BY 可以配合聚合函数一起使用,通过使用聚合函数,在分组之后可以对组内结果进行计数(COUNT)、求和(SUM),求平均数(AVG)操作等。

GROUP BY会先按照指定字段的值是否相同来将数据分组

更加详细的介绍可以看下面这篇:

GROUP BY与COUNT用法详解_group by count_鲲鹏之上的博客-CSDN博客

HAVING

HAVING 子句可以筛选通过 GROUP BY 分组且聚合后的各组数据。

聚合函数(avg、sum、max、min、count),不能作为条件放在where之后,但可以放在having之后

GROUP BY、HAVING、WHERE之间的关系

在语句的位置上,where在group by前, having在group by 之后

在执行顺序上,以下面这个SQL语句为例

select city ,count(*) as num from staff  where age> 19 group by city having num >= 3;
  1. 执行where子句查找符合年龄大于19的员工数据
  2. group by子句对员工数据,根据城市分组。
  3. 对group by子句形成的城市组,运行聚集函数计算每一组的员工数量值;
  4. 最后用having子句选出员工数量大于等于3的城市组。

所以执行顺序为:WHEREGROUP BY聚合函数HAVING

regexp

REGEXP的基本语法如下:

column_name REGEXP pattern

这里,column_name 是要搜索的列,pattern 是正则表达式模式。

regexp表达式可以放在where后面作为查询的限制条件,也可以搭配if或者case,作为条件语句

原理

SQL注入就是在数据交互中,前端数据传到后台时没有做严格的判断,导致传进来的数据被拼接到sql语句中,被当作sql语句的一部分进行执行,从而导致数据泄露,丢失甚至服务器瘫痪。如果代码中没有过滤或者过滤不严谨是会出现漏洞的。

SQL注入攻击的本质,是把用户输入的数据当做代码执行

SQL注入的条件是可控变量和可带入数据库查询

信息收集

操作系统

数据库

判断注入点

  1. and 1=1 页面不变
    and 1=2 页面出现区别
    则该地址可能存在注入漏洞

    这种方法太过常见,可能会被一些站点的防火墙拦截。

    此时可以稍微做一些变形,比如%26%26 -1 like -1

  2. id = 杂乱字符串

    若页面出现区别,则该地址可能存在注入漏洞

  3. 通过运算符检测漏洞

    id = 2-1,id运算结果与原来一致

    如果页面也一致,则该地址可能存在注入漏洞

如果测试注入点时页面返回404,则大概率没有注入点

注入点类型

POST注入

POST和GET注入的区别就是注入点位置发生了变化,在浏览器中已经无法直接进行查看与修改。

POST注入高危点:网页中的登录框、查询框等各种和数据库有交互的框

手动POST注入一般使用burpsuite工具进行抓包

使用sqlmap自动进行POST注入有两种方法

可以使用--forms对页面的表单进行测试

也可以先用burpsuite抓包,并将数据包保存,然后使用-r 数据包目录对数据包中的POST注入点进行分析

数字型注入

数字型注入是指在一个期望数字的输入位置注入SQL代码。因为数字型数据通常不需要引号包围,所以注入相对简单。例如,一个基于数字的 SQL 注入可能在一个像这样的查询中实现:

SELECT * FROM users WHERE id = [input]

如果正常输入为 1,那么查询变为 SELECT * FROM users WHERE id = 1。如果输入为 1 OR 1=1,则查询变为 SELECT * FROM users WHERE id = 1 OR 1=1,这将返回所有用户的数据,因为 1=1 总是真。

字符型注入

字符型注入发生在处理字符串数据的查询中。攻击者必须闭合开放的字符串(使用引号),然后注入额外的 SQL 代码。例如:

SELECT * FROM users WHERE username = '[input]'

正常输入可能是 alice,查询为 SELECT * FROM users WHERE username = 'alice'。如果输入是 '; DROP TABLE users; --,那么查询就变成了 SELECT * FROM users WHERE username = ''; DROP TABLE users; --',这会尝试删除整个 users 表。

搜索型注入

搜索型注入通常出现在搜索功能中,特别是当查询设计成模糊匹配用户输入时。例如:

SELECT * FROM products WHERE name LIKE '%[input]%'

这种情况我们仍然可以只闭合前面的引号

Insert/update/delete注入

当页面中存在修改账号信息、注册账号、删除账号等操作时,事实上就是存在插入、修改数据库数据的操作

insert型注入相关的sql语句形式 INSERT INTO table_name VALUES (值1, 值2,....)或者INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

update型注入相关的sql语句形式: UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值

delete型注入相关的sql语句形式:DELETE FROM 表名称 WHERE 列名称 = 值

这些类型的注入点由于没有select语句,所以适合使用

HEADER注入

HEADER注入通过修改请求报文中的请求头部(head)来进行注入。

PHP中通常使用**$_SERVER**数组来收集请求头信息

手动HEAD注入可以使用burpsuite工具进行抓包

Order By注入

当我们的注入点在SQL语句的Order By关键字之后时,常规的联合注入无法实现,因为通常回显的内容是前半段语句

那么我们可以考虑使用报错注入和盲注

针对Order By关键字,可以使用rand()函数来构造布尔盲注的条件

由于rand(0)rand(1)返回的内容不同,我们可以将判断语句放在rand中,这样布尔值不同,回显的结果也不同

当然也可以使用时间盲注,不过由于查询的条数比较多,所以延时时间最好设短一些

闭合方式

闭合

在注入漏洞中,构造payload语句的精髓之一在于闭合

不同的场景下我们需要通过猜测源码中的SQL语句、试验不同的方法来构造闭合

转义符号报错得到闭合方式

如果程序开启了sql语句的报错信息,可以尝试利用转义符号报错得到闭合方式

当原语句的闭合字符遇到转义字符时,会被转义,那么没有闭合符的语句就不完整了,导致报错,通过报错信息我们就可以推断出闭合符。

payload示例如下

?id=1\

使用表达式来判断是否带括号及引号类型(适用无报错)

测试?id=2'%26%26 '1'='1?id=2"%26%26 “1"="1这两个payload

  • 如果都回显id=2的用户,则说明不带括号。此时单双引号需要使用?id=1'?id=1"来进一步判断

  • 哪一个payload如果回显id=1的用户,说明原SQL语句带括号,且使用的是该payload中的引号类型

  • 如果都没有回显,说明可能是数字型注入

这种判断方法比较适合在程序关闭了报错信息的情况下使用

时间盲注遍历闭合方式

由于时间盲注的场景中,页面没有任何回显,我们只能通过延时时间来判断正确的闭合方式

?id=1' and sleep(5) --+
?id=1" and sleep(5) --+
?id=1') and sleep(5) --+
?id=1')) and sleep(5) --+
?id=1") and sleep(5) --+

注释

常规情况下一般是通过在payload的最后加上注释符,将后半段语句整个注释掉

SQL语句中的注释符还是挺多的

  1. --空格

    该注释符在GET注入时也常被写作--+,因为+放在url中会被认为是空格符

  2. #

    #在URL 中会被认为是锚点,所以 如果想要在GET注入中使用该注释符,需要对其需要进行url编码。#的url 编码为%23

  3. ;%00

    分号可以结束当前sql语句,而%00会让程序认为这是字符串的末尾

注入手段

联合查询

联合查询主要是运用SQL的union语法

将需要执行的语句与原语句使用union拼接在一起

判断字段数

order by 1开始一直到order by n,观察是否有查询结果,用来判断当前数据表有多少字段

判断字段数可以使用二分法,先判断1和一个大数n,若n无显示则判断n/2

判断数据显示位

若 注入语句-1 union select 1,2,3,而页面只输出2

说明第二个字段为当前页面的输出点(显示位),数据库只输出该字段上的内容

这里使用-1使之前的语句查询无结果,即空查询,则显示的时候就会显示union之后的第二条语句。

报错注入

报错注入 (Error-based injuction),就是利用数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中

当代码中使用die(mysql_error())来返回错误信息时,我们可以使用报错注入

XPATH报错注入

通过输入非法路径来导致XPATH syntax error

extractvalue(arg1,arg2)

接受两个参数,arg1:XML文档,arg2:XPATH语句
条件:mysql5.1及以上版本
标准payload:and extractvalue(1,concat(0x7e,(select user()),0x7e))
返回结果:XPATH syntax error.’~root@localhost~’

updatexml(arg1,arg2,arg3)

arg1为xml文档对象的名称,arg2为xpath格式的字符串;arg3为string格式替换查找到的符合条件的数据
条件:mysql5.1.5及以上版本
标准payload:and updatexml(1,concat(0x7e,(select user()),0x7e),1)
返回结果:XPATH syntax error:’~root@localhost~’

布尔盲注

**布尔盲注(Boolean-based Blind SQL Injection)**属于SQL注入的一种形式。其主要原理是通过向数据库发送特制的SQL查询语句,根据应用程序的不同响应(通常是真或假)来推断数据库中的信息。布尔盲注不直接显示数据库中的数据,而是通过观察应用程序对注入恶意SQL语句的响应来推测数据。

注入流程

布尔盲注强调一个字,所以每次我们只能从返回的布尔值获取有关数据库的某一项信息

例如通过length()函数来判断字符串的长度,通过substr()substring()逐个试出字符串中的每个字符

当然,我们想要获取数据库中的某个数据,肯定是要从库、表、字段逐步来获取信息

下面是常见的注入流程:

  • 求当前数据库长度
  • 求当前数据库表的ASCII
  • 求当前数据库中表的个数
  • 求当前数据库中其中一个表名的长度
  • 求当前数据库中其中一个表名的ASCII
  • 求列名的数量
  • 求列名的长度
  • 求列名的ASCII
  • 求字段的数量
  • 求字段内容的长度
  • 求字段内容对应的ASCII

常用函数

  • ascii() 函数,返回字符ascii码值
    参数 : str单字符
  • length() 函数,返回字符串的长度
    参数 : str 字符串
  • left() 函数,返回从左至右截取固定长度的字符串
    参数str,length
    str : 字符串
    length:截取长度
  • substr()/substring() 函数 , 返回从pos位置开始到length长度的子字符串
    参数,str,pos,length
    str: 字符串
    pos:开始位置

payload示例

以数据库这一层为例,我们需要得到数据库名称的长度,然后求数据库名称中有哪些字符

首先获取长度,我们可以使用二分法,先选一个较大的数,将其与leng'r'h的值进行比较

?id = 1 and (length(database())<8) --+
?id = 1 and (length(database())>8) --+

如果长度小于8,则再与4进行比较

获取数据库名时,以left()函数为例

-- 从左至右截取一个字符
?id = 1 and (left(database(),1)='s') --+
-- 从左只有截取两个字符
?id = 1 and (left(database(),2)='se') --+

时间盲注

时间盲注是指基于时间的盲注,也叫延时注入,根据页面的响应时间来判断是否存在注入。

使用场景

时间盲注使用的优先级并不高,通常是在联合注入、报错注入、布尔盲注都无法使用时才会考虑使用:

  1. 页面没有回显位置(联合注入无法使用)
  2. 页面不显示数据库的报错信息(报错注入无法使用)
  3. 无论成功还是失败,页面只响应一种结果(布尔盲注无法使用)

判断注入点

依次尝试以下类型的测试payload,延时5秒以上则说明判断成立,即存在注入

?id=1 and if(1,sleep(5),3) -- a
?id=1' and if(1,sleep(5),3) -- a

if(1,sleep(5),3) 是一个条件表达式,其中 1 总是真(因为1在逻辑上代表真),因此执行 sleep(5),这使得数据库暂停5秒。

IF语句基本语法如下

IF(condition, true_value, false_value)
  • condition: 这是需要评估的条件表达式。
  • true_value: 如果条件为真时返回的值。
  • false_value: 如果条件为假时返回的值。

宽字节注入

原理

计算机底层由二进制存储数据,不同的编码映射着不同的二进制数据,我们以8位二进制为单字节,也称标准字节。宽字节指比标准字节有更多的字节
常见的单字节编码:ASCII
常见的宽字节编码:GB2312,GBK,GB18030,BIG5等

以GBK为例,它以2个字节进行编码

服务端对用户输入的敏感数据(主要是单双引号等特殊字符)进行了转义,如利用mysql_real_escape_string()或addslashes()等函数

它会将用户输入的/?id=1'转换为/?id=1\'·,这样的目的是为了防止sql注入构造闭合.

此时我们可以使用宽字节注入来摧毁转义,当然前提是PHP发送请求到MySql时使用了语句SET NAMES 'gbk' 或是set character_set_client =gbk 进行了一次编码

当转义使用的\为ASCII编码,而客户端传入的参数被当成GBK等宽字节编码,则可以通过在\之前插入一个十六进制字节(ASCII码要大于128,才到汉字的范围)来让mysql以为插入的字节和\是一个中文字符,从而吃掉\,摧毁转义。

漏洞发现

  1. preg_quote函数

    preg_quote() 将字符串中所有正则表达式的特殊字符前添加反斜杠(\)。这些特殊字符包括:. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

    语法:

    string preg_quote ( string $str  )
    

    参数:

    • $str:要进行转义的字符串。

    例如

    function check_addslashes($string)
    {$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash$string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash$string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslashreturn $string;
    }

    这段代码分别转义了反斜杠\、单引号'和双引号"

  2. addslashes 函数

    addslashes()是PHP中的一个内置函数,用于在某些特殊字符前添加反斜杠

    特殊字符包括单引号 ',双引号 ",反斜杠 \ 和 NULL 字符

  3. mysql_real_escape_string函数

    mysql_real_escape_string的作用和用法和addslashes基本一致

示例

比如使用%df'会被PHP当中的addslashes函数转义为“%df\'
\ 即url里面的%5c , '对应的url编码是%27,那么也就是说,%df\' 会被转义%df%5c%27
倘若网站的字符集是GBK,mysql使用的编码也是GBK的话,就会认为%df%5c%27是一个宽字节。
%df%5c会结合(因为宽字节是占两个字节),也就是。后面就有一个,这样就能成功构造注入语句。

二次注入

原理

在第一次进行数据库插入数据的时候,后端仅仅只是使用了 addslashes 或者是借助get_magic_quotes_gpc 对其中的特殊字符进行了转义,但在存入数据库时还是原来的数据,数据中一般带有单引号和#号,然后下次使用在拼凑SQL中,所以就形成了二次注入。

示例

  1. 插入1‘#
  2. 转义成1\’#
  3. 不能注入,但是保存在数据库时变成了原来的1’#
  4. 利用1’#进行注入,这里利用时要求取出数据时不转义

堆叠注入

原理

在堆叠注入中,攻击者通常会使用分号(;)将多条SQL命令分隔开来。这种方法的成功执行依赖于后端数据库管理系统的支持,因为并非所有的数据库系统都支持一次执行多个查询。

同时也并非什么情况下都能使用堆叠注入,例如PHP中的mysql_query函数不支持执行多个语句,而mysqli_multi_query函数则允许在一个调用中执行多个SQL语句

由于页面的回显通常只会展示第一个语句的结果,所以后面那些语句适合执行一些非查询的SQL语句操作

示例

下面列举了一些堆叠注入中可能用到的SQL操作

  1. 修改数据库中的数据项(账户密码)

    ?id=1';update users set password='12345' where username='Dumb' ;--+

  2. 增加一条数据

    ?id=1';insert into users values(3,'R1ck','123456');

  3. 加载文件

    ?id=1';select load_file('/etc/passwd');--+

特殊场景

md5()函数

题目中可能会计算密码的md5值来比对

$password = md5($_POST['password'],true);

我们需要了解一下md5()函数中,设置true参数有什么用

string md5( string $str[, bool $raw_output = false] )

  • raw_output:如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。

那么当我们输入的password参数内容在计算md5哈希值后,会将哈希值根据转为原始二进制数据的字符串

此时我们可以通过精心构造输入,例如ffifdyop

它在经过md5函数后会得到'or'6�]��!r,��b

请添加图片描述

那么就可以作为万能密码来使用

例题:ctfshow平台的web187

弱类型比较

PHP 是一种弱类型语言,它在比较数字和字符串时会进行类型转换

  • 当数字与字符串比较时,PHP 通常会尝试将字符串转换成数字。如果字符串的开头部分包含数字,那么这些数字将被用来进行比较。如果字符串开头不是数字,它通常会被转换为 0。例如,比较 "123" == 123 将返回 true,而 "abc" == 0 也会返回 true
  • 使用 =====:PHP 中 == 用于值的比较,它会进行类型转换。=== 用于严格比较,即值和类型都必须相同,因此 "123" === 123 将返回 false

SQL中,类型转换规则依赖于使用的数据库系统,但大多数数据库管理系统(如 MySQL)也表现出一定的弱类型特征:

数字和字符串比较少时,字符串会转换为数字,如0==admin,那么如果输入的username是0,则会匹配所有开头不是数字或者为0的字符串和数字0

例题:ctfshow平台的web188

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

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

相关文章

数学中的连分式、无穷连根式、平方根

连分式 连分式&#xff08;continued fraction&#xff09;由和与倒数的多层嵌套构成&#xff0c;可以是有限的&#xff0c;也可以是无限的。 表达式&#xff1a;或 import mathdef fraction_to_continued_fraction(numerator, denominator, max_terms):"""计算…

【无标题】web+http协议+nginx搭建+nginx反向代理(环境准备)

一&#xff0e;Web 为用户提供互联网上浏览信息的服务&#xff0c;web服务是动态的&#xff0c;可交互的。 1.安装httpd yum -y install httpd 2.启动 systemctl start httpd 3.关闭防火墙 systemctl stop firewalld [rootrs html]# echo "我手机号是" > …

如何在 cPanel 上更改主共享 IP 地址

cPanel & WHM的主共享IP地址是服务器上新建虚拟主机账户时的默认IP地址。这使得主机服务商能够轻松创建新账户&#xff0c;并简化原本复杂且耗时的域名和网络服务器配置过程。但如果你想更改cPanel服务器的主共享IP地址&#xff0c;该怎么办呢&#xff1f; 本文将概述更改服…

PHP经销商订货管理系统小程序源码

经销商订货管理系统&#xff1a;重塑供应链效率的利器 &#x1f680; 开篇&#xff1a;解锁供应链管理的新纪元 在竞争激烈的商业环境中&#xff0c;经销商作为供应链的关键一环&#xff0c;其订货效率直接影响到整个供应链的流畅度和响应速度。传统的订货方式往往繁琐、易出…

精品PPT | 云原生大数据平台构建及落地实践.pptx

1、监控和可观测性的关系及渊源 2、当前阶段落地可观测性的挑战在哪里 3、落地好一个可观测系统的三大要素 4、面向故障处理过程的可观测性体系建设案例 5、思考&#xff1a;人工智能2.0对可观测性技术和产品演进的影响

YOLO入门教程(一)——训练自己的模型【含教程源码 + 故障排查】

目录 引言前期准备Step1 打标训练Step2 格式转换Step3 整理训练集Step4 训练数据集4.1创建yaml文件4.2训练4.3故障排查4.3.1OpenCV版本故障&#xff0c;把OpenCV版本升级到4.0以上4.3.2NumPy版本故障&#xff0c;把NumPy降低版本到1.26.44.3.3没有安装ultralytics模块4.3.4Aria…

Web 安全:Memcached 未授权访问漏洞.(11211端口)

Web 安全&#xff1a;Memcached 未授权访问漏洞 Memcached 是一套常用的 key-value 缓存系统&#xff0c;由于它本身没有权限控制模块&#xff0c;所以对公网开放的 Memcache 服务很容易被攻击者扫描发现。然而 Memcached 的默认配置&#xff0c;11211 端口 不需要密码即可访问…

ROUND() Function in SQL(四舍五入)

ROUND() Function in SQL ROUND() 函数用于将数值四舍五入到指定的小数位数或者整数位数。 不同的数据库系统可能会有一些细微的语法差异&#xff0c;但基本功能都是一致的。 1. 基本语法 ROUND(number, decimal_places)number: 要进行四舍五入的数值。decimal_places: 可选参…

Spring事件监听的核心机制及其原理

Spring事件监听 Spring的事件监听机制主要由三大核心部分组成即事件&#xff0c;监听器和播放器三部分组成。 事件的发布是通过spring当中的pulishEvent方法实现。事件监听实现是通过监听器监听了对应事件的监听器来实现的。 事件监听的作用&#xff1a;为系统业务之间进行一…

1、AI测试辅助-提示词优化

AI测试辅助-提示词优化 一、基本规则二、提示词优化技巧&#xff1a;2.1 Prompt 逆向工程2.2 提示词框架2.2.1 CO-STAR 框架 2.3 提示词生成器 三、总结 一、基本规则 写提示词有个通用的基本规则&#xff0c;遵循这个规则基本上能解决大部分的问答&#xff1a; 角色任务要求 …

2024经济师考试报名『注册流程』图解!

⏰报名时间&#xff1a;8月12日—9月11日 ☑️报名注册流程 1、经济师考试报名注册网站&#xff1a;中国人事考试网. 2、点击考生登录栏目中的【新用户注册】按钮&#xff0c;进行注册。 3、进入用户注册界面&#xff0c;填写注册信息。 4、填写完毕确认无误后点击【提交】&…

thinkPHP开发的彩漂网站源码,含pc端和手机端

源码简介 后台thinkPHP架构,页面程序双分离,Mysql数据库严谨数据结构、多重数据审核机制、出票机制和监控机制,html5前端技术适用移动端,后台逻辑更多以server接口可快捷实现对接pc和ap,下载会有少量图片素材丢失,附件有下载说明前端demo账户密码和后台管理地址管理员账户密码…

【C++】C++11的新特性 --- lambda表达式 ,新的类功能,模块的可变参数 , emplace系列接口

如果你停止,就是谷底! 如果你还在继续,就是上坡! 这是我听过关于人生低谷最好的阐述。 -- 刘同 C11的新特性 1 lambda表达式1.1 基本用法1.2 细谈参数列表与捕捉列表 2 新的类功能2.1 移动构造与移动赋值2.2 default和delete 3 模块的可变参数4 emplace系列接口Thanks♪(&…

C语言:指针(1)

一. 内存和地址 比如&#xff0c;我们的内存就相当⼀栋宿舍楼&#xff0c;楼里有很多的房间&#xff0c;每个房间都有一个房间号&#xff0c;每个房间里都住着8个人。这时如果你的朋友想要来找你&#xff0c;我们只需要把房间号告诉他就能快速的找到我们。 然而&#xff0c;&…

Stable Diffusion 提示词攻略

一、提示词作用 提示词所做的工作是缩小模型出图的解空间&#xff0c;即缩小生成内容时在模型数据里的检索范围&#xff0c;而非直接指 定作画结果。 提示词的效果也受模型的影响&#xff0c;有些模型对自然语言做特化训练&#xff0c;有些模型对单词标签对做特化训练&#xf…

负债了,打死也别干的六件事!逾期了,六句谎言千万别信!

负债这事儿&#xff0c;真是一言难尽&#xff0c;稍不留神&#xff0c;就可能让情况雪上加霜。今儿咱们聊聊&#xff0c;负债后那几件打死也别干的几件事&#xff0c;尤其是针对还没有逾期的朋友们&#xff0c;免得后悔莫及。 首先&#xff0c;千万别动歪脑筋&#xff0c;拿公款…

【Golang 面试 - 基础题】每日 5 题(十)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

YOLOV8-人员越界识别

原文:YOLOV8-人员越界识别 - 知乎 (zhihu.com) 一、人员越界识别背景描述 实际生活中某些场景下需要配合摄像头自动识别危险区域,并在发现有人员闯入危险区域(禁止进入区域)时进行报警。翻越围墙监测预警系统对监控区域内的护栏、围墙设定警戒围墙区域,一旦有可疑人员靠…

springboot电子产品销售系统-计算机毕业设计源码80294

摘 要 电子商务行业在全球范围内迅速发展&#xff0c;随之而来的是电子产品销售市场的快速增长和消费者对在线购物体验的需求提升&#xff0c;因此&#xff0c;电子产品销售系统应运而生。该系统旨在满足电子产品市场的需求&#xff0c;提供全面的购物功能和高效的管理操作。 …

高级及架构师高频面试题-基础型

1、设计模式有哪些原则&#xff08;待解释的更直白&#xff09; 单一职责原则&#xff1a;一个类或方法应只负责一项职责&#xff0c;避免一个类因为多个变化原因而改变。开闭原则&#xff1a;软件实体应对扩展开放&#xff0c;对修改封闭。比如要增加用户类别的时候可以新增一…