CTFer成长之路-Web入门之SQL注入

SQL注入基础

数字型注入和UNION注入

http://192.168.20.133/sql1.php?id=-1 union select 1,group_concat(table_name)from information_schema.tables where table_schema=database()

table_name字段是information_schema库的tables表的表名字段,表中还有数据库名字段table_schema。
database()函数返回的内容是当前数据库的名称。
group_concat是用“,”联合多行记录的函数。也就是说,该语句可以联合查询当前库的所有(事实上有一定的长度限制)表名并显示在一个字段中。

字符型注入和布尔盲注

在GET参数输入的地方包裹了单引号,让其变成字符串。

http://192.168.20.133/sql2.php?id=1'and (select mid((select concat(user,0x7e,pwd) from wp_user),2,1))='d'%23

说明第2位是'd'。以此类推,即可得到相应的数据。

时间盲注

由于某些情况下,页面回显的内容完全一致,故需要借助其他手段对SQL注入的执行结果进行判断,如通过服务器执行SQL语句所需要的时间。
在执行的语句中,由于sleep(1)的存在,使整个语句在执行时需要等待1秒,导致执行该查询需要至少1秒的时间。通过修改sleep()函数中的参数,我们可以延时更长,来保证是注入导致的延时,而不是业务正常处理导致的延时。
与回显的盲注的直观结果不同,通过sleep()函数,利用IF条件函数或AND、OR函数的短路特性和SQL执行的时间判断SQL攻击的结果,这种注入的方式被称为时间盲注。

报错注入

只要触发SQL语句的错误,即可在页面上看到错误信息。这种攻击方式则是因为MySQL会将语句执行后的报错信息输出,故称为报错注入。
updatexml在执行时,第二个参数应该为合法的XPATH路径,否则会在引发报错的同时将传入的参数进行输出。
利用这个特征,针对存在报错显示的例子,将我们想得到的信息传入updatexml函数的第二个参数,在浏览器中尝试访问链接http://192.168.20.133/sql3.php?id=1' or updatexml(1,concat(0x7e,(select pwd from wp_user)),1)%23

堆叠注入

当目标开启多语句执行的时候,可以采用多语句执行的方式修改数据库的任意结构和数据,这种特殊的注入情况被称为堆叠注入。

注入点位置

注入点在select_expr
注入点在table_reference
注入点在WHERE或HAVING后
注入点在GROUP BY或ORDER BY后
注入点在LIMIT后

注入点位于tbl_name
注入点位于VALUES
INSERT注入
UPDATE注入
DELETE注入

注入和防御

1.只过滤了空格

除了空格,在代码中可以代替的空白符还有%0a、%0b、%0c、%0d、%09、%a0(均为URL编码,%a0在特定字符集才能利用)和/**/组合、括号等。

2.将SELECT替换成空

遇到将SELECT替换为空的情况,可以用嵌套的方式,如SESELECTLECT形式,在经过过滤后又变回了SELECT。

3.大小写匹配

在MySQL中,关键字是不区分大小写的,如果只匹配了"SELECT",便能用大小写混写的方式轻易绕过,如"sEleCT"。

4.正则匹配

正则匹配关键字"\bselect\b"可以用形如/*!50000select*/的方式绕过,

5.替换了单引号或双引号,忘记了反斜杠

第1个可控点的反斜杠转义了可控点1预置的单引号,导致可控点2逃逸出单引号。
逃逸引号注入的重点在于逃逸引号,而开发者常会将用户的输入全局地做一次addslashes,也就是转义如单引号、反斜杠等字符,如“'”变为“'”。在这种情况下,看似不存在SQL注入,但在某些条件下仍然能够被突破。

逃逸引号

1.编码解码
开发者常常会用到形如urldecode、base64_decode的解码函数或者自定义的加解密函数。当用户输入addslashes函数时,数据处于编码状态,引号无法被转义,解码后如果直接进入SQL语句即可造成注入,同样的情况也发生在加密/解密、字符集转换的情况。宽字节注入就是由字符集转换而发生注入的经典案例。
2.意料之外的输入点
开发者在转义用户输入时遗漏了一些可控点,以PHP为例,形如上传的文件名、http header、$_SERVER['PHP_SELF']这些变量通常被开发者遗忘,导致被注入。
3.二次注入
二次注入的根源在于,开发者信任数据库中取出的数据是无害的。假设用户输入的用户名admin'or'1经过转义为了admin'or'1,于是SQL语句为:
INSERT INTO wp_user VALUES(2,'admin'or'1','some_pass');
此时,由于引号被转义,并没有注入产生,数据正常入库,但是,当这个用户名再次被使用时(通常为session信息),注入就发生了。

注入的功效

前面讲述了SQL注入的基础和绕过的方法,那么,注入到底有什么用呢?结合作者的实战经验,总结如下。
❖ 在有写文件权限的情况下,直接用INTO OUTFILE或者DUMPFILE向Web目录写文件,或者写文件后结合文件包含漏洞达到代码执行的效果、。
❖ 在有读文件权限的情况下,用load_file()函数读取网站源码和配置信息,获取敏感数据。
❖ 提升权限,获得更高的用户权限或者管理员权限,绕过登录,添加用户,调整用户权限等,从而拥有更多的网站功能。
❖ 通过注入控制数据库查询出来的数据,控制如模板、缓存等文件的内容来获取权限,或者删除、读取某些关键文件。
❖ 在可以执行多语句的情况下,控制整个数据库,包括控制任意数据、任意字段长度等。
❖ 在SQL Server这类数据库中可以直接执行系统命令。

SQL注入小结

❖根据不同的SQL服务器类型,查找相关资料,通过fuzz得出被过滤掉的字符、函数、关键词等,在文档中查找功能相同但不包含过滤特征的替代品,最终完成对相关防御功能的绕过。
❖sqli-labs(https://github.com/Audi-1/sqli-labs)提供不同过滤等级下的注入题目,其中涵盖了大多数出题点。

你可能感兴趣的:(CTFer成长之路-Web入门之SQL注入)