CTFshow文件上传刷题

张开发
2026/5/8 18:39:43 15 分钟阅读

分享文章

CTFshow文件上传刷题
本来一开始是想打一个文件上传的靶场但是这个靶场搭的有问题然后一直修改也没有修改好所以就从CTFshow上面做题一.web151打开看到前台效验不可靠猜测是不是前端验证然后我想到禁用java但是发现禁用java后上传图片的按钮无法使用然后测试一下发现这里限制只能上传.png图片一种方法是上传一张.png图片然后用bp修改一下后缀成功上传然后用蚁剑连接然后我了解到的另一种方法是用开发者工具修改限制因为前端限制只能上传png文件因此修改png为php就可以直接上传php文件用蚁剑连接得到flag二.web152打开依旧看到相同的画面上传几个文件发现都无法成功然后使用开发者工具发现还是限制png但是这里不是简单的前端验证应该是对MIME类型进行检测因此我们可以使用抓包修改然后用蚁剑连接三.web153打开依旧看到相似的页面使用F12发现依旧是png文件使用抓包修改后缀发现依旧不能成功那么尝试一下使用配置文件发现可以上传再上传一下.png文件发现成功上传但是无法连接原因是.htaccess是Apache服务器的配置文件但是这里是Nginx服务器因此可以试一下使用另外一个配置文件.user.ini.user.ini不仅限于 Apache 服务器,同样适用于 Nginx 和 IIS 服务器,适用范围更广,只要服务器启用了 fastcgi 模式(在phpstudy中切换为 nts 模式即可让.user.ini配置文件生效)作用相当于在可执行的php文件 最开始或者最末尾 通过使用 auto_prepend_file包含在文件头 或者 auto_append_file包含在文件尾 来包含写入的文件当访问这个可执行文件时就会解析执行其中的php代码同时就会使用PHP解析这个包含的文件也就是说文件上传后保存的路径中需要存在可执行的php文件才能利用.user.ini我们开始已经知道上传的目录是upload那么我们访问一下upload看看能不能找到该目录下存在的可执行的PHP文件一般这个文件都是index.php文件页面显示nothing here其实也是暗示我们该目录下存在一个php文件该文件的内容是输出nothing here也就是说我们具备使用.user.ini配置文件的条件那么我们接下来就试一下然后上传我们写入了一句话木马的文件2.png但是这里我们使用蚁剑连接时要注意之前我们的url后面的是上传的文件地址但是使用.user.ini使用的是upload目录下的可执行的PHP文件因此这里要使用index.php来连接得到flag四.web154使用开发者工具打开发现依旧只能上传png那么试一下我们上一个题的2.png文件看看有什么提示提示文件内容不合规那么应该是对文件内容进行了检测然后去bp里测试一下发现她对?php进行了过滤尝试试一下大小写绕过发现可以上传但是.php后缀也被过滤了前面我们看到这里的服务器也是Nginx服务器默认配置通常只解析 .php 所以这里也不能用phtml来代替这里我是试了一下但是我们可以考虑使用.user.ini配置文件然后用蚁剑连接得到flag这里注意不能使用? ?来绕过?php ?过滤因为? ?依赖于 PHP 配置文件 php.ini 中的 short_open_tag 选项并且从PHP8.0开始short_open_tag配置项已经被移除我试过这个它用蚁剑连接不上五.web155依旧只能上传png文件先上传一个试试有什么提示提示文件类型不合规猜测应该也是检测了内容用抓包修改一下发现确实检测文件头并且这里过滤了php大小写也无法绕过试一下? ?它等价于?php echo ?然后再试一下配置文件试一下蚁剑连接得到flag六.web156依旧只能上传png文件直接去抓包里修改上传失败测试发现php被过滤了但是可以使用? ?代替然后还有 [ ] 被过滤了但是可以用{ }代替发现可以成功上传那么再试一下.user.ini配置文件蚁剑可以连接然后得到flag七.web157依旧是前端验证上传.png文件直接上传肯定是上传不了的去抓包里面测试一下发现过滤了php但是可以用?代替然后[ ] 和 { } 都被过滤了还有;这里可以了解一个函数 extract()函数 它是PHP的内置函数它的作用是把数组里的键名变成变量名它可以与compact函数配合使用compact() 可以根据变量名创建数组键值变成变量值$_POST是 PHP 的超全局变量它也是一个数组常用的一句话木马是?php eval($_POST[x]); ?就可以写成?php extract($_POST);eval($x); ?但是这里;被过滤了所以不能使用eval因为eval必须有;assert通常不需要但是这里是两句代码这两句代码直接需要;来分隔所以不能使用这个函数但是这里我们可以在文件里直接写入system(ls /)再上传.user.ini配置文件访问一下看是否执行了我们上传的文件访问一下html目录执行一下读取flag.php执行一下八.web158打开环境还是前端验证只能上传.png文件先上传然后去抓包里面修改测试一下发现过滤了php; [ ] { } 试一下使用上一关的语法发现可以上传试一下配置文件可不可以发现也能上传访问一下看是否执行了成功执行查看flag所在目录读取flag九.web159依旧是前端验证只能上传png文件然后我们还是去抓包里面修改先上传一个配置文件成功上传再看一下过滤了什么发现比上一题多过滤了一个( 因此这里我们就不能使用函数但是可以使用 PHP中的执行操作符成功上传看看有没有被执行成功执行读取flag十.web160依旧是上传.png文件然后在抓包里面修改发现php[ { ( 空格 ; 都被过滤了然后我想到了一个伪协议php://filter 伪协议它可以在读取或写入数据之前对其进行处理但是()被过滤了我们要通过什么来使用这个伪协议呢这里可以了解一下PHP的语言构造它们不需要括号其中包含构造可以用来与伪协议结合因为包含构造的核心功能是加载并执行指定路径的文件。PHP 的伪协议如 php://file://data:// 等本质上是一种特殊的“路径”或“流”它们告诉 PHP 如何获取要包含的内容。接下来就是构造伪协议因为flag一般是在/var/www/html目录下所以我们试一下直接构造试一下然后上传配置文件访问一下解码一下我看其他大佬的wp还有一种方法是日志文件包含Nginx Web 服务器的访问日志文件路径是/var/log/nginx/access.log这里log也被过滤了·因此也要用 . 拼接依旧先上传配置文件然后上传2.png文件访问一下看到成功回显代表我们的日志文件包含成功执行然后在最后看到User-Agent的内容那么我们试一下UA头注入试一下蚁剑连接十一.web161开发者工具查看一下依旧只能上传png文件直接去抓包里面修改但是这里我修改了很多次都显示报错哪怕只有一个都显示报错然后我解码报错信息意思是文件类型不合规然后MIME类型是正确的我猜测是不是检测了文件头试一下发现加上GIF89a之后可以使用??但是php([{; 空格log 都被过滤了试一下伪协议的方法成功上传再上传配置文件再访问一下解码一下也可以用日志包含的方法访问一下依旧是UA头使用UA头注入蚁剑成功连接读取flag十二.web162依旧直接去抓包里面修改然后发现这里比上一题多了一个 . 过滤因此无法使用伪协议拼接也不能使用日志包含这里看了其他大佬的wp要使用session注入这里涉及到session包含竞争它的核心原理是利用了 PHP 在处理文件上传时会将上传进度信息临时存储在 Session 文件中而攻击者通过“条件竞争”的手段在服务器删除这些临时文件之前通过文件包含漏洞将其作为 PHP 代码执行。条件竞争条件竞争也叫竞态条件是一个在并发编程中常见的概念。它指的是当一个系统的行为或最终结果依赖于多个事件发生的先后顺序或相对时间而这些顺序和时间又是不可控或无法预测时就可能出现意想不到的错误。条件竞争的核心原理是利用系统处理文件时的检查-使用时间差进行攻击这里有一个我找到的session包含竞争的脚本import requests import threading sessionrequests.session() sess1 #和png后面要包含文件的对应 url1http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/ # url1 用于触发 Session 写入 url2http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/upload # url2 用于触发文件包含或读取。 data1{ PHP_SESSION_UPLOAD_PROGRESS:?php system(tac ../f*);? } file{ file:1 #无所谓 } cookies{ PHPSESSID: sess } def write(): while True: r session.post(url1,datadata1,filesfile,cookiescookies) # 持续不断地向 url1 发送 POST 请求。 def read(): while True: r session.get(url2) # 持续不断地向 url2 发送 GET 请求。 if flag in r.text: print(r.text) threads [threading.Thread(targetwrite), threading.Thread(targetread)] #同时启动两个死循环线程利用高频请求增加攻击成功的概率。 for t in threads: t.start()先了解一下这个代码sess1作用是设置Session ID攻击者通过控制 Cookie 中的 PHPSESSID确保知道恶意代码会被写入哪个具体的文件例如 /tmp/sess_1。PHP Session Upload Progress PHP 有一个特性当 php.ini 中开启 session.upload_progress.enabled 时用户在上传文件的过程中PHP 会将上传进度信息POST 的内容序列化并写入 Session 文件中。这个Session文件通常位于 /tmp 目录下文件名为 sess_PHPSESSIDdata1POST数据file:伪造的文件上传字段。为了触发 session.upload_progress.enabled 机制必须发起一个 multipart/form-data 类型的 POST 请求所以需要包含一个文件字段内容无所谓。url1(写入端):这是触发 Session 文件写入的 URL。它必须是一个能接收POST请求的接口通常是文件上传功能。url2(读取/执行端):这是触发文件包含的 URL。它通常是一个存在文件包含漏洞LFI的页面这里的 url2 必须存在一个漏洞能够包含并执行 sess_1 文件中的代码。这里我们依旧要上传配置文件.user.ini再上传png文件png文件的内容就是包含sess_1文件然后运行脚本十三.web163依旧是png文件直接去抓包里修改发现依旧是把 . 过滤了试一下上一题的方法成功上传再上传一下png文件但是这里我访问upload目录却显示报错但是我一直无法解决这个报错我也找不到wp来解决十四.web164这里依旧是上传png文件但是我在抓包里修改了好几次都是显示文件类型不合规然后我试一下图片马发现可以上传成功但是上传成功后我们也无法上传.user.ini配置文件也无法执行里面的一句话木马查看图片也没有什么信息然后看了一下wp这个题是考二次渲染的由于之前没有了解过二次渲染因此我们先了解一下二次渲染1.二次渲染的概念二次渲染是指上传的文件如图片为了显示的更加规范尺寸、像素网站会对文件进行二次处理经过解码或转换可能导致其中的恶意代码失效。2.二次渲染的原理在PHP中二次渲染所涉及的函数包括imagecreatefromjpegimagecreatefromgif和imagecreatefrompng他们用于从不同格式的图像文件创建图像资源这些函数的核心功能是将图像文件加载到内存中并将其转换为一个图像资源resource以便后续进行图像处理操作。它们的工作流程如下文件读取函数首先打开指定的图像文件或 URL读取文件的内容。格式解析根据文件的格式JPEG、GIF 或 PNG函数解析文件的结构和数据。例如JPEG 文件使用 DCT离散余弦变换进行压缩而 PNG 文件使用无损压缩算法。创建图像资源解析完成后函数将图像数据存储在内存中并返回一个图像资源标识符。这个标识符是一个指向内存中图像数据的指针后续再通过图像处理函数如 imagejpeg()imagepng() 等将这个内存中的图片重新编码生成一个新的图片文件imagecreatefromjpeg、imagecreatfromgif 和 imagecreatfrompng 这些函数在加载图像文件时会对图像文件的内容进行解析和检查以确保文件是一个有效的图像文件并提取必要的信息以便后续操作。这些函数会检查进行文件格式验证图像元数据和图像数据如果文件格式不正确或文件损坏他们会返回 FALSE并可能触发错误或警告这些函数也会根据图像的尺寸和颜色信息为图像数据分配内存不同图片格式有不同的压缩方式和数据结构其绕过方式也不同GIF图片的压缩方式是无损压缩对于GIF格式可以利用文件结构GIF格式由文件头、多个图像/注释块和文件结束符组成。GD库在二次渲染时主要处理图像的像素数据而对于某些非关键数据块如注释扩展块或文件结束符;之后的内容则可能原封不动地保留因此对于GIF格式的我们可以将一句话木马插到渲染后不被修改的区域JPG图片的压缩方式也是无损压缩但是它的数据结构比GIF更复杂二次渲染会重组大部分数据块但某些特定块在特定条件下可能被保留。3.二次渲染的存在性判断1根据文件大小判断访问上传的文件地址重新下载下来查看文件大小是否发生改变2图片数据包将上传图片的发送包和访问文件地址的返回包发到burpsuite的compare模块查看是否存在差异3使用010Editor查看将图片下载下来后使用010Editor查看根据上面举的例子能判断出上传的文件已经经过二次渲染了他被改变了web164解题接下来就是绕过二次渲染其中一个方法是在010Editor的比较文件中尽量找地址相同且大小size相同的块在没有改变的地方插入我们的恶意代码灰色表示数据在这两个文件中完全一样红色表示不一样黄色表示只在原图有地址表示起始位置大小表示数据块长度但是这里的灰色部分都太短了我们无法将一句话木马写入然后这里我找到了一个脚本运行一下生成图片之后上传然后查看图片但是这里注入system(ls)时不能使用hackbar直接注入因为此时发送的包是GET包如果用hackbar直接发送它会忽略POST框里面的数据会回显示图片错误因此要去bp里面修改请求方式再上传看到一个flag.php文件读取一下十五.web165打开环境这次是上传jpg文件上传一个jpg文件然后上传成功后显示查看图片将图片保存下来查看一下发现大小改变了可能是存在二次渲染这个依旧找不到修改的地方因此我们要借助脚本但是肯定不能用上一题的png脚本要找一个jpg脚本

更多文章