[HarekazeCTF2019]Avatar Uploader 1

符合pattern,随便弄个admin进去看看玄虚

 

根据要求传png图片后发现只是换了个头像,通过F12可以看到上传图片的位置

 

我在这里想是不是要伪造一个木马文件传入进去,但是感觉是白名单过滤,有点难搞,没有切入点,后面看wp的时候发现原题给了源码

<?php
error_reporting(0);

require_once('config.php');
require_once('lib/util.php');
require_once('lib/session.php');

$session = new SecureClientSession(CLIENT_SESSION_ID, SECRET_KEY);

// check whether file is uploaded
if (!file_exists($_FILES['file']['tmp_name']) || !is_uploaded_file($_FILES['file']['tmp_name'])) {
    error('No file was uploaded.');
}

// check file size
if ($_FILES['file']['size'] > 256000) {
    error('Uploaded file is too large.');
}

// check file type
$finfo = finfo_open(FILEINFO_MIME_TYPE);//获取文件MIME类型
$type = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if (!in_array($type, ['image/png'])) {
    error('Uploaded file is not PNG format.');
}

// check file width/height
$size = getimagesize($_FILES['file']['tmp_name']);
if ($size[0] > 256 || $size[1] > 256) {
    error('Uploaded image is too large.');
}
if ($size[2] !== IMAGETYPE_PNG) {
    // I hope this never happens...
    error('What happened...? OK, the flag for part 1 is: <code>' . getenv('FLAG1') . '</code>');
}

// ok
$filename = bin2hex(random_bytes(4)) . '.png';
move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_DIR . '/' . $filename);

$session->set('avatar', $filename);
flash('info', 'Your avatar has been successfully updated!');
redirect('/');

 其余代码看了没啥用,重要的是upload.php代码,可以看到flag的显示

if ($size[2] !== IMAGETYPE_PNG) {
    // I hope this never happens...
    error('What happened...? OK, the flag for part 1 is: <code>' . getenv('FLAG1') . '</code>');
}

它来源于getimagesize函数的返回值php getimagesize 函数 – 获取图像信息 | 菜鸟教程

在往上看有一个finfo_open函数使用finfo_file()函数检测上传图片的类型_weixin_33690367的博客-优快云博客

它可以检测图片的MIME值,通过文件头的十六进制来判断

学一下网上的getimagesize的代码实现

果然是一个返回图片信息的数组

索引 0 给出的是图像宽度的像素值
索引 1 给出的是图像高度的像素值
索引 2 给出的是图像的类型,返回的是数字,其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
索引 3 给出的是一个宽度和高度的字符串,可以直接用于 HTML 的 <image> 标签
索引 bits 给出的是图像的每种颜色的位数,二进制格式
索引 channels 给出的是图像的通道值,RGB 图像默认是 3
索引 mime 给出的是图像的 MIME 信息,此信息可以用来在 HTTP Content-type 头信息中发送正确的信息,如: header("Content-type: image/jpeg");

 现在思路就是

1、finfo_file()函数检测上传图片的类型是否是image/png,我们需要通过这个函数的检测,不然会返回error

2、getimagesize函数返回图片信息,第三个元素不能等于IMAGETYPE_PNG,也就是不能为3,因此我们需要绕过这个函数

又要是png图片,又不能是png图片,真是奇怪;因为finfo_file()函数是检测文件头十六进制的,因此我们要保存下来

打开多个png图片

 

可以看到第一行十六进制代表png图片(也就是IHDR及其之前,后面后空格不算),因此这一行我们不能动他 ,现在是关键怎么修改来绕过了getimagesize函数了,因为他要返回长宽高等一些信息,每个图片肯定不一样,但是第一行十六进制又都是一样的,因此我们知道不是根据第一行十六进制来判断的,是后面那一些数据

此时我有个想法将后面的数据打乱,让getimagesize函数无法识别

 可以看到图片已经损坏了,但是从本地测试出来还可以识别,看来删的不够多,继续删,

删了很多自然可以执行……我直接保存文件头部其余全给删除

执行失败,上传看看能不能行

 

之前做过一些题发现很多都是这些函数的,没想要细用起来竟然也有漏洞呀 

感谢其余的师傅的wp呀,我第一修改思路是做misc的时候找到十六进制对印的信息去修改,没想到直接全删了让它检测不到就行了,还是太菜了呀我哈哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值