这道题表面上是文件上传类型,我们先想办法获取源码
使用dirsearch进行目录扫描
dirsearch -u http://challenge-d3a1884e2249c619.sandbox.ctfhub.com:10800/ -e php
安装diesearch的方法
在kali中先apt-get update,等待反应后apt-get install dirsearch
选项 | 含义 |
---|---|
-u | 指定url |
-e | 语言 指定网站语言,一般用-e*即所有语言 |
-i | 保留响应状态码(不同状态码用逗号分隔,可指定范围,如-i 200,300-400) |
-x | 排除响应状态码(不同状态码用逗号分隔,可指定范围,如-x 400,400-500) |
-w | 指定字典 |
-r | 递归目录(即可扫描新扫描出的目录下的目录) |
-random-agents | 使用随机User-Agent |
<?php /* PHP Encode by http://Www.PHPJiaMi.Com/ */error_reporting(0);ini_set("display_errors", 0);if(!defined('jnggfmpt')){define('jnggfmpt',__FILE__);if(!function_exists("��������")){function ��������(&$������ꤸ��,$���������){$���Ň������=$��տ���=$������=$��������=$����Ե='�����';$�Å��=$���Ň������('E�����昤���');$ȻȚ���=$��տ���('E���F1�');$��������=$������('B��C1ޘ�E��B�A�');$�豓̗���=$��������('E���DEְ����Cβ�');$�ɿ���=$��������('B�5�C��A�A==');$ԡ�岖=$�Å��($ȻȚ���($��������($�豓̗���($����Ե('G��E63��8Τ�0�����A2��4�C����H�F0��2��3�؞�D���2�AA ���G0�02��H�����0�+�/�FB0���7DGD�F�HB�+���7��7���A����Ԝ��E�/�����8B�/7ؚ�H�ƒ��D39�F6/��/8��B�C1ܖ��/0�9��7�C�В�̬G��G�ʬA��7+�G��')))));$��������=$�ɿ���(',',$ԡ�岖);$������ꤸ��=$��������[$���������];}function ʬ������($������){global$���������,$������,$���������,$��ˎӑ�,$������,$���ߟ�,$���������,$������,$Ĩ����ƒ���,$��씮��,$¨��ɽ,$�凹�Ѭ�,$��������,$������,$�ə���,$������;$���Ň������=$��տ���=$������=$��������=$����Ե=$����ٱ挝=$�샥��=$�˱�������=$�ܜڎ�=$��躅�����=$�����=$���ѝ=$�Ѡ�ǰ��=$��髶=$ʲ�������='�����';$Ϝ�������=$���Ň������('E�5����F��0+DA����==');$����¬�����=$���Ň������('B�9�');$�����������=$���Ň������('A��');$с����=$���Ň������('D�9�F1���F�E');$����=$���Ň������('�1����==');$��ѫ�����=$���Ň������('A��B�==');$җ���Ҍ��=$���Ň������('A��E�==');$����������=$���Ň������('�Ԕ蜮�����1');$��ө����=$���Ň������('����3�2�ܪؔ�E=');$�����=$���Ň������('�C�0��0��ܪؔ�E=');$Ϝ�������()==$�����������?$����¬�����():'';$�ч����=$���������($���ߟ�($���Ň������('CA��A�8���A=')));if(!isset($_SERVER[$����������])&&!isset($_SERVER[$��ө����])&&!isset($_SERVER[$�����])){$����¬�����();};$��ѫ�����=$с����(true)*$����;eval("");if(($с����(true)*$����-$��ѫ�����)>100){$����¬�����();}eval($���Ň������('C�A�F�0���榦��6ư�9�D��Ь��F�CA�֬F�ΦE1�̤�ؚ��B��AήB�B���֢�0�='));!$¨��ɽ($ʲ�������($������($�ч����,$��տ���('�1��'),$������('�1�='))),$������($������($�ч����,$����Ե('��=='),$����ٱ挝('�1��'))))?$�˶�����():$��������;$聺�۶�ܥ=$�샥��('�1ƚ���=');$˞ء���=$�˱�������('�1��');$˞ء���=$��������(@$Ĩ����ƒ���($�����($������($�ч����,$聺�۶�ܥ,$˞ء���))));return$˞ء���;}function �����($Æ���,$���ញ�=''){$����Ÿ��='base64_decode';$������=$����Ÿ��('bWQ1');$�������̺�=$������('������');$�����̻=$����Ÿ��('b3Jk');$��������ƃ=$����Ÿ��('c3RybGVu');$����������=$����Ÿ��('Y2hy');$���ញ�=!$���ញ�?$�����̻('�'):$���ញ�;$���������=$θ����㺖;for(;$���������<$��������ƃ($Æ���);$���������++)$����Ⲵ��.=$�����̻($Æ���{$���������})<$�����̻('�')?(($�����̻($Æ���{$���������})>$���ញ�&&$�����̻($Æ���{$���������})<$�����̻('�'))?$����������($�����̻($Æ���{$���������})/2):$Æ���{$���������}):'';$˞ء���=$����Ÿ��($����Ⲵ��);$���������=$θ����㺖;$�����̻=$���˼ŗ�=$��������ƃ($�������̺�);for(;$���������<$��������ƃ($˞ء���);$���������++){$�����̻=$�����̻?$�����̻:$���˼ŗ�;$�����̻--;$������.=$˞ء���[$���������]^$�������̺�[$�����̻];}return$������;}}}global$���������,$����ʻ�Ү,$������,$���������,$������㽓,$��ˎӑ�,$������,$���ߟ�,$���������,$������,$Ĩ����ƒ���,$��씮��,$¨��ɽ,$�凹�Ѭ�,$��������,$������,$�ə���,$������;$��������=$���Ɨ�=$���排��=$�❇�亝�=$����˩���=$������=$ֻ������=$�����ߎ=$����������=$�����ߖ���=$�������ۿ=$���Ċ��έ�=$��ȁӢ=$ĥ������=$ŝʥ�������=$��=$�ӯ�Ԫ�����=$�Ȩ������=$��Å�����='��������';if(!$���������){$��������($���������,8);$���Ɨ�($������,9);$���排��($������,10);$�❇�亝�($Ĩ����ƒ���,4);$����˩���($��씮��,13);$������($¨��ɽ,12);$ֻ������($�凹�Ѭ�,2);$�����ߎ($��������,14);$����������($������,15);$�����ߖ���($�ə���,16);$�������ۿ($������,17);$���Ċ��έ�($���������,18);$��ȁӢ($������,19);$ĥ������($���ߟ�,11);$ŝʥ�������($��ˎӑ�,5);$��($���������,6);$�ӯ�Ԫ�����($����ʻ�Ү,1);$�Ȩ������($������,3);$��Å�����($������㽓,7);}$���Ň������=$��տ���=$������=$��������='�����';$������=$���Ň������('��B�');$˞ء���=ʬ������($$������);$�ə���($������($$������));$Ը���˽�=$������($˞ء���);eval($���Ň������('B�B�C�EG�E�E�F�6�1����B���H���C��6/�Դ��G18='));$������=$������;$�ə���($������($$������));return$������;?>G��ƚ좖�Μ�3�К����H¦�1�����A4�C�11䲢���C����0�Ԩ�2������+�Ԓ3F���ư�F4/�3�����C�5�5���+�9A��16��G��7�77�ĪH�ꔰ�ԚF̔��3���/�C2A��A�0��+5�1G���B�D�1��7�HFؤ⢦�A���87����6��9/��2Ȭ�60Ԩ���1�7�B�����1B���4�����AG�C8�0�Ҫ9̔ڜ���F700�Қ��ܰ+E4�7Ψ�52��BƬ691�9�ȠȜ�3F���Ԥ氨�3��7����813�����0��1�������ؔ�9�آ7F4ҞECܠ��������G2�Ī���D��C�EƜ��A5�8�֤����/D���H�ڪ��0��B�����0��4�¨��HD������F֜���B��1�����/�H�Ԣ�83�G�5��E��G�AH��5��D�ް��33����3��1��+C̘����6H�ަ�5�6���ʚ�6�C���958��A�976��E�47�/G6������ꬮ��A0�����FA��H������6E֬Ԛ�ؤ����7E7��1��C+�6�4��2��Ʈ���D�//��1�0B��8�����ʜ0̴�B��������8�3ʬ��/���3��H6�����B���䠦���E�0EAB0��6���B������FȚ�3�94��0�F��C72�27���D�55��D��ࢪȚ�2�����GB2��E����0��4D��Җ��̬�4�/1�E���������B�2�5G���G�̘������6��5C��0Ԝ/H�0֬�1�8�H��G�D�A��8����/���F���+�A9�44����5�+��1ʘD8����ஒ7�����֨�1Ę3��1�3������E����3C��C6�6�����ƴ7ȬC��9C���̚��A�G�1���֠�G�+Ҙ�E�/�5����C0��B5�2���1���ΤEF��H���1�9��A4�����Ḛ��55B�F��0���EH04��A�Ԛ�+ܔ7�䖪�C�5֦��+��87�̖���F���EG�Ƞ6D�����+9E�����8ڰ�2�7�0+�11����9��ި�AC430��+3H�31���Bܢ�7+G�25���B�4+E��E�1/�������ܘE+H����+خG殴���/�����F6��6�8��6ƪC�Ɩ�Eܪ���GA�Ԭ�7������6�3��6�ؖ�5H��8�447��40F�F����Ȱ�A�H��Cڲ��𢤰�İ���9�5A���1/3�������GG�6����ʠ8�3��Ψ���7�����CAܰ��B��9��Ē�����D�6��B�ʒ�4��5+���D����F���ޘ�¦�Bְ5�0��謞D���BG3F����6���E��̔�����8䲞1��35��5������/�9�9ܬ0���1��+6�����욨3�Ƣ9��A1�9ښ��9����5ؔ5�3�4�+����3A�̰�9�B��EAA�BB�BDؔ�B�E�BFȰ��Ȫ�A�CA�EG;
脚本获取
我们可以发现,源码使用了PHPjiami的方法,我们可以找脚本
从网上找到的脚本下载
https://vsalw.oss-cn-shanghai.aliyuncs.com/phpjiami.zip
解题过程
<?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
我们发现,需要从UploadFile.class.php文件里面获取后续
继续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
];
}
}
if(!in_array($filename[count($filename)-1], $this->allow_ext)) {
return $this->error('只允许上传图片文件');
}
$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;
这里我们发现,$this->field = $field,$field='upfile',所以存在绕过
利用上传数组upfile('1'->'jpg','0'->'php')
所以$filename[count($filename)-1]
取出的是jpgend($filename)
取出的是php
绕过达成
上传后使用蚁剑连接 获取flag(记录删了,借用)