php危险函数文章总结(一)
php危险函数文章总结(一)
因为被分配的任务是总结文章,所以就对一篇文章深深的研究了一下,以下基本都是对该下的文章的总结。
原文在这里
in_array()
in_array :(PHP 4, PHP 5, PHP 7)
功能 :检查数组中是否存在某个值
定义 : bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
在 $haystack 中搜索 $needle ,如果第三个参数 $strict 的值为 TRUE ,则 in_array() 函数会进行强检查,检查 $needle 的类型是否和 $haystack 中的相同。如果找到 $haystack,则返回 TRUE,否则返回 FALSE。
存在漏洞:
1. 上传漏洞(使用==)
原理:in_array()第三个参数默认为false。如果不进行设置,将会进行弱检查,即不会检查数据的类型。在校验的过程中,会自动选择性的进行强制类型转换,从而导致了弱类型的绕过。如:
in_array()函数检测上传文件时候,可未将第三个参数设置为true,从而导致攻击者构造文件名绕过服务端的检测。例如上传7shell.php在in_array()函数强制转换后变为7.php
例子:
<?php
$array = array(
'abc' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking -- return values are in comments
// First three make sense, last four do not
var_dump(in_array(null, $array)); // true 强制类型转换bool(false)
var_dump(in_array(false, $array)); // true //可以被强制类型转换为null
var_dump(in_array(765, $array)); // true
var_dump(in_array(763, $array)); // true 被强制类型转换为bool(true)
var_dump(in_array('egg', $array)); // true被强制类型转换为bool(true)
var_dump(in_array('hhh', $array)); // true被强制类型转换为bool(true)
var_dump(in_array(array(), $array)); // true被强制类型转换为bool(false) 和null
// Strict checking
var_dump(in_array(null, $array, true)); // true
var_dump(in_array(false, $array, true)); // true
var_dump(in_array(765, $array, true)); // true
var_dump(in_array(763, $array, true)); // false
var_dump(in_array('egg', $array, true)); // false
var_dump(in_array('hhh', $array, true)); // false
var_dump(in_array(array(), $array, true)); // false
?>
2、Sql注入
原理:与xss类似
$allow = array(1,true);
$payload = "1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));";
var_dump(in_array($a,$allow));
//转换为int(1)或 转换为bool(true) 从而绕过
修复建议:
可以看到这个漏洞的原因是弱类型比较问题,那么我们就可以使用强匹配进行修复。例如将 in_array() 函数的第三个参数设置为 true ,或者使用 intval() 函数将变量强转成数字,又或者使用正则匹配来处理变量。这里我将 in_array() 函数的第三个参数设置为 true ,并使用===
参考文献
http://www.mamicode.com/info-detail-2494382.html
https://blog.csdn.net/weixin_38230961/article/details/82142432
filter_var()
filter_var : (PHP 5 >= 5.2.0, PHP 7)
功能 : 使用特定的过滤器过滤一个变量
定义 : mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )
作用: filter_var() 函数通过指定的过滤器过滤一个变量。
返回值: 如果成功,则返回被过滤的数据。如果失败,则返回 FALSE。
fileter可选项:
FILTER_VALIDATE_URL 过滤器把值作为 URL 进行验证。
FILTER_FLAG_SCHEME_REQUIRED — 要求 URL 是 RFC 兼容 URL。(比如:http://example)
FILTER_FLAG_HOST_REQUIRED — 要求 URL 包含主机名(http://www.example.com)
FILTER_FLAG_PATH_REQUIRED — 要求 URL 在主机名后存在路径(比如:eg.com/example1/)
FILTER_FLAG_QUERY_REQUIRED — 要求 URL 存在查询字符串(比如:”eg.php?age=37")
存在的漏洞
1、xss漏洞
原理:
但是虽然是进行校验,在底层也是进行的正则匹配,因为验证的并不是非常严格,从而导致漏洞。如:
FILTER_VALIDATE_URL 过滤器把值作为 URL 进行验证。
只需要满足url格式,无论输入什么都满足,比如 abc://a 只要有这个格式,后边无论是什么都满足。所以导致了使用javascript中的伪协议
if(isset($_GET['url'])){
if($url = filter_var($_GET['url'],FILTER_VALIDATE_URL))
{
echo $url;
}else{
echo "this url is not allow";
}
}else{
echo "not found \$_GET['url']";
}
(PHP7.3.0+弃用)
FILTER_FLAG_SCHEME_REQUIRED - 要求 URL 是 RFC 兼容 URL(比如 http://example)
FILTER_FLAG_HOST_REQUIRED - 要求 URL 包含主机名(比如 http://www.example.com)
FILTER_FLAG_PATH_REQUIRED - 要求 URL 在域名后存在路径(比如 www.example.com/example1/test2/)
FILTER_FLAG_QUERY_REQUIRED - 要求 URL 存在查询字符串(比如 “example.php?name=Peter&age=37”)
伪协议绕过
例子 :
payload : ?url=javascript://comment%250aalert(1)
注:javascript后面的//是注释符,%25是url转义后的% ,所以%250a就是%0a,所以payload就成了javascript://comment
Alert(1)
参考文献
javascript绕过xss
同上
filter_var 函数()使用javascript伪协议绕过执行xss
关于filter_var函数弃用参数
2、ssrf漏洞
原理: 同样是因为filter_var基层的正则匹配不严格
<?php
if(filter_var($_GET['url'],FILTER_VALIDATE_URL)){
$r = parse_url($_GET['url']); print_r($r);
if(preg_match('/google.com$/', $r['host'])) {
echo exec('curl "'.$r['host'].'"',$a);
print_r($a);
}
else { echo "Error: Host not allowed"; }
}
else { echo "Error: Invalid URL"; } ?>
payload : http://127.0.0.1/test2.php?url=0://www.baidu.com$google.com(虽然话是这么说,但是我第一次弄,出来了。第二次再次尝试,却失败,哪里出错了呢?有大佬知道吗?)
解释:
其中可见过滤使用的是filter_var(URL,FILTER_VALIDATE_URL)+ parse_url(URL)+preg_match(’/google.com$/’, URL)+ file_get_contents(URL)
绕过正则匹配,只需要是以google.com结尾就OK了,所以这个时候就需要用到另外一个知识,如下:
许多URL方案中都有保留字符,保留字符都有特定含义。它们在URL的方案特定部分中的外观具有指定的语义。如果在一个方案中保留了与八位组相对应的字符,则该八位组必须被编码。除了字符“;”, “/”, “?”, “:”, “@”, “=” 和 “&” 被定义为保留字符,其余一律为不保留字符。
除了分层路径中的dot-segments之外,一般语法认为路径段不透明。 生成应用程序的URI通常使用段中允许的保留字符来分隔scheme-specific或者dereference-handler-specific子组件。 例如分号(“;”) 和等于(“=”) 保留字符通常用于分隔适用于该段的参数和参数值。 逗号(“,”) 保留字符通常用于类似目的。
例如,一个URI生产者可能使用一个段name;v=1.1来表示对“name”版本1.1的引用,而另一个可能使用诸如“name,1.1”的段来表示相同含义。参数类型可以由scheme-specific 语义来定义,但在大多数情况下,一个参数的语法是特定的URI引用算法的实现。
所以绕过的手段就成了
http://localhost/index.php?url=http://aaa@qq.com
http://localhost/index.php?url=http://demo.com&sec-redclub.com
http://localhost/index.php?url=http://demo.com?sec-redclub.com
http://localhost/index.php?url=http://demo.com/sec-redclub.com
http://localhost/index.php?url=demo://demo.com,sec-redclub.com
http://localhost/index.php?url=demo://demo.com:80;sec-redclub.com:80/
http://localhost/index.php?url=http://demo.com#sec-redclub.com
http://127.0.0.1/test/?1=data://google.com/123;base64,SSBsb3ZlIFBIUAo=
PS: 最后一个payload的#符号,请换成对应的url编码 %23
再配合http:// file:// test://绕过 filter_var 的 FILTER_VALIDATE_URL 过滤器,这就导致了SSRF
Payload:
http://127.0.0.1/test/index7.php?1=data://google.com/123;base64,PHNjcmlwdD5hbGVydCgnMScpOzwvc2NyaXB0Pg==
注:base64,<script>alert(‘1’);</script>
参考文献
https://blog.csdn.net/qq_33020901/article/details/79580531
http://www.52bug.cn/hkjs/4631.html
命令执行:
换汤不换药,以下是一个CTF题型 原文
Payload: windows:
http://127.0.0.1/exchange/filter_var/domo2.php?url=test://"|type=flag.php;||"sec-redclub.com
自己搭建的与上类似的命令执行
Payload:
127.0.0.1/test/index7.php?1=abc://whoami||;google.com
注: || 表示当前一句命令失败后才执行后面的语句
修复:
别过于信任filter_var对url,进行的判断,或者自己编写正则表达式进行匹配,另外注意避免同时使用 escapeshellcmd() 和 escapeshellarg() 函数对参数进行过滤
参考
https://xz.aliyun.com/t/2501#toc-5
http://www.am0s.com/functions/227.html
mail函数
php 内置函数 mail 所引发的命令执行漏洞。我们先看看 php 自带的 mail 函数的用法:
bool mail (
string $to ,
string $subject ,
string $message [,
string $additional_headers [,
string $additional_parameters ]]
)
其参数含义分别表示如下:
• to,指定邮件接收者,即接收人
• subject,邮件的标题
• message,邮件的正文内容
• additional_headers,指定邮件发送时其他的额外头部,如发送者From,抄送CC,隐藏抄送BCC
• additional_parameters,指定传递给发送程序sendmail的额外参数。
在Linux系统上, php 的 mail 函数在底层中已经写好了,默认调用 Linux 的 sendmail 程序发送邮件。而在额外参数( additional_parameters )中, sendmail 主要支持的选项有以下三种:
• -O option = value
QueueDirectory = queuedir 选择队列消息
• -X logfile
这个参数可以指定一个目录来记录发送邮件时的详细日志情况。
• -f from email
这个参数可以让我们指定我们发送邮件的邮箱地址。
下面这个样例中,我们使用 -X 参数指定日志文件,最终会在 /var/www/html/rce.php 中写入如下数据:
上一篇: IIS 网站 HTTP 转 HTTPS
下一篇: wordpress网站全站迁移