preg_match(_all)的变量初始化问题 's

admin 2017年4月30日19:18:41评论231 views字数 2591阅读8分38秒阅读模式
摘要

author: 80vul-B
team:http://www.80vul.com
date:2009-04-27一 描叙php手册里:
—————————————————————————————–
int preg_match ( string pattern, string subject [, array matches [, int flags]] )

author: 80vul-B
team:http://www.80vul.com
date:2009-04-27

一 描叙

php手册里:
—————————————————————————————–
int preg_match ( string pattern, string subject [, array matches [, int flags]] )

在 subject 字符串中搜索与 pattern 给出的正则表达式相匹配的内容。
如果提供了 matches,则其会被搜索的结果所填充。$matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。
—————————————————————————————–

这个是一个应用比较多的函数,很多应用程序忘记对preg_match(_all)的变量进行初始化,导致安全漏洞.

二 分析

patch_match的部分源码:

PHP_FUNCTION(preg_match) {  php_do_pcre_match(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } ... // php_pcre.c static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ */ { ...  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ((global) ? "ssz|ll" : "ss|zll"), &regex, &regex_len,          &subject, &subject_len, &subpats, &flags, &start_offset) == FAILURE) {   RETURN_FALSE;  } // 调用zend_parse_parameters检查传入的参数,参数类型及格式限定为了ss|zll  // zend_API.c ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...) { ...  retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC); ... static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int flags TSRMLS_DC) { ...  while (num_args-- > 0) {   arg = (zval **) p - (arg_count-i);   if (*type_spec == '|') {    type_spec++;   }   if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) { // 调用zend_parse_arg检查每个参数的类型    return FAILURE;   } ... static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int quiet TSRMLS_DC) { ...  expected_type = zend_parse_arg_impl(arg_num, arg, va, spec TSRMLS_CC);  if (expected_type) {   if (!quiet && *expected_type) {    char *space;    char *class_name = get_active_class_name(&space TSRMLS_CC);     zend_error(E_WARNING, "%s%s%s() expects parameter %d to be %s, %s given",      class_name, space, get_active_function_name(TSRMLS_C), arg_num, expected_type,      zend_zval_type_name(*arg)); // 如果参数的类型非法,报错并导致zend_parse_parameters返回FAILURE   } ... static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec TSRMLS_DC) {  char *spec_walk = *spec;  char c = *spec_walk++; ...  switch (c) { ...   case 's':    {     char **p = va_arg(*va, char **);     int *pl = va_arg(*va, int *);     switch (Z_TYPE_PP(arg)) {      case IS_NULL:       if (return_null) {        *p = NULL;        *pl = 0;        break;       }       /* break omitted intentionally */       case IS_STRING:      case IS_LONG:      case IS_DOUBLE:      case IS_BOOL:       convert_to_string_ex(arg);       *p = Z_STRVAL_PP(arg);       *pl = Z_STRLEN_PP(arg);       break;       case IS_OBJECT:       if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) {        break;       }       case IS_ARRAY:      case IS_RESOURCE:      default:       return "string";     }    }    break; ...

// 由上面的代码可以看到如果传入preg_match的第一个或者第二个参数是一个数组或者资源类型的话,将会报错并返回false,这将导致如果使用第三个参数的话,该变量将不会被赋值

三 测试代码

<?php //preg_match.php?ipmatches[]=1111 $ip[]='1'; preg_match("/[/d/.]{7,15}/", $ip, $ipmatches); var_dump($ipmatches); ?>

四 实际应用

[SODB-2009-01]:Discuz!<5.50 preg_match()的变量$onlineipmatches未初始化漏洞
[http://www.80vul.com/dzvul/]

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2017年4月30日19:18:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   preg_match(_all)的变量初始化问题 'shttps://cn-sec.com/archives/44708.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息