BChecks 自定义poc检测 - 把BurpSuite 打造成强大的漏洞扫描器

news2024/12/25 16:51:24

在这里插入图片描述

BChecks是什么?

BChecks可以创建和导入的自定义扫描检查。Burp Scanner在执行其内置扫描例程的同时运行这些检查,帮助您定位扫描并使测试工作流尽可能高效。
每个BCheck都定义为一个以.bcheck文件扩展名结尾的纯文本文件。这些文件使用自定义语言来指定检查的行为。

为什么用BChecks?

BurpSuite 自带的扫描引擎只能扫描某种类型的漏洞,如SQL注入,XSS,没有对特定漏洞,如某OA漏洞,shiro反序列化漏洞等漏洞的扫描,当我们要扫描特定漏洞时,需要用Java编写burpsuite插件,门槛较高,而且不同的漏洞往往有不同的作者编写,需要加载不同的插件,比较麻烦。同时我们往往需要使用外部的扫描器来补充对特定漏洞的检测,如用 xray 等扫描器。但BCheck 的出现,将改变这一现状,使 burpsuite可以直接加载各种漏洞的 poc,获得对特定漏洞的强大检测能力。 理想情况下,只要BCheck脚本足够多,使用burpsuite 就可以检测几乎所有Web漏洞,不需要额外的Web扫描器。

如何使用 BCheck?

要使用BCheck 脚本,你需要安装 Burp Suite 2023.7.1 以及更新的版本。然后插件处导入 BCheck 脚本,现在官方维护着一个 BCheck 脚本的仓库,地址如下:
https://github.com/PortSwigger/BChecks
本次演示使用 Burp Suite 2023.10.2
在 Extensions -> BChecks 处点击 Import ,导入 .bcheck 后缀的 bcheck 脚本。
在这里插入图片描述
在这里插入图片描述
导入后把 bcheck 脚本勾上就可以在扫描时调用了。
在这里插入图片描述
接着在想扫描的请求上右键,新建扫描
在这里插入图片描述
我们也可以在新建扫描时,只调用 bcheck 扫描,具体操作如下:
在这里插入图片描述
在扫描设置处点击 select from library
在这里插入图片描述
选择 BChecks only,即可只调用BCheck
扫描,不过在用默认的扫描配置时,会默认调用BCheck,并不用特意选择。
在这里插入图片描述
在Dashborad面板处可以看到已经扫描出一个 Shiro 漏洞了。
在这里插入图片描述

如何编写BCheck脚本?

怎样编写BCheck脚本呢?可以先看看 BCheck 的定义文档:
https://portswigger.net/burp/documentation/scanner/bchecks/bcheck-definition-reference
还可以看看官方的一些例子脚本,从而快速上手:
https://github.com/PortSwigger/BChecks/tree/main/examples
下面是根据文档翻译的定义,如果想直接看编写实操,可以跳过这段

BCheck 定义

Metadata 元数据

包含有关检查本身的信息。对于所有BChecks,必须将元数据对象放置在定义的开始。


metadata:
  language: v1-beta
  name: "Simple SQLi"
  description: "Tests insertion points for basic SQLi"
  author: "Peter Wiener"
  tags: "sql", "active", "sql-injection"
属性描述类型
language*BCheck 的语言版本。enum [v1-beta]
name*BCheck 的名字.当BCheck 报告一个问题时,这将显示在Burp Suite UI中。
StringdescriptionBCheck 的描述。
Stringauthor作者名
Stringtags标签名

Control flow 控制流

这些关键字控制定义的执行流程。

run for each

声明一个可以迭代的数组变量。当变量称为检查时,该数组中的每个项目一次运行一次。声明的变量具有外部范围。
run for each 关键字的运行是可选的。如果使用,则必须将其放置在given…then 之前,然后在定义中进行陈述。

run for each:
variable_name = "variable value 1", "variable value 2", etc.

例子

该示例声明一个称为 url_array 的变量,列出了三个URL。如果您正在编写需要针对多个URL进行相同的测试(例如,依次添加作为 Origin 头来检测 CORS 错误配置)。

run for each:
url_array =
null,
"http://example.com",
`https://{random_str(5)}{base.response.url}`

define 声明

声明具有内部作用域的变量。define关键字是可选的。如果使用,你必须把它放在given…then 语句的前面。

define:
  variable_name = "variable_content"

例子
该示例调用generate_collaborator_address()函数生成新的Burp collaborator地址,并将其存储在名为collaborator_address的变量中。

define:
  collaborator_address = {generate_collaborator_address()}

given…then

根据被检测的内容,定义检查何时运行。
given [response|request|host] | [ [any|query|header|body|cookie]* + insertion point] then
每个 BCheck 必须有一个 given / then 语句,其中包含:
以下任一情况:

  • given response then - 针对每一个检查的响应运行一次。
  • given request then - 针对每一个检查的请求运行一次。
  • given host then - 针对每一个检查的主机运行一次。
    或者以下插入点关键字之一:
  • given any insertion point then - 检查针对审核的每个插入点(任何类型)运行一次。如果您未指定插入点类型(即使用给定的插入点),Burp Scanner 也会使用此默认选项。
  • given query insertion point then - 该检查针对每个审核的查询运行一次。
  • given header insertion point then - 该检查针对每个审核的 http 头运行一次。
  • given body insertion point then - 该检查针对审核的每组http body 内容运行一次。
  • given cookie insertion point then - 该检查针对每个审核的 cookie 运行一次。

可以使用 or 关键字来组合插入点。例如:

  • given query or body insertion point then - 该检查针对审核的每个查询或一组 body 内容运行一次。
  • given header or cookie insertion point then - 该检查针对每个审核的 http 头或 cookie 运行一次。

Conditionals 条件语句

这些关键字控制由于设定条件而发生的操作。只能在给定given…then 语句中使用条件关键字。

if… then

如果满足设定条件则执行操作。需要以下内容:
一个条件
一个 操作
一个end if 关键词.
例子
如果最新响应包含 Apache Struts 版本号,则报告问题:

if {latest.response} matches "Apache Struts [\d\s\.]+" then
  report issue:
    severity: info
    confidence: certain
    detail: "Disclosed Apache Server"
    remediation: "Do not reveal error messages"
end if

else if… then

在 if 语句中使用。如果前面的条件为假且 else if 条件为真,则执行操作。您可以在 BCheck 中使用多个 else if 语句。

if [condition 1] then
  [action 1]
  else if [condition 2] then
   [action 2]
end if

例子
如果检查结果表明Collaborator 收到 DNS 交互,则坚定地报告问题。否则,检查协作者是否已收到任何 SMTP 交互。如果有,请暂时放心地报告问题。

if dns interactions then
  report issue:
    severity: high
    confidence: firm
  else if smtp interactions then
    report issue:
      severity: high
      confidence: tentative
end if

else then

在 if 语句中使用。如果该语句的条件和任何前面的 else/if 语句的条件不满足,则执行操作。

if [condition] then
  [action]
  else then
    [action 2]
end if

例子
如果最新响应与基本响应不同,但具有相同的 HTTP 状态代码,请坚定地报告问题。否则,请暂时放心地报告问题。

if {latest.response} differs from {base.response} and {latest.response.status_code} is {base.response.status_code} then
      report issue:
        severity: high
        confidence: firm
      else then
        report issue:
          severity: high
          confidence: tentative
    end if

end if

表示 if 语句的结束。

if [condition] then
  [action]
end if

Conditions 条件

您可以在 if 语句中使用以下条件:

  • {X} matches “[regex]” - 如果 X 与提供的正则表达式匹配,则为 True
  • {X} differs from {Y} - 如果响应 X 与响应 Y 不同,则为 True。
  • {X} in {Y} - 如果 Y 包含 X,则为 True(例如,Y 可以是响应,X 可以是要在该响应中搜索的标头)。
  • {X} is {Y} - 如果提供的参数相同,则为 True。
  • any interactions - 如果 Burp Collaborator 已收到任何交互,则为 True。
  • dns interactions - 如果 Burp Collaborator 已收到任何 DNS 交互,则为 true。
  • http interactions - 如果 Burp Collaborator 已收到任何 HTTP 交互,则为 true。
  • smtp interactions - 如果 Burp Collaborator 已收到任何 SMTP 交互,则为 True。

您还可以组合和修改条件:

  • {condition} and {condition} - 如果两个条件都为真,则为真。
  • {condition} or {condition} - 如果一个或两个条件为真,则为 True。
  • not({condition}) - 如果条件不为真则为真。

Brackets 括号

您可以在条件中使用括号来优化检查的逻辑流程。例如,A 或 B 和 C 创建一个条件,如果满足以下条件之一,则该条件的计算结果为 true:
A is true.
Both B and C are true.

Actions 动作

这些关键字提示 Burp Scanner 执行特定操作。
其中一些关键字只能与某些插入点结合使用。有关定义在哪些插入点上使用检查逻辑的更多信息,请参阅 given…then。

send request

发送包含指定信息的请求。可与除给定响应之外的所有扫描检查模式一起使用。
注意:如果未提供操作关键字,则所有请求属性默认为替换。例如:

headers:
  "name_of_header1": "value of header1",
  "name_of_header2": "value of header2"

与下面是相同的

replacing headers:
  "name_of_header1": "value of header1",
  "name_of_header2": "value of header2"
send request [called request_name]:
  [appending|replacing] headers:
"name_of_header1": "value of header1",
"name_of_header2": "value of header2"
  removing headers:
"name_of_header1",
"name_of_header2"
  [appending|replacing] queries:
"name_of_query_1=http://portswigger.net",
"name_of_query_2=https://portswigger.net"
  removing queries:
"name_of_query_1",
"name_of_query_2"
  [appending|replacing] path: "/test"
  removing path
  [appending|replacing] method: "GET"
  removing method
  [appending|replacing] body: "contents of body"
  removing body
关键词描述例子
called(string)为请求命名,以便稍后在检查中引用“Example request”
appending headers:(1-n name:value pairs)将指定的标头添加到请求中。如果请求中已存在同名标头,则添加具有新值的第二个标头。您可以列出多个标头/值对“Origin”: “http://example.com”
removing headers:(1-n header names)从请求中删除指定的标头。您可以列出多个标头名称“Origin”
appending queries:(1-n query names and values)将指定的查询参数添加到请求 URL。如果请求中已存在同名查询,则会添加具有新值的第二个标头。您可以列出多个查询“title=example_query”
replacing queries:(1-n query names and values)将指定查询参数的值替换为新值。如果没有具有指定名称的查询,则会附加一个新查询。您可以列出多个查询“title=example_query”
removing queries:(1-n query names)从请求中删除指定的查询参数。您可以列出多个查询“title”
appending path:(string)将指定的路径参数添加到请求 URL“/admin”
replacing path:(string)将 URL 中的路径参数替换为指定值。保留所有查询参数“/admin”
removing path从请求中删除所有路径参数。
appending method:(string)将指定的 HTTP 方法添加到请求中“GET”
replacing method:(string)将请求方法替换为指定值“GET”
removing method删除请求方法
appending body:(string)将指定的正文内容附加到请求中“body content”
replacing body:(string)将请求体替换为指定内容“body content”
removing body删除请求正文

send request (raw)

将包含指定信息的请求作为原始 HTTP 请求发送。可与除given response之外的所有扫描检查模式一起使用。
例子

send request [called request_name]:
  "GET /catalog/product?productId=2 HTTP/2
  Host: ginandjuice.shop
  Cookie: session=qwertyuiop
  Content-Length: 2"

send payload

发送附加或替换指定负载的新请求。只能与 given insertion point一起使用。

send payload [called payload_name]:
  appending: "payload"
  replacing: "payload"
属性描述类型
appending:将指定的负载附加到请求的负载集中。字符串/变量
replacing:将请求的现有负载集替换为指定的负载。字符串/变量

report issue

导致 Burp Scanner 报告问题。BChecks 报告的所有问题都具有声明性扫描检查生成的问题类型。问题的显示名称取自 BCheck 的名称元数据属性。

report issue:
  severity:
  confidence:
  remediation:
  detail:
属性描述类型
severity*问题的严重性[info
confidence*问题存在的置信度[certain
remediation补救建议String
detail有关该问题的更多信息String

报告问题时控制流程
report issue 操作会终止 BCheck,即使检查的某些部分尚未运行。您在设计 BCheck 时应该考虑这一点。
例如,考虑以下 BCheck:

given host:
  send request:
    method: `GET`
    headers: `Host`: `{collaborator_address}`

  if dns interactions then
    report issue:
      severity: info
      confidence: certain
  end if

  if http interactions then
    report issue:
      severity: high
      confidence: certain
  end if

此检查首先查找 DNS,然后查找由 Burp Collaborator 负载产生的 HTTP 交互。但是,如果检查发现 DNS 交互,则它会执行第一个报告问题操作,并且随后不会报告任何 HTTP 交互,即使存在 HTTP 交互也是如此。

Reserved variables 保留变量

这些关键字引用特定的请求或响应属性。
注意:确保在命名自己的变量时不要使用这些保留的属性名称,因为这会导致 BCheck 运行时出错。

request / response

这些关键字引用特定的请求或响应属性。您可以参考:

  • base - Burp Scanner 在抓取过程中针对指定扫描模式发送的请求和接收的响应。
  • latest - 此扫描模式的最新请求/响应对。
  • {request_name} - 特定的请求/响应对,使用 Called 关键字命名。
base|latest|{request_name} {
  response {
    status_code
    headers
    body
    http_version
  }
  request {
    method
    url {
      protocol
      host
      port
      path
      file
      query
    }
    http_version
    headers
    body
  }
}

Response

属性描述
response返回响应的全部内容。
response.status_code返回响应的 HTTP 状态代码。
response.headers返回响应头的列表。
response.body返回响应的正文内容。
response.http_version返回响应中使用的 HTTP 版本。

Request

属性描述
request返回请求的全部内容。
request.method返回请求中使用的 HTTP 方法。
request.url返回请求发送到的 URL。
request.url.protocol返回请求 URL 的协议。
request.url.host返回请求发送到的主机。
request.url.port返回发送请求所通过的端口。
request.url.path返回请求 URL 路径。
request.url.file返回 URL 文件(即 URL 中初始斜杠之后的部分)。
request.url.query返回请求 URL 中使用的查询字符串。
request.http_version返回请求中使用的 HTTP 版本。
request.headers返回请求头列表。
request.body返回请求的正文内容。

Functions 函数

这些关键字在调用时执行特定任务。
请注意,所有 BCheck 函数都用大括号 {} 表示。

random_str

{random_str(int)} 返回指定长度的随机字符串。长度必须介于 0 和 9,999,999 之间。输入 0 将返回空字符串。

Example

{random_str(13)} // "qpald95nbjkig"

regex_replace

regex_replace(String source, String regex, String replacement) 获取源字符串并用替换字符串替换与指定正则表达式模式匹配的任何内容。
Example

regex_replace ({var}, "[a-z]*@", "abc@")

在此示例中,假设 {var} 的值为“xyz@portswigger.net”。正则表达式模式匹配电子邮件地址的第一部分,并将其替换为替换字符串,以创建 abc@portswigger.net 的最终输出。

to_lower

{to_lower(string)}
将指定字符串转换为小写。
Example

{to_lower("Carlos MONTOYA")} // carlos montoya

to_upper

{to_upper(string)}
将指定字符串转换为大写。
Example

{to_lower("Peter weiner")} // PETER WEINER

base64_encode

{base64_encode(string)}
使用 base64 对指定字符串进行编码。
Example

hello world // aGVsbG8gd29ybGQ=

base64_decode

{base64_decode(string)}
从 base64 解码指定的字符串。
Example

hello world // aGVsbG8gd29ybGQ=

generate_collaborator_address

{generate_collaborator_address}

生成一个新的 Burp Collaborator 地址以在请求中使用。您可以通过多次调用 {generate_collaborator_address} 在同一个 BCheck 中生成多个地址。

SHA1

sha1(String)
使用 SHA1 哈希函数对提供的输入进行哈希处理。
Example

sha1("Hello") // aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d

SHA256

sha256(String)
使用 SHA256 哈希函数对提供的输入进行哈希处理。

Example

sha256("Hello") // 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

MD5

md5(String)

使用 MD5 哈希函数对提供的输入进行哈希处理。
Example

MD5("Hello") // 5d41402abc4b2a76b9719d911017c592

组合函数

如果需要,可以嵌套这些函数。例如,以下函数将变量转换为小写,然后通过一个操作将其编码为 Base64:

{base64_encode(to_lower(my_variable))}

注意:确保在命名变量时不要使用这些函数名称,因为这会导致 BCheck 运行时出错。

杂项

Strings

使用双引号 (“”) 表示文字字符串 - “delete carlos”
使用反引号 (``) 表示可插值字符串 - `https://{random_str(5)}.com`
处理多行字符串时,Burp Scanner 将行结尾替换为 \r\n 并修剪每行上的尾随和前导空格(左引号之后和右引号之前的空格除外)。
例如:

"__GET / HTTP/1.1__
___Host: portswigger.net_"

变成

"__GET / HTTP/1.1
Host: portswigger.net__"    

要在可插值字符串中显式指定尾随/前导空格,请改用 \s 字符。

字符转义

在字符串中使用 \ 字符来转义字符。例如,{var} 被转义,但 {var} 打印 var 的值。

正则表达式

BChecks 支持 Java 风格的正则表达式。
“2[0-9][0-9]”

注释

使用 # 来表示注释行。
#Hello

特殊字符

这些字符可以用作可插值字符串的一部分。例如,“\s”被解释为空格,但文字字符串“\s”被解释为两个单独的字符。
\n - 新行
\r - 回车
\s - 空格
\t - 制表符
\b - 退格键
\f - 换页

BCheck 结构

为了创建有效的 BCheck,您需要遵循一些结构规则:
每个定义必须以 metadata 对象开始。.
每个定义必须有一个given… then 语句.
条件语句只能出现在 given… then 语句中.
任何define 或run for each 语句使用时必须放在metadata 块后面并在given… then 语句之前.
变量定义使用 run for each 具有外部作用域,而使用 define 声明的变量具有内部作用域. 这意味着您不能在run for each语句的后续运行中使用通过 Define 声明的变量。

bcheck定义介绍到这里结束了,下面进行 bcheck 编写实操教程

bcheck 编写实操教程

点击 New

在这里插入图片描述
选择从模板创建,这样可以省不少时间

在这里插入图片描述
点击相应模板,如想写一个被动扫描的插件,可以选择 response-level这个

在这里插入图片描述

下面编写一个被动检测使用了 shiro 框架的插件,代码如下:

metadata:
    language: v1-beta
    name: "Shiro Cookie Check Passive"
    description: "Check for Shiro Vulnerability in Response"
    author: "timeshatter"
    tags: "Shiro,passive"

given response then
    if "rememberMe=deleteMe" in {latest.response} then
        report issue:
            severity: info
            confidence: certain
            detail: "Shiro Vulnerability Detected: rememberMe=deleteMe"
            remediation: "Investigate and fix the Shiro vulnerability immediately."
    end if

第8行的 given response 为接收到请求响应时进行检测,也就是被动的检测,第9行处如果 rememberMe=deleteMe 在响应内容中,则报告检测到 shiro 框架。写完代码后,我们使用 vulhub的靶场来搭建个 shiro环境
https://github.com/vulhub/vulhub/tree/master/shiro/CVE-2016-4437

在这里插入图片描述
输入账号密码,勾选 Remember me,点击登录

在这里插入图片描述
可以看到响应中有 deleteMe

在这里插入图片描述
在这个请求上右键,选择 Send to BCheck editor

在这里插入图片描述
点击 Run test,可以看到在 issue activity 上已经有结果了

在这里插入图片描述

可以看到,已经成功检测到该漏洞了
在这里插入图片描述
没问题了,可以点Save&close保存成一个bcheck脚本。
接下来再写一个主动检测 shiro框架的脚本,代码如下:

metadata:
    language: v1-beta
    name: "Shiro Cookie Check Active"
    description: "Detects Shiro Vulnerability by Manipulating Cookie"
    author: "timeshatter"
    tags: "Shiro,active"

define:
    shiroExploit = "rememberMe=1"
    issueDetail = "Shiro Cookie Exploit Detected: rememberMe=deleteMe"
    issueRemediation = "Immediately investigate and fix the Shiro vulnerability."

given request then
    send request called check:
        replacing headers:
            "Cookie": {shiroExploit}
    
    if "rememberMe=deleteMe" in {check.response} then
        report issue:
            severity: info
            confidence: certain
            detail: {issueDetail}
            remediation: {issueRemediation}
    end if

第13行的 given request 为主动发送一个请求进行检测,也就是主动的检测,当我们对某个请求进行扫描时会调用,第16行处替换请求头的内容为rememberMe=1 ,18行处检测如果 rememberMe=deleteMe 在响应内容中,刚报告漏洞。
同样的,我们把一个正常的请求发送到 BCheck editor
在这里插入图片描述
在这里插入图片描述成功发现漏洞

在这里插入图片描述点击Logger可以看这次发送的检测请求,也可以用来调试是否有问题

在这里插入图片描述
BCheck脚本的编写教程就写到这里,下面是我写的一些检测 shiro和 spring漏洞的 bcheck脚本,在 github上:
https://github.com/QdghJ/burpsuite-bchecks
还有官方的BChecks库:
https://github.com/PortSwigger/BChecks
欢迎大家编写poc提交到我的仓库或者官方的仓库,丰富漏洞库,这样就不用再开额外的扫描器了,直接 burpsuite 一把梭。
虽然现在 BCheck 脚本刚出来不久,还有一些 bug,功能也不算很强大,但基本可以满足我们对漏洞检测,毕竟检测漏洞也就是发送请求,然后检测响应内容,相信在以后可以得到广泛应用。

本文章也在我的公众号发布
在这里插入图片描述

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

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

相关文章

配置OSPF路由

OSPF路由 1.OSPF路由 1.1 OSPF简介 OSPF(Open Shortest Path First,开放式最短路径优先)路由协议是另一个比较常用的路由协议之一,它通过路由器之间通告网络接口的状态,使用最短路径算法建立路由表。在生成路由表时,…

Spring Cloud Netflix 教程和源码

本教程目标 想要系统地学习 Spring Cloud Netflix, 把自己的学习过程记录下来。 状态 持续更新中 微服务架构 微服务架构是一种将应用程序拆分为一组独立的、可独立部署的服务的架构模式。每个服务都运行在自己的进程中,可以独立地进行开发、测试和…

数据库管理-第108期 因Exadata存储节点操作系统空间异常的紧急处理(20230928)

数据库管理-第108期 因Exadata存储节点操作系统空间异常的紧急处理(20230928) 众所周知,明天放假了,本着对客户数据库软硬件负责任的态度,进行了一次深入彻底的软硬件巡检(就是检查包括计算节点、存储节点…

vue3中状态适配

写一个函数,在函数中定义一个对象 用于存放键值对,最后返回指定状态所对应的的值,即对象[指定状态] 的 对象的值。 在模板中把状态传入 // vue3 setup语法糖中 const formatXXXState (xxxState)>{const stateMap {键1: 值1,键2: 值2,.…

Linux-正则三剑客

目录 一、正则简介 1.正则表达式分两类: 2.正则表达式的意义 二、Linux三剑客简介 1.文本处理工具,均支持正则表达式引擎 2.正则表达式分类 3.基本正则表达式BRE集合 4.扩展正则表达式ere集合 三、grep 1.简介 2.实践 3.贪婪匹配 四、sed …

VS+Qt+opencascade三维绘图stp/step/igs/stl格式图形读取显示

程序示例精选 VSQtopencascade三维绘图stp/step/igs/stl格式图形读取显示 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《VSQtopencascade三维绘图stp/step/igs/stl格式图形读取显示》编写…

postman安装使用教程

本文只是基于 Chrome 浏览器的扩展插件来进行的安装,并非单独应用程序。 首先,你要台电脑,其次,安装有 Chrome 浏览器,那你接着往下看吧。 1. 官网安装(别看) 打开官网,https://ww…

【计算机网络】P2P文件分发介绍

文章目录 P2P体系结构的自扩展性BitTorrent协议参考资料 考虑一个场景:从单一服务器向大量主机(称为对等方)分发一个大文件。 两种处理方式 客户-服务器文件分发:服务器需要向每个对等方发送该文件的一个副本 P2P文件分发&#xf…

使用代理后pip install 出现ssl错误

window直接设置代理 httphttp://127.0.0.1:7890;httpshttp://127.0.0.1

Java 并发编程面试题——BlockingQueue

目录 1.什么是阻塞队列 (BlockingQueue)?2.BlockingQueue 有哪些核心方法?3.BlockingQueue 有哪些常用的实现类?3.1.ArrayBlockingQueue3.2.DelayQueue3.3.LinkedBlockingQueue3.4.PriorityBlockingQueue3.5.SynchronousQueue 4.✨BlockingQu…

【C++】构造函数和析构函数第二部分(拷贝构造函数)--- 2023.9.28

目录 什么是拷贝构造函数?编译器默认的拷贝构造函数构造函数的分类及调用结束语 什么是拷贝构造函数? 用一句话来描述为拷贝构造即 “用一个已知的对象去初始化另一个对象” 具体怎么使用我们直接看代码,代码如下: class Maker…

什么是DOM和DOM操作

什么是DOM? DOM(文档对象模型):HTML文档的结构化表示。允许JavaScript访问HTML元素和样式来操作它们。(更改文本,HTML属性甚至CSS样式) 树结构由HTML加载后自动生成 DOM树结构 这个是一个很简单的HTML代…

Redis与分布式-主从复制

接上文 常用中间件-OAuth2 1.主从复制 启动两个redis服务器。 修改第一个服务器地址 修改第二个redis 然后分别启动 redis-server.exe redis.windows.conf) 查看当前服务器的主从状态,打开客户端:输入info replication命令来查看当前的主从状态&am…

数据结构基础9:排序全家桶

排序全家桶: 一:插入排序:1.简单插入排序:2.希尔排序: 二:选择排序:1.简单选择排序:2.堆排序(空间复杂度为O(1)): 三:快速排序;方法一…

共同见证丨酷雷曼武汉运营中心成立2周年

酷雷曼武汉运营中心2周年 全国合作商齐贺武汉公司2周年庆 2021年 作为酷雷曼辐射全国版图的又一重要据点 酷雷曼武汉运营中心 在“中国光谷”正式成立 沉浸式参观酷雷曼武汉公司 2年时间 尽管历经诸多客观因素的挑战 但后浪扬帆,依然交出了不斐的成绩 解决…

用AI写文章被百家号封禁

我是卢松松,点点上面的头像,欢迎关注我哦! 千万不要用AI创作,尤其是原文照搬!不要用ai,不要用,不要用!重要的事情说三遍。 近日ID名为“爸爸在家赚钱”用AI写了4-5篇文章投稿在百家号,随后百度就把他帐号…

【Bond与你白话IaC之Terraform for Docker篇】 攻城狮如何向女友解释IaC呢?

前言: 最近有机会与朋友聊到IaC(Infra as code)说到是否有比较好的切入点进行学习。 客观地说,看到XaX或XasX结构的的名词,让人立刻会与最前沿的云技术联系起来,但实际上其背后的思想仍然来自于传统系统的痛…

python web编程一:token、session、cookie、密码加解密

1 认证 1 传统的session-cookie机制 HTTP协议是无状态协议,为了解决它产生了cookie和session技术。 浏览器发起第一次请求到服务器,服务器发现浏览器没有提供session id,就认为这是第一次请求,会返回一个新的session id给浏览器…

Flask扩展:简化开发的利器以及26个日常高效开发的第三方模块(库/插件)清单和特点总结

目录 寻找扩展 使用扩展 创建扩展 26个常用的Flask扩展模块 总结 原文:Flask扩展:简化开发的利器以及26个日常高效开发的第三方模块(库/插件)清单和特点总结 (qq.com) Flask是一个轻量级的Python Web框架,它提供…

14.(开发工具篇github)如何在Github配置ssh key

第一步:检查本地主机是否已经存在ssh key 上图表示已存在。跳第三步 第二步:生成ssh key ssh-keygen -t rsa -C "xxxxxx.com"第三步:获取ssh key公钥内容(id_rsa.pub) cat id_rsa.pub第四步:G…