1. 题目环境与初步观察
拿到这道BabySQli题目时,我首先用Burp Suite抓取了HTTP请求包。在测试过程中发现,无论输入什么用户名和密码,响应中都包含一段奇怪的编码字符串。这段编码看起来像是Base家族的一员,但具体是哪种还需要进一步测试。
我注意到注释中的这段编码:MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5。这种长度和字符组合很典型地符合Base32编码特征。于是我先尝试用Base32解码,果然得到了一段新的编码:c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==。
看到末尾的两个等号,这明显是Base64编码的标志。继续用Base64解码后,终于露出了庐山真面目:select * from user where username = '$name'。这个发现非常关键,它直接暴露了后端执行的SQL查询语句结构。
2. SQL注入类型判断
从解码得到的SQL语句可以看出,用户输入的$name参数直接被拼接到了查询中,这明显存在SQL注入漏洞。为了确定注入类型,我进行了以下测试:
输入1时,系统正常响应;输入1'时,页面返回了数据库错误信息。这个现象明确告诉我们,这是一个字符型注入漏洞,因为单引号破坏了原始SQL语句的语法结构。
接着尝试经典的万能密码:1' or '1'='1,但发现这个payload被拦截了。这说明系统可能对某些关键词进行了过滤。于是我改用更简单的测试方式,先猜测常见用户名,比如admin,同时观察系统反应。
3. 字段数与关键位置探测
为了构造有效的联合查询,我需要先确定查询返回的字段数量。通过逐步增加union select后的字段数进行测试:
1' union select 1,2# → 报错 1' union select 1,2,3# → 正常返回测试结果显示原始查询返回3个字段。接下来需要确定这些字段在前端页面的显示位置,以及admin用户可能所在的列:
1' union select 'admin',2,3# → 检查admin是否在第一列 1' union select 1,'admin',3# → 成功返回特定内容通过这种测试,不仅确认了admin用户存在,还确定了用户名字段在第二列。这个信息对后续构造payload至关重要。
4. 源码分析与认证机制突破
查看search.php的源码后,发现了关键的认证逻辑:
if($arr[1] == "admin"){ if(md5($password) == $arr[2]){ echo $flag; } else{ die("wrong pass!"); } }这段代码揭示了三件事:
- 用户数据表的第二列是用户名
- 第三列存储的是密码的MD5值
- 认证时会将用户输入的密码进行MD5加密后与存储值比较
这意味着我们需要构造一个查询结果,使得:
- 第二列值为'admin'
- 第三列值为已知密码的MD5哈希
5. 最终Payload构造与Flag获取
基于以上分析,我构造了如下payload:
1'union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#这里'e10adc3949ba59abbe56e057f20f883e'是'123456'的MD5值。当这个payload被执行时:
- 原始查询因条件不匹配返回空结果
- union查询返回我们构造的记录
- 系统检查到第二列是admin
- 将用户输入的密码'123456'进行MD5加密
- 比较后发现与第三列值匹配
- 最终返回flag:flag{3c7be44e-df35-40a7-bd91-1b210bf75fcb}
这个题目巧妙地将Base编码、SQL注入和MD5认证机制结合在一起,考察了选手的多方面技能。在实际操作中,关键在于逐步解码隐藏信息、准确判断注入类型、合理猜测数据结构,最终构造出符合认证逻辑的有效payload。