题目地址:https://buuoj.cn/challenges
解题思路
第一步:进入题目,一个登陆页面,输入语句1'or 1=1#
之后报错,尝试注册登录
第二步:了解网页业务流程
- 由于没有注册页面,在URL访问register.php进入到注册页面
- 注册后给一个超链接让我们去登陆
- 登陆后跳转到update页面,让我们输入手机号,邮箱,nikename以及上传一张照片
- 上传后给出一个提示,让我们访问profile页面,profile页面展示update输入的信息
第三步:代码审计
-
使用dirsearch扫描到www.zip目录,下载下来发现有class,config,index,profile,register,update
-
在class.php里面发现需要使用mysql操作
-
在config.php里面发现flag字段,但是为空,猜想因该是在mysql里面去查
-
在profile里面发现photo字段执行了file_get_contents操作,猜想从数据库查了后将flag存放在config,在使用photo获取config.php得到flag
-
在update里面发现photo就是在上传页面上选择的文件名,并引入了class.php执行函数update_profile,update_profile函数在class.php中执行filter函数,将’select’, ‘insert’, ‘update’, ‘delete’, 'where’字段变成hacker
-
可以看到在执行update_profile函数前,还将profile这个类进行了序列化。
第四步:构建漏洞
- 在第三步得出要让profile这个类的photo值为config.php,而photo的值我们无法指定,但是可以通过序列化之后的过滤函数让photo指向config
- 由于filter函数将’select’, ‘insert’, ‘update’, ‘delete’, 'where’字段变成hacker,出了where是五个字符,其他都是与hacker一样是6个字符,由此,可以得出序列化漏洞
- 由于profile.php中使用了反序列化,反序列化会按照序列化给的字符串长度读取键名与值,在经过filter函数是where值会变成hacker增加一个字符,导致序列化读取时出错
- 原本的序列化是:
O:4:"Test":4:{s:5:"phone";i:12345;s:5:"email";s:12:"12345@qq.com";s:8:"nikename";i:123;s:5:"photo";s:4:"xxxx";}
,而我们想要的是:O:4:"Test":4:{s:5:"phone";i:12345;s:5:"email";s:12:"12345@qq.com";s:8:"nikename";i:123;s:5:"photo";s:10:"config.php";}
需要将photo后的值修改,在nikename后面的值输入wherewheres:5:“photo”;s:10:“config.php”;},构成闭合,由于要添加s:5:"photo";s:10:"config.php";}
32个字符需要输入33个where,但是update对nikename的长度进行了限制
- 我们可以让nike变成数组来让过此限制,因为正则在处理数组是返回flase,false>10也会变成false从而绕过
- 由于输入了数组,而数组在序列化时增加了一个},所以nikename里面的是";}s:5:“photo”;s:10:“config.php”;}34个字符
第五步:获取flag
-
在update使用burpsuite抓包后修改流量包
-
提交后给出profile超链接
-
点击后,在img标签中发现base64编码
-
解码后得到flag