考点
phpjiami
代码审计
工具
dirsearch
蚁剑
bp
phpjiami脚本
WP
扫目录
发现备份文件index.php.bak
下载并打开
备注显示通过phpjiami加密
phpjiami加密流程
加密流程:源码 -> 加密处理(压缩,替换,BASE64,转义)-> 安全处理(验证文件 MD5 值,限制
IP、限域名、限时间、防破解、防命令行调试)-> 加密程序成品,再简单的说:源码 + 加密外壳
代码分析破解
根据解密脚本(膜拜大佬orz)解码
步骤:
- 下载脚本
encode文件夹里放待解密的文件 文件格式恢复为.php
decode文件为明文 - 运行
php phpjiami.php
解码结果如下:
<?php
if($_FILES) {
include 'UploadFile.class.php';
$dist = 'upload';
$upload = new UploadFile($dist, 'upfile');
$data = $upload->upload();
}
?><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pwnhub6669</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Armata">
<link rel="stylesheet" href="assets/css/Responsive-feedback-form.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<div class="container" style="margin-top:51px;">
<div id="form-div" style="margin-right:50px;margin-left:50px;">
<form method="post" enctype="multipart/form-data">
<div class="form-group">
<div class="row">
<div class="col-md-12">
<h1 class="text-center" style="font-family:Armata, sans-serif;font-size:30px;"><strong>File Upload</strong></h1></div>
</div>
<hr id="hr" style="background-color:#c3bfbf;">
<?php if(!empty($upload)): ?>
<div class="row text-center">
<?php if(!empty($data)): ?>
<img src="<?=$dist.'/'.$data['filename']?>" alt="<?=$data['name']?>">
<?php else: ?>
<div class="col-xs-10 col-xs-offset-1">
<div class="alert alert-warning" role="alert"><?=$upload->error?></div>
</div>
<?php endif; ?>
</div>
<hr id="hr" style="background-color:#c3bfbf;">
<?php endif; ?>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
<p style="font-family:Armata, sans-serif;font-size:22px;">File Name</p>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
<input class="form-control" type="text" name="upfile" placeholder="默认使用文件名" style="font-size:15px;font-family:Armata, sans-serif;">
</div>
</div>
<div class="row" style="font-family:Armata, sans-serif;margin-top:10px;">
<div class="col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
<p style="font-family:Armata, sans-serif;font-size:22px;"><strong>File Upload</strong></p>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
<input type="file" name="upfile">
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
<p class="text-right" style="font-family:Armata, sans-serif;">Allow One Image File</p>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-5 col-sm-5 col-sm-offset-4 col-xs-9 col-xs-offset-1">
<button class="btn btn-warning" type="reset" style="font-family:Armata, sans-serif;font-size:14px;color:rgb(0,0,0);">Reset </button>
<button class="btn btn-success" type="submit" id="submit-btn" style="font-family:Armata, sans-serif;font-size:14px;color:rgb(0,0,0);">Submit </button>
</div>
</div>
</div>
</form>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
</body>
</html><?php
不放过蛛丝马迹
继续
http://AAAAA/UploadFile.class.php.bak
接下来解码得
<?php
class UploadFile {
public $error = '';
protected $field;
protected $allow_ext;
protected $allow_size;
protected $dist_path;
protected $new_path;
function __construct($dist_path, $field='upfile', $new_name='random', $allow_ext=['gif', 'jpg', 'jpeg', 'png'], $allow_size=102400)
{
$this->field = $field;
$this->allow_ext = $allow_ext;
$this->allow_size = $allow_size;
$this->dist_path = realpath($dist_path);
if ($new_name === 'random') {
$this->new_name = uniqid();
} elseif (is_string($new_name)) {
$this->new_name = $new_name;
} else {
$this->new_name = null;
}
}
protected function codeToMessage($code)
{
switch ($code) {
case UPLOAD_ERR_INI_SIZE:
$message = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
break;
case UPLOAD_ERR_FORM_SIZE:
$message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
break;
case UPLOAD_ERR_PARTIAL:
$message = "The uploaded file was only partially uploaded";
break;
case UPLOAD_ERR_NO_FILE:
$message = "No file was uploaded";
break;
case UPLOAD_ERR_NO_TMP_DIR:
$message = "Missing a temporary folder";
break;
case UPLOAD_ERR_CANT_WRITE:
$message = "Failed to write file to disk";
break;
case UPLOAD_ERR_EXTENSION:
$message = "File upload stopped by extension";
break;
default:
$message = "Unknown upload error";
break;
}
return $message;
}
protected function error($info)
{
$this->error = $info;
return false;
}
public function upload()
{
if(empty($_FILES[$this->field])) {
return $this->error('上传文件为空');
}
if(is_array($_FILES[$this->field]['error'])) {
return $this->error('一次只能上传一个文件');
}
if($_FILES[$this->field]['error'] != UPLOAD_ERR_OK) {
return $this->error($this->codeToMessage($_FILES[$this->field]['error']));
}
$filename = !empty($_POST[$this->field]) ? $_POST[$this->field] : $_FILES[$this->field]['name'];
if(!is_array($filename)) {
$filename = explode('.', $filename);
}
foreach ($filename as $name) {
if(preg_match('#[<>:"/\\|?*.]#is', $name)) {
return $this->error('文件名中包含非法字符');
}
}
if($_FILES[$this->field]['size'] > $this->allow_size) {
return $this->error('你上传的文件太大');
}
if(!in_array($filename[count($filename)-1], $this->allow_ext)) {
return $this->error('只允许上传图片文件');
}
// 用.分割文件名,只保留首尾两个字符串,防御Apache解析漏洞
$origin_name = current($filename);
$ext = end($filename);
$new_name = ($this->new_name ? $this->new_name : $origin_name) . '.' . $ext;
$target_fullpath = $this->dist_path . DIRECTORY_SEPARATOR . $new_name;
// 创建目录
if(!is_dir($this->dist_path)) {
mkdir($this->dist_path);
}
if(is_uploaded_file($_FILES[$this->field]['tmp_name']) && move_uploaded_file($_FILES[$this->field]['tmp_name'], $target_fullpath)) {
// Success upload
} elseif (rename($_FILES[$this->field]['tmp_name'], $target_fullpath)) {
// Success upload
} else {
return $this->error('写入文件失败,可能是目标目录不可写');
}
return [
'name' => $origin_name,
'filename' => $new_name,
'type' => $ext
];
}
}
核心:
存在绕过
利用上传数组upfile('1'->'jpg','0'->'php')
所以$filename[count($filename)-1]
取出的是jpg
end($filename)
取出的是php
绕过达成
playload
request
response
蚁剑连接