一道有意思的CTF题目
2020-06-18 11:40:00 Author: www.4hou.com(查看原文) 阅读量:347 收藏

前言

近期在整理题目的时候,发现了一道质量不错的Web题,出自2019 TMCTF Final,特此记录一下。

信息搜集

题目描述:

Hack the following server.
http://10.0.106.(team number)/
User NamePassword
guestpassword
admin(Unknown)
Note: You do not have to use way of brute force or DoS to solve this challenge. Please do not put a load on bandwidth or disk space.

题目给了一个网站,具备以下2种功能:

upload:http://10.0.106.10/tmctf2019/upload.php
download:http://10.0.106.10/tmctf2019/download.php

对于上传,可以指定public / private上传,对于download也可以指定public / private下载,上传至public的文件,只能用download的public文件下载。

也就是说题目给了我们一个文件上传,一个文件下载,而对于目录的划分(public / private),现在看不出多大作用来。

随便测试了一通,发现文件上传时,会拼接sha256的后缀,例如上传:

1.jpg

得到的文件名会变为:

1.jpg_sha256(salt+'1.jpg')所以无法控制后缀,而尝试登陆功能注入和弱密码爆破登入也无法突破,无法将身份转换为admin,陷入僵局。

那么自然想到扫一扫目录,可以发现文件夹:

http://10.0.106.10/tmctf2019/include/

该文件夹并没有做权限控制,我们可以看到如下4个文件:

files.inc
functions.php
import_theme.inc
login.php

显然我们只能读取.inc文件,php文件会被解析无法直接访问源码。

import_theme.inc

2019-12-08-16-16-05.png

files.inc

2019-12-08-16-16-33.png

代码审计

既然有文件上传和文件下载,这势必是我们解题的主要突破口,故此审计了一下,发现:

2019-12-08-16-16-54.png

我们很难直接进行目录穿越,无论上传还是下载,都会在最后进行限制。

同时通过源码,我们可以发现还存在一个theme功能,但是需要admin授权:

check_login_session_admin();

但是该功能并没有相应的目录穿越限制:

2019-12-08-16-17-47.png

我们观察到会有解压7z的操作,这里不难想到软连接 / 写php后门,因为解压目录在web路径下。

但是这一切都需要我们先变成admin身份,否则将无法利用theme功能。

admin身份伪造

那么如何变成admin呢?我们注意到一个特别点:

session_save_path("/var/tmctf/");

题目将session文件都置于

/var/tmctf

而我们的上传目录位于:

2019-12-08-16-19-12.png

即如果我们上传到public,路径为:

/var/tmctf/public/

如果我们上传到private,则路径为:

/var/tmctf/private/guest/

但是有意思的是,对于我们的$attr,也就是public / private,并没有任何的限制,我们可以将其指定为:

.

这样我们的上传路径将变为:

/var/tmctf/./

即可和session文件共享目录,但是新的问题又来了,我们如何拿到session文件内容格式呢?

这里注意到download功能,其文件读取路径为:

2019-12-08-16-19-28.png

所以我们同理,可以将attr赋值为.,这样即可读取/var/tmctf目录下任意文件,而我们知道session文件格式为:

sess_phpsessid

故此,可以尝试读取session文件,可以发现文件内容为:

username|s:5:"guest";remote_addr|s:13:"192.168.10.27";

于是我们可以伪造session文件内容为:

username|s:5:"admin";remote_addr|s:13:"192.168.10.27";

2019-11-26-10-58-52.png

但是上传后,发现我们的文件名变为:

sess_d182e6417ac7068fb6e4788a44264ab61d5cc43a56f4f3796ffafb0d50bffsky_7470b54ce8e4f6016425b5113ae9425e7d6b6582cb6473e8b7e95278fd3e9e3e

也就意味着我们的phpsession id为:

d182e6417ac7068fb6e4788a44264ab61d5cc43a56f4f3796ffafb0d50bffsky_7470b54ce8e4f6016425b5113ae9425e7d6b6582cb6473e8b7e95278fd3e9e3e

但是phpsessionid中无法带入下划线,故此会触发报错:

Warning:  session_destroy(): Trying to destroy uninitialized session in /var/www/html/tmctf2019/include/functions.php on line 16

Warning:  Cannot modify header information - headers already sent by (output started at /var/www/html/tmctf2019/include/functions.php:16) in /var/www/html/tmctf2019/include/functions.php on line 17

那么我们该如何bypass sha256后缀拼接呢?

不难想到,我们可以上传sess文件名,拼接上后缀后,可以变为:

sess_7470b54ce8e4f6016425b5113ae9425e7d6b6582cb6473e8b7e95278fd3e9e3e

2019-11-26-10-59-26.png

那么这样,我们即可拿到不带无效字母的phpsessionid,读取验证:

2019-11-26-10-04-32.png

发现我们成功伪造了admin的sessionid,至此登入,我们可以变成admin,看见theme功能。

任意7z上传

拿到theme功能后,不容乐观,我们发现了新的问题:

2019-12-08-16-18-29.png

对于任意文件上传,后缀总会被拼接上sha256,我们上传的7z都会变成类似:

answer.7z_bab6c9f7fc17fbc85916afe883ac4cb5030e3089cc8086e71ef4669f9b5decc5

故此无法通过.7z拼接的文件存在check,同时00截断无效。

除此之外,我们发现管理员的private,出题人预留了一个answer.7z_bab6c9f7fc17fbc85916afe883ac4cb5030e3089cc8086e71ef4669f9b5decc5:

2019-11-26-10-10-34.png

下载解压后,发现是解密脚本:

2019-12-08-16-19-46.png

该压缩包的路径为:

/var/tmctf/private/admin/answer.7z_bab6c9f7fc17fbc85916afe883ac4cb5030e3089cc8086e71ef4669f9b5decc5

而我们目前的路径为

/usr/local/tmctf/theme/$theme.7z

但是无论如何控制$theme上跳,指定路径,都无法bypass .7z的后缀拼接。

那么如何上传出.7z结尾的文件,成为了难题。

回到上传点,我们分析路径构造:

2019-12-08-16-20-03.png

我们关注到,路径构造为

/var/tmctf/ + $attr + / + filename + _ + hash_file

我们可以如下方式bypass:

attr = skynb.7z

2019-11-26-11-00-01.png

这样得到的文件路径为

/var/tmctf/skynb.7z/ + filename + _ + hash_file

这样即可截断后面的hash_file拼接,构造出:

/var/tmctf/skynb.7z

我们再控制theme为:

theme = ../../../../../../../var/tmctf/skynb

2019-11-26-11-00-43.png

即可让服务端解压任意7z至目录:

/var/www/html/skins/css/theme/

同理,我们可以如法炮制,上传题目给的answer.7z,并让其解压至目录:

/var/www/html/skins/css/theme/

访问:

http://10.0.106.10/skins/css/theme/answer.php

却发现该目录无法解析php文件,同时尝试软连接读取密文:

ln -s /usr/local/tmctf/enc_data data
7za a exploit.7z pass data

但发现软连接都是403,无法读取。又陷入僵局。

命令注入

那么现在的问题非常明显,我们需要将answer.php解压至其他文件目录下,但是我们注意到源码中有拼接:

$cmd = '7za x '.$zipfile.' -y -o/var/www/html/skins/css/theme/';

已经将解压目录指定到了:

/var/www/html/skins/css/theme/

那么应该如何bypass呢?这里可以想到,我们可以利用`--`进行bypass:

2019-11-29-12-15-19.png

../../../../../../../var/tmctf/skynb.7z -y -o/var/www/html/tmctf2019/  e answer.php -- -o/../../../../../../../../../../../../../../../../../../usr/local/tmctf/theme/red

即可bypass目录指定,将answer.php放置于web目录下,此时访问:

http://10.0.106.10/tmctf2019/answer.php

即可拿到flag。

后记

这道题目出的真的蛮有意思的,趋势科技的题目真的质量不错,明年还要努努力,争取再去一次~

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


文章来源: https://www.4hou.com/posts/1QVG
如有侵权请联系:admin#unsafe.sh