SQL注入基础知识详解
slug
series-status
status
summary
date
series
type
password
icon
tags
category
分类
基于服务器的响应
- 基于错误的SQL注入,报错注入
- 联合查询的类型
- 堆查询注入
- SQL盲注
- 基于布尔类型的盲注
- 基于时间的盲注
- 基于报错的盲注
基于如何处理输入的SQL查询
- 基于字符串
- 数字或整数为基础的
基于程度和顺序
- 一阶注入
- 二阶注入
- 一阶注射是指输入的注射语句对WEB 直接产生了影响,出现了结果;二阶注入类似存储型XSS,是指输入提交的语句,无法直接对WEB 应用程序产生影响,通过其它的辅助间接的对WEB 产生危害,这样的就被称为是二阶注入.
基于注入点的
- 通过用户输入的表单域的注入
- 基于cookie的注入
- 通过服务器变量的注入
常用系统函数
- version()
数据库版本
- user()
数据库用户名
- database()
数据库名
- @@datadir
数据库路径
- @@version_compile_os
操作系统版本
字符串拼接函数
- concat(str1, str2, ...)
- concat_ws(separator, str1, str2, ...)
- group_concat(str1, str2, ...)
用于尝试的语句
Ps:--+可以用#替换,url 提交过程中Url 编码后的#为%23
or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
")or 1=1 --+
"))or 1=1--+
SQL中的逻辑运算


关键数据库
information_schema
盲注
分类
- 基于布尔的
- 基于时间的
- 基于报错的
基于布尔的
常用函数
left函数可以取database()的前1位,然后和s比较
截取数据库名的第一位,判断其ascii码是不是101
同上
截取
((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1)
的第1-1位并转为ascii码后做对比正则注入
基于报错的
rand + group by
原理是利用rand()*2重复计数和group by配合,导致临时表插入的主键重复以报错,不适用于表中只有2条数据以下的情况
标准payload
分析
payload和过程分析
count(*)计数,concat的是group by的对象,按对象取数据计数时建一个两列的临时表,group by对象即为主键
group by和rand()一起使用时,如果临时表中没有该主键,在插入前rand()会再计算一次
concat函数会拼合成security0或者security1,由于此处floor函数生成的前六个数是固定的011011,而在from表里取完数据并按group by的对象分组时,如果主键不存在临时表则会插入。
当从from表中取第一条记录的时候,此时group by的对象是concat函数聚合floor函数第一次计算值的security0,临时表中不存在此主键,将插入主键,但是注意,由于我们的语句是group by floor(rand(0)*2),所以插入的时候并不是直接插入security0,而是floor(rand(0)2),正是在这时候floor(rand(0)2)会再被计算一次,导致此时concat拼接出的是security1,其被插入临时表中作为主键,并count()计1
接着从from表取第二条记录,group by分组的对象是以concat聚合floor计算的第三个值security1,临时表中已存在此主键,所以只需将其count()+1
接着取from表第三条记录,group by的对象是第四次计算的security0,很明显,开始重复步骤1,至将主键security1插入临时表时,发现此主键已存在,于是报错主键重复,并在报错信息中抛出重复的主键,此主键即我们payload查询的记录
以此达到双注入
exp
Exp()为以e 为底的对数函数;版本在5.5.5 及其以上,当exp传入的参数为大于709的一个值的时候就会报错溢出
bigint
bigint取反溢出
extractvalue
mysql 对xml 数据进行查询和修改的xpath 函数,xpath 语法错误
解析
extractvalue(目标xml文档,xml路径)
函数的第二个参数是可以进行操作的地方,xml文件中查询使用的是/xx/xx/的格式,如果我们写成其他的格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法格式的内容就是我们想要查询的内容。
如果是正常的格式,即查询不到也不会报错
updatexml
mysql 对xml 数据进行查询和修改的xpath 函数,xpath 语法错误
解析
updatexml(目标xml文档,xml路径,更新的内容)
和extractvalue()相同的是都是对第二个参数进行操作的,通过构造非法格式的查询语句,来使其返回错误的信息,并将其更新出来。
重复
mysql 重复特性,此处重复了version,所以报错。
查询的内容需是定值(约束条件过于苛刻,可操作的内容极其少)
基于时间的
sleep
if 判断语句,条件为假,执行sleep
BENCHMARK
BENCHMARK(count,expr)用于测试函数的性能,参数一为次数,二为要执行的表达式。可以让函数执行若干次,返回结果比平时要长,通过时间长短的变化,判断语句是否执行成功。这是一种边信道攻击,在运行过程中占用大量的cpu 资源。推荐使用sleep()
文件操作
load_file()
load_file(file_name)读取文件并返回文件的内容作为一个字符串。
条件
- 必须有权限读取并且文件必须完全可读
测试权限:
如果返回正常说明具有读写权限,如果返回错误应该是管理员给数据库账户进行了降权
- 要读取的文件必须在服务器上
- 必须知道文件的绝对路径
- 读取的文件大小必须小于
max_allowed_packet
如果该文件不存在,或因为上面的任一原因而不能被读出,函数返回空。比较难满足的就是权限,在windows 下,如果NTFS 设置得当,是不能读取相关的文件的,当遇到只有administrators 才能访问的文件,users 就别想load_file 出来。
- 在实际的注入中,我们有两个难点需要解决:
- 绝对物理路径
- 构造有效的畸形语句(报错爆出绝对路径)
在很多PHP 程序中,当提交一个错误的Query,如果display_errors = on,程序就会暴露 WEB 目录的绝对路径,只要知道路径,那么对于一个可以注入的PHP 程序来说,整个服务器的安全将受到严重的威胁。
into outfile
可以把被选择的行写入到一个文件里,该文件会被创建到服务器主机上,因此必须拥有file权限才能使用此语法,且要写入的文件不能存在。
常用形式
- 直接将selct的内容写入文件
一句话木马
- 修改文件尾
宽字节注入
mysql 在使用GBK 编码的时候,会认为两个字符为一个汉字,例如%aa%5c 就是一个汉字(前一个ascii 码大于128 才能到汉字的范围)。我们在过滤’ 的时候,往往利用的思路是将‘ 转换为\’ (转换的函数或者思路会在每一关遇到的时候介绍)。
因此我们在此想办法将‘ 前面添加的\ 除掉,一般有两种思路:
- %df 吃掉\ 具体的原因是urlencode(‘\) = %5c%27,我们在%5c%27 前面添加%df,形成%df%5c%27,而上面提到的mysql 在GBK 编码方式的时候会将两个字节当做一个汉字,此事%df%5c 就是一个汉字,%27 则作为一个单独的符号在外面,同时也就达到了我们的目的。
- 将\’ 中的\ 过滤掉,例如可以构造%**%5c%5c%27 的情况,后面的%5c 会被前面的%5c给注释掉。这也是bypass 的一种方法。
常见问题解答
为什么要用id=-1?
为了使得原语句的搜索结果为空,使得后边我们想执行的语句的结果可以显示出来。
phpinfo()中应该重点观察哪些内容?
- 网站的真实ip(可以避开cdn)

- 网站的绝对路径

- 是否带有特殊服务(redis、memcache等)
- allow_url_include是否开启(该项如果开启,则支持远程文件包含,如果有存在文件包含的文件则可直接getshell,或可以使用php伪协议)

- disable_function是否开启 #该项表示禁用的函数名

- magic_quotes_gpc是否开启 #php5.4以下版本有的函数,默认开启,会对特殊字符进行转移
Loading...