渗透学习之PHP--细节篇

1.1 任意代码执行

  • eval
  • assert
  • call_user_func

1.2 执行系统命令 

  • pcntl_exec
  • exec
  • passthru
  • popen
  • shell_exec
  • system
  • proc_open

 1.3 Magic函数

  • __construct() 构建对象的时被调用
  • __destruct() 销毁对象或脚本结束时被调用
  • __call() 调用不可访问或不存在的方法时被调用
  • __callStatic() 调用不可访问或不存在的静态方法时被调用
  • __get() 读取不可访问或不存在属性时被调用
  • __set() 给不可访问或不存在属性赋值时被调用
  • __isset() 对不可访问或不存在的属性调用 isset 或 empty() 时被调用
  • __unset() 对不可访问或不存在的属性进行 unset 时被调用
  • __sleep() 对象序列化时被调用
  • __wakeup() 对象反序列化时被调用,其中序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过wakeup的执行
  • __toString() 当一个类被转换成字符串时被调用
  • __invoke() 对象被以函数方式调用时被调用
  • __set_state() 调用 var_export() 导出类时被调用
  • __clone() 进行对象clone时被调用
  • __debugInfo() 调用 var_dump() 打印对象时被调用

1.4 文件相关敏感函数

  • move_uploaded_file
  • file_put_contents / file_get_contents
  • unlink
  • fopen / fgets

1.5 低精度

php中并不是用高精度来存储浮点数,而是用使用 IEEE 754 双精度格式,造成在涉及到浮点数比较的时候可能会出现预期之外的错误。 比如 php -r "var_dump(0.2+0.7==0.9);" 这行代码的输出是 bool(false) 而不是 bool(true)。这在一些情况下可能出现问题。

1.6 弱类型

如果使用 == 来判断相等,则会因为类型推断出现一些预料之外的行为,比如magic hash,指当两个md5值都是 0e[0-9]{30} 的时候,就会认为两个hash值相等。 另外在判断字符串和数字的时候,PHP会自动做类型转换,那么 1=="1a.php" 的结果会是true

另外在判断一些hash时,如果传入的是数组,返回值会为 NULL, 因此在判断来自网络请求的数据的哈希值时需要先判断数据类型。

同样的, strcmp() ereg() strpos() 这些函数在处理数组的时候也会异常,返回NULL

1.7 命令执行

preg_replace 第一个参数是//e的时候,第二个参数会被当作命令执行

1.8 截断

PHP字符存在截断行为,可以使用 ereg / %00 / iconv 等实现php字符截断的操作,从而触发漏洞。

1.9 变量覆盖

当使用 extract / parse_str 等函数时,或者使用php的 $$ 特性时,如果没有正确的调用,则可能使得用户可以任意修改变量。

1.10 php特性

  • php自身在解析请求的时候,如果参数名字中包含" "、"."、"["这几个字符,会将他们转换成下划线
  • 由于历史原因, urlencode 和RFC3896存在一定的不同,PHP另外提供了 rawurlencode 对RFC3896完成标准的实现

1.11 /tmp临时文件竞争

phpinfo可访问时,可以看到上传的临时文件的路径,从而实现LFI。