前面有很多攻击细节都是讲html、浏览器、javascript的
这一章节比较偏后端。
注入攻击的本质就是用户输入的数据当作代码去执行了。
1、用户能够控制输入
2、程序要执行的代码拼接了用户的数据
sql注入:
例如要执行用户输入的查询条件xxxx
select * from tablea where a=xxxx;
但是如果输入的xxxx是恶意的,变成了xxxx;drop table tablea;
那么执行代码拼接了用户的输入数据后 执行了:select * from tablea where a=xxxx;drop table tablea;
就这样数据库被人给黑掉了。
这样的输入条件还有很多场景。如果服务器还把数据库执行错误回显,那么无异于暴露出去了一个可以给人家摸索的客户端了
就算没有回显错误,也有一些and or等条件语句去实现盲注。
盲注手段:timing attach
有漏洞的前提下,破坏比较容易,但是要为了达到窃取数据的目的,需要些分析,黑客可以利用mysql的benchmark,设置条件表达式启动这个函数,根据后端的耗时来判断猜测是否正确。
如果数据库用户具有目录写权限 还可以将数据dump到服务器目录上 download下来。
注入攻击常常会用到读写文件的技巧,所以应该禁止普通数据库用户具有读写文件的权限。
自动化注入工具sqlmap集成了非常多的功能 包括利用udf功能,取得帐号权限。
http://www.2cto.com/Article/201209/156409.html
存储过程(http://baike.baidu.com/view/68525.htm?fr=aladdin)也成为攻击对象,ms sql server的xp_cmdshell比较臭名昭著,还有一系列能操作注册表的存储过程。
因为存储过程本来也是一堆sql逻辑的集合预设而已,如果依赖一些用户数据,也存在被注入的风险
宽字符(http://baike.baidu.com/link?url=LIYJ3YcICNs0-QNOgpxybNgV4iJCHbrpJ6RPF1X7h15Jvf7npgzV7aDCru8V1r7rbzeThJrSOpzMHlLPEaUkF_)编码问题:
为了防御,程序中一般会在特殊的引号字符前 加斜杠去转义。但是当mysql采用了gbk等宽字符集合的时候 某些特殊输入会带来意外
在gbk:0xbf27 0xbf5c 是一个双字节字符
攻击者输入0xbf27 or 1=1
web层通常自动addslash或者magic_quotes_gpc开启的情况下 会给0x27(单引号)前面加速斜杠0x5c
输入就变成了0xbf5c27 or 1=1。0xbf5c又是一个gbk双字节字符,于是防御用的斜杠被吃掉了 成了0xbf5c ' or 1=1
最好的方式是统一数据库、操作系统、web层的应用字符集 最好是都是utf8
sql column truncation:
sql mode不是strict的时候。insert value的值如果超过长度限制,会直接截断且插入成功。只有warning信息。
加入用户名密码表里 用户名字段长度限制20
那么插入admin和admin(50个空格)+x,会得到同样的用户名,这样很可能盗取admin资格
如何防御:
转义特殊字符是不够的,mysql_real_escape_string只会处理 ' " \r \n null ctrl+z
但是很多攻击代码可以完全不用这些字符,例如and or union等关键词
靠过滤关键词又容易误伤。
书里推荐采用预编译sql语句,绑定变量。一个罗卜一个坑,让攻击者无法改sql的结构。
另外就是使用存储过程,但是因为存储过程本身也有被注入的风险,且还需要在数据库预先定义。
检查数据类型,是比较靠谱。例如某个输入限定必须是整数,那么就完全可以杜绝歪门邪道
其它注入攻击:
xml注入 类似html注入,改变了结构导致
代码注入,使用高危函数eval system的函数,让数据成为代码可执行了。在鹅厂所有代码都禁止用高危函数。曾经见过一个病毒,是把vps上默默部署了一个cgi,把接受到的参数base64decode后eval执行了。直接被遥控成肉机了。
CRLF注入,利用\r(CR) \n(LF)来改变了排版。
如果打的日志里用用了输入数据 可能会导致日志伪造(有点牵强)
注入http头还是可以的(http response splitting),例如给的数据里有两次CRLF且后面跟随一段xss代码,如果服务器会把这个数据设置到cookie,http response在返回cookie信息的时候就因为两次crlf提前把http头截断,浏览器了开始执行后面的xss代码。
杜绝注入攻击要牢记 数据于代码的分离,所有拼接的地方做好严格检查。
由于注入漏洞和逻辑相关有比较大关系,一般要求web层不直接操作数据库。尽量按私有协议先走到逻辑层,这样做到了环境隔离,且通过一次协议转换也间接促使开发注意类型检查。