进来只有一个登录框
查看页面源代码,没重要东西
看题目BabySqli,应该是sql注入的问题
尝试一下登录框,发现username内容是可见的,password内容是不可见的
为了方便,就注入username,因为输入的内容可见
先用sql万能密码注入试试
1' or 1=1 #
密码随便输.
提交登录
提示不给万能密码登录
观察这是一个新的页面,显示是search.php
养成习惯,查看页面源代码(每个页面的页面源代码都不同)
这回发现了有用的
有时候有用的甚至关键的信息就是放在页面源代码里的,不是第一个页面,就是进一步的第二,第三个页面,容易被忽视,让我们被卡死,解决这个问题的办法就是养成习惯用bp抓包,bp里面Request和Response页面都会将页面源码和回显内容一起返回,不容易忽视源码中藏着的注释信息
接着看这个注释信息,
MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5
全是字母,又没有==的base64特征,那么首先猜是base32加密的
在线网站base32解密
结果是:
c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==
"=="结尾,明显的base64特征,果断拿去base64解密
结果
select * from user where username = '$name'
这是在告诉我们后端sql查询逻辑,注入点是name
因为username框注入的是name,所以我们前面注入用户名框是正确的,是注入点(带入数据库中查询)
密码框可能就不是注入点(内容不带入数据库中查询)
知道注入点在usename,知道是单引号注入,那就开始构建语句吧
先用联合查询查询字段数(列数)
1' union select 1,2,3#
回显wrong user,但是没有说字段数错误,这应该是另一个问题,用户错误的问题
先继续搞定字段数的问题,再解决这个用户的问题
加一个字段,这次查询4个字段,1' union select 1,2,3,4# 返回
Error: The used SELECT statements have a different number of columns
说明是字段数错误,说明这个数据库只有3列数据,字段数为3,
接着我们要解决wrong user的问题了,
发现当1' union select 1,2,3#改为admin' union select 1,2,3#时,这个wrong user就不会出现了,而是出现wrong pass了,也就是后端有可能会判断我们传入的sql语句,判断里面有没有admin,admin可能是正确的用户名,他只需要我们语句里面有admin就行了,
那wrong pass又是什么呢?猜测应该是指pw的值错误,尝试数组绕过pw的值
pw[]=1
还是提示wrong pass,此外还提示了md5(),应该是指pass的值得是md5值?
到这里实在不会了,没思路
正解:
利用sqli的特性:当联合查询并不存在的数据时,联合查询会构造一个虚拟的数据在数据库当中
比如联合查询之前,数据库是这样子的
执行联合查询:
select * from 'users' where name='person' union select 1,'admin','e10adc3949ba59abbe56057f20f883e',4,5
执行后数据库:
按照我们的输入,sqli在数据库中写入数据,相当于伪造了一个身份,就可以用这个身份登录了
相当于我们伪造了一条数据
id=1,name=admin,password=e10adc3949ba59abbe56057f20f883e,photo=4,money=5
当数据库中没有这条数据时,执行联合查询,就会将查询的值用来创建这条数据
我们现在知道对方数据库里的字段数是3,即只有3列数据
那根据刚刚的wrong user和wrong pass,猜测其中有两列分别是user和pass,即用户名和密码,剩下一列可能是id,或者其他,反正影响也不大,最重要的是user和pass这两列,因为这两列的值会检测,不对的时候会报错
那就猜测3个字段是id,user,pass先吧
但是我们不知道他们的顺序,即有可能是user,pass,id
可以通过测试来判断顺序
返回wrong user,说明第一个字段(第一列)不是放用户名的地方,即不是user
放第二列看看
报错变为wrong pass,说明第二列放的是user,只不过pass有误
pass的值是我们可以控制的,传入md5值就好
将123的md5值202CB962AC59075B964B07152D234B70传进去,
后面试了下发现他后台对md5值的大小写敏感,大写不能过,小写才能过
用小写吧 ,123的小写md5 32位加密是202cb962ac59075b964b07152d234b70
当我们联合查询注入1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#的时候,对方数据库就已经产生了以下的数据了
id | user | pass |
1 | admin | 202cb962ac59075b964b07152d234b70 |
这个时候再与运算这个密码123,即&pw=123,就能登陆这个新创建的用户admin了,
这道题登陆成功后就会回显flag 像这样
疑问解决:
为什么#后面的内容pw=1不会被注释?
因为在网址栏中#只是单纯的字符,带入数据库中才是注释作用,但是name带入数据库,pw不带入,所以name中的#不会注释pw