1.注入攻击的本质,是把用户输入的数据当做代码执行。两个关键条件:
(1)用户能够控制输入
(2)原本程序要执行的代码,拼接了用户输入的数据。
2.SQL注入:错误回显能为攻击者提供极大的便利。
(1)盲注:服务器没有错误回显时完成注入攻击。
(2)Timing Attack:利用BENCHMARK()函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长;通过时间长短的变化,可以判断出注入语句是否执行成功。这是一种边信道攻击。
3.数据库攻击技巧:
(1)union select
(2)Sqlmap
(3)读写文件的技巧:首先通过LOAD_FILE将系统文件读出,再通过INTO DUMPFILE将该文件写入系统中,然后通过LOAD DATA INFILE将文件导入创建的表中,最后就可以通过一般注入技巧直接操作表数据了。前提是当前数据库用户有创建表的权限。(除了可以使用INTO DUMPFILE外还可以使用INTO OUTFILE,区别:DUMPFILE适用于二进制文件,会将目标文件写入同一行内;而OUTFILE适用于文本文件)
导出webshell间接地执行命令
(4)命令执行:利用“用户自定义函数”的技巧,即UDF来执行命令
创建UDF:CREATE FUNCTION name RETURNS INTEGER SONAME shared_library
通过lib_mysqludf_sys提供的几个函数执行系统命令,最主要的函数是sys_eval()和sys_exec():将lib_mysqludf_sys.so上传到数据库能访问到的路径下。在创建UDF之后,就可以使用sys_eval()等函数执行系统命令了。
sys_eval:执行任意命令,并将输出返回。
sys_exec:执行任意命令,并将退出码返回。
sys_get:创建一个环境变量。
sys_set:创建或修改一个环境变量。
以上为MYSQL Server环境下,而在MSSQL中,则可以使用存储过程“xp_cmdshell”执行系统命令。
(5)攻击存储过程:与UDF很像,但存储过程必须使用CALL或者EXECUTE来执行。在MSSQL Server和Oracle数据库中有大量内置的存储过程。
xp_cmdshell在SQL Server2000中默认开启,但在2005及以后版本则默认禁止了。但是当前数据库用户拥有sysadmin权限的话,可以使用sp_configure(2005和2008)重新开启它。如果在2000中禁止了可以用sp_addextendedproc开启。
xp_regread、xp_regaddmultistring、xp_regdeletekey、xp_regdeletevalue、xp_regwrite等可以操作注册表
除了利用存储过程直接攻击外,存储过程本身也可能会存在注入漏洞。
(6)编码问题:进入数据库之前,在web语言中双字节符会被认为是两个字节。
PHP中的addslashes()函数(转义’ “ \ NUL),或者当magic_quotes_gpc开启时,会在特殊字符前增加一个转义字符\
要解决需要统一数据、操作系统、web应用所使用的字符集,以避免各层对字符的理解存在差异。或者根据系统使用的不同字符集来限制用户输入数据的字符允许范围,以实现安全过滤。
基于字符集的攻击并不局限于SQL注入,凡是会解析数据的地方可能存在这个问题。比如在XSS中,由于浏览器和服务器返回的字符编码不同,也可能会存在字符集攻击。解决办法就是在HTML页面的<meta>标签中指定当前页面的charset。
(7)SQL Column Truncation:当MySQL的sql_mode设置为default时即没有开启STRICT_ALL_TABLES选项时,MySQL对于用户插入的超长值只会提示warning,而不是error(如果是error则插入不成功),这可能会导致发生一些“截断”问题。
4.正确的防御SQL注入:
(1)总的来说就是:找到所有的SQL注入漏洞,修补这些漏洞。
(2)使用预编译语句:防御SQL注入的最佳方式,就是使用预编译语句,绑定变量。变量用?表示。
(3)使用存储过程:使用存储过程和使用预编译语句类似,其区别就是存储过程先将SQL语句定义在数据库中。但需要注意的是:存储过程中也可能会存在注入问题,因此应该尽量避免在存储过程内使用动态的SQL语句。如果无法避免,则应该使用严格的输入过滤或者是编码函数来处理用户的输入数据。
(4)检查数据类型
(5)使用安全函数:ESAPI.encoder().encodeForSQL( new OracleCodec(), queryparam );
数据库应使用最小权限原则,避免Web应用直接使用root、dbowner等高权限账户直接连接数据库。Web应用使用的数据库账户,不应该有创建自定义函数、操作本地文件的权限。
5.其他注入攻击:都违背了“数据域代码分离”原则
(1)XML注入:两大条件一样。
对用户输入数据中包含的“语言本身的保留字符”转义
(2)代码注入:代码注入与命令注入往往都是由一些不安全的函数或者方法引起的,其中的典型代表就是eval()
严格来说,PHP、JSP的动态include(文件包含漏洞)导致的代码执行,都可以算是一种代码注入。
禁用eval()、system()等可以执行命令的函数
(3)CRLF注入:CRLF实际上是两个字符。CR:\r 与LF:\n。\r\n这两个字符是用于表示换行的,其十六进制分别为0x0d、0x0a
在HTTP头中的CRLF注入,又称为“Http Response Splitting”
对抗CRLF只需要处理好\r\n这两个保留字符即可,尤其是使用“换行符”作为分隔符的应用。