一来就试了一下sql注入 无
然后找到一个register.php 的页面 那边有个上传 也无上传漏洞
dirsearch 添加延时参数 找到www.zip 下载下来得到源码
拿到源码 class.php config.php index.php profile.php register.php update.php
config.php 那边有flag 从那边应该可以拿到flag
update.php 这边正则匹配了 过滤提交的数据 但是判断nickname那边有长度限制可以用nickname的数组来绕过长度限制就不会die
png29 这边用到了serialize() 可以试一下反序列化
前面
有个update_profile 到class.php 看一下update_profile 的定义方法
1 | public function update_profile($username, $new_profile) { |
再往下有个filter()
1 | public function filter($string) { |
update()
1 | public function update($table, $key, $value, $where) { |
update.php 就先正则表达式将提交的参数值过滤 再序列化将非法字符替换成hacker
这反序列化还有文件读取
flag在config中 这边有序列化 过滤替换 反序列化 文件读取
就是反序列化字符逃逸 构造包含config.php的数据利用字符串逃逸 再在profile.php中读取得到
反序列化是以”;}结束的 把这个往前放置 就可以将反序列化提前结束的内容就丢弃了
突破口:
反序列化字符逃逸,首先序列化的字符是可控的 前面的长度是可控的 但是update.php将参数序列化,可控变量的长度就被写死了
要控制得通过序列化后数据过滤替代那边
1 | public function filter($string) { |
select insert update delete where替换成hacker 写入where替换成hacker 字符串长度+1 因此实际的长的都大于序列化固定长度
i:0;s:3:”123”; -> 就是类似于s:后面这个值 反序列化字符串的逃逸,反序列化只能将nickname的s长度反序列化成功其他的长度已经被写死了, 剩下的字符串 构造class.php因为里面包含了flag 并将其位置放到photo上然后将photo扔掉
这样profile.php 中读取的photo就是我么构造的config.php 就能拿到flag了
假设:
构造这样一个 defg会被丢弃qwert占了原本的位置
目的是将”;}s:5:photo;s:10:”config.php”;} 这串总共34位 插入到序列化的字符串中
hacker比where多一个字符那就得需要挤出34位 也就是34个where 上传后再去profile查看内容
payload :wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere”;}s:5:photo;s:10:”config.php”;}
profile.php 那边查看源码 base64解码一下就可以了